@sortsys/ui 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +38 -0
- package/dist/dev.js +2022 -0
- package/dist/dev.jsx +3489 -0
- package/dist/index.d.ts +367 -0
- package/dist/index.js +2022 -0
- package/dist/index.jsx +1601 -0
- package/package.json +93 -0
package/dist/dev.jsx
ADDED
|
@@ -0,0 +1,3489 @@
|
|
|
1
|
+
// src/components/SSButton.tsx
|
|
2
|
+
function SSButton(props) {
|
|
3
|
+
const classes = () => [
|
|
4
|
+
"ss_button",
|
|
5
|
+
props.isIconOnly ? "ss_button--icon" : "",
|
|
6
|
+
props.class ?? ""
|
|
7
|
+
].filter(Boolean).join(" ");
|
|
8
|
+
return <button
|
|
9
|
+
type={props.type ?? "button"}
|
|
10
|
+
class={classes()}
|
|
11
|
+
disabled={props.disabled}
|
|
12
|
+
aria-label={props.ariaLabel}
|
|
13
|
+
form={props.form}
|
|
14
|
+
onclick={props.onclick}
|
|
15
|
+
>
|
|
16
|
+
{props.children}
|
|
17
|
+
</button>;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// src/components/SSCallout.tsx
|
|
21
|
+
function SSCallout(props) {
|
|
22
|
+
const { icon, color, class: className2, style: style2, children: children3, ...rest } = props;
|
|
23
|
+
return <div
|
|
24
|
+
{...rest}
|
|
25
|
+
class={`ss_callout ss_callout--${color} ${className2 ?? ""}`}
|
|
26
|
+
style={style2}
|
|
27
|
+
>
|
|
28
|
+
<span class="ss_callout__icon">
|
|
29
|
+
{icon}
|
|
30
|
+
</span>
|
|
31
|
+
<div class="ss_callout__content">
|
|
32
|
+
<span>{children3}</span>
|
|
33
|
+
</div>
|
|
34
|
+
</div>;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// src/components/SSChip.tsx
|
|
38
|
+
function SSChip(props) {
|
|
39
|
+
const commonClass = `ss_chip ss_chip--${props.color ?? "blue"} ${props.class ?? ""}`;
|
|
40
|
+
if ("onclick" in props && props.onclick) {
|
|
41
|
+
return <button
|
|
42
|
+
type="button"
|
|
43
|
+
class={`${commonClass} ss_chip--clickable`}
|
|
44
|
+
style={props.style}
|
|
45
|
+
onclick={props.onclick}
|
|
46
|
+
>
|
|
47
|
+
<span class="ss_chip__label">{props.children}</span>
|
|
48
|
+
</button>;
|
|
49
|
+
}
|
|
50
|
+
return <div class={commonClass} style={props.style}>
|
|
51
|
+
<span class="ss_chip__label">{props.children}</span>
|
|
52
|
+
{"ondismiss" in props && props.ondismiss && <button
|
|
53
|
+
type="button"
|
|
54
|
+
class="ss_chip__dismiss"
|
|
55
|
+
aria-label="Entfernen"
|
|
56
|
+
onclick={props.ondismiss}
|
|
57
|
+
>
|
|
58
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon icon-tabler icons-tabler-outline icon-tabler-x"><path stroke="none" d="M0 0h24v24H0z" fill="none" /><path d="M18 6l-12 12" /><path d="M6 6l12 12" /></svg>
|
|
59
|
+
</button>}
|
|
60
|
+
</div>;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// node_modules/solid-js/dist/solid.js
|
|
64
|
+
var sharedConfig = {
|
|
65
|
+
context: void 0,
|
|
66
|
+
registry: void 0,
|
|
67
|
+
effects: void 0,
|
|
68
|
+
done: false,
|
|
69
|
+
getContextId() {
|
|
70
|
+
return getContextId(this.context.count);
|
|
71
|
+
},
|
|
72
|
+
getNextContextId() {
|
|
73
|
+
return getContextId(this.context.count++);
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
function getContextId(count) {
|
|
77
|
+
const num = String(count), len = num.length - 1;
|
|
78
|
+
return sharedConfig.context.id + (len ? String.fromCharCode(96 + len) : "") + num;
|
|
79
|
+
}
|
|
80
|
+
function setHydrateContext(context) {
|
|
81
|
+
sharedConfig.context = context;
|
|
82
|
+
}
|
|
83
|
+
var IS_DEV = false;
|
|
84
|
+
var equalFn = (a, b) => a === b;
|
|
85
|
+
var $PROXY = /* @__PURE__ */ Symbol("solid-proxy");
|
|
86
|
+
var SUPPORTS_PROXY = typeof Proxy === "function";
|
|
87
|
+
var $TRACK = /* @__PURE__ */ Symbol("solid-track");
|
|
88
|
+
var signalOptions = {
|
|
89
|
+
equals: equalFn
|
|
90
|
+
};
|
|
91
|
+
var ERROR = null;
|
|
92
|
+
var runEffects = runQueue;
|
|
93
|
+
var STALE = 1;
|
|
94
|
+
var PENDING = 2;
|
|
95
|
+
var UNOWNED = {
|
|
96
|
+
owned: null,
|
|
97
|
+
cleanups: null,
|
|
98
|
+
context: null,
|
|
99
|
+
owner: null
|
|
100
|
+
};
|
|
101
|
+
var NO_INIT = {};
|
|
102
|
+
var Owner = null;
|
|
103
|
+
var Transition = null;
|
|
104
|
+
var Scheduler = null;
|
|
105
|
+
var ExternalSourceConfig = null;
|
|
106
|
+
var Listener = null;
|
|
107
|
+
var Updates = null;
|
|
108
|
+
var Effects = null;
|
|
109
|
+
var ExecCount = 0;
|
|
110
|
+
function createRoot(fn, detachedOwner) {
|
|
111
|
+
const listener = Listener, owner = Owner, unowned = fn.length === 0, current = detachedOwner === void 0 ? owner : detachedOwner, root = unowned ? UNOWNED : {
|
|
112
|
+
owned: null,
|
|
113
|
+
cleanups: null,
|
|
114
|
+
context: current ? current.context : null,
|
|
115
|
+
owner: current
|
|
116
|
+
}, updateFn = unowned ? fn : () => fn(() => untrack(() => cleanNode(root)));
|
|
117
|
+
Owner = root;
|
|
118
|
+
Listener = null;
|
|
119
|
+
try {
|
|
120
|
+
return runUpdates(updateFn, true);
|
|
121
|
+
} finally {
|
|
122
|
+
Listener = listener;
|
|
123
|
+
Owner = owner;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
function createSignal(value, options) {
|
|
127
|
+
options = options ? Object.assign({}, signalOptions, options) : signalOptions;
|
|
128
|
+
const s = {
|
|
129
|
+
value,
|
|
130
|
+
observers: null,
|
|
131
|
+
observerSlots: null,
|
|
132
|
+
comparator: options.equals || void 0
|
|
133
|
+
};
|
|
134
|
+
const setter = (value2) => {
|
|
135
|
+
if (typeof value2 === "function") {
|
|
136
|
+
if (Transition && Transition.running && Transition.sources.has(s)) value2 = value2(s.tValue);
|
|
137
|
+
else value2 = value2(s.value);
|
|
138
|
+
}
|
|
139
|
+
return writeSignal(s, value2);
|
|
140
|
+
};
|
|
141
|
+
return [readSignal.bind(s), setter];
|
|
142
|
+
}
|
|
143
|
+
function createComputed(fn, value, options) {
|
|
144
|
+
const c = createComputation(fn, value, true, STALE);
|
|
145
|
+
if (Scheduler && Transition && Transition.running) Updates.push(c);
|
|
146
|
+
else updateComputation(c);
|
|
147
|
+
}
|
|
148
|
+
function createRenderEffect(fn, value, options) {
|
|
149
|
+
const c = createComputation(fn, value, false, STALE);
|
|
150
|
+
if (Scheduler && Transition && Transition.running) Updates.push(c);
|
|
151
|
+
else updateComputation(c);
|
|
152
|
+
}
|
|
153
|
+
function createEffect(fn, value, options) {
|
|
154
|
+
runEffects = runUserEffects;
|
|
155
|
+
const c = createComputation(fn, value, false, STALE), s = SuspenseContext && useContext(SuspenseContext);
|
|
156
|
+
if (s) c.suspense = s;
|
|
157
|
+
if (!options || !options.render) c.user = true;
|
|
158
|
+
Effects ? Effects.push(c) : updateComputation(c);
|
|
159
|
+
}
|
|
160
|
+
function createMemo(fn, value, options) {
|
|
161
|
+
options = options ? Object.assign({}, signalOptions, options) : signalOptions;
|
|
162
|
+
const c = createComputation(fn, value, true, 0);
|
|
163
|
+
c.observers = null;
|
|
164
|
+
c.observerSlots = null;
|
|
165
|
+
c.comparator = options.equals || void 0;
|
|
166
|
+
if (Scheduler && Transition && Transition.running) {
|
|
167
|
+
c.tState = STALE;
|
|
168
|
+
Updates.push(c);
|
|
169
|
+
} else updateComputation(c);
|
|
170
|
+
return readSignal.bind(c);
|
|
171
|
+
}
|
|
172
|
+
function isPromise(v) {
|
|
173
|
+
return v && typeof v === "object" && "then" in v;
|
|
174
|
+
}
|
|
175
|
+
function createResource(pSource, pFetcher, pOptions) {
|
|
176
|
+
let source;
|
|
177
|
+
let fetcher;
|
|
178
|
+
let options;
|
|
179
|
+
if (typeof pFetcher === "function") {
|
|
180
|
+
source = pSource;
|
|
181
|
+
fetcher = pFetcher;
|
|
182
|
+
options = pOptions || {};
|
|
183
|
+
} else {
|
|
184
|
+
source = true;
|
|
185
|
+
fetcher = pSource;
|
|
186
|
+
options = pFetcher || {};
|
|
187
|
+
}
|
|
188
|
+
let pr = null, initP = NO_INIT, id = null, loadedUnderTransition = false, scheduled = false, resolved = "initialValue" in options, dynamic = typeof source === "function" && createMemo(source);
|
|
189
|
+
const contexts = /* @__PURE__ */ new Set(), [value, setValue] = (options.storage || createSignal)(options.initialValue), [error, setError] = createSignal(void 0), [track, trigger] = createSignal(void 0, {
|
|
190
|
+
equals: false
|
|
191
|
+
}), [state, setState] = createSignal(resolved ? "ready" : "unresolved");
|
|
192
|
+
if (sharedConfig.context) {
|
|
193
|
+
id = sharedConfig.getNextContextId();
|
|
194
|
+
if (options.ssrLoadFrom === "initial") initP = options.initialValue;
|
|
195
|
+
else if (sharedConfig.load && sharedConfig.has(id)) initP = sharedConfig.load(id);
|
|
196
|
+
}
|
|
197
|
+
function loadEnd(p, v, error2, key) {
|
|
198
|
+
if (pr === p) {
|
|
199
|
+
pr = null;
|
|
200
|
+
key !== void 0 && (resolved = true);
|
|
201
|
+
if ((p === initP || v === initP) && options.onHydrated) queueMicrotask(() => options.onHydrated(key, {
|
|
202
|
+
value: v
|
|
203
|
+
}));
|
|
204
|
+
initP = NO_INIT;
|
|
205
|
+
if (Transition && p && loadedUnderTransition) {
|
|
206
|
+
Transition.promises.delete(p);
|
|
207
|
+
loadedUnderTransition = false;
|
|
208
|
+
runUpdates(() => {
|
|
209
|
+
Transition.running = true;
|
|
210
|
+
completeLoad(v, error2);
|
|
211
|
+
}, false);
|
|
212
|
+
} else completeLoad(v, error2);
|
|
213
|
+
}
|
|
214
|
+
return v;
|
|
215
|
+
}
|
|
216
|
+
function completeLoad(v, err) {
|
|
217
|
+
runUpdates(() => {
|
|
218
|
+
if (err === void 0) setValue(() => v);
|
|
219
|
+
setState(err !== void 0 ? "errored" : resolved ? "ready" : "unresolved");
|
|
220
|
+
setError(err);
|
|
221
|
+
for (const c of contexts.keys()) c.decrement();
|
|
222
|
+
contexts.clear();
|
|
223
|
+
}, false);
|
|
224
|
+
}
|
|
225
|
+
function read() {
|
|
226
|
+
const c = SuspenseContext && useContext(SuspenseContext), v = value(), err = error();
|
|
227
|
+
if (err !== void 0 && !pr) throw err;
|
|
228
|
+
if (Listener && !Listener.user && c) {
|
|
229
|
+
createComputed(() => {
|
|
230
|
+
track();
|
|
231
|
+
if (pr) {
|
|
232
|
+
if (c.resolved && Transition && loadedUnderTransition) Transition.promises.add(pr);
|
|
233
|
+
else if (!contexts.has(c)) {
|
|
234
|
+
c.increment();
|
|
235
|
+
contexts.add(c);
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
});
|
|
239
|
+
}
|
|
240
|
+
return v;
|
|
241
|
+
}
|
|
242
|
+
function load(refetching = true) {
|
|
243
|
+
if (refetching !== false && scheduled) return;
|
|
244
|
+
scheduled = false;
|
|
245
|
+
const lookup = dynamic ? dynamic() : source;
|
|
246
|
+
loadedUnderTransition = Transition && Transition.running;
|
|
247
|
+
if (lookup == null || lookup === false) {
|
|
248
|
+
loadEnd(pr, untrack(value));
|
|
249
|
+
return;
|
|
250
|
+
}
|
|
251
|
+
if (Transition && pr) Transition.promises.delete(pr);
|
|
252
|
+
let error2;
|
|
253
|
+
const p = initP !== NO_INIT ? initP : untrack(() => {
|
|
254
|
+
try {
|
|
255
|
+
return fetcher(lookup, {
|
|
256
|
+
value: value(),
|
|
257
|
+
refetching
|
|
258
|
+
});
|
|
259
|
+
} catch (fetcherError) {
|
|
260
|
+
error2 = fetcherError;
|
|
261
|
+
}
|
|
262
|
+
});
|
|
263
|
+
if (error2 !== void 0) {
|
|
264
|
+
loadEnd(pr, void 0, castError(error2), lookup);
|
|
265
|
+
return;
|
|
266
|
+
} else if (!isPromise(p)) {
|
|
267
|
+
loadEnd(pr, p, void 0, lookup);
|
|
268
|
+
return p;
|
|
269
|
+
}
|
|
270
|
+
pr = p;
|
|
271
|
+
if ("v" in p) {
|
|
272
|
+
if (p.s === 1) loadEnd(pr, p.v, void 0, lookup);
|
|
273
|
+
else loadEnd(pr, void 0, castError(p.v), lookup);
|
|
274
|
+
return p;
|
|
275
|
+
}
|
|
276
|
+
scheduled = true;
|
|
277
|
+
queueMicrotask(() => scheduled = false);
|
|
278
|
+
runUpdates(() => {
|
|
279
|
+
setState(resolved ? "refreshing" : "pending");
|
|
280
|
+
trigger();
|
|
281
|
+
}, false);
|
|
282
|
+
return p.then((v) => loadEnd(p, v, void 0, lookup), (e) => loadEnd(p, void 0, castError(e), lookup));
|
|
283
|
+
}
|
|
284
|
+
Object.defineProperties(read, {
|
|
285
|
+
state: {
|
|
286
|
+
get: () => state()
|
|
287
|
+
},
|
|
288
|
+
error: {
|
|
289
|
+
get: () => error()
|
|
290
|
+
},
|
|
291
|
+
loading: {
|
|
292
|
+
get() {
|
|
293
|
+
const s = state();
|
|
294
|
+
return s === "pending" || s === "refreshing";
|
|
295
|
+
}
|
|
296
|
+
},
|
|
297
|
+
latest: {
|
|
298
|
+
get() {
|
|
299
|
+
if (!resolved) return read();
|
|
300
|
+
const err = error();
|
|
301
|
+
if (err && !pr) throw err;
|
|
302
|
+
return value();
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
});
|
|
306
|
+
let owner = Owner;
|
|
307
|
+
if (dynamic) createComputed(() => (owner = Owner, load(false)));
|
|
308
|
+
else load(false);
|
|
309
|
+
return [read, {
|
|
310
|
+
refetch: (info) => runWithOwner(owner, () => load(info)),
|
|
311
|
+
mutate: setValue
|
|
312
|
+
}];
|
|
313
|
+
}
|
|
314
|
+
function untrack(fn) {
|
|
315
|
+
if (!ExternalSourceConfig && Listener === null) return fn();
|
|
316
|
+
const listener = Listener;
|
|
317
|
+
Listener = null;
|
|
318
|
+
try {
|
|
319
|
+
if (ExternalSourceConfig) return ExternalSourceConfig.untrack(fn);
|
|
320
|
+
return fn();
|
|
321
|
+
} finally {
|
|
322
|
+
Listener = listener;
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
function onMount(fn) {
|
|
326
|
+
createEffect(() => untrack(fn));
|
|
327
|
+
}
|
|
328
|
+
function onCleanup(fn) {
|
|
329
|
+
if (Owner === null) ;
|
|
330
|
+
else if (Owner.cleanups === null) Owner.cleanups = [fn];
|
|
331
|
+
else Owner.cleanups.push(fn);
|
|
332
|
+
return fn;
|
|
333
|
+
}
|
|
334
|
+
function getListener() {
|
|
335
|
+
return Listener;
|
|
336
|
+
}
|
|
337
|
+
function getOwner() {
|
|
338
|
+
return Owner;
|
|
339
|
+
}
|
|
340
|
+
function runWithOwner(o, fn) {
|
|
341
|
+
const prev = Owner;
|
|
342
|
+
const prevListener = Listener;
|
|
343
|
+
Owner = o;
|
|
344
|
+
Listener = null;
|
|
345
|
+
try {
|
|
346
|
+
return runUpdates(fn, true);
|
|
347
|
+
} catch (err) {
|
|
348
|
+
handleError(err);
|
|
349
|
+
} finally {
|
|
350
|
+
Owner = prev;
|
|
351
|
+
Listener = prevListener;
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
function startTransition(fn) {
|
|
355
|
+
if (Transition && Transition.running) {
|
|
356
|
+
fn();
|
|
357
|
+
return Transition.done;
|
|
358
|
+
}
|
|
359
|
+
const l = Listener;
|
|
360
|
+
const o = Owner;
|
|
361
|
+
return Promise.resolve().then(() => {
|
|
362
|
+
Listener = l;
|
|
363
|
+
Owner = o;
|
|
364
|
+
let t;
|
|
365
|
+
if (Scheduler || SuspenseContext) {
|
|
366
|
+
t = Transition || (Transition = {
|
|
367
|
+
sources: /* @__PURE__ */ new Set(),
|
|
368
|
+
effects: [],
|
|
369
|
+
promises: /* @__PURE__ */ new Set(),
|
|
370
|
+
disposed: /* @__PURE__ */ new Set(),
|
|
371
|
+
queue: /* @__PURE__ */ new Set(),
|
|
372
|
+
running: true
|
|
373
|
+
});
|
|
374
|
+
t.done || (t.done = new Promise((res) => t.resolve = res));
|
|
375
|
+
t.running = true;
|
|
376
|
+
}
|
|
377
|
+
runUpdates(fn, false);
|
|
378
|
+
Listener = Owner = null;
|
|
379
|
+
return t ? t.done : void 0;
|
|
380
|
+
});
|
|
381
|
+
}
|
|
382
|
+
var [transPending, setTransPending] = /* @__PURE__ */ createSignal(false);
|
|
383
|
+
function createContext(defaultValue, options) {
|
|
384
|
+
const id = /* @__PURE__ */ Symbol("context");
|
|
385
|
+
return {
|
|
386
|
+
id,
|
|
387
|
+
Provider: createProvider(id),
|
|
388
|
+
defaultValue
|
|
389
|
+
};
|
|
390
|
+
}
|
|
391
|
+
function useContext(context) {
|
|
392
|
+
let value;
|
|
393
|
+
return Owner && Owner.context && (value = Owner.context[context.id]) !== void 0 ? value : context.defaultValue;
|
|
394
|
+
}
|
|
395
|
+
function children(fn) {
|
|
396
|
+
const children3 = createMemo(fn);
|
|
397
|
+
const memo2 = createMemo(() => resolveChildren(children3()));
|
|
398
|
+
memo2.toArray = () => {
|
|
399
|
+
const c = memo2();
|
|
400
|
+
return Array.isArray(c) ? c : c != null ? [c] : [];
|
|
401
|
+
};
|
|
402
|
+
return memo2;
|
|
403
|
+
}
|
|
404
|
+
var SuspenseContext;
|
|
405
|
+
function readSignal() {
|
|
406
|
+
const runningTransition = Transition && Transition.running;
|
|
407
|
+
if (this.sources && (runningTransition ? this.tState : this.state)) {
|
|
408
|
+
if ((runningTransition ? this.tState : this.state) === STALE) updateComputation(this);
|
|
409
|
+
else {
|
|
410
|
+
const updates = Updates;
|
|
411
|
+
Updates = null;
|
|
412
|
+
runUpdates(() => lookUpstream(this), false);
|
|
413
|
+
Updates = updates;
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
if (Listener) {
|
|
417
|
+
const sSlot = this.observers ? this.observers.length : 0;
|
|
418
|
+
if (!Listener.sources) {
|
|
419
|
+
Listener.sources = [this];
|
|
420
|
+
Listener.sourceSlots = [sSlot];
|
|
421
|
+
} else {
|
|
422
|
+
Listener.sources.push(this);
|
|
423
|
+
Listener.sourceSlots.push(sSlot);
|
|
424
|
+
}
|
|
425
|
+
if (!this.observers) {
|
|
426
|
+
this.observers = [Listener];
|
|
427
|
+
this.observerSlots = [Listener.sources.length - 1];
|
|
428
|
+
} else {
|
|
429
|
+
this.observers.push(Listener);
|
|
430
|
+
this.observerSlots.push(Listener.sources.length - 1);
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
if (runningTransition && Transition.sources.has(this)) return this.tValue;
|
|
434
|
+
return this.value;
|
|
435
|
+
}
|
|
436
|
+
function writeSignal(node, value, isComp) {
|
|
437
|
+
let current = Transition && Transition.running && Transition.sources.has(node) ? node.tValue : node.value;
|
|
438
|
+
if (!node.comparator || !node.comparator(current, value)) {
|
|
439
|
+
if (Transition) {
|
|
440
|
+
const TransitionRunning = Transition.running;
|
|
441
|
+
if (TransitionRunning || !isComp && Transition.sources.has(node)) {
|
|
442
|
+
Transition.sources.add(node);
|
|
443
|
+
node.tValue = value;
|
|
444
|
+
}
|
|
445
|
+
if (!TransitionRunning) node.value = value;
|
|
446
|
+
} else node.value = value;
|
|
447
|
+
if (node.observers && node.observers.length) {
|
|
448
|
+
runUpdates(() => {
|
|
449
|
+
for (let i = 0; i < node.observers.length; i += 1) {
|
|
450
|
+
const o = node.observers[i];
|
|
451
|
+
const TransitionRunning = Transition && Transition.running;
|
|
452
|
+
if (TransitionRunning && Transition.disposed.has(o)) continue;
|
|
453
|
+
if (TransitionRunning ? !o.tState : !o.state) {
|
|
454
|
+
if (o.pure) Updates.push(o);
|
|
455
|
+
else Effects.push(o);
|
|
456
|
+
if (o.observers) markDownstream(o);
|
|
457
|
+
}
|
|
458
|
+
if (!TransitionRunning) o.state = STALE;
|
|
459
|
+
else o.tState = STALE;
|
|
460
|
+
}
|
|
461
|
+
if (Updates.length > 1e6) {
|
|
462
|
+
Updates = [];
|
|
463
|
+
if (IS_DEV) ;
|
|
464
|
+
throw new Error();
|
|
465
|
+
}
|
|
466
|
+
}, false);
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
return value;
|
|
470
|
+
}
|
|
471
|
+
function updateComputation(node) {
|
|
472
|
+
if (!node.fn) return;
|
|
473
|
+
cleanNode(node);
|
|
474
|
+
const time = ExecCount;
|
|
475
|
+
runComputation(node, Transition && Transition.running && Transition.sources.has(node) ? node.tValue : node.value, time);
|
|
476
|
+
if (Transition && !Transition.running && Transition.sources.has(node)) {
|
|
477
|
+
queueMicrotask(() => {
|
|
478
|
+
runUpdates(() => {
|
|
479
|
+
Transition && (Transition.running = true);
|
|
480
|
+
Listener = Owner = node;
|
|
481
|
+
runComputation(node, node.tValue, time);
|
|
482
|
+
Listener = Owner = null;
|
|
483
|
+
}, false);
|
|
484
|
+
});
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
function runComputation(node, value, time) {
|
|
488
|
+
let nextValue;
|
|
489
|
+
const owner = Owner, listener = Listener;
|
|
490
|
+
Listener = Owner = node;
|
|
491
|
+
try {
|
|
492
|
+
nextValue = node.fn(value);
|
|
493
|
+
} catch (err) {
|
|
494
|
+
if (node.pure) {
|
|
495
|
+
if (Transition && Transition.running) {
|
|
496
|
+
node.tState = STALE;
|
|
497
|
+
node.tOwned && node.tOwned.forEach(cleanNode);
|
|
498
|
+
node.tOwned = void 0;
|
|
499
|
+
} else {
|
|
500
|
+
node.state = STALE;
|
|
501
|
+
node.owned && node.owned.forEach(cleanNode);
|
|
502
|
+
node.owned = null;
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
node.updatedAt = time + 1;
|
|
506
|
+
return handleError(err);
|
|
507
|
+
} finally {
|
|
508
|
+
Listener = listener;
|
|
509
|
+
Owner = owner;
|
|
510
|
+
}
|
|
511
|
+
if (!node.updatedAt || node.updatedAt <= time) {
|
|
512
|
+
if (node.updatedAt != null && "observers" in node) {
|
|
513
|
+
writeSignal(node, nextValue, true);
|
|
514
|
+
} else if (Transition && Transition.running && node.pure) {
|
|
515
|
+
Transition.sources.add(node);
|
|
516
|
+
node.tValue = nextValue;
|
|
517
|
+
} else node.value = nextValue;
|
|
518
|
+
node.updatedAt = time;
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
function createComputation(fn, init, pure, state = STALE, options) {
|
|
522
|
+
const c = {
|
|
523
|
+
fn,
|
|
524
|
+
state,
|
|
525
|
+
updatedAt: null,
|
|
526
|
+
owned: null,
|
|
527
|
+
sources: null,
|
|
528
|
+
sourceSlots: null,
|
|
529
|
+
cleanups: null,
|
|
530
|
+
value: init,
|
|
531
|
+
owner: Owner,
|
|
532
|
+
context: Owner ? Owner.context : null,
|
|
533
|
+
pure
|
|
534
|
+
};
|
|
535
|
+
if (Transition && Transition.running) {
|
|
536
|
+
c.state = 0;
|
|
537
|
+
c.tState = state;
|
|
538
|
+
}
|
|
539
|
+
if (Owner === null) ;
|
|
540
|
+
else if (Owner !== UNOWNED) {
|
|
541
|
+
if (Transition && Transition.running && Owner.pure) {
|
|
542
|
+
if (!Owner.tOwned) Owner.tOwned = [c];
|
|
543
|
+
else Owner.tOwned.push(c);
|
|
544
|
+
} else {
|
|
545
|
+
if (!Owner.owned) Owner.owned = [c];
|
|
546
|
+
else Owner.owned.push(c);
|
|
547
|
+
}
|
|
548
|
+
}
|
|
549
|
+
if (ExternalSourceConfig && c.fn) {
|
|
550
|
+
const [track, trigger] = createSignal(void 0, {
|
|
551
|
+
equals: false
|
|
552
|
+
});
|
|
553
|
+
const ordinary = ExternalSourceConfig.factory(c.fn, trigger);
|
|
554
|
+
onCleanup(() => ordinary.dispose());
|
|
555
|
+
const triggerInTransition = () => startTransition(trigger).then(() => inTransition.dispose());
|
|
556
|
+
const inTransition = ExternalSourceConfig.factory(c.fn, triggerInTransition);
|
|
557
|
+
c.fn = (x) => {
|
|
558
|
+
track();
|
|
559
|
+
return Transition && Transition.running ? inTransition.track(x) : ordinary.track(x);
|
|
560
|
+
};
|
|
561
|
+
}
|
|
562
|
+
return c;
|
|
563
|
+
}
|
|
564
|
+
function runTop(node) {
|
|
565
|
+
const runningTransition = Transition && Transition.running;
|
|
566
|
+
if ((runningTransition ? node.tState : node.state) === 0) return;
|
|
567
|
+
if ((runningTransition ? node.tState : node.state) === PENDING) return lookUpstream(node);
|
|
568
|
+
if (node.suspense && untrack(node.suspense.inFallback)) return node.suspense.effects.push(node);
|
|
569
|
+
const ancestors = [node];
|
|
570
|
+
while ((node = node.owner) && (!node.updatedAt || node.updatedAt < ExecCount)) {
|
|
571
|
+
if (runningTransition && Transition.disposed.has(node)) return;
|
|
572
|
+
if (runningTransition ? node.tState : node.state) ancestors.push(node);
|
|
573
|
+
}
|
|
574
|
+
for (let i = ancestors.length - 1; i >= 0; i--) {
|
|
575
|
+
node = ancestors[i];
|
|
576
|
+
if (runningTransition) {
|
|
577
|
+
let top = node, prev = ancestors[i + 1];
|
|
578
|
+
while ((top = top.owner) && top !== prev) {
|
|
579
|
+
if (Transition.disposed.has(top)) return;
|
|
580
|
+
}
|
|
581
|
+
}
|
|
582
|
+
if ((runningTransition ? node.tState : node.state) === STALE) {
|
|
583
|
+
updateComputation(node);
|
|
584
|
+
} else if ((runningTransition ? node.tState : node.state) === PENDING) {
|
|
585
|
+
const updates = Updates;
|
|
586
|
+
Updates = null;
|
|
587
|
+
runUpdates(() => lookUpstream(node, ancestors[0]), false);
|
|
588
|
+
Updates = updates;
|
|
589
|
+
}
|
|
590
|
+
}
|
|
591
|
+
}
|
|
592
|
+
function runUpdates(fn, init) {
|
|
593
|
+
if (Updates) return fn();
|
|
594
|
+
let wait = false;
|
|
595
|
+
if (!init) Updates = [];
|
|
596
|
+
if (Effects) wait = true;
|
|
597
|
+
else Effects = [];
|
|
598
|
+
ExecCount++;
|
|
599
|
+
try {
|
|
600
|
+
const res = fn();
|
|
601
|
+
completeUpdates(wait);
|
|
602
|
+
return res;
|
|
603
|
+
} catch (err) {
|
|
604
|
+
if (!wait) Effects = null;
|
|
605
|
+
Updates = null;
|
|
606
|
+
handleError(err);
|
|
607
|
+
}
|
|
608
|
+
}
|
|
609
|
+
function completeUpdates(wait) {
|
|
610
|
+
if (Updates) {
|
|
611
|
+
if (Scheduler && Transition && Transition.running) scheduleQueue(Updates);
|
|
612
|
+
else runQueue(Updates);
|
|
613
|
+
Updates = null;
|
|
614
|
+
}
|
|
615
|
+
if (wait) return;
|
|
616
|
+
let res;
|
|
617
|
+
if (Transition) {
|
|
618
|
+
if (!Transition.promises.size && !Transition.queue.size) {
|
|
619
|
+
const sources = Transition.sources;
|
|
620
|
+
const disposed = Transition.disposed;
|
|
621
|
+
Effects.push.apply(Effects, Transition.effects);
|
|
622
|
+
res = Transition.resolve;
|
|
623
|
+
for (const e2 of Effects) {
|
|
624
|
+
"tState" in e2 && (e2.state = e2.tState);
|
|
625
|
+
delete e2.tState;
|
|
626
|
+
}
|
|
627
|
+
Transition = null;
|
|
628
|
+
runUpdates(() => {
|
|
629
|
+
for (const d of disposed) cleanNode(d);
|
|
630
|
+
for (const v of sources) {
|
|
631
|
+
v.value = v.tValue;
|
|
632
|
+
if (v.owned) {
|
|
633
|
+
for (let i = 0, len = v.owned.length; i < len; i++) cleanNode(v.owned[i]);
|
|
634
|
+
}
|
|
635
|
+
if (v.tOwned) v.owned = v.tOwned;
|
|
636
|
+
delete v.tValue;
|
|
637
|
+
delete v.tOwned;
|
|
638
|
+
v.tState = 0;
|
|
639
|
+
}
|
|
640
|
+
setTransPending(false);
|
|
641
|
+
}, false);
|
|
642
|
+
} else if (Transition.running) {
|
|
643
|
+
Transition.running = false;
|
|
644
|
+
Transition.effects.push.apply(Transition.effects, Effects);
|
|
645
|
+
Effects = null;
|
|
646
|
+
setTransPending(true);
|
|
647
|
+
return;
|
|
648
|
+
}
|
|
649
|
+
}
|
|
650
|
+
const e = Effects;
|
|
651
|
+
Effects = null;
|
|
652
|
+
if (e.length) runUpdates(() => runEffects(e), false);
|
|
653
|
+
if (res) res();
|
|
654
|
+
}
|
|
655
|
+
function runQueue(queue) {
|
|
656
|
+
for (let i = 0; i < queue.length; i++) runTop(queue[i]);
|
|
657
|
+
}
|
|
658
|
+
function scheduleQueue(queue) {
|
|
659
|
+
for (let i = 0; i < queue.length; i++) {
|
|
660
|
+
const item = queue[i];
|
|
661
|
+
const tasks = Transition.queue;
|
|
662
|
+
if (!tasks.has(item)) {
|
|
663
|
+
tasks.add(item);
|
|
664
|
+
Scheduler(() => {
|
|
665
|
+
tasks.delete(item);
|
|
666
|
+
runUpdates(() => {
|
|
667
|
+
Transition.running = true;
|
|
668
|
+
runTop(item);
|
|
669
|
+
}, false);
|
|
670
|
+
Transition && (Transition.running = false);
|
|
671
|
+
});
|
|
672
|
+
}
|
|
673
|
+
}
|
|
674
|
+
}
|
|
675
|
+
function runUserEffects(queue) {
|
|
676
|
+
let i, userLength = 0;
|
|
677
|
+
for (i = 0; i < queue.length; i++) {
|
|
678
|
+
const e = queue[i];
|
|
679
|
+
if (!e.user) runTop(e);
|
|
680
|
+
else queue[userLength++] = e;
|
|
681
|
+
}
|
|
682
|
+
if (sharedConfig.context) {
|
|
683
|
+
if (sharedConfig.count) {
|
|
684
|
+
sharedConfig.effects || (sharedConfig.effects = []);
|
|
685
|
+
sharedConfig.effects.push(...queue.slice(0, userLength));
|
|
686
|
+
return;
|
|
687
|
+
}
|
|
688
|
+
setHydrateContext();
|
|
689
|
+
}
|
|
690
|
+
if (sharedConfig.effects && (sharedConfig.done || !sharedConfig.count)) {
|
|
691
|
+
queue = [...sharedConfig.effects, ...queue];
|
|
692
|
+
userLength += sharedConfig.effects.length;
|
|
693
|
+
delete sharedConfig.effects;
|
|
694
|
+
}
|
|
695
|
+
for (i = 0; i < userLength; i++) runTop(queue[i]);
|
|
696
|
+
}
|
|
697
|
+
function lookUpstream(node, ignore) {
|
|
698
|
+
const runningTransition = Transition && Transition.running;
|
|
699
|
+
if (runningTransition) node.tState = 0;
|
|
700
|
+
else node.state = 0;
|
|
701
|
+
for (let i = 0; i < node.sources.length; i += 1) {
|
|
702
|
+
const source = node.sources[i];
|
|
703
|
+
if (source.sources) {
|
|
704
|
+
const state = runningTransition ? source.tState : source.state;
|
|
705
|
+
if (state === STALE) {
|
|
706
|
+
if (source !== ignore && (!source.updatedAt || source.updatedAt < ExecCount)) runTop(source);
|
|
707
|
+
} else if (state === PENDING) lookUpstream(source, ignore);
|
|
708
|
+
}
|
|
709
|
+
}
|
|
710
|
+
}
|
|
711
|
+
function markDownstream(node) {
|
|
712
|
+
const runningTransition = Transition && Transition.running;
|
|
713
|
+
for (let i = 0; i < node.observers.length; i += 1) {
|
|
714
|
+
const o = node.observers[i];
|
|
715
|
+
if (runningTransition ? !o.tState : !o.state) {
|
|
716
|
+
if (runningTransition) o.tState = PENDING;
|
|
717
|
+
else o.state = PENDING;
|
|
718
|
+
if (o.pure) Updates.push(o);
|
|
719
|
+
else Effects.push(o);
|
|
720
|
+
o.observers && markDownstream(o);
|
|
721
|
+
}
|
|
722
|
+
}
|
|
723
|
+
}
|
|
724
|
+
function cleanNode(node) {
|
|
725
|
+
let i;
|
|
726
|
+
if (node.sources) {
|
|
727
|
+
while (node.sources.length) {
|
|
728
|
+
const source = node.sources.pop(), index = node.sourceSlots.pop(), obs = source.observers;
|
|
729
|
+
if (obs && obs.length) {
|
|
730
|
+
const n = obs.pop(), s = source.observerSlots.pop();
|
|
731
|
+
if (index < obs.length) {
|
|
732
|
+
n.sourceSlots[s] = index;
|
|
733
|
+
obs[index] = n;
|
|
734
|
+
source.observerSlots[index] = s;
|
|
735
|
+
}
|
|
736
|
+
}
|
|
737
|
+
}
|
|
738
|
+
}
|
|
739
|
+
if (node.tOwned) {
|
|
740
|
+
for (i = node.tOwned.length - 1; i >= 0; i--) cleanNode(node.tOwned[i]);
|
|
741
|
+
delete node.tOwned;
|
|
742
|
+
}
|
|
743
|
+
if (Transition && Transition.running && node.pure) {
|
|
744
|
+
reset(node, true);
|
|
745
|
+
} else if (node.owned) {
|
|
746
|
+
for (i = node.owned.length - 1; i >= 0; i--) cleanNode(node.owned[i]);
|
|
747
|
+
node.owned = null;
|
|
748
|
+
}
|
|
749
|
+
if (node.cleanups) {
|
|
750
|
+
for (i = node.cleanups.length - 1; i >= 0; i--) node.cleanups[i]();
|
|
751
|
+
node.cleanups = null;
|
|
752
|
+
}
|
|
753
|
+
if (Transition && Transition.running) node.tState = 0;
|
|
754
|
+
else node.state = 0;
|
|
755
|
+
}
|
|
756
|
+
function reset(node, top) {
|
|
757
|
+
if (!top) {
|
|
758
|
+
node.tState = 0;
|
|
759
|
+
Transition.disposed.add(node);
|
|
760
|
+
}
|
|
761
|
+
if (node.owned) {
|
|
762
|
+
for (let i = 0; i < node.owned.length; i++) reset(node.owned[i]);
|
|
763
|
+
}
|
|
764
|
+
}
|
|
765
|
+
function castError(err) {
|
|
766
|
+
if (err instanceof Error) return err;
|
|
767
|
+
return new Error(typeof err === "string" ? err : "Unknown error", {
|
|
768
|
+
cause: err
|
|
769
|
+
});
|
|
770
|
+
}
|
|
771
|
+
function runErrors(err, fns, owner) {
|
|
772
|
+
try {
|
|
773
|
+
for (const f of fns) f(err);
|
|
774
|
+
} catch (e) {
|
|
775
|
+
handleError(e, owner && owner.owner || null);
|
|
776
|
+
}
|
|
777
|
+
}
|
|
778
|
+
function handleError(err, owner = Owner) {
|
|
779
|
+
const fns = ERROR && owner && owner.context && owner.context[ERROR];
|
|
780
|
+
const error = castError(err);
|
|
781
|
+
if (!fns) throw error;
|
|
782
|
+
if (Effects) Effects.push({
|
|
783
|
+
fn() {
|
|
784
|
+
runErrors(error, fns, owner);
|
|
785
|
+
},
|
|
786
|
+
state: STALE
|
|
787
|
+
});
|
|
788
|
+
else runErrors(error, fns, owner);
|
|
789
|
+
}
|
|
790
|
+
function resolveChildren(children3) {
|
|
791
|
+
if (typeof children3 === "function" && !children3.length) return resolveChildren(children3());
|
|
792
|
+
if (Array.isArray(children3)) {
|
|
793
|
+
const results = [];
|
|
794
|
+
for (let i = 0; i < children3.length; i++) {
|
|
795
|
+
const result = resolveChildren(children3[i]);
|
|
796
|
+
Array.isArray(result) ? results.push.apply(results, result) : results.push(result);
|
|
797
|
+
}
|
|
798
|
+
return results;
|
|
799
|
+
}
|
|
800
|
+
return children3;
|
|
801
|
+
}
|
|
802
|
+
function createProvider(id, options) {
|
|
803
|
+
return function provider(props) {
|
|
804
|
+
let res;
|
|
805
|
+
createRenderEffect(() => res = untrack(() => {
|
|
806
|
+
Owner.context = {
|
|
807
|
+
...Owner.context,
|
|
808
|
+
[id]: props.value
|
|
809
|
+
};
|
|
810
|
+
return children(() => props.children);
|
|
811
|
+
}), void 0);
|
|
812
|
+
return res;
|
|
813
|
+
};
|
|
814
|
+
}
|
|
815
|
+
var FALLBACK = /* @__PURE__ */ Symbol("fallback");
|
|
816
|
+
function dispose(d) {
|
|
817
|
+
for (let i = 0; i < d.length; i++) d[i]();
|
|
818
|
+
}
|
|
819
|
+
function mapArray(list, mapFn, options = {}) {
|
|
820
|
+
let items = [], mapped = [], disposers = [], len = 0, indexes = mapFn.length > 1 ? [] : null;
|
|
821
|
+
onCleanup(() => dispose(disposers));
|
|
822
|
+
return () => {
|
|
823
|
+
let newItems = list() || [], newLen = newItems.length, i, j;
|
|
824
|
+
newItems[$TRACK];
|
|
825
|
+
return untrack(() => {
|
|
826
|
+
let newIndices, newIndicesNext, temp, tempdisposers, tempIndexes, start, end, newEnd, item;
|
|
827
|
+
if (newLen === 0) {
|
|
828
|
+
if (len !== 0) {
|
|
829
|
+
dispose(disposers);
|
|
830
|
+
disposers = [];
|
|
831
|
+
items = [];
|
|
832
|
+
mapped = [];
|
|
833
|
+
len = 0;
|
|
834
|
+
indexes && (indexes = []);
|
|
835
|
+
}
|
|
836
|
+
if (options.fallback) {
|
|
837
|
+
items = [FALLBACK];
|
|
838
|
+
mapped[0] = createRoot((disposer) => {
|
|
839
|
+
disposers[0] = disposer;
|
|
840
|
+
return options.fallback();
|
|
841
|
+
});
|
|
842
|
+
len = 1;
|
|
843
|
+
}
|
|
844
|
+
} else if (len === 0) {
|
|
845
|
+
mapped = new Array(newLen);
|
|
846
|
+
for (j = 0; j < newLen; j++) {
|
|
847
|
+
items[j] = newItems[j];
|
|
848
|
+
mapped[j] = createRoot(mapper);
|
|
849
|
+
}
|
|
850
|
+
len = newLen;
|
|
851
|
+
} else {
|
|
852
|
+
temp = new Array(newLen);
|
|
853
|
+
tempdisposers = new Array(newLen);
|
|
854
|
+
indexes && (tempIndexes = new Array(newLen));
|
|
855
|
+
for (start = 0, end = Math.min(len, newLen); start < end && items[start] === newItems[start]; start++) ;
|
|
856
|
+
for (end = len - 1, newEnd = newLen - 1; end >= start && newEnd >= start && items[end] === newItems[newEnd]; end--, newEnd--) {
|
|
857
|
+
temp[newEnd] = mapped[end];
|
|
858
|
+
tempdisposers[newEnd] = disposers[end];
|
|
859
|
+
indexes && (tempIndexes[newEnd] = indexes[end]);
|
|
860
|
+
}
|
|
861
|
+
newIndices = /* @__PURE__ */ new Map();
|
|
862
|
+
newIndicesNext = new Array(newEnd + 1);
|
|
863
|
+
for (j = newEnd; j >= start; j--) {
|
|
864
|
+
item = newItems[j];
|
|
865
|
+
i = newIndices.get(item);
|
|
866
|
+
newIndicesNext[j] = i === void 0 ? -1 : i;
|
|
867
|
+
newIndices.set(item, j);
|
|
868
|
+
}
|
|
869
|
+
for (i = start; i <= end; i++) {
|
|
870
|
+
item = items[i];
|
|
871
|
+
j = newIndices.get(item);
|
|
872
|
+
if (j !== void 0 && j !== -1) {
|
|
873
|
+
temp[j] = mapped[i];
|
|
874
|
+
tempdisposers[j] = disposers[i];
|
|
875
|
+
indexes && (tempIndexes[j] = indexes[i]);
|
|
876
|
+
j = newIndicesNext[j];
|
|
877
|
+
newIndices.set(item, j);
|
|
878
|
+
} else disposers[i]();
|
|
879
|
+
}
|
|
880
|
+
for (j = start; j < newLen; j++) {
|
|
881
|
+
if (j in temp) {
|
|
882
|
+
mapped[j] = temp[j];
|
|
883
|
+
disposers[j] = tempdisposers[j];
|
|
884
|
+
if (indexes) {
|
|
885
|
+
indexes[j] = tempIndexes[j];
|
|
886
|
+
indexes[j](j);
|
|
887
|
+
}
|
|
888
|
+
} else mapped[j] = createRoot(mapper);
|
|
889
|
+
}
|
|
890
|
+
mapped = mapped.slice(0, len = newLen);
|
|
891
|
+
items = newItems.slice(0);
|
|
892
|
+
}
|
|
893
|
+
return mapped;
|
|
894
|
+
});
|
|
895
|
+
function mapper(disposer) {
|
|
896
|
+
disposers[j] = disposer;
|
|
897
|
+
if (indexes) {
|
|
898
|
+
const [s, set] = createSignal(j);
|
|
899
|
+
indexes[j] = set;
|
|
900
|
+
return mapFn(newItems[j], s);
|
|
901
|
+
}
|
|
902
|
+
return mapFn(newItems[j]);
|
|
903
|
+
}
|
|
904
|
+
};
|
|
905
|
+
}
|
|
906
|
+
function trueFn() {
|
|
907
|
+
return true;
|
|
908
|
+
}
|
|
909
|
+
var propTraps = {
|
|
910
|
+
get(_, property, receiver) {
|
|
911
|
+
if (property === $PROXY) return receiver;
|
|
912
|
+
return _.get(property);
|
|
913
|
+
},
|
|
914
|
+
has(_, property) {
|
|
915
|
+
if (property === $PROXY) return true;
|
|
916
|
+
return _.has(property);
|
|
917
|
+
},
|
|
918
|
+
set: trueFn,
|
|
919
|
+
deleteProperty: trueFn,
|
|
920
|
+
getOwnPropertyDescriptor(_, property) {
|
|
921
|
+
return {
|
|
922
|
+
configurable: true,
|
|
923
|
+
enumerable: true,
|
|
924
|
+
get() {
|
|
925
|
+
return _.get(property);
|
|
926
|
+
},
|
|
927
|
+
set: trueFn,
|
|
928
|
+
deleteProperty: trueFn
|
|
929
|
+
};
|
|
930
|
+
},
|
|
931
|
+
ownKeys(_) {
|
|
932
|
+
return _.keys();
|
|
933
|
+
}
|
|
934
|
+
};
|
|
935
|
+
function resolveSource(s) {
|
|
936
|
+
return !(s = typeof s === "function" ? s() : s) ? {} : s;
|
|
937
|
+
}
|
|
938
|
+
function resolveSources() {
|
|
939
|
+
for (let i = 0, length = this.length; i < length; ++i) {
|
|
940
|
+
const v = this[i]();
|
|
941
|
+
if (v !== void 0) return v;
|
|
942
|
+
}
|
|
943
|
+
}
|
|
944
|
+
function mergeProps(...sources) {
|
|
945
|
+
let proxy = false;
|
|
946
|
+
for (let i = 0; i < sources.length; i++) {
|
|
947
|
+
const s = sources[i];
|
|
948
|
+
proxy = proxy || !!s && $PROXY in s;
|
|
949
|
+
sources[i] = typeof s === "function" ? (proxy = true, createMemo(s)) : s;
|
|
950
|
+
}
|
|
951
|
+
if (SUPPORTS_PROXY && proxy) {
|
|
952
|
+
return new Proxy({
|
|
953
|
+
get(property) {
|
|
954
|
+
for (let i = sources.length - 1; i >= 0; i--) {
|
|
955
|
+
const v = resolveSource(sources[i])[property];
|
|
956
|
+
if (v !== void 0) return v;
|
|
957
|
+
}
|
|
958
|
+
},
|
|
959
|
+
has(property) {
|
|
960
|
+
for (let i = sources.length - 1; i >= 0; i--) {
|
|
961
|
+
if (property in resolveSource(sources[i])) return true;
|
|
962
|
+
}
|
|
963
|
+
return false;
|
|
964
|
+
},
|
|
965
|
+
keys() {
|
|
966
|
+
const keys = [];
|
|
967
|
+
for (let i = 0; i < sources.length; i++) keys.push(...Object.keys(resolveSource(sources[i])));
|
|
968
|
+
return [...new Set(keys)];
|
|
969
|
+
}
|
|
970
|
+
}, propTraps);
|
|
971
|
+
}
|
|
972
|
+
const sourcesMap = {};
|
|
973
|
+
const defined = /* @__PURE__ */ Object.create(null);
|
|
974
|
+
for (let i = sources.length - 1; i >= 0; i--) {
|
|
975
|
+
const source = sources[i];
|
|
976
|
+
if (!source) continue;
|
|
977
|
+
const sourceKeys = Object.getOwnPropertyNames(source);
|
|
978
|
+
for (let i2 = sourceKeys.length - 1; i2 >= 0; i2--) {
|
|
979
|
+
const key = sourceKeys[i2];
|
|
980
|
+
if (key === "__proto__" || key === "constructor") continue;
|
|
981
|
+
const desc = Object.getOwnPropertyDescriptor(source, key);
|
|
982
|
+
if (!defined[key]) {
|
|
983
|
+
defined[key] = desc.get ? {
|
|
984
|
+
enumerable: true,
|
|
985
|
+
configurable: true,
|
|
986
|
+
get: resolveSources.bind(sourcesMap[key] = [desc.get.bind(source)])
|
|
987
|
+
} : desc.value !== void 0 ? desc : void 0;
|
|
988
|
+
} else {
|
|
989
|
+
const sources2 = sourcesMap[key];
|
|
990
|
+
if (sources2) {
|
|
991
|
+
if (desc.get) sources2.push(desc.get.bind(source));
|
|
992
|
+
else if (desc.value !== void 0) sources2.push(() => desc.value);
|
|
993
|
+
}
|
|
994
|
+
}
|
|
995
|
+
}
|
|
996
|
+
}
|
|
997
|
+
const target = {};
|
|
998
|
+
const definedKeys = Object.keys(defined);
|
|
999
|
+
for (let i = definedKeys.length - 1; i >= 0; i--) {
|
|
1000
|
+
const key = definedKeys[i], desc = defined[key];
|
|
1001
|
+
if (desc && desc.get) Object.defineProperty(target, key, desc);
|
|
1002
|
+
else target[key] = desc ? desc.value : void 0;
|
|
1003
|
+
}
|
|
1004
|
+
return target;
|
|
1005
|
+
}
|
|
1006
|
+
function splitProps(props, ...keys) {
|
|
1007
|
+
const len = keys.length;
|
|
1008
|
+
if (SUPPORTS_PROXY && $PROXY in props) {
|
|
1009
|
+
const blocked = len > 1 ? keys.flat() : keys[0];
|
|
1010
|
+
const res = keys.map((k) => {
|
|
1011
|
+
return new Proxy({
|
|
1012
|
+
get(property) {
|
|
1013
|
+
return k.includes(property) ? props[property] : void 0;
|
|
1014
|
+
},
|
|
1015
|
+
has(property) {
|
|
1016
|
+
return k.includes(property) && property in props;
|
|
1017
|
+
},
|
|
1018
|
+
keys() {
|
|
1019
|
+
return k.filter((property) => property in props);
|
|
1020
|
+
}
|
|
1021
|
+
}, propTraps);
|
|
1022
|
+
});
|
|
1023
|
+
res.push(new Proxy({
|
|
1024
|
+
get(property) {
|
|
1025
|
+
return blocked.includes(property) ? void 0 : props[property];
|
|
1026
|
+
},
|
|
1027
|
+
has(property) {
|
|
1028
|
+
return blocked.includes(property) ? false : property in props;
|
|
1029
|
+
},
|
|
1030
|
+
keys() {
|
|
1031
|
+
return Object.keys(props).filter((k) => !blocked.includes(k));
|
|
1032
|
+
}
|
|
1033
|
+
}, propTraps));
|
|
1034
|
+
return res;
|
|
1035
|
+
}
|
|
1036
|
+
const objects = [];
|
|
1037
|
+
for (let i = 0; i <= len; i++) {
|
|
1038
|
+
objects[i] = {};
|
|
1039
|
+
}
|
|
1040
|
+
for (const propName of Object.getOwnPropertyNames(props)) {
|
|
1041
|
+
let keyIndex = len;
|
|
1042
|
+
for (let i = 0; i < keys.length; i++) {
|
|
1043
|
+
if (keys[i].includes(propName)) {
|
|
1044
|
+
keyIndex = i;
|
|
1045
|
+
break;
|
|
1046
|
+
}
|
|
1047
|
+
}
|
|
1048
|
+
const desc = Object.getOwnPropertyDescriptor(props, propName);
|
|
1049
|
+
const isDefaultDesc = !desc.get && !desc.set && desc.enumerable && desc.writable && desc.configurable;
|
|
1050
|
+
isDefaultDesc ? objects[keyIndex][propName] = desc.value : Object.defineProperty(objects[keyIndex], propName, desc);
|
|
1051
|
+
}
|
|
1052
|
+
return objects;
|
|
1053
|
+
}
|
|
1054
|
+
var counter = 0;
|
|
1055
|
+
function createUniqueId() {
|
|
1056
|
+
const ctx = sharedConfig.context;
|
|
1057
|
+
return ctx ? sharedConfig.getNextContextId() : `cl-${counter++}`;
|
|
1058
|
+
}
|
|
1059
|
+
var narrowedError = (name) => `Stale read from <${name}>.`;
|
|
1060
|
+
function For(props) {
|
|
1061
|
+
const fallback = "fallback" in props && {
|
|
1062
|
+
fallback: () => props.fallback
|
|
1063
|
+
};
|
|
1064
|
+
return createMemo(mapArray(() => props.each, props.children, fallback || void 0));
|
|
1065
|
+
}
|
|
1066
|
+
function Show(props) {
|
|
1067
|
+
const keyed = props.keyed;
|
|
1068
|
+
const conditionValue = createMemo(() => props.when, void 0, void 0);
|
|
1069
|
+
const condition = keyed ? conditionValue : createMemo(conditionValue, void 0, {
|
|
1070
|
+
equals: (a, b) => !a === !b
|
|
1071
|
+
});
|
|
1072
|
+
return createMemo(() => {
|
|
1073
|
+
const c = condition();
|
|
1074
|
+
if (c) {
|
|
1075
|
+
const child = props.children;
|
|
1076
|
+
const fn = typeof child === "function" && child.length > 0;
|
|
1077
|
+
return fn ? untrack(() => child(keyed ? c : () => {
|
|
1078
|
+
if (!untrack(condition)) throw narrowedError("Show");
|
|
1079
|
+
return conditionValue();
|
|
1080
|
+
})) : child;
|
|
1081
|
+
}
|
|
1082
|
+
return props.fallback;
|
|
1083
|
+
}, void 0, void 0);
|
|
1084
|
+
}
|
|
1085
|
+
|
|
1086
|
+
// src/components/SSDataTable.tsx
|
|
1087
|
+
function SSDataCell(props) {
|
|
1088
|
+
const rendered = createMemo(() => props.render(props.row));
|
|
1089
|
+
const [asyncContent] = createResource(async () => {
|
|
1090
|
+
const value = rendered();
|
|
1091
|
+
if (value && typeof value.then === "function") {
|
|
1092
|
+
return await value;
|
|
1093
|
+
}
|
|
1094
|
+
return null;
|
|
1095
|
+
});
|
|
1096
|
+
return <div>
|
|
1097
|
+
{(() => {
|
|
1098
|
+
const value = rendered();
|
|
1099
|
+
if (value && typeof value.then === "function") {
|
|
1100
|
+
return asyncContent() ?? "";
|
|
1101
|
+
}
|
|
1102
|
+
return value;
|
|
1103
|
+
})()}
|
|
1104
|
+
</div>;
|
|
1105
|
+
}
|
|
1106
|
+
function SSDataTable(props) {
|
|
1107
|
+
const [sortIndex, setSortIndex] = createSignal(-1);
|
|
1108
|
+
const [sortDir, setSortDir] = createSignal(null);
|
|
1109
|
+
const [page, setPage] = createSignal(1);
|
|
1110
|
+
const pageSize = () => Math.max(1, props.pageSize ?? 25);
|
|
1111
|
+
const sortedRows = createMemo(() => {
|
|
1112
|
+
const index = sortIndex();
|
|
1113
|
+
const dir = sortDir();
|
|
1114
|
+
if (index < 0 || !dir) return props.rows;
|
|
1115
|
+
const column = props.columns[index];
|
|
1116
|
+
if (!column?.sortKey) return props.rows;
|
|
1117
|
+
const entries = props.rows.map((row, idx) => ({
|
|
1118
|
+
row,
|
|
1119
|
+
idx,
|
|
1120
|
+
key: column.sortKey(row)
|
|
1121
|
+
}));
|
|
1122
|
+
entries.sort((a, b) => {
|
|
1123
|
+
if (a.key === b.key) return a.idx - b.idx;
|
|
1124
|
+
if (a.key < b.key) return dir === "asc" ? -1 : 1;
|
|
1125
|
+
return dir === "asc" ? 1 : -1;
|
|
1126
|
+
});
|
|
1127
|
+
return entries.map((entry) => entry.row);
|
|
1128
|
+
});
|
|
1129
|
+
const totalPages = createMemo(() => {
|
|
1130
|
+
return Math.max(1, Math.ceil(sortedRows().length / pageSize()));
|
|
1131
|
+
});
|
|
1132
|
+
const pagedRows = createMemo(() => {
|
|
1133
|
+
const current = Math.min(page(), totalPages());
|
|
1134
|
+
const start = (current - 1) * pageSize();
|
|
1135
|
+
return sortedRows().slice(start, start + pageSize());
|
|
1136
|
+
});
|
|
1137
|
+
createEffect(() => {
|
|
1138
|
+
if (page() > totalPages()) setPage(totalPages());
|
|
1139
|
+
});
|
|
1140
|
+
const toggleSort = (index) => {
|
|
1141
|
+
if (sortIndex() !== index) {
|
|
1142
|
+
setSortIndex(index);
|
|
1143
|
+
setSortDir("asc");
|
|
1144
|
+
setPage(1);
|
|
1145
|
+
return;
|
|
1146
|
+
}
|
|
1147
|
+
if (sortDir() === "asc") {
|
|
1148
|
+
setSortDir("desc");
|
|
1149
|
+
return;
|
|
1150
|
+
}
|
|
1151
|
+
if (sortDir() === "desc") {
|
|
1152
|
+
setSortIndex(-1);
|
|
1153
|
+
setSortDir(null);
|
|
1154
|
+
setPage(1);
|
|
1155
|
+
return;
|
|
1156
|
+
}
|
|
1157
|
+
setSortDir("asc");
|
|
1158
|
+
setPage(1);
|
|
1159
|
+
};
|
|
1160
|
+
const goToPage = (next) => {
|
|
1161
|
+
const safePage = Math.min(Math.max(1, next), totalPages());
|
|
1162
|
+
setPage(safePage);
|
|
1163
|
+
};
|
|
1164
|
+
const paginationPosition = () => props.paginationPosition ?? "bottom";
|
|
1165
|
+
const containerClass = () => `ss_table ${paginationPosition() === "top" ? "ss_table--pagination-top" : ""} ${props.class ?? ""}`;
|
|
1166
|
+
const paginationBar = () => <div class="ss_table__pagination">
|
|
1167
|
+
<button
|
|
1168
|
+
type="button"
|
|
1169
|
+
class="ss_table__page_button"
|
|
1170
|
+
disabled={page() === 1}
|
|
1171
|
+
aria-label="Erste Seite"
|
|
1172
|
+
onclick={() => goToPage(1)}
|
|
1173
|
+
>
|
|
1174
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon icon-tabler icons-tabler-outline icon-tabler-chevron-left-pipe"><path stroke="none" d="M0 0h24v24H0z" fill="none" /><path d="M7 6v12" /><path d="M18 6l-6 6l6 6" /></svg>
|
|
1175
|
+
</button>
|
|
1176
|
+
<button
|
|
1177
|
+
type="button"
|
|
1178
|
+
class="ss_table__page_button"
|
|
1179
|
+
disabled={page() === 1}
|
|
1180
|
+
aria-label="Vorherige Seite"
|
|
1181
|
+
onclick={() => goToPage(page() - 1)}
|
|
1182
|
+
>
|
|
1183
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon icon-tabler icons-tabler-outline icon-tabler-chevron-left"><path stroke="none" d="M0 0h24v24H0z" fill="none" /><path d="M15 6l-6 6l6 6" /></svg>
|
|
1184
|
+
</button>
|
|
1185
|
+
<span class="ss_table__page_info">
|
|
1186
|
+
Seite {page()} von {totalPages()}
|
|
1187
|
+
</span>
|
|
1188
|
+
<button
|
|
1189
|
+
type="button"
|
|
1190
|
+
class="ss_table__page_button"
|
|
1191
|
+
disabled={page() === totalPages()}
|
|
1192
|
+
aria-label="Nächste Seite"
|
|
1193
|
+
onclick={() => goToPage(page() + 1)}
|
|
1194
|
+
>
|
|
1195
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon icon-tabler icons-tabler-outline icon-tabler-chevron-right"><path stroke="none" d="M0 0h24v24H0z" fill="none" /><path d="M9 6l6 6l-6 6" /></svg>
|
|
1196
|
+
</button>
|
|
1197
|
+
<button
|
|
1198
|
+
type="button"
|
|
1199
|
+
class="ss_table__page_button"
|
|
1200
|
+
disabled={page() === totalPages()}
|
|
1201
|
+
aria-label="Letzte Seite"
|
|
1202
|
+
onclick={() => goToPage(totalPages())}
|
|
1203
|
+
>
|
|
1204
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon icon-tabler icons-tabler-outline icon-tabler-chevron-right-pipe"><path stroke="none" d="M0 0h24v24H0z" fill="none" /><path d="M6 6l6 6l-6 6" /><path d="M17 5v13" /></svg>
|
|
1205
|
+
</button>
|
|
1206
|
+
</div>;
|
|
1207
|
+
return <div class={containerClass()} style={props.style}>
|
|
1208
|
+
{paginationPosition() === "top" && paginationBar()}
|
|
1209
|
+
<div class="ss_table__scroll">
|
|
1210
|
+
<table>
|
|
1211
|
+
<thead>
|
|
1212
|
+
<tr>
|
|
1213
|
+
<For each={props.columns}>
|
|
1214
|
+
{(column, index) => {
|
|
1215
|
+
const sortable = !!column.sortKey;
|
|
1216
|
+
const isActive = () => sortIndex() === index();
|
|
1217
|
+
const currentDir = () => isActive() ? sortDir() : null;
|
|
1218
|
+
return <th>
|
|
1219
|
+
{sortable ? <button
|
|
1220
|
+
type="button"
|
|
1221
|
+
class="ss_table__sort_button"
|
|
1222
|
+
aria-sort={currentDir() === "asc" ? "ascending" : currentDir() === "desc" ? "descending" : "none"}
|
|
1223
|
+
data-sort={currentDir() ?? "none"}
|
|
1224
|
+
onclick={() => toggleSort(index())}
|
|
1225
|
+
>
|
|
1226
|
+
{column.label}
|
|
1227
|
+
<span class="ss_table__sort_icon" aria-hidden="true">
|
|
1228
|
+
{currentDir() === "asc" ? <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon icon-tabler icons-tabler-outline icon-tabler-chevron-down"><path stroke="none" d="M0 0h24v24H0z" fill="none" /><path d="M6 9l6 6l6 -6" /></svg> : currentDir() === "desc" ? <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon icon-tabler icons-tabler-outline icon-tabler-chevron-up"><path stroke="none" d="M0 0h24v24H0z" fill="none" /><path d="M6 15l6 -6l6 6" /></svg> : <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon icon-tabler icons-tabler-outline icon-tabler-selector"><path stroke="none" d="M0 0h24v24H0z" fill="none" /><path d="M8 9l4 -4l4 4" /><path d="M16 15l-4 4l-4 -4" /></svg>}
|
|
1229
|
+
</span>
|
|
1230
|
+
</button> : <span class="ss_table__header_label">{column.label}</span>}
|
|
1231
|
+
</th>;
|
|
1232
|
+
}}
|
|
1233
|
+
</For>
|
|
1234
|
+
</tr>
|
|
1235
|
+
</thead>
|
|
1236
|
+
<tbody>
|
|
1237
|
+
<For each={pagedRows()}>
|
|
1238
|
+
{(row) => <tr
|
|
1239
|
+
data-clickable={props.onRowClick ? "true" : void 0}
|
|
1240
|
+
onclick={() => props.onRowClick?.(row)}
|
|
1241
|
+
>
|
|
1242
|
+
<For each={props.columns}>
|
|
1243
|
+
{(column) => <td>
|
|
1244
|
+
<SSDataCell row={row} render={column.render} />
|
|
1245
|
+
</td>}
|
|
1246
|
+
</For>
|
|
1247
|
+
</tr>}
|
|
1248
|
+
</For>
|
|
1249
|
+
</tbody>
|
|
1250
|
+
</table>
|
|
1251
|
+
</div>
|
|
1252
|
+
{paginationPosition() === "bottom" && paginationBar()}
|
|
1253
|
+
</div>;
|
|
1254
|
+
}
|
|
1255
|
+
|
|
1256
|
+
// src/components/SSDropdown.tsx
|
|
1257
|
+
function SSDropdown(props) {
|
|
1258
|
+
const [open, setOpen] = createSignal(false);
|
|
1259
|
+
const [renderMenu, setRenderMenu] = createSignal(false);
|
|
1260
|
+
const [menuState, setMenuState] = createSignal("closed");
|
|
1261
|
+
let rootRef;
|
|
1262
|
+
const close = () => setOpen(false);
|
|
1263
|
+
createEffect(() => {
|
|
1264
|
+
if (open()) {
|
|
1265
|
+
setRenderMenu(true);
|
|
1266
|
+
requestAnimationFrame(() => setMenuState("open"));
|
|
1267
|
+
return;
|
|
1268
|
+
}
|
|
1269
|
+
if (!renderMenu()) return;
|
|
1270
|
+
setMenuState("closed");
|
|
1271
|
+
const timeout = window.setTimeout(() => setRenderMenu(false), 160);
|
|
1272
|
+
onCleanup(() => window.clearTimeout(timeout));
|
|
1273
|
+
});
|
|
1274
|
+
onMount(() => {
|
|
1275
|
+
const handlePointerDown = (event) => {
|
|
1276
|
+
const target = event.target;
|
|
1277
|
+
if (!rootRef || !target) return;
|
|
1278
|
+
if (!rootRef.contains(target)) close();
|
|
1279
|
+
};
|
|
1280
|
+
const handleKeyDown = (event) => {
|
|
1281
|
+
if (event.key === "Escape") close();
|
|
1282
|
+
};
|
|
1283
|
+
document.addEventListener("mousedown", handlePointerDown);
|
|
1284
|
+
window.addEventListener("keydown", handleKeyDown);
|
|
1285
|
+
onCleanup(() => {
|
|
1286
|
+
document.removeEventListener("mousedown", handlePointerDown);
|
|
1287
|
+
window.removeEventListener("keydown", handleKeyDown);
|
|
1288
|
+
});
|
|
1289
|
+
});
|
|
1290
|
+
return <div class={`ss_dropdown ${props.class ?? ""}`} style={props.style} ref={(el) => rootRef = el}>
|
|
1291
|
+
<button
|
|
1292
|
+
type="button"
|
|
1293
|
+
class="ss_dropdown__trigger ss_button ss_button--icon"
|
|
1294
|
+
aria-haspopup="menu"
|
|
1295
|
+
aria-expanded={open()}
|
|
1296
|
+
aria-label={props.ariaLabel ?? "Aktionen \xF6ffnen"}
|
|
1297
|
+
onclick={() => setOpen((value) => !value)}
|
|
1298
|
+
>
|
|
1299
|
+
{props.icon ?? <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon icon-tabler icons-tabler-outline icon-tabler-dots-vertical"><path stroke="none" d="M0 0h24v24H0z" fill="none" /><path d="M11 12a1 1 0 1 0 2 0a1 1 0 1 0 -2 0" /><path d="M11 19a1 1 0 1 0 2 0a1 1 0 1 0 -2 0" /><path d="M11 5a1 1 0 1 0 2 0a1 1 0 1 0 -2 0" /></svg>}
|
|
1300
|
+
</button>
|
|
1301
|
+
|
|
1302
|
+
<Show when={renderMenu()}>
|
|
1303
|
+
<div
|
|
1304
|
+
class="ss_dropdown__menu"
|
|
1305
|
+
role="menu"
|
|
1306
|
+
data-state={menuState()}
|
|
1307
|
+
>
|
|
1308
|
+
<For each={props.items}>
|
|
1309
|
+
{(item) => <button
|
|
1310
|
+
type="button"
|
|
1311
|
+
class="ss_dropdown__item"
|
|
1312
|
+
role={item.checked ? "menuitemcheckbox" : "menuitem"}
|
|
1313
|
+
aria-checked={item.checked ? "true" : void 0}
|
|
1314
|
+
onclick={async () => {
|
|
1315
|
+
close();
|
|
1316
|
+
await item.onclick?.();
|
|
1317
|
+
}}
|
|
1318
|
+
>
|
|
1319
|
+
<span class="ss_dropdown__item_icon">{item.icon}</span>
|
|
1320
|
+
<span class="ss_dropdown__item_label">{item.label}</span>
|
|
1321
|
+
{item.checked && <span class="ss_dropdown__item_check" aria-hidden="true">
|
|
1322
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon icon-tabler icons-tabler-outline icon-tabler-check"><path stroke="none" d="M0 0h24v24H0z" fill="none" /><path d="M5 12l5 5l10 -10" /></svg>
|
|
1323
|
+
</span>}
|
|
1324
|
+
</button>}
|
|
1325
|
+
</For>
|
|
1326
|
+
</div>
|
|
1327
|
+
</Show>
|
|
1328
|
+
</div>;
|
|
1329
|
+
}
|
|
1330
|
+
|
|
1331
|
+
// src/components/SSExpandable.tsx
|
|
1332
|
+
var TRANSITION_MS = 200;
|
|
1333
|
+
function SSExpandable(props) {
|
|
1334
|
+
const [height, setHeight] = createSignal(props.initiallyExpanded ? "auto" : 0);
|
|
1335
|
+
const isExpanded = createMemo(() => height() !== 0);
|
|
1336
|
+
let contentRef;
|
|
1337
|
+
let timeoutId;
|
|
1338
|
+
const toggle = () => {
|
|
1339
|
+
if (timeoutId) clearTimeout(timeoutId);
|
|
1340
|
+
const targetHeight = contentRef?.scrollHeight ?? 0;
|
|
1341
|
+
if (isExpanded()) {
|
|
1342
|
+
setHeight(targetHeight);
|
|
1343
|
+
timeoutId = window.setTimeout(() => setHeight(0), 1);
|
|
1344
|
+
return;
|
|
1345
|
+
}
|
|
1346
|
+
setHeight(targetHeight);
|
|
1347
|
+
timeoutId = window.setTimeout(() => setHeight("auto"), TRANSITION_MS);
|
|
1348
|
+
};
|
|
1349
|
+
onCleanup(() => {
|
|
1350
|
+
if (timeoutId) clearTimeout(timeoutId);
|
|
1351
|
+
});
|
|
1352
|
+
return <div
|
|
1353
|
+
class={`ss_expandable ${props.class ?? ""}`}
|
|
1354
|
+
style={props.style}
|
|
1355
|
+
data-state={isExpanded() ? "open" : "closed"}
|
|
1356
|
+
>
|
|
1357
|
+
<div
|
|
1358
|
+
class="ss_expandable__header"
|
|
1359
|
+
role="button"
|
|
1360
|
+
tabindex="0"
|
|
1361
|
+
aria-expanded={isExpanded()}
|
|
1362
|
+
onclick={toggle}
|
|
1363
|
+
onkeydown={(event) => {
|
|
1364
|
+
if (event.key === "Enter" || event.key === " ") {
|
|
1365
|
+
event.preventDefault();
|
|
1366
|
+
toggle();
|
|
1367
|
+
}
|
|
1368
|
+
}}
|
|
1369
|
+
>
|
|
1370
|
+
<span class="ss_expandable__icon" aria-hidden="true">
|
|
1371
|
+
{isExpanded() ? <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon icon-tabler icons-tabler-outline icon-tabler-chevron-down"><path stroke="none" d="M0 0h24v24H0z" fill="none" /><path d="M6 9l6 6l6 -6" /></svg> : <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon icon-tabler icons-tabler-outline icon-tabler-chevron-right"><path stroke="none" d="M0 0h24v24H0z" fill="none" /><path d="M9 6l6 6l-6 6" /></svg>}
|
|
1372
|
+
</span>
|
|
1373
|
+
<span class="ss_expandable__title">{props.title}</span>
|
|
1374
|
+
</div>
|
|
1375
|
+
|
|
1376
|
+
<div
|
|
1377
|
+
ref={(el) => contentRef = el}
|
|
1378
|
+
class="ss_expandable__content"
|
|
1379
|
+
style={{
|
|
1380
|
+
height: typeof height() === "number" ? `${height()}px` : height(),
|
|
1381
|
+
"transition-duration": `${TRANSITION_MS}ms`
|
|
1382
|
+
}}
|
|
1383
|
+
>
|
|
1384
|
+
<div class='ss_expandable__divider_wrapper'>
|
|
1385
|
+
<div class="ss_expandable__divider" />
|
|
1386
|
+
{props.children}
|
|
1387
|
+
</div>
|
|
1388
|
+
</div>
|
|
1389
|
+
</div>;
|
|
1390
|
+
}
|
|
1391
|
+
|
|
1392
|
+
// src/hooks/createLoading.ts
|
|
1393
|
+
function createLoading() {
|
|
1394
|
+
const [loading, setLoading] = createSignal(false);
|
|
1395
|
+
return [loading, async (callback) => {
|
|
1396
|
+
if (loading()) return;
|
|
1397
|
+
try {
|
|
1398
|
+
setLoading(true);
|
|
1399
|
+
await callback();
|
|
1400
|
+
} finally {
|
|
1401
|
+
setLoading(false);
|
|
1402
|
+
}
|
|
1403
|
+
}];
|
|
1404
|
+
}
|
|
1405
|
+
|
|
1406
|
+
// src/components/SSForm.tsx
|
|
1407
|
+
var SSFormContext = createContext();
|
|
1408
|
+
var SSForm = function(props) {
|
|
1409
|
+
const [loading, process] = createLoading();
|
|
1410
|
+
const fields = {};
|
|
1411
|
+
const context = {
|
|
1412
|
+
loading,
|
|
1413
|
+
process: (action) => process(() => action(context)),
|
|
1414
|
+
field: (name) => fields[name] ?? null,
|
|
1415
|
+
setField: (name, field) => {
|
|
1416
|
+
fields[name] = field;
|
|
1417
|
+
},
|
|
1418
|
+
delField: (name) => {
|
|
1419
|
+
delete fields[name];
|
|
1420
|
+
},
|
|
1421
|
+
setValues: (values) => Object.entries(values).forEach(([name, value]) => fields[name]?.setValue(value)),
|
|
1422
|
+
getValues: () => Object.fromEntries(Object.entries(fields).map(([name, field]) => [name, field.getValue()])),
|
|
1423
|
+
validate: () => Promise.all(Object.values(fields).map((field) => field.validate())).then(),
|
|
1424
|
+
hasError: () => Object.values(fields).some((field) => field.hasError()),
|
|
1425
|
+
submit: () => process(async () => {
|
|
1426
|
+
await context.validate();
|
|
1427
|
+
if (context.hasError()) return;
|
|
1428
|
+
await props.onsubmit?.(context);
|
|
1429
|
+
})
|
|
1430
|
+
};
|
|
1431
|
+
return <form class="ss_form" onsubmit={(e) => {
|
|
1432
|
+
e.preventDefault();
|
|
1433
|
+
context.submit();
|
|
1434
|
+
}}>
|
|
1435
|
+
<SSFormContext.Provider value={context}>
|
|
1436
|
+
{props.children}
|
|
1437
|
+
</SSFormContext.Provider>
|
|
1438
|
+
</form>;
|
|
1439
|
+
};
|
|
1440
|
+
SSForm.Input = function(props) {
|
|
1441
|
+
const context = useContext(SSFormContext);
|
|
1442
|
+
const [value, setValue] = createSignal("");
|
|
1443
|
+
const [error, setError] = createSignal(null);
|
|
1444
|
+
const field = {
|
|
1445
|
+
getValue: () => {
|
|
1446
|
+
const trimmed = value().trim();
|
|
1447
|
+
if (!trimmed) return null;
|
|
1448
|
+
return trimmed;
|
|
1449
|
+
},
|
|
1450
|
+
setValue: (value2) => {
|
|
1451
|
+
if (typeof value2 === "number") {
|
|
1452
|
+
setValue(value2.toLocaleString());
|
|
1453
|
+
return;
|
|
1454
|
+
}
|
|
1455
|
+
setValue(`${value2}`);
|
|
1456
|
+
},
|
|
1457
|
+
hasError: () => !!error(),
|
|
1458
|
+
validate: async () => {
|
|
1459
|
+
const rules = [...props.rules ?? []];
|
|
1460
|
+
if (props.required) rules.unshift(SSForm.rules.required);
|
|
1461
|
+
const value2 = await field.getValue();
|
|
1462
|
+
for (const rule of rules) {
|
|
1463
|
+
const newError = await rule(value2);
|
|
1464
|
+
if (newError) {
|
|
1465
|
+
setError(newError);
|
|
1466
|
+
return;
|
|
1467
|
+
}
|
|
1468
|
+
}
|
|
1469
|
+
setError(null);
|
|
1470
|
+
}
|
|
1471
|
+
};
|
|
1472
|
+
if (props.name && context) {
|
|
1473
|
+
const name = props.name;
|
|
1474
|
+
onMount(() => context.setField(name, field));
|
|
1475
|
+
onCleanup(() => context.delField(name));
|
|
1476
|
+
}
|
|
1477
|
+
let suggInitData = null;
|
|
1478
|
+
const [suggItems, setSuggItems] = createSignal([]);
|
|
1479
|
+
const [suggIndex, setSuggIndex] = createSignal(-1);
|
|
1480
|
+
let suggListRef;
|
|
1481
|
+
if (props.suggestions) {
|
|
1482
|
+
const sugg = props.suggestions;
|
|
1483
|
+
const [initialized, setInitialized] = createSignal(!sugg.prepare);
|
|
1484
|
+
if (sugg.prepare) onMount(async () => {
|
|
1485
|
+
if (!sugg.prepare) return;
|
|
1486
|
+
suggInitData = await sugg.prepare();
|
|
1487
|
+
setInitialized(true);
|
|
1488
|
+
});
|
|
1489
|
+
let timeout;
|
|
1490
|
+
createEffect(() => {
|
|
1491
|
+
clearTimeout(timeout ?? void 0);
|
|
1492
|
+
if (!initialized()) return;
|
|
1493
|
+
setSuggItems([]);
|
|
1494
|
+
const query2 = value().trim().toLowerCase();
|
|
1495
|
+
if (!query2) return;
|
|
1496
|
+
timeout = setTimeout(async () => {
|
|
1497
|
+
const items = await sugg.getItems({ query: query2, init: suggInitData });
|
|
1498
|
+
setSuggItems(items);
|
|
1499
|
+
}, 250);
|
|
1500
|
+
});
|
|
1501
|
+
onCleanup(() => clearTimeout(timeout ?? void 0));
|
|
1502
|
+
}
|
|
1503
|
+
createEffect(() => {
|
|
1504
|
+
const items = suggItems();
|
|
1505
|
+
if (!items.length) {
|
|
1506
|
+
setSuggIndex(-1);
|
|
1507
|
+
return;
|
|
1508
|
+
}
|
|
1509
|
+
if (suggIndex() >= items.length) setSuggIndex(items.length - 1);
|
|
1510
|
+
});
|
|
1511
|
+
const scrollToIndex = (idx) => {
|
|
1512
|
+
const list = suggListRef;
|
|
1513
|
+
if (!list || idx < 0) return;
|
|
1514
|
+
const item = list.querySelectorAll("li")[idx];
|
|
1515
|
+
if (!item) return;
|
|
1516
|
+
const itemTop = item.offsetTop;
|
|
1517
|
+
const itemBottom = itemTop + item.offsetHeight;
|
|
1518
|
+
const viewTop = list.scrollTop;
|
|
1519
|
+
const viewBottom = viewTop + list.clientHeight;
|
|
1520
|
+
if (itemTop < viewTop) list.scrollTop = itemTop;
|
|
1521
|
+
else if (itemBottom > viewBottom) list.scrollTop = itemBottom - list.clientHeight;
|
|
1522
|
+
};
|
|
1523
|
+
const moveIndex = (delta) => {
|
|
1524
|
+
const items = suggItems();
|
|
1525
|
+
if (!items.length) return;
|
|
1526
|
+
const next = Math.max(-1, Math.min(suggIndex() + delta, items.length - 1));
|
|
1527
|
+
setSuggIndex(next);
|
|
1528
|
+
scrollToIndex(next);
|
|
1529
|
+
};
|
|
1530
|
+
const selectSuggestion = (item) => {
|
|
1531
|
+
setValue(props.suggestions.stringify({ item, init: suggInitData }));
|
|
1532
|
+
setSuggIndex(-1);
|
|
1533
|
+
};
|
|
1534
|
+
const handleKeyDown = (e) => {
|
|
1535
|
+
if (!suggItems().length) return;
|
|
1536
|
+
if (e.key === "ArrowDown") {
|
|
1537
|
+
e.preventDefault();
|
|
1538
|
+
moveIndex(1);
|
|
1539
|
+
} else if (e.key === "ArrowUp") {
|
|
1540
|
+
e.preventDefault();
|
|
1541
|
+
moveIndex(-1);
|
|
1542
|
+
} else if (e.key === "Enter" && suggIndex() >= 0) {
|
|
1543
|
+
e.preventDefault();
|
|
1544
|
+
const item = suggItems()[suggIndex()];
|
|
1545
|
+
if (item) selectSuggestion(item);
|
|
1546
|
+
} else if (e.key === "Escape") {
|
|
1547
|
+
setSuggIndex(-1);
|
|
1548
|
+
}
|
|
1549
|
+
};
|
|
1550
|
+
const handleInputChange = (next) => {
|
|
1551
|
+
setValue(next);
|
|
1552
|
+
setSuggIndex(-1);
|
|
1553
|
+
};
|
|
1554
|
+
const _id = createUniqueId();
|
|
1555
|
+
return <div class="ss_form_input">
|
|
1556
|
+
<label for={props.id || _id}>{props.label}</label>
|
|
1557
|
+
|
|
1558
|
+
<div class="ss__wrapper">
|
|
1559
|
+
{props.textArea ? <textarea
|
|
1560
|
+
id={props.id || _id}
|
|
1561
|
+
value={value()}
|
|
1562
|
+
oninput={(e) => handleInputChange(e.target.value)}
|
|
1563
|
+
onkeydown={handleKeyDown}
|
|
1564
|
+
disabled={props.disabled || context?.loading()}
|
|
1565
|
+
/> : <input
|
|
1566
|
+
id={props.id || _id}
|
|
1567
|
+
value={value()}
|
|
1568
|
+
oninput={(e) => handleInputChange(e.target.value)}
|
|
1569
|
+
onkeydown={handleKeyDown}
|
|
1570
|
+
disabled={props.disabled || context?.loading()}
|
|
1571
|
+
type={props.type}
|
|
1572
|
+
/>}
|
|
1573
|
+
|
|
1574
|
+
{!!suggItems().length && <ul class="ss__suggestions" ref={(el) => suggListRef = el}>
|
|
1575
|
+
<For each={suggItems()}>
|
|
1576
|
+
{(item, idx) => {
|
|
1577
|
+
const handleSelect = () => {
|
|
1578
|
+
const active = document.activeElement;
|
|
1579
|
+
if (active instanceof HTMLElement) active.blur();
|
|
1580
|
+
selectSuggestion(item);
|
|
1581
|
+
};
|
|
1582
|
+
return <li
|
|
1583
|
+
onpointerdown={(e) => e.preventDefault()}
|
|
1584
|
+
onclick={handleSelect}
|
|
1585
|
+
classList={{ "ss__hovered": idx() === suggIndex() }}
|
|
1586
|
+
>
|
|
1587
|
+
{props.suggestions.stringify({ item, init: suggInitData })}
|
|
1588
|
+
</li>;
|
|
1589
|
+
}}
|
|
1590
|
+
</For>
|
|
1591
|
+
</ul>}
|
|
1592
|
+
</div>
|
|
1593
|
+
|
|
1594
|
+
{!!error() && <span role="alert">{error()}</span>}
|
|
1595
|
+
</div>;
|
|
1596
|
+
};
|
|
1597
|
+
SSForm.Date = function(props) {
|
|
1598
|
+
const context = useContext(SSFormContext);
|
|
1599
|
+
const [value, setValue] = createSignal("");
|
|
1600
|
+
const [error, setError] = createSignal(null);
|
|
1601
|
+
const [open, setOpen] = createSignal(false);
|
|
1602
|
+
const [viewDate, setViewDate] = createSignal(/* @__PURE__ */ new Date());
|
|
1603
|
+
let containerRef;
|
|
1604
|
+
const pad = (num) => `${num}`.padStart(2, "0");
|
|
1605
|
+
const formatDate = (date) => {
|
|
1606
|
+
const day = pad(date.getDate());
|
|
1607
|
+
const month = pad(date.getMonth() + 1);
|
|
1608
|
+
const year = date.getFullYear();
|
|
1609
|
+
return `${day}.${month}.${year}`;
|
|
1610
|
+
};
|
|
1611
|
+
const parseDate = (input) => {
|
|
1612
|
+
const trimmed = input.trim();
|
|
1613
|
+
if (!trimmed) return null;
|
|
1614
|
+
const match = /^(\d{1,2})\.(\d{1,2})\.(\d{4})$/.exec(trimmed);
|
|
1615
|
+
if (!match) return null;
|
|
1616
|
+
const day = Number(match[1]);
|
|
1617
|
+
const month = Number(match[2]);
|
|
1618
|
+
const year = Number(match[3]);
|
|
1619
|
+
if (!day || !month) return null;
|
|
1620
|
+
const date = new Date(year, month - 1, day);
|
|
1621
|
+
if (date.getFullYear() !== year || date.getMonth() !== month - 1 || date.getDate() !== day) {
|
|
1622
|
+
return null;
|
|
1623
|
+
}
|
|
1624
|
+
return date;
|
|
1625
|
+
};
|
|
1626
|
+
createEffect(() => {
|
|
1627
|
+
if (!open()) return;
|
|
1628
|
+
const parsed = parseDate(value());
|
|
1629
|
+
setViewDate(parsed ?? /* @__PURE__ */ new Date());
|
|
1630
|
+
});
|
|
1631
|
+
const field = {
|
|
1632
|
+
getValue: () => {
|
|
1633
|
+
const trimmed = value().trim();
|
|
1634
|
+
if (!trimmed) return null;
|
|
1635
|
+
return trimmed;
|
|
1636
|
+
},
|
|
1637
|
+
setValue: (value2) => {
|
|
1638
|
+
if (value2 instanceof Date) {
|
|
1639
|
+
setValue(formatDate(value2));
|
|
1640
|
+
return;
|
|
1641
|
+
}
|
|
1642
|
+
setValue(`${value2 ?? ""}`);
|
|
1643
|
+
},
|
|
1644
|
+
hasError: () => !!error(),
|
|
1645
|
+
validate: async () => {
|
|
1646
|
+
const rules = [...props.rules ?? []];
|
|
1647
|
+
if (props.required) rules.unshift(SSForm.rules.required);
|
|
1648
|
+
const value2 = await field.getValue();
|
|
1649
|
+
for (const rule of rules) {
|
|
1650
|
+
const newError = await rule(value2);
|
|
1651
|
+
if (newError) {
|
|
1652
|
+
setError(newError);
|
|
1653
|
+
return;
|
|
1654
|
+
}
|
|
1655
|
+
}
|
|
1656
|
+
if (value2 && !parseDate(value2)) {
|
|
1657
|
+
setError("Ung\xFCltiges Datum");
|
|
1658
|
+
return;
|
|
1659
|
+
}
|
|
1660
|
+
setError(null);
|
|
1661
|
+
}
|
|
1662
|
+
};
|
|
1663
|
+
if (props.name && context) {
|
|
1664
|
+
const name = props.name;
|
|
1665
|
+
onMount(() => context.setField(name, field));
|
|
1666
|
+
onCleanup(() => context.delField(name));
|
|
1667
|
+
}
|
|
1668
|
+
const _id = createUniqueId();
|
|
1669
|
+
const isSelected = (day) => {
|
|
1670
|
+
const parsed = parseDate(value());
|
|
1671
|
+
if (!parsed) return false;
|
|
1672
|
+
return parsed.getFullYear() === viewDate().getFullYear() && parsed.getMonth() === viewDate().getMonth() && parsed.getDate() === day;
|
|
1673
|
+
};
|
|
1674
|
+
const isToday = (day) => {
|
|
1675
|
+
const today = /* @__PURE__ */ new Date();
|
|
1676
|
+
return today.getFullYear() === viewDate().getFullYear() && today.getMonth() === viewDate().getMonth() && today.getDate() === day;
|
|
1677
|
+
};
|
|
1678
|
+
const buildCalendar = () => {
|
|
1679
|
+
const current = viewDate();
|
|
1680
|
+
const year = current.getFullYear();
|
|
1681
|
+
const month = current.getMonth();
|
|
1682
|
+
const firstDay = new Date(year, month, 1);
|
|
1683
|
+
const daysInMonth = new Date(year, month + 1, 0).getDate();
|
|
1684
|
+
const startOffset = (firstDay.getDay() + 6) % 7;
|
|
1685
|
+
const cells = [];
|
|
1686
|
+
for (let i = 0; i < startOffset; i += 1) cells.push(null);
|
|
1687
|
+
for (let day = 1; day <= daysInMonth; day += 1) cells.push(day);
|
|
1688
|
+
while (cells.length % 7 !== 0) cells.push(null);
|
|
1689
|
+
return cells;
|
|
1690
|
+
};
|
|
1691
|
+
const monthLabel = () => {
|
|
1692
|
+
return viewDate().toLocaleDateString("de-DE", { month: "long", year: "numeric" });
|
|
1693
|
+
};
|
|
1694
|
+
const handleSelect = (day) => {
|
|
1695
|
+
const next = new Date(viewDate().getFullYear(), viewDate().getMonth(), day);
|
|
1696
|
+
setValue(formatDate(next));
|
|
1697
|
+
setOpen(false);
|
|
1698
|
+
};
|
|
1699
|
+
onMount(() => {
|
|
1700
|
+
const handleOutside = (event) => {
|
|
1701
|
+
if (!open()) return;
|
|
1702
|
+
const target = event.target;
|
|
1703
|
+
if (containerRef && target && !containerRef.contains(target)) {
|
|
1704
|
+
setOpen(false);
|
|
1705
|
+
}
|
|
1706
|
+
};
|
|
1707
|
+
const handleKeyDown = (event) => {
|
|
1708
|
+
if (event.key === "Escape") setOpen(false);
|
|
1709
|
+
};
|
|
1710
|
+
document.addEventListener("mousedown", handleOutside);
|
|
1711
|
+
window.addEventListener("keydown", handleKeyDown);
|
|
1712
|
+
onCleanup(() => {
|
|
1713
|
+
document.removeEventListener("mousedown", handleOutside);
|
|
1714
|
+
window.removeEventListener("keydown", handleKeyDown);
|
|
1715
|
+
});
|
|
1716
|
+
});
|
|
1717
|
+
return <div class="ss_form_date" ref={(el) => containerRef = el}>
|
|
1718
|
+
<label for={props.id || _id}>{props.label}</label>
|
|
1719
|
+
|
|
1720
|
+
<div class="ss__wrapper">
|
|
1721
|
+
<input
|
|
1722
|
+
id={props.id || _id}
|
|
1723
|
+
value={value()}
|
|
1724
|
+
oninput={(e) => setValue(e.target.value)}
|
|
1725
|
+
onfocus={() => setOpen(true)}
|
|
1726
|
+
disabled={props.disabled || context?.loading()}
|
|
1727
|
+
readonly={!props.editable}
|
|
1728
|
+
type="text"
|
|
1729
|
+
inputmode="numeric"
|
|
1730
|
+
autocomplete="off"
|
|
1731
|
+
placeholder="TT.MM.JJJJ"
|
|
1732
|
+
/>
|
|
1733
|
+
<button
|
|
1734
|
+
type="button"
|
|
1735
|
+
class="ss_form_date__icon"
|
|
1736
|
+
aria-label="Kalender öffnen"
|
|
1737
|
+
aria-haspopup="dialog"
|
|
1738
|
+
aria-expanded={open()}
|
|
1739
|
+
onclick={() => setOpen((value2) => !value2)}
|
|
1740
|
+
disabled={props.disabled || context?.loading()}
|
|
1741
|
+
>
|
|
1742
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="currentColor" class="icon icon-tabler icons-tabler-filled icon-tabler-calendar-week"><path stroke="none" d="M0 0h24v24H0z" fill="none" /><path d="M16 2c.183 0 .355 .05 .502 .135l.033 .02c.28 .177 .465 .49 .465 .845v1h1a3 3 0 0 1 2.995 2.824l.005 .176v12a3 3 0 0 1 -2.824 2.995l-.176 .005h-12a3 3 0 0 1 -2.995 -2.824l-.005 -.176v-12a3 3 0 0 1 2.824 -2.995l.176 -.005h1v-1a1 1 0 0 1 .514 -.874l.093 -.046l.066 -.025l.1 -.029l.107 -.019l.12 -.007q .083 0 .161 .013l.122 .029l.04 .012l.06 .023c.328 .135 .568 .44 .61 .806l.007 .117v1h6v-1a1 1 0 0 1 1 -1m3 7h-14v9.625c0 .705 .386 1.286 .883 1.366l.117 .009h12c.513 0 .936 -.53 .993 -1.215l.007 -.16z" /><path d="M9.015 13a1 1 0 0 1 -1 1a1.001 1.001 0 1 1 -.005 -2c.557 0 1.005 .448 1.005 1" /><path d="M13.015 13a1 1 0 0 1 -1 1a1.001 1.001 0 1 1 -.005 -2c.557 0 1.005 .448 1.005 1" /><path d="M17.02 13a1 1 0 0 1 -1 1a1.001 1.001 0 1 1 -.005 -2c.557 0 1.005 .448 1.005 1" /><path d="M12.02 15a1 1 0 0 1 0 2a1.001 1.001 0 1 1 -.005 -2z" /><path d="M9.015 16a1 1 0 0 1 -1 1a1.001 1.001 0 1 1 -.005 -2c.557 0 1.005 .448 1.005 1" /></svg>
|
|
1743
|
+
</button>
|
|
1744
|
+
</div>
|
|
1745
|
+
|
|
1746
|
+
{open() && <div class="ss_form_date__picker" role="dialog" aria-label="Datum auswählen">
|
|
1747
|
+
<div class="ss_form_date__header">
|
|
1748
|
+
<div class="ss_form_date__nav_group">
|
|
1749
|
+
<button type="button" class="ss_form_date__nav" onclick={() => {
|
|
1750
|
+
const current = viewDate();
|
|
1751
|
+
setViewDate(new Date(current.getFullYear() - 1, current.getMonth(), 1));
|
|
1752
|
+
}}>
|
|
1753
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon icon-tabler icons-tabler-outline icon-tabler-chevron-left-pipe"><path stroke="none" d="M0 0h24v24H0z" fill="none" /><path d="M7 6v12" /><path d="M18 6l-6 6l6 6" /></svg>
|
|
1754
|
+
</button>
|
|
1755
|
+
<button type="button" class="ss_form_date__nav" onclick={() => {
|
|
1756
|
+
const current = viewDate();
|
|
1757
|
+
setViewDate(new Date(current.getFullYear(), current.getMonth() - 1, 1));
|
|
1758
|
+
}}>
|
|
1759
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon icon-tabler icons-tabler-outline icon-tabler-chevron-left"><path stroke="none" d="M0 0h24v24H0z" fill="none" /><path d="M15 6l-6 6l6 6" /></svg>
|
|
1760
|
+
</button>
|
|
1761
|
+
</div>
|
|
1762
|
+
<div class="ss_form_date__title">{monthLabel()}</div>
|
|
1763
|
+
<div class="ss_form_date__nav_group">
|
|
1764
|
+
<button type="button" class="ss_form_date__nav" onclick={() => {
|
|
1765
|
+
const current = viewDate();
|
|
1766
|
+
setViewDate(new Date(current.getFullYear(), current.getMonth() + 1, 1));
|
|
1767
|
+
}}>
|
|
1768
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon icon-tabler icons-tabler-outline icon-tabler-chevron-right"><path stroke="none" d="M0 0h24v24H0z" fill="none" /><path d="M9 6l6 6l-6 6" /></svg>
|
|
1769
|
+
</button>
|
|
1770
|
+
<button type="button" class="ss_form_date__nav" onclick={() => {
|
|
1771
|
+
const current = viewDate();
|
|
1772
|
+
setViewDate(new Date(current.getFullYear() + 1, current.getMonth(), 1));
|
|
1773
|
+
}}>
|
|
1774
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon icon-tabler icons-tabler-outline icon-tabler-chevron-right-pipe"><path stroke="none" d="M0 0h24v24H0z" fill="none" /><path d="M6 6l6 6l-6 6" /><path d="M17 5v13" /></svg>
|
|
1775
|
+
</button>
|
|
1776
|
+
</div>
|
|
1777
|
+
</div>
|
|
1778
|
+
<div class="ss_form_date__weekdays">
|
|
1779
|
+
{["Mo", "Di", "Mi", "Do", "Fr", "Sa", "So"].map((day) => <span>{day}</span>)}
|
|
1780
|
+
</div>
|
|
1781
|
+
<div class="ss_form_date__grid">
|
|
1782
|
+
{buildCalendar().map((day) => day ? <button
|
|
1783
|
+
type="button"
|
|
1784
|
+
class="ss_form_date__day"
|
|
1785
|
+
classList={{ "is-selected": isSelected(day), "is-today": isToday(day) }}
|
|
1786
|
+
onclick={() => handleSelect(day)}
|
|
1787
|
+
>
|
|
1788
|
+
{day}
|
|
1789
|
+
</button> : <span class="ss_form_date__day is-empty" />)}
|
|
1790
|
+
</div>
|
|
1791
|
+
</div>}
|
|
1792
|
+
|
|
1793
|
+
{!!error() && <span role="alert">{error()}</span>}
|
|
1794
|
+
</div>;
|
|
1795
|
+
};
|
|
1796
|
+
SSForm.Checkbox = function(props) {
|
|
1797
|
+
const context = useContext(SSFormContext);
|
|
1798
|
+
const [value, setValue] = createSignal(false);
|
|
1799
|
+
const [error, setError] = createSignal(null);
|
|
1800
|
+
const field = {
|
|
1801
|
+
getValue: () => value(),
|
|
1802
|
+
setValue: (value2) => setValue(!!value2),
|
|
1803
|
+
hasError: () => !!error(),
|
|
1804
|
+
validate: async () => {
|
|
1805
|
+
const rules = [...props.rules ?? []];
|
|
1806
|
+
if (props.required) rules.unshift(SSForm.rules.required);
|
|
1807
|
+
const value2 = await field.getValue();
|
|
1808
|
+
for (const rule of rules) {
|
|
1809
|
+
const newError = await rule(value2);
|
|
1810
|
+
if (newError) {
|
|
1811
|
+
setError(newError);
|
|
1812
|
+
return;
|
|
1813
|
+
}
|
|
1814
|
+
}
|
|
1815
|
+
setError(null);
|
|
1816
|
+
}
|
|
1817
|
+
};
|
|
1818
|
+
if (props.name && context) {
|
|
1819
|
+
const name = props.name;
|
|
1820
|
+
onMount(() => context.setField(name, field));
|
|
1821
|
+
onCleanup(() => context.delField(name));
|
|
1822
|
+
}
|
|
1823
|
+
const _id = createUniqueId();
|
|
1824
|
+
return <div class="ss_form_checkbox">
|
|
1825
|
+
<div class="ss__wrapper">
|
|
1826
|
+
<input
|
|
1827
|
+
id={props.id || _id}
|
|
1828
|
+
type="checkbox"
|
|
1829
|
+
checked={value()}
|
|
1830
|
+
onchange={(e) => setValue(e.target.checked)}
|
|
1831
|
+
disabled={props.disabled || context?.loading()}
|
|
1832
|
+
/>
|
|
1833
|
+
<label for={props.id || _id}>{props.label}</label>
|
|
1834
|
+
</div>
|
|
1835
|
+
|
|
1836
|
+
{!!error() && <span role="alert">{error()}</span>}
|
|
1837
|
+
</div>;
|
|
1838
|
+
};
|
|
1839
|
+
SSForm.useContext = function() {
|
|
1840
|
+
const context = useContext(SSFormContext);
|
|
1841
|
+
if (!context) return null;
|
|
1842
|
+
const { setField, delField, ...publicContext } = context;
|
|
1843
|
+
return publicContext;
|
|
1844
|
+
};
|
|
1845
|
+
SSForm.Select = function(props) {
|
|
1846
|
+
const context = useContext(SSFormContext);
|
|
1847
|
+
const [options, setOptions] = createSignal([]);
|
|
1848
|
+
const [value, setValue] = createSignal(null);
|
|
1849
|
+
const [error, setError] = createSignal(null);
|
|
1850
|
+
const handleSetOptions = (result) => {
|
|
1851
|
+
const built = result.map((opt) => ({ id: opt.id, label: props.buildOption(opt) }));
|
|
1852
|
+
setOptions(built);
|
|
1853
|
+
if (!result.length) {
|
|
1854
|
+
setValue(null);
|
|
1855
|
+
return;
|
|
1856
|
+
}
|
|
1857
|
+
if (value() && built.some((e) => e.id === value())) return;
|
|
1858
|
+
setValue(built[0].id);
|
|
1859
|
+
};
|
|
1860
|
+
createEffect(() => {
|
|
1861
|
+
const newOptions = props.getOptions();
|
|
1862
|
+
if ("then" in newOptions && typeof newOptions.then === "function" || newOptions instanceof Promise) {
|
|
1863
|
+
newOptions.then(handleSetOptions);
|
|
1864
|
+
} else {
|
|
1865
|
+
handleSetOptions(newOptions);
|
|
1866
|
+
}
|
|
1867
|
+
});
|
|
1868
|
+
const field = {
|
|
1869
|
+
getValue: () => {
|
|
1870
|
+
const _value = value();
|
|
1871
|
+
const availableOptions = options();
|
|
1872
|
+
if (!availableOptions.some((e) => e.id === _value)) {
|
|
1873
|
+
return null;
|
|
1874
|
+
}
|
|
1875
|
+
return _value;
|
|
1876
|
+
},
|
|
1877
|
+
setValue: (newValue) => {
|
|
1878
|
+
const availableOptions = options();
|
|
1879
|
+
if (!availableOptions.length) {
|
|
1880
|
+
setValue(null);
|
|
1881
|
+
return;
|
|
1882
|
+
}
|
|
1883
|
+
const defaultOption = availableOptions[0].id;
|
|
1884
|
+
if (typeof newValue !== "string") {
|
|
1885
|
+
setValue(defaultOption);
|
|
1886
|
+
return;
|
|
1887
|
+
}
|
|
1888
|
+
const _newValue = newValue.trim();
|
|
1889
|
+
if (!availableOptions.some((e) => e.id === _newValue)) {
|
|
1890
|
+
setValue(defaultOption);
|
|
1891
|
+
return;
|
|
1892
|
+
}
|
|
1893
|
+
setValue(_newValue);
|
|
1894
|
+
},
|
|
1895
|
+
hasError: () => !!error(),
|
|
1896
|
+
validate: async () => {
|
|
1897
|
+
const availableOptions = options();
|
|
1898
|
+
const value2 = await field.getValue();
|
|
1899
|
+
if (!value2) {
|
|
1900
|
+
setError("Pflichtfeld");
|
|
1901
|
+
return;
|
|
1902
|
+
}
|
|
1903
|
+
if (!availableOptions.some((e) => e.id === value2)) {
|
|
1904
|
+
setError("Option nicht verf\xFCgbar");
|
|
1905
|
+
return;
|
|
1906
|
+
}
|
|
1907
|
+
for (const rule of props.rules ?? []) {
|
|
1908
|
+
const err = await rule(value2);
|
|
1909
|
+
if (err) {
|
|
1910
|
+
setError(err);
|
|
1911
|
+
return;
|
|
1912
|
+
}
|
|
1913
|
+
}
|
|
1914
|
+
setError(null);
|
|
1915
|
+
}
|
|
1916
|
+
};
|
|
1917
|
+
field.setOptions = handleSetOptions;
|
|
1918
|
+
if (props.name && context) {
|
|
1919
|
+
const name = props.name;
|
|
1920
|
+
onMount(() => context.setField(name, field));
|
|
1921
|
+
onCleanup(() => context.delField(name));
|
|
1922
|
+
}
|
|
1923
|
+
const _id = createUniqueId();
|
|
1924
|
+
return <div class="ss_form_select">
|
|
1925
|
+
<label for={props.id || _id}>{props.label}</label>
|
|
1926
|
+
|
|
1927
|
+
<div class="ss_form_select__field">
|
|
1928
|
+
<select
|
|
1929
|
+
id={props.id || _id}
|
|
1930
|
+
onchange={(e) => setValue(e.target.value)}
|
|
1931
|
+
disabled={props.disabled || context?.loading()}
|
|
1932
|
+
>
|
|
1933
|
+
<For each={options()}>
|
|
1934
|
+
{(opt) => <option value={opt.id} selected={value() === opt.id}>{opt.label}</option>}
|
|
1935
|
+
</For>
|
|
1936
|
+
</select>
|
|
1937
|
+
<span class="ss_form_select__icon" aria-hidden="true">
|
|
1938
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon icon-tabler icons-tabler-outline icon-tabler-chevron-down"><path stroke="none" d="M0 0h24v24H0z" fill="none" /><path d="M6 9l6 6l6 -6" /></svg>
|
|
1939
|
+
</span>
|
|
1940
|
+
</div>
|
|
1941
|
+
|
|
1942
|
+
{!!error() && <span role="alert">{error()}</span>}
|
|
1943
|
+
</div>;
|
|
1944
|
+
};
|
|
1945
|
+
SSForm.ACSelect = function(props) {
|
|
1946
|
+
const context = useContext(SSFormContext);
|
|
1947
|
+
const [query2, setQuery] = createSignal("");
|
|
1948
|
+
const [value, setValue] = createSignal([]);
|
|
1949
|
+
const [error, setError] = createSignal(null);
|
|
1950
|
+
const field = {
|
|
1951
|
+
getValue: () => value(),
|
|
1952
|
+
setValue: (newValue) => setValue(newValue),
|
|
1953
|
+
hasError: () => !!error(),
|
|
1954
|
+
validate: async () => {
|
|
1955
|
+
const value2 = await field.getValue();
|
|
1956
|
+
const min = props.minSelectedItems;
|
|
1957
|
+
const max = props.maxSelectedItems;
|
|
1958
|
+
if (min) {
|
|
1959
|
+
if (value2.length < min) {
|
|
1960
|
+
setError(`Mindestens ${min} ${min > 1 ? "Elemente m\xFCssen" : "Element muss"} ausgew\xE4hlt werden`);
|
|
1961
|
+
return;
|
|
1962
|
+
}
|
|
1963
|
+
}
|
|
1964
|
+
if (max) {
|
|
1965
|
+
if (value2.length > max) {
|
|
1966
|
+
setError(`Maximal ${max} ${max > 1 ? "Elemente d\xFCrfen" : "Element darf"} ausgew\xE4hlt werden`);
|
|
1967
|
+
return;
|
|
1968
|
+
}
|
|
1969
|
+
}
|
|
1970
|
+
for (const rule of props.rules ?? []) {
|
|
1971
|
+
const err = await rule(value2);
|
|
1972
|
+
if (err) {
|
|
1973
|
+
setError(err);
|
|
1974
|
+
return;
|
|
1975
|
+
}
|
|
1976
|
+
}
|
|
1977
|
+
setError(null);
|
|
1978
|
+
}
|
|
1979
|
+
};
|
|
1980
|
+
if (props.name && context) {
|
|
1981
|
+
const name = props.name;
|
|
1982
|
+
onMount(() => context.setField(name, field));
|
|
1983
|
+
onCleanup(() => context.delField(name));
|
|
1984
|
+
}
|
|
1985
|
+
let initData = null;
|
|
1986
|
+
const [initialized, setInitialized] = createSignal(!props.prepare);
|
|
1987
|
+
if (props.prepare) onMount(async () => {
|
|
1988
|
+
if (!props.prepare) return;
|
|
1989
|
+
initData = await props.prepare();
|
|
1990
|
+
setInitialized(true);
|
|
1991
|
+
});
|
|
1992
|
+
const [suggItems, setSuggItems] = createSignal([]);
|
|
1993
|
+
const [suggIndex, setSuggIndex] = createSignal(-1);
|
|
1994
|
+
let suggListRef;
|
|
1995
|
+
let timeout;
|
|
1996
|
+
createEffect(() => {
|
|
1997
|
+
if (!initialized()) return;
|
|
1998
|
+
clearTimeout(timeout);
|
|
1999
|
+
const _query = query2().trim().toLowerCase();
|
|
2000
|
+
if (!_query) {
|
|
2001
|
+
setSuggItems(untrack(() => value()));
|
|
2002
|
+
return;
|
|
2003
|
+
}
|
|
2004
|
+
setSuggItems([]);
|
|
2005
|
+
timeout = setTimeout(async () => {
|
|
2006
|
+
const items = await props.getOptions({ query: _query, init: initData });
|
|
2007
|
+
setSuggItems(items);
|
|
2008
|
+
}, 250);
|
|
2009
|
+
});
|
|
2010
|
+
createEffect(() => {
|
|
2011
|
+
const _query = query2().trim().toLowerCase();
|
|
2012
|
+
if (_query) return;
|
|
2013
|
+
if (suggItems().length !== value().length) setSuggItems(value());
|
|
2014
|
+
});
|
|
2015
|
+
onCleanup(() => clearTimeout(timeout));
|
|
2016
|
+
createEffect(() => {
|
|
2017
|
+
const items = suggItems();
|
|
2018
|
+
if (!items.length) {
|
|
2019
|
+
setSuggIndex(-1);
|
|
2020
|
+
return;
|
|
2021
|
+
}
|
|
2022
|
+
if (suggIndex() >= items.length) setSuggIndex(items.length - 1);
|
|
2023
|
+
});
|
|
2024
|
+
const scrollToIndex = (idx) => {
|
|
2025
|
+
const list = suggListRef;
|
|
2026
|
+
if (!list || idx < 0) return;
|
|
2027
|
+
const item = list.querySelectorAll("li")[idx];
|
|
2028
|
+
if (!item) return;
|
|
2029
|
+
const itemTop = item.offsetTop;
|
|
2030
|
+
const itemBottom = itemTop + item.offsetHeight;
|
|
2031
|
+
const viewTop = list.scrollTop;
|
|
2032
|
+
const viewBottom = viewTop + list.clientHeight;
|
|
2033
|
+
if (itemTop < viewTop) list.scrollTop = itemTop;
|
|
2034
|
+
else if (itemBottom > viewBottom) list.scrollTop = itemBottom - list.clientHeight;
|
|
2035
|
+
};
|
|
2036
|
+
const moveIndex = (delta) => {
|
|
2037
|
+
const items = suggItems();
|
|
2038
|
+
if (!items.length) return;
|
|
2039
|
+
const next = Math.max(-1, Math.min(suggIndex() + delta, items.length - 1));
|
|
2040
|
+
setSuggIndex(next);
|
|
2041
|
+
scrollToIndex(next);
|
|
2042
|
+
};
|
|
2043
|
+
const _id = createUniqueId();
|
|
2044
|
+
const selectedIds = createMemo(() => {
|
|
2045
|
+
return new Set(value().map(({ id }) => id));
|
|
2046
|
+
});
|
|
2047
|
+
const selectItem = (item, resetIndex = true) => {
|
|
2048
|
+
const isSelected = selectedIds().has(item.id);
|
|
2049
|
+
if (props.maxSelectedItems === 1) {
|
|
2050
|
+
setValue(isSelected ? [] : [item]);
|
|
2051
|
+
setQuery("");
|
|
2052
|
+
if (resetIndex) setSuggIndex(-1);
|
|
2053
|
+
return;
|
|
2054
|
+
}
|
|
2055
|
+
if (isSelected) {
|
|
2056
|
+
setValue((value2) => value2.filter(({ id }) => id !== item.id));
|
|
2057
|
+
} else {
|
|
2058
|
+
setValue((value2) => [...value2.filter(({ id }) => id !== item.id), item]);
|
|
2059
|
+
}
|
|
2060
|
+
if (resetIndex) setSuggIndex(-1);
|
|
2061
|
+
};
|
|
2062
|
+
const handleKeyDown = (e) => {
|
|
2063
|
+
if (!suggItems().length) return;
|
|
2064
|
+
if (e.key === "ArrowDown") {
|
|
2065
|
+
e.preventDefault();
|
|
2066
|
+
moveIndex(1);
|
|
2067
|
+
} else if (e.key === "ArrowUp") {
|
|
2068
|
+
e.preventDefault();
|
|
2069
|
+
moveIndex(-1);
|
|
2070
|
+
} else if (e.key === "Enter" && suggIndex() >= 0) {
|
|
2071
|
+
e.preventDefault();
|
|
2072
|
+
const item = suggItems()[suggIndex()];
|
|
2073
|
+
if (item) selectItem(item, false);
|
|
2074
|
+
} else if (e.key === "Escape") {
|
|
2075
|
+
setSuggIndex(-1);
|
|
2076
|
+
}
|
|
2077
|
+
};
|
|
2078
|
+
const isDisabled = () => props.disabled || context?.loading();
|
|
2079
|
+
return <div class="ss_form_ac_select">
|
|
2080
|
+
<label for={props.id || _id}>{props.label}</label>
|
|
2081
|
+
|
|
2082
|
+
{props.maxSelectedItems === 1 && !!props.renderSelection && value().length === 1 ? <div class="ss__selection">
|
|
2083
|
+
<div class="ss__content">
|
|
2084
|
+
{props.renderSelection({ item: value()[0], init: initData })}
|
|
2085
|
+
</div>
|
|
2086
|
+
<button
|
|
2087
|
+
type="button"
|
|
2088
|
+
class="ss__clear"
|
|
2089
|
+
disabled={isDisabled()}
|
|
2090
|
+
aria-label="Auswahl entfernen"
|
|
2091
|
+
onclick={() => {
|
|
2092
|
+
setValue([]);
|
|
2093
|
+
setQuery("");
|
|
2094
|
+
setTimeout(() => document.getElementById(props.id || _id)?.focus(), 0);
|
|
2095
|
+
}}
|
|
2096
|
+
>
|
|
2097
|
+
×
|
|
2098
|
+
</button>
|
|
2099
|
+
</div> : <div class="ss__wrapper">
|
|
2100
|
+
|
|
2101
|
+
<div class="ss__input_row">
|
|
2102
|
+
{!!value().length && <span
|
|
2103
|
+
class="ss__prefix"
|
|
2104
|
+
role="button"
|
|
2105
|
+
tabindex={isDisabled() ? -1 : 0}
|
|
2106
|
+
aria-disabled={isDisabled() ? "true" : void 0}
|
|
2107
|
+
onkeydown={(event) => {
|
|
2108
|
+
if (isDisabled()) return;
|
|
2109
|
+
if (event.key === "Enter" || event.key === " ") {
|
|
2110
|
+
event.preventDefault();
|
|
2111
|
+
setValue([]);
|
|
2112
|
+
}
|
|
2113
|
+
}}
|
|
2114
|
+
onclick={() => {
|
|
2115
|
+
if (isDisabled()) return;
|
|
2116
|
+
setValue([]);
|
|
2117
|
+
}}
|
|
2118
|
+
>
|
|
2119
|
+
{value().length}
|
|
2120
|
+
</span>}
|
|
2121
|
+
|
|
2122
|
+
<input
|
|
2123
|
+
id={props.id || _id}
|
|
2124
|
+
value={query2()}
|
|
2125
|
+
oninput={(e) => {
|
|
2126
|
+
if (isDisabled()) return;
|
|
2127
|
+
setQuery(e.target.value);
|
|
2128
|
+
setSuggIndex(-1);
|
|
2129
|
+
}}
|
|
2130
|
+
onkeydown={handleKeyDown}
|
|
2131
|
+
disabled={isDisabled()}
|
|
2132
|
+
/>
|
|
2133
|
+
</div>
|
|
2134
|
+
|
|
2135
|
+
{!!suggItems().length && <ul class="ss__suggestions" ref={(el) => suggListRef = el}>
|
|
2136
|
+
<For each={suggItems()}>
|
|
2137
|
+
{(item, idx) => {
|
|
2138
|
+
const handleSelect = () => {
|
|
2139
|
+
if (isDisabled()) return;
|
|
2140
|
+
selectItem(item);
|
|
2141
|
+
document.getElementById(props.id || _id)?.focus();
|
|
2142
|
+
};
|
|
2143
|
+
return <li
|
|
2144
|
+
onpointerdown={(e) => e.preventDefault()}
|
|
2145
|
+
onclick={handleSelect}
|
|
2146
|
+
classList={{
|
|
2147
|
+
"ss__selected": selectedIds().has(item.id),
|
|
2148
|
+
"ss__hovered": idx() === suggIndex()
|
|
2149
|
+
}}
|
|
2150
|
+
>
|
|
2151
|
+
{props.renderItem({ item, init: initData })}
|
|
2152
|
+
</li>;
|
|
2153
|
+
}}
|
|
2154
|
+
</For>
|
|
2155
|
+
</ul>}
|
|
2156
|
+
</div>}
|
|
2157
|
+
|
|
2158
|
+
{!!error() && <span role="alert">{error()}</span>}
|
|
2159
|
+
</div>;
|
|
2160
|
+
};
|
|
2161
|
+
SSForm.SubmitButton = function(props) {
|
|
2162
|
+
const context = useContext(SSFormContext);
|
|
2163
|
+
return <SSButton
|
|
2164
|
+
type="submit"
|
|
2165
|
+
class="ss_form_submit"
|
|
2166
|
+
disabled={props.disabled || context?.loading()}
|
|
2167
|
+
>
|
|
2168
|
+
{props.children}
|
|
2169
|
+
</SSButton>;
|
|
2170
|
+
};
|
|
2171
|
+
SSForm.rules = {
|
|
2172
|
+
required: (value) => !value ? "Pflichtfeld" : null,
|
|
2173
|
+
minLength: (length) => (value) => {
|
|
2174
|
+
if (value === null) value = "";
|
|
2175
|
+
if (typeof value !== "string") {
|
|
2176
|
+
throw new Error(`invalid rule minLength(..) for non-string value ${value}`);
|
|
2177
|
+
}
|
|
2178
|
+
if (value.length < length) return `Mindestens ${length} Zeichen`;
|
|
2179
|
+
return null;
|
|
2180
|
+
},
|
|
2181
|
+
maxLength: (length) => (value) => {
|
|
2182
|
+
if (value === null) value = "";
|
|
2183
|
+
if (typeof value !== "string") {
|
|
2184
|
+
throw new Error(`invalid rule maxLength(..) for non-string value ${value}`);
|
|
2185
|
+
}
|
|
2186
|
+
if (value.length < length) return `Maximal ${length} Zeichen`;
|
|
2187
|
+
return null;
|
|
2188
|
+
},
|
|
2189
|
+
pattern: (pattern) => (value) => {
|
|
2190
|
+
if (value === null) value = "";
|
|
2191
|
+
if (typeof value !== "string") {
|
|
2192
|
+
throw new Error(`invalid rule pattern(..) for non-string value ${value}`);
|
|
2193
|
+
}
|
|
2194
|
+
if (!pattern.test(value)) return "Eingabe widerspricht erwartetem Muster";
|
|
2195
|
+
return null;
|
|
2196
|
+
}
|
|
2197
|
+
};
|
|
2198
|
+
|
|
2199
|
+
// src/components/SSHeader.tsx
|
|
2200
|
+
function SSHeader(props) {
|
|
2201
|
+
return <div class={`ss_header ${props.class ?? ""}`} style={props.style}>
|
|
2202
|
+
<div class="ss_header__text">
|
|
2203
|
+
<h3 class="ss_header__title">{props.title}</h3>
|
|
2204
|
+
{props.subtitle && <h5 class="ss_header__subtitle">{props.subtitle}</h5>}
|
|
2205
|
+
</div>
|
|
2206
|
+
<div class="ss_header__actions">{props.actions}</div>
|
|
2207
|
+
</div>;
|
|
2208
|
+
}
|
|
2209
|
+
|
|
2210
|
+
// node_modules/solid-js/web/dist/web.js
|
|
2211
|
+
var booleans = [
|
|
2212
|
+
"allowfullscreen",
|
|
2213
|
+
"async",
|
|
2214
|
+
"alpha",
|
|
2215
|
+
"autofocus",
|
|
2216
|
+
"autoplay",
|
|
2217
|
+
"checked",
|
|
2218
|
+
"controls",
|
|
2219
|
+
"default",
|
|
2220
|
+
"disabled",
|
|
2221
|
+
"formnovalidate",
|
|
2222
|
+
"hidden",
|
|
2223
|
+
"indeterminate",
|
|
2224
|
+
"inert",
|
|
2225
|
+
"ismap",
|
|
2226
|
+
"loop",
|
|
2227
|
+
"multiple",
|
|
2228
|
+
"muted",
|
|
2229
|
+
"nomodule",
|
|
2230
|
+
"novalidate",
|
|
2231
|
+
"open",
|
|
2232
|
+
"playsinline",
|
|
2233
|
+
"readonly",
|
|
2234
|
+
"required",
|
|
2235
|
+
"reversed",
|
|
2236
|
+
"seamless",
|
|
2237
|
+
"selected",
|
|
2238
|
+
"adauctionheaders",
|
|
2239
|
+
"browsingtopics",
|
|
2240
|
+
"credentialless",
|
|
2241
|
+
"defaultchecked",
|
|
2242
|
+
"defaultmuted",
|
|
2243
|
+
"defaultselected",
|
|
2244
|
+
"defer",
|
|
2245
|
+
"disablepictureinpicture",
|
|
2246
|
+
"disableremoteplayback",
|
|
2247
|
+
"preservespitch",
|
|
2248
|
+
"shadowrootclonable",
|
|
2249
|
+
"shadowrootcustomelementregistry",
|
|
2250
|
+
"shadowrootdelegatesfocus",
|
|
2251
|
+
"shadowrootserializable",
|
|
2252
|
+
"sharedstoragewritable"
|
|
2253
|
+
];
|
|
2254
|
+
var Properties = /* @__PURE__ */ new Set([
|
|
2255
|
+
"className",
|
|
2256
|
+
"value",
|
|
2257
|
+
"readOnly",
|
|
2258
|
+
"noValidate",
|
|
2259
|
+
"formNoValidate",
|
|
2260
|
+
"isMap",
|
|
2261
|
+
"noModule",
|
|
2262
|
+
"playsInline",
|
|
2263
|
+
"adAuctionHeaders",
|
|
2264
|
+
"allowFullscreen",
|
|
2265
|
+
"browsingTopics",
|
|
2266
|
+
"defaultChecked",
|
|
2267
|
+
"defaultMuted",
|
|
2268
|
+
"defaultSelected",
|
|
2269
|
+
"disablePictureInPicture",
|
|
2270
|
+
"disableRemotePlayback",
|
|
2271
|
+
"preservesPitch",
|
|
2272
|
+
"shadowRootClonable",
|
|
2273
|
+
"shadowRootCustomElementRegistry",
|
|
2274
|
+
"shadowRootDelegatesFocus",
|
|
2275
|
+
"shadowRootSerializable",
|
|
2276
|
+
"sharedStorageWritable",
|
|
2277
|
+
...booleans
|
|
2278
|
+
]);
|
|
2279
|
+
var ChildProperties = /* @__PURE__ */ new Set(["innerHTML", "textContent", "innerText", "children"]);
|
|
2280
|
+
var Aliases = /* @__PURE__ */ Object.assign(/* @__PURE__ */ Object.create(null), {
|
|
2281
|
+
className: "class",
|
|
2282
|
+
htmlFor: "for"
|
|
2283
|
+
});
|
|
2284
|
+
var PropAliases = /* @__PURE__ */ Object.assign(/* @__PURE__ */ Object.create(null), {
|
|
2285
|
+
class: "className",
|
|
2286
|
+
novalidate: {
|
|
2287
|
+
$: "noValidate",
|
|
2288
|
+
FORM: 1
|
|
2289
|
+
},
|
|
2290
|
+
formnovalidate: {
|
|
2291
|
+
$: "formNoValidate",
|
|
2292
|
+
BUTTON: 1,
|
|
2293
|
+
INPUT: 1
|
|
2294
|
+
},
|
|
2295
|
+
ismap: {
|
|
2296
|
+
$: "isMap",
|
|
2297
|
+
IMG: 1
|
|
2298
|
+
},
|
|
2299
|
+
nomodule: {
|
|
2300
|
+
$: "noModule",
|
|
2301
|
+
SCRIPT: 1
|
|
2302
|
+
},
|
|
2303
|
+
playsinline: {
|
|
2304
|
+
$: "playsInline",
|
|
2305
|
+
VIDEO: 1
|
|
2306
|
+
},
|
|
2307
|
+
readonly: {
|
|
2308
|
+
$: "readOnly",
|
|
2309
|
+
INPUT: 1,
|
|
2310
|
+
TEXTAREA: 1
|
|
2311
|
+
},
|
|
2312
|
+
adauctionheaders: {
|
|
2313
|
+
$: "adAuctionHeaders",
|
|
2314
|
+
IFRAME: 1
|
|
2315
|
+
},
|
|
2316
|
+
allowfullscreen: {
|
|
2317
|
+
$: "allowFullscreen",
|
|
2318
|
+
IFRAME: 1
|
|
2319
|
+
},
|
|
2320
|
+
browsingtopics: {
|
|
2321
|
+
$: "browsingTopics",
|
|
2322
|
+
IMG: 1
|
|
2323
|
+
},
|
|
2324
|
+
defaultchecked: {
|
|
2325
|
+
$: "defaultChecked",
|
|
2326
|
+
INPUT: 1
|
|
2327
|
+
},
|
|
2328
|
+
defaultmuted: {
|
|
2329
|
+
$: "defaultMuted",
|
|
2330
|
+
AUDIO: 1,
|
|
2331
|
+
VIDEO: 1
|
|
2332
|
+
},
|
|
2333
|
+
defaultselected: {
|
|
2334
|
+
$: "defaultSelected",
|
|
2335
|
+
OPTION: 1
|
|
2336
|
+
},
|
|
2337
|
+
disablepictureinpicture: {
|
|
2338
|
+
$: "disablePictureInPicture",
|
|
2339
|
+
VIDEO: 1
|
|
2340
|
+
},
|
|
2341
|
+
disableremoteplayback: {
|
|
2342
|
+
$: "disableRemotePlayback",
|
|
2343
|
+
AUDIO: 1,
|
|
2344
|
+
VIDEO: 1
|
|
2345
|
+
},
|
|
2346
|
+
preservespitch: {
|
|
2347
|
+
$: "preservesPitch",
|
|
2348
|
+
AUDIO: 1,
|
|
2349
|
+
VIDEO: 1
|
|
2350
|
+
},
|
|
2351
|
+
shadowrootclonable: {
|
|
2352
|
+
$: "shadowRootClonable",
|
|
2353
|
+
TEMPLATE: 1
|
|
2354
|
+
},
|
|
2355
|
+
shadowrootdelegatesfocus: {
|
|
2356
|
+
$: "shadowRootDelegatesFocus",
|
|
2357
|
+
TEMPLATE: 1
|
|
2358
|
+
},
|
|
2359
|
+
shadowrootserializable: {
|
|
2360
|
+
$: "shadowRootSerializable",
|
|
2361
|
+
TEMPLATE: 1
|
|
2362
|
+
},
|
|
2363
|
+
sharedstoragewritable: {
|
|
2364
|
+
$: "sharedStorageWritable",
|
|
2365
|
+
IFRAME: 1,
|
|
2366
|
+
IMG: 1
|
|
2367
|
+
}
|
|
2368
|
+
});
|
|
2369
|
+
function getPropAlias(prop, tagName) {
|
|
2370
|
+
const a = PropAliases[prop];
|
|
2371
|
+
return typeof a === "object" ? a[tagName] ? a["$"] : void 0 : a;
|
|
2372
|
+
}
|
|
2373
|
+
var DelegatedEvents = /* @__PURE__ */ new Set(["beforeinput", "click", "dblclick", "contextmenu", "focusin", "focusout", "input", "keydown", "keyup", "mousedown", "mousemove", "mouseout", "mouseover", "mouseup", "pointerdown", "pointermove", "pointerout", "pointerover", "pointerup", "touchend", "touchmove", "touchstart"]);
|
|
2374
|
+
var SVGNamespace = {
|
|
2375
|
+
xlink: "http://www.w3.org/1999/xlink",
|
|
2376
|
+
xml: "http://www.w3.org/XML/1998/namespace"
|
|
2377
|
+
};
|
|
2378
|
+
function reconcileArrays(parentNode, a, b) {
|
|
2379
|
+
let bLength = b.length, aEnd = a.length, bEnd = bLength, aStart = 0, bStart = 0, after = a[aEnd - 1].nextSibling, map = null;
|
|
2380
|
+
while (aStart < aEnd || bStart < bEnd) {
|
|
2381
|
+
if (a[aStart] === b[bStart]) {
|
|
2382
|
+
aStart++;
|
|
2383
|
+
bStart++;
|
|
2384
|
+
continue;
|
|
2385
|
+
}
|
|
2386
|
+
while (a[aEnd - 1] === b[bEnd - 1]) {
|
|
2387
|
+
aEnd--;
|
|
2388
|
+
bEnd--;
|
|
2389
|
+
}
|
|
2390
|
+
if (aEnd === aStart) {
|
|
2391
|
+
const node = bEnd < bLength ? bStart ? b[bStart - 1].nextSibling : b[bEnd - bStart] : after;
|
|
2392
|
+
while (bStart < bEnd) parentNode.insertBefore(b[bStart++], node);
|
|
2393
|
+
} else if (bEnd === bStart) {
|
|
2394
|
+
while (aStart < aEnd) {
|
|
2395
|
+
if (!map || !map.has(a[aStart])) a[aStart].remove();
|
|
2396
|
+
aStart++;
|
|
2397
|
+
}
|
|
2398
|
+
} else if (a[aStart] === b[bEnd - 1] && b[bStart] === a[aEnd - 1]) {
|
|
2399
|
+
const node = a[--aEnd].nextSibling;
|
|
2400
|
+
parentNode.insertBefore(b[bStart++], a[aStart++].nextSibling);
|
|
2401
|
+
parentNode.insertBefore(b[--bEnd], node);
|
|
2402
|
+
a[aEnd] = b[bEnd];
|
|
2403
|
+
} else {
|
|
2404
|
+
if (!map) {
|
|
2405
|
+
map = /* @__PURE__ */ new Map();
|
|
2406
|
+
let i = bStart;
|
|
2407
|
+
while (i < bEnd) map.set(b[i], i++);
|
|
2408
|
+
}
|
|
2409
|
+
const index = map.get(a[aStart]);
|
|
2410
|
+
if (index != null) {
|
|
2411
|
+
if (bStart < index && index < bEnd) {
|
|
2412
|
+
let i = aStart, sequence = 1, t;
|
|
2413
|
+
while (++i < aEnd && i < bEnd) {
|
|
2414
|
+
if ((t = map.get(a[i])) == null || t !== index + sequence) break;
|
|
2415
|
+
sequence++;
|
|
2416
|
+
}
|
|
2417
|
+
if (sequence > index - bStart) {
|
|
2418
|
+
const node = a[aStart];
|
|
2419
|
+
while (bStart < index) parentNode.insertBefore(b[bStart++], node);
|
|
2420
|
+
} else parentNode.replaceChild(b[bStart++], a[aStart++]);
|
|
2421
|
+
} else aStart++;
|
|
2422
|
+
} else a[aStart++].remove();
|
|
2423
|
+
}
|
|
2424
|
+
}
|
|
2425
|
+
}
|
|
2426
|
+
var $$EVENTS = "_$DX_DELEGATE";
|
|
2427
|
+
function template(html, isImportNode, isSVG, isMathML) {
|
|
2428
|
+
let node;
|
|
2429
|
+
const create = () => {
|
|
2430
|
+
const t = isMathML ? document.createElementNS("http://www.w3.org/1998/Math/MathML", "template") : document.createElement("template");
|
|
2431
|
+
t.innerHTML = html;
|
|
2432
|
+
return isSVG ? t.content.firstChild.firstChild : isMathML ? t.firstChild : t.content.firstChild;
|
|
2433
|
+
};
|
|
2434
|
+
const fn = isImportNode ? () => untrack(() => document.importNode(node || (node = create()), true)) : () => (node || (node = create())).cloneNode(true);
|
|
2435
|
+
fn.cloneNode = fn;
|
|
2436
|
+
return fn;
|
|
2437
|
+
}
|
|
2438
|
+
function delegateEvents(eventNames, document2 = window.document) {
|
|
2439
|
+
const e = document2[$$EVENTS] || (document2[$$EVENTS] = /* @__PURE__ */ new Set());
|
|
2440
|
+
for (let i = 0, l = eventNames.length; i < l; i++) {
|
|
2441
|
+
const name = eventNames[i];
|
|
2442
|
+
if (!e.has(name)) {
|
|
2443
|
+
e.add(name);
|
|
2444
|
+
document2.addEventListener(name, eventHandler);
|
|
2445
|
+
}
|
|
2446
|
+
}
|
|
2447
|
+
}
|
|
2448
|
+
function setAttribute(node, name, value) {
|
|
2449
|
+
if (isHydrating(node)) return;
|
|
2450
|
+
if (value == null) node.removeAttribute(name);
|
|
2451
|
+
else node.setAttribute(name, value);
|
|
2452
|
+
}
|
|
2453
|
+
function setAttributeNS(node, namespace, name, value) {
|
|
2454
|
+
if (isHydrating(node)) return;
|
|
2455
|
+
if (value == null) node.removeAttributeNS(namespace, name);
|
|
2456
|
+
else node.setAttributeNS(namespace, name, value);
|
|
2457
|
+
}
|
|
2458
|
+
function setBoolAttribute(node, name, value) {
|
|
2459
|
+
if (isHydrating(node)) return;
|
|
2460
|
+
value ? node.setAttribute(name, "") : node.removeAttribute(name);
|
|
2461
|
+
}
|
|
2462
|
+
function className(node, value) {
|
|
2463
|
+
if (isHydrating(node)) return;
|
|
2464
|
+
if (value == null) node.removeAttribute("class");
|
|
2465
|
+
else node.className = value;
|
|
2466
|
+
}
|
|
2467
|
+
function addEventListener(node, name, handler, delegate) {
|
|
2468
|
+
if (delegate) {
|
|
2469
|
+
if (Array.isArray(handler)) {
|
|
2470
|
+
node[`$$${name}`] = handler[0];
|
|
2471
|
+
node[`$$${name}Data`] = handler[1];
|
|
2472
|
+
} else node[`$$${name}`] = handler;
|
|
2473
|
+
} else if (Array.isArray(handler)) {
|
|
2474
|
+
const handlerFn = handler[0];
|
|
2475
|
+
node.addEventListener(name, handler[0] = (e) => handlerFn.call(node, handler[1], e));
|
|
2476
|
+
} else node.addEventListener(name, handler, typeof handler !== "function" && handler);
|
|
2477
|
+
}
|
|
2478
|
+
function classList(node, value, prev = {}) {
|
|
2479
|
+
const classKeys = Object.keys(value || {}), prevKeys = Object.keys(prev);
|
|
2480
|
+
let i, len;
|
|
2481
|
+
for (i = 0, len = prevKeys.length; i < len; i++) {
|
|
2482
|
+
const key = prevKeys[i];
|
|
2483
|
+
if (!key || key === "undefined" || value[key]) continue;
|
|
2484
|
+
toggleClassKey(node, key, false);
|
|
2485
|
+
delete prev[key];
|
|
2486
|
+
}
|
|
2487
|
+
for (i = 0, len = classKeys.length; i < len; i++) {
|
|
2488
|
+
const key = classKeys[i], classValue = !!value[key];
|
|
2489
|
+
if (!key || key === "undefined" || prev[key] === classValue || !classValue) continue;
|
|
2490
|
+
toggleClassKey(node, key, true);
|
|
2491
|
+
prev[key] = classValue;
|
|
2492
|
+
}
|
|
2493
|
+
return prev;
|
|
2494
|
+
}
|
|
2495
|
+
function style(node, value, prev) {
|
|
2496
|
+
if (!value) return prev ? setAttribute(node, "style") : value;
|
|
2497
|
+
const nodeStyle = node.style;
|
|
2498
|
+
if (typeof value === "string") return nodeStyle.cssText = value;
|
|
2499
|
+
typeof prev === "string" && (nodeStyle.cssText = prev = void 0);
|
|
2500
|
+
prev || (prev = {});
|
|
2501
|
+
value || (value = {});
|
|
2502
|
+
let v, s;
|
|
2503
|
+
for (s in prev) {
|
|
2504
|
+
value[s] == null && nodeStyle.removeProperty(s);
|
|
2505
|
+
delete prev[s];
|
|
2506
|
+
}
|
|
2507
|
+
for (s in value) {
|
|
2508
|
+
v = value[s];
|
|
2509
|
+
if (v !== prev[s]) {
|
|
2510
|
+
nodeStyle.setProperty(s, v);
|
|
2511
|
+
prev[s] = v;
|
|
2512
|
+
}
|
|
2513
|
+
}
|
|
2514
|
+
return prev;
|
|
2515
|
+
}
|
|
2516
|
+
function spread(node, props = {}, isSVG, skipChildren) {
|
|
2517
|
+
const prevProps = {};
|
|
2518
|
+
if (!skipChildren) {
|
|
2519
|
+
createRenderEffect(() => prevProps.children = insertExpression(node, props.children, prevProps.children));
|
|
2520
|
+
}
|
|
2521
|
+
createRenderEffect(() => typeof props.ref === "function" && use(props.ref, node));
|
|
2522
|
+
createRenderEffect(() => assign(node, props, isSVG, true, prevProps, true));
|
|
2523
|
+
return prevProps;
|
|
2524
|
+
}
|
|
2525
|
+
function use(fn, element, arg) {
|
|
2526
|
+
return untrack(() => fn(element, arg));
|
|
2527
|
+
}
|
|
2528
|
+
function insert(parent, accessor, marker, initial) {
|
|
2529
|
+
if (marker !== void 0 && !initial) initial = [];
|
|
2530
|
+
if (typeof accessor !== "function") return insertExpression(parent, accessor, initial, marker);
|
|
2531
|
+
createRenderEffect((current) => insertExpression(parent, accessor(), current, marker), initial);
|
|
2532
|
+
}
|
|
2533
|
+
function assign(node, props, isSVG, skipChildren, prevProps = {}, skipRef = false) {
|
|
2534
|
+
props || (props = {});
|
|
2535
|
+
for (const prop in prevProps) {
|
|
2536
|
+
if (!(prop in props)) {
|
|
2537
|
+
if (prop === "children") continue;
|
|
2538
|
+
prevProps[prop] = assignProp(node, prop, null, prevProps[prop], isSVG, skipRef, props);
|
|
2539
|
+
}
|
|
2540
|
+
}
|
|
2541
|
+
for (const prop in props) {
|
|
2542
|
+
if (prop === "children") {
|
|
2543
|
+
if (!skipChildren) insertExpression(node, props.children);
|
|
2544
|
+
continue;
|
|
2545
|
+
}
|
|
2546
|
+
const value = props[prop];
|
|
2547
|
+
prevProps[prop] = assignProp(node, prop, value, prevProps[prop], isSVG, skipRef, props);
|
|
2548
|
+
}
|
|
2549
|
+
}
|
|
2550
|
+
function isHydrating(node) {
|
|
2551
|
+
return !!sharedConfig.context && !sharedConfig.done && (!node || node.isConnected);
|
|
2552
|
+
}
|
|
2553
|
+
function toPropertyName(name) {
|
|
2554
|
+
return name.toLowerCase().replace(/-([a-z])/g, (_, w) => w.toUpperCase());
|
|
2555
|
+
}
|
|
2556
|
+
function toggleClassKey(node, key, value) {
|
|
2557
|
+
const classNames = key.trim().split(/\s+/);
|
|
2558
|
+
for (let i = 0, nameLen = classNames.length; i < nameLen; i++) node.classList.toggle(classNames[i], value);
|
|
2559
|
+
}
|
|
2560
|
+
function assignProp(node, prop, value, prev, isSVG, skipRef, props) {
|
|
2561
|
+
let isCE, isProp, isChildProp, propAlias, forceProp;
|
|
2562
|
+
if (prop === "style") return style(node, value, prev);
|
|
2563
|
+
if (prop === "classList") return classList(node, value, prev);
|
|
2564
|
+
if (value === prev) return prev;
|
|
2565
|
+
if (prop === "ref") {
|
|
2566
|
+
if (!skipRef) value(node);
|
|
2567
|
+
} else if (prop.slice(0, 3) === "on:") {
|
|
2568
|
+
const e = prop.slice(3);
|
|
2569
|
+
prev && node.removeEventListener(e, prev, typeof prev !== "function" && prev);
|
|
2570
|
+
value && node.addEventListener(e, value, typeof value !== "function" && value);
|
|
2571
|
+
} else if (prop.slice(0, 10) === "oncapture:") {
|
|
2572
|
+
const e = prop.slice(10);
|
|
2573
|
+
prev && node.removeEventListener(e, prev, true);
|
|
2574
|
+
value && node.addEventListener(e, value, true);
|
|
2575
|
+
} else if (prop.slice(0, 2) === "on") {
|
|
2576
|
+
const name = prop.slice(2).toLowerCase();
|
|
2577
|
+
const delegate = DelegatedEvents.has(name);
|
|
2578
|
+
if (!delegate && prev) {
|
|
2579
|
+
const h = Array.isArray(prev) ? prev[0] : prev;
|
|
2580
|
+
node.removeEventListener(name, h);
|
|
2581
|
+
}
|
|
2582
|
+
if (delegate || value) {
|
|
2583
|
+
addEventListener(node, name, value, delegate);
|
|
2584
|
+
delegate && delegateEvents([name]);
|
|
2585
|
+
}
|
|
2586
|
+
} else if (prop.slice(0, 5) === "attr:") {
|
|
2587
|
+
setAttribute(node, prop.slice(5), value);
|
|
2588
|
+
} else if (prop.slice(0, 5) === "bool:") {
|
|
2589
|
+
setBoolAttribute(node, prop.slice(5), value);
|
|
2590
|
+
} else if ((forceProp = prop.slice(0, 5) === "prop:") || (isChildProp = ChildProperties.has(prop)) || !isSVG && ((propAlias = getPropAlias(prop, node.tagName)) || (isProp = Properties.has(prop))) || (isCE = node.nodeName.includes("-") || "is" in props)) {
|
|
2591
|
+
if (forceProp) {
|
|
2592
|
+
prop = prop.slice(5);
|
|
2593
|
+
isProp = true;
|
|
2594
|
+
} else if (isHydrating(node)) return value;
|
|
2595
|
+
if (prop === "class" || prop === "className") className(node, value);
|
|
2596
|
+
else if (isCE && !isProp && !isChildProp) node[toPropertyName(prop)] = value;
|
|
2597
|
+
else node[propAlias || prop] = value;
|
|
2598
|
+
} else {
|
|
2599
|
+
const ns = isSVG && prop.indexOf(":") > -1 && SVGNamespace[prop.split(":")[0]];
|
|
2600
|
+
if (ns) setAttributeNS(node, ns, prop, value);
|
|
2601
|
+
else setAttribute(node, Aliases[prop] || prop, value);
|
|
2602
|
+
}
|
|
2603
|
+
return value;
|
|
2604
|
+
}
|
|
2605
|
+
function eventHandler(e) {
|
|
2606
|
+
if (sharedConfig.registry && sharedConfig.events) {
|
|
2607
|
+
if (sharedConfig.events.find(([el, ev]) => ev === e)) return;
|
|
2608
|
+
}
|
|
2609
|
+
let node = e.target;
|
|
2610
|
+
const key = `$$${e.type}`;
|
|
2611
|
+
const oriTarget = e.target;
|
|
2612
|
+
const oriCurrentTarget = e.currentTarget;
|
|
2613
|
+
const retarget = (value) => Object.defineProperty(e, "target", {
|
|
2614
|
+
configurable: true,
|
|
2615
|
+
value
|
|
2616
|
+
});
|
|
2617
|
+
const handleNode = () => {
|
|
2618
|
+
const handler = node[key];
|
|
2619
|
+
if (handler && !node.disabled) {
|
|
2620
|
+
const data = node[`${key}Data`];
|
|
2621
|
+
data !== void 0 ? handler.call(node, data, e) : handler.call(node, e);
|
|
2622
|
+
if (e.cancelBubble) return;
|
|
2623
|
+
}
|
|
2624
|
+
node.host && typeof node.host !== "string" && !node.host._$host && node.contains(e.target) && retarget(node.host);
|
|
2625
|
+
return true;
|
|
2626
|
+
};
|
|
2627
|
+
const walkUpTree = () => {
|
|
2628
|
+
while (handleNode() && (node = node._$host || node.parentNode || node.host)) ;
|
|
2629
|
+
};
|
|
2630
|
+
Object.defineProperty(e, "currentTarget", {
|
|
2631
|
+
configurable: true,
|
|
2632
|
+
get() {
|
|
2633
|
+
return node || document;
|
|
2634
|
+
}
|
|
2635
|
+
});
|
|
2636
|
+
if (sharedConfig.registry && !sharedConfig.done) sharedConfig.done = _$HY.done = true;
|
|
2637
|
+
if (e.composedPath) {
|
|
2638
|
+
const path = e.composedPath();
|
|
2639
|
+
retarget(path[0]);
|
|
2640
|
+
for (let i = 0; i < path.length - 2; i++) {
|
|
2641
|
+
node = path[i];
|
|
2642
|
+
if (!handleNode()) break;
|
|
2643
|
+
if (node._$host) {
|
|
2644
|
+
node = node._$host;
|
|
2645
|
+
walkUpTree();
|
|
2646
|
+
break;
|
|
2647
|
+
}
|
|
2648
|
+
if (node.parentNode === oriCurrentTarget) {
|
|
2649
|
+
break;
|
|
2650
|
+
}
|
|
2651
|
+
}
|
|
2652
|
+
} else walkUpTree();
|
|
2653
|
+
retarget(oriTarget);
|
|
2654
|
+
}
|
|
2655
|
+
function insertExpression(parent, value, current, marker, unwrapArray) {
|
|
2656
|
+
const hydrating = isHydrating(parent);
|
|
2657
|
+
if (hydrating) {
|
|
2658
|
+
!current && (current = [...parent.childNodes]);
|
|
2659
|
+
let cleaned = [];
|
|
2660
|
+
for (let i = 0; i < current.length; i++) {
|
|
2661
|
+
const node = current[i];
|
|
2662
|
+
if (node.nodeType === 8 && node.data.slice(0, 2) === "!$") node.remove();
|
|
2663
|
+
else cleaned.push(node);
|
|
2664
|
+
}
|
|
2665
|
+
current = cleaned;
|
|
2666
|
+
}
|
|
2667
|
+
while (typeof current === "function") current = current();
|
|
2668
|
+
if (value === current) return current;
|
|
2669
|
+
const t = typeof value, multi = marker !== void 0;
|
|
2670
|
+
parent = multi && current[0] && current[0].parentNode || parent;
|
|
2671
|
+
if (t === "string" || t === "number") {
|
|
2672
|
+
if (hydrating) return current;
|
|
2673
|
+
if (t === "number") {
|
|
2674
|
+
value = value.toString();
|
|
2675
|
+
if (value === current) return current;
|
|
2676
|
+
}
|
|
2677
|
+
if (multi) {
|
|
2678
|
+
let node = current[0];
|
|
2679
|
+
if (node && node.nodeType === 3) {
|
|
2680
|
+
node.data !== value && (node.data = value);
|
|
2681
|
+
} else node = document.createTextNode(value);
|
|
2682
|
+
current = cleanChildren(parent, current, marker, node);
|
|
2683
|
+
} else {
|
|
2684
|
+
if (current !== "" && typeof current === "string") {
|
|
2685
|
+
current = parent.firstChild.data = value;
|
|
2686
|
+
} else current = parent.textContent = value;
|
|
2687
|
+
}
|
|
2688
|
+
} else if (value == null || t === "boolean") {
|
|
2689
|
+
if (hydrating) return current;
|
|
2690
|
+
current = cleanChildren(parent, current, marker);
|
|
2691
|
+
} else if (t === "function") {
|
|
2692
|
+
createRenderEffect(() => {
|
|
2693
|
+
let v = value();
|
|
2694
|
+
while (typeof v === "function") v = v();
|
|
2695
|
+
current = insertExpression(parent, v, current, marker);
|
|
2696
|
+
});
|
|
2697
|
+
return () => current;
|
|
2698
|
+
} else if (Array.isArray(value)) {
|
|
2699
|
+
const array = [];
|
|
2700
|
+
const currentArray = current && Array.isArray(current);
|
|
2701
|
+
if (normalizeIncomingArray(array, value, current, unwrapArray)) {
|
|
2702
|
+
createRenderEffect(() => current = insertExpression(parent, array, current, marker, true));
|
|
2703
|
+
return () => current;
|
|
2704
|
+
}
|
|
2705
|
+
if (hydrating) {
|
|
2706
|
+
if (!array.length) return current;
|
|
2707
|
+
if (marker === void 0) return current = [...parent.childNodes];
|
|
2708
|
+
let node = array[0];
|
|
2709
|
+
if (node.parentNode !== parent) return current;
|
|
2710
|
+
const nodes = [node];
|
|
2711
|
+
while ((node = node.nextSibling) !== marker) nodes.push(node);
|
|
2712
|
+
return current = nodes;
|
|
2713
|
+
}
|
|
2714
|
+
if (array.length === 0) {
|
|
2715
|
+
current = cleanChildren(parent, current, marker);
|
|
2716
|
+
if (multi) return current;
|
|
2717
|
+
} else if (currentArray) {
|
|
2718
|
+
if (current.length === 0) {
|
|
2719
|
+
appendNodes(parent, array, marker);
|
|
2720
|
+
} else reconcileArrays(parent, current, array);
|
|
2721
|
+
} else {
|
|
2722
|
+
current && cleanChildren(parent);
|
|
2723
|
+
appendNodes(parent, array);
|
|
2724
|
+
}
|
|
2725
|
+
current = array;
|
|
2726
|
+
} else if (value.nodeType) {
|
|
2727
|
+
if (hydrating && value.parentNode) return current = multi ? [value] : value;
|
|
2728
|
+
if (Array.isArray(current)) {
|
|
2729
|
+
if (multi) return current = cleanChildren(parent, current, marker, value);
|
|
2730
|
+
cleanChildren(parent, current, null, value);
|
|
2731
|
+
} else if (current == null || current === "" || !parent.firstChild) {
|
|
2732
|
+
parent.appendChild(value);
|
|
2733
|
+
} else parent.replaceChild(value, parent.firstChild);
|
|
2734
|
+
current = value;
|
|
2735
|
+
} else ;
|
|
2736
|
+
return current;
|
|
2737
|
+
}
|
|
2738
|
+
function normalizeIncomingArray(normalized, array, current, unwrap) {
|
|
2739
|
+
let dynamic = false;
|
|
2740
|
+
for (let i = 0, len = array.length; i < len; i++) {
|
|
2741
|
+
let item = array[i], prev = current && current[normalized.length], t;
|
|
2742
|
+
if (item == null || item === true || item === false) ;
|
|
2743
|
+
else if ((t = typeof item) === "object" && item.nodeType) {
|
|
2744
|
+
normalized.push(item);
|
|
2745
|
+
} else if (Array.isArray(item)) {
|
|
2746
|
+
dynamic = normalizeIncomingArray(normalized, item, prev) || dynamic;
|
|
2747
|
+
} else if (t === "function") {
|
|
2748
|
+
if (unwrap) {
|
|
2749
|
+
while (typeof item === "function") item = item();
|
|
2750
|
+
dynamic = normalizeIncomingArray(normalized, Array.isArray(item) ? item : [item], Array.isArray(prev) ? prev : [prev]) || dynamic;
|
|
2751
|
+
} else {
|
|
2752
|
+
normalized.push(item);
|
|
2753
|
+
dynamic = true;
|
|
2754
|
+
}
|
|
2755
|
+
} else {
|
|
2756
|
+
const value = String(item);
|
|
2757
|
+
if (prev && prev.nodeType === 3 && prev.data === value) normalized.push(prev);
|
|
2758
|
+
else normalized.push(document.createTextNode(value));
|
|
2759
|
+
}
|
|
2760
|
+
}
|
|
2761
|
+
return dynamic;
|
|
2762
|
+
}
|
|
2763
|
+
function appendNodes(parent, array, marker = null) {
|
|
2764
|
+
for (let i = 0, len = array.length; i < len; i++) parent.insertBefore(array[i], marker);
|
|
2765
|
+
}
|
|
2766
|
+
function cleanChildren(parent, current, marker, replacement) {
|
|
2767
|
+
if (marker === void 0) return parent.textContent = "";
|
|
2768
|
+
const node = replacement || document.createTextNode("");
|
|
2769
|
+
if (current.length) {
|
|
2770
|
+
let inserted = false;
|
|
2771
|
+
for (let i = current.length - 1; i >= 0; i--) {
|
|
2772
|
+
const el = current[i];
|
|
2773
|
+
if (node !== el) {
|
|
2774
|
+
const isParent = el.parentNode === parent;
|
|
2775
|
+
if (!inserted && !i) isParent ? parent.replaceChild(node, el) : parent.insertBefore(node, marker);
|
|
2776
|
+
else isParent && el.remove();
|
|
2777
|
+
} else inserted = true;
|
|
2778
|
+
}
|
|
2779
|
+
} else parent.insertBefore(node, marker);
|
|
2780
|
+
return [node];
|
|
2781
|
+
}
|
|
2782
|
+
var voidFn = () => void 0;
|
|
2783
|
+
var isServer = false;
|
|
2784
|
+
var SVG_NAMESPACE = "http://www.w3.org/2000/svg";
|
|
2785
|
+
function createElement(tagName, isSVG = false, is = void 0) {
|
|
2786
|
+
return isSVG ? document.createElementNS(SVG_NAMESPACE, tagName) : document.createElement(tagName, {
|
|
2787
|
+
is
|
|
2788
|
+
});
|
|
2789
|
+
}
|
|
2790
|
+
function Portal(props) {
|
|
2791
|
+
const {
|
|
2792
|
+
useShadow
|
|
2793
|
+
} = props, marker = document.createTextNode(""), mount = () => props.mount || document.body, owner = getOwner();
|
|
2794
|
+
let content;
|
|
2795
|
+
let hydrating = !!sharedConfig.context;
|
|
2796
|
+
createEffect(() => {
|
|
2797
|
+
if (hydrating) getOwner().user = hydrating = false;
|
|
2798
|
+
content || (content = runWithOwner(owner, () => createMemo(() => props.children)));
|
|
2799
|
+
const el = mount();
|
|
2800
|
+
if (el instanceof HTMLHeadElement) {
|
|
2801
|
+
const [clean, setClean] = createSignal(false);
|
|
2802
|
+
const cleanup = () => setClean(true);
|
|
2803
|
+
createRoot((dispose2) => insert(el, () => !clean() ? content() : dispose2(), null));
|
|
2804
|
+
onCleanup(cleanup);
|
|
2805
|
+
} else {
|
|
2806
|
+
const container = createElement(props.isSVG ? "g" : "div", props.isSVG), renderRoot = useShadow && container.attachShadow ? container.attachShadow({
|
|
2807
|
+
mode: "open"
|
|
2808
|
+
}) : container;
|
|
2809
|
+
Object.defineProperty(container, "_$host", {
|
|
2810
|
+
get() {
|
|
2811
|
+
return marker.parentNode;
|
|
2812
|
+
},
|
|
2813
|
+
configurable: true
|
|
2814
|
+
});
|
|
2815
|
+
insert(renderRoot, content);
|
|
2816
|
+
el.appendChild(container);
|
|
2817
|
+
props.ref && props.ref(container);
|
|
2818
|
+
onCleanup(() => el.removeChild(container));
|
|
2819
|
+
}
|
|
2820
|
+
}, void 0, {
|
|
2821
|
+
render: !hydrating
|
|
2822
|
+
});
|
|
2823
|
+
return marker;
|
|
2824
|
+
}
|
|
2825
|
+
|
|
2826
|
+
// src/components/SSModal.tsx
|
|
2827
|
+
var CLOSE_ANIMATION_MS = 180;
|
|
2828
|
+
function SSModal(props) {
|
|
2829
|
+
const [isMounted, setIsMounted] = createSignal(props.open);
|
|
2830
|
+
const [state, setState] = createSignal("closed");
|
|
2831
|
+
const titleId = createUniqueId();
|
|
2832
|
+
let closeTimeout;
|
|
2833
|
+
let rafId;
|
|
2834
|
+
let panelRef;
|
|
2835
|
+
createEffect(() => {
|
|
2836
|
+
if (closeTimeout) clearTimeout(closeTimeout);
|
|
2837
|
+
if (rafId) cancelAnimationFrame(rafId);
|
|
2838
|
+
if (props.open) {
|
|
2839
|
+
if (!isMounted()) setIsMounted(true);
|
|
2840
|
+
setState("closed");
|
|
2841
|
+
rafId = requestAnimationFrame(() => setState("open"));
|
|
2842
|
+
} else {
|
|
2843
|
+
setState("closed");
|
|
2844
|
+
if (isMounted()) {
|
|
2845
|
+
closeTimeout = window.setTimeout(() => setIsMounted(false), CLOSE_ANIMATION_MS);
|
|
2846
|
+
}
|
|
2847
|
+
}
|
|
2848
|
+
});
|
|
2849
|
+
onMount(() => {
|
|
2850
|
+
if (!props.open) return;
|
|
2851
|
+
if (props.lockScroll !== false) {
|
|
2852
|
+
const prev = document.body.style.overflowY;
|
|
2853
|
+
document.body.style.overflowY = "hidden";
|
|
2854
|
+
onCleanup(() => {
|
|
2855
|
+
document.body.style.overflowY = prev;
|
|
2856
|
+
});
|
|
2857
|
+
}
|
|
2858
|
+
rafId = requestAnimationFrame(() => panelRef?.focus());
|
|
2859
|
+
const handleKeyDown = (event) => {
|
|
2860
|
+
if (event.key === "Escape" && props.dismissible !== false) {
|
|
2861
|
+
props.onClose?.();
|
|
2862
|
+
}
|
|
2863
|
+
};
|
|
2864
|
+
window.addEventListener("keydown", handleKeyDown);
|
|
2865
|
+
onCleanup(() => window.removeEventListener("keydown", handleKeyDown));
|
|
2866
|
+
});
|
|
2867
|
+
onCleanup(() => {
|
|
2868
|
+
if (closeTimeout) clearTimeout(closeTimeout);
|
|
2869
|
+
if (rafId) cancelAnimationFrame(rafId);
|
|
2870
|
+
});
|
|
2871
|
+
const handleBackdropClick = () => {
|
|
2872
|
+
if (props.dismissible === false) return;
|
|
2873
|
+
props.onClose?.();
|
|
2874
|
+
};
|
|
2875
|
+
return <Show when={isMounted()}>
|
|
2876
|
+
<Portal>
|
|
2877
|
+
<div class="ss_modal" data-state={state()} aria-hidden={state() === "closed"}>
|
|
2878
|
+
<div class="ss_modal__backdrop" onclick={handleBackdropClick} />
|
|
2879
|
+
<div
|
|
2880
|
+
class="ss_modal__panel"
|
|
2881
|
+
classList={{
|
|
2882
|
+
"ss_modal__panel--sm": props.size === "sm",
|
|
2883
|
+
"ss_modal__panel--lg": props.size === "lg",
|
|
2884
|
+
"ss_modal__panel--fullscreen": props.fullscreen,
|
|
2885
|
+
"ss_modal__panel--no-fullscreen": props.disableResponsiveFullscreen
|
|
2886
|
+
}}
|
|
2887
|
+
ref={(el) => panelRef = el}
|
|
2888
|
+
role="dialog"
|
|
2889
|
+
aria-modal="true"
|
|
2890
|
+
aria-labelledby={props.title ? titleId : void 0}
|
|
2891
|
+
tabindex="-1"
|
|
2892
|
+
>
|
|
2893
|
+
{(props.title || props.onClose) && <div class="ss_modal__header">
|
|
2894
|
+
{props.title && <h2 id={titleId} class="ss_modal__title">
|
|
2895
|
+
{props.title}
|
|
2896
|
+
</h2>}
|
|
2897
|
+
<Show when={props.onClose}>
|
|
2898
|
+
<SSButton
|
|
2899
|
+
type="button"
|
|
2900
|
+
class="ss_modal__close"
|
|
2901
|
+
isIconOnly
|
|
2902
|
+
ariaLabel="Dialog schließen"
|
|
2903
|
+
onclick={() => {
|
|
2904
|
+
if (props.dismissible === false) return;
|
|
2905
|
+
props.onClose?.();
|
|
2906
|
+
}}
|
|
2907
|
+
>
|
|
2908
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon icon-tabler icons-tabler-outline icon-tabler-x"><path stroke="none" d="M0 0h24v24H0z" fill="none" /><path d="M18 6l-12 12" /><path d="M6 6l12 12" /></svg>
|
|
2909
|
+
</SSButton>
|
|
2910
|
+
</Show>
|
|
2911
|
+
</div>}
|
|
2912
|
+
|
|
2913
|
+
<div class="ss_modal__body">
|
|
2914
|
+
<div class="ss_modal__body_inner">{props.children}</div>
|
|
2915
|
+
</div>
|
|
2916
|
+
|
|
2917
|
+
<Show when={props.footer}>
|
|
2918
|
+
<div class="ss_modal__footer">{props.footer}</div>
|
|
2919
|
+
</Show>
|
|
2920
|
+
</div>
|
|
2921
|
+
</div>
|
|
2922
|
+
</Portal>
|
|
2923
|
+
</Show>;
|
|
2924
|
+
}
|
|
2925
|
+
|
|
2926
|
+
// node_modules/@solidjs/router/dist/index.js
|
|
2927
|
+
var depth;
|
|
2928
|
+
function saveCurrentDepth() {
|
|
2929
|
+
if (!window.history.state || window.history.state._depth == null) {
|
|
2930
|
+
window.history.replaceState({
|
|
2931
|
+
...window.history.state,
|
|
2932
|
+
_depth: window.history.length - 1
|
|
2933
|
+
}, "");
|
|
2934
|
+
}
|
|
2935
|
+
depth = window.history.state._depth;
|
|
2936
|
+
}
|
|
2937
|
+
if (!isServer) {
|
|
2938
|
+
saveCurrentDepth();
|
|
2939
|
+
}
|
|
2940
|
+
var trimPathRegex = /^\/+|(\/)\/+$/g;
|
|
2941
|
+
function normalizePath(path, omitSlash = false) {
|
|
2942
|
+
const s = path.replace(trimPathRegex, "$1");
|
|
2943
|
+
return s ? omitSlash || /^[?#]/.test(s) ? s : "/" + s : "";
|
|
2944
|
+
}
|
|
2945
|
+
function invariant(value, message) {
|
|
2946
|
+
if (value == null) {
|
|
2947
|
+
throw new Error(message);
|
|
2948
|
+
}
|
|
2949
|
+
return value;
|
|
2950
|
+
}
|
|
2951
|
+
var RouterContextObj = createContext();
|
|
2952
|
+
var RouteContextObj = createContext();
|
|
2953
|
+
var useRouter = () => invariant(useContext(RouterContextObj), "<A> and 'use' router primitives can be only used inside a Route.");
|
|
2954
|
+
var useRoute = () => useContext(RouteContextObj) || useRouter().base;
|
|
2955
|
+
var useResolvedPath = (path) => {
|
|
2956
|
+
const route = useRoute();
|
|
2957
|
+
return createMemo(() => route.resolvePath(path()));
|
|
2958
|
+
};
|
|
2959
|
+
var useHref = (to) => {
|
|
2960
|
+
const router = useRouter();
|
|
2961
|
+
return createMemo(() => {
|
|
2962
|
+
const to_ = to();
|
|
2963
|
+
return to_ !== void 0 ? router.renderPath(to_) : to_;
|
|
2964
|
+
});
|
|
2965
|
+
};
|
|
2966
|
+
var useNavigate = () => useRouter().navigatorFactory();
|
|
2967
|
+
var useLocation = () => useRouter().location;
|
|
2968
|
+
var intent;
|
|
2969
|
+
function getIntent() {
|
|
2970
|
+
return intent;
|
|
2971
|
+
}
|
|
2972
|
+
var inPreloadFn = false;
|
|
2973
|
+
function getInPreloadFn() {
|
|
2974
|
+
return inPreloadFn;
|
|
2975
|
+
}
|
|
2976
|
+
var LocationHeader = "Location";
|
|
2977
|
+
var PRELOAD_TIMEOUT = 5e3;
|
|
2978
|
+
var CACHE_TIMEOUT = 18e4;
|
|
2979
|
+
var cacheMap = /* @__PURE__ */ new Map();
|
|
2980
|
+
if (!isServer) {
|
|
2981
|
+
setInterval(() => {
|
|
2982
|
+
const now = Date.now();
|
|
2983
|
+
for (let [k, v] of cacheMap.entries()) {
|
|
2984
|
+
if (!v[4].count && now - v[0] > CACHE_TIMEOUT) {
|
|
2985
|
+
cacheMap.delete(k);
|
|
2986
|
+
}
|
|
2987
|
+
}
|
|
2988
|
+
}, 3e5);
|
|
2989
|
+
}
|
|
2990
|
+
function getCache() {
|
|
2991
|
+
if (!isServer) return cacheMap;
|
|
2992
|
+
const req = voidFn();
|
|
2993
|
+
if (!req) throw new Error("Cannot find cache context");
|
|
2994
|
+
return (req.router || (req.router = {})).cache || (req.router.cache = /* @__PURE__ */ new Map());
|
|
2995
|
+
}
|
|
2996
|
+
function query(fn, name) {
|
|
2997
|
+
if (fn.GET) fn = fn.GET;
|
|
2998
|
+
const cachedFn = (...args) => {
|
|
2999
|
+
const cache = getCache();
|
|
3000
|
+
const intent2 = getIntent();
|
|
3001
|
+
const inPreloadFn2 = getInPreloadFn();
|
|
3002
|
+
const owner = getOwner();
|
|
3003
|
+
const navigate = owner ? useNavigate() : void 0;
|
|
3004
|
+
const now = Date.now();
|
|
3005
|
+
const key = name + hashKey(args);
|
|
3006
|
+
let cached = cache.get(key);
|
|
3007
|
+
let tracking;
|
|
3008
|
+
if (isServer) {
|
|
3009
|
+
const e = voidFn();
|
|
3010
|
+
if (e) {
|
|
3011
|
+
const dataOnly = (e.router || (e.router = {})).dataOnly;
|
|
3012
|
+
if (dataOnly) {
|
|
3013
|
+
const data = e && (e.router.data || (e.router.data = {}));
|
|
3014
|
+
if (data && key in data) return data[key];
|
|
3015
|
+
if (Array.isArray(dataOnly) && !matchKey(key, dataOnly)) {
|
|
3016
|
+
data[key] = void 0;
|
|
3017
|
+
return Promise.resolve();
|
|
3018
|
+
}
|
|
3019
|
+
}
|
|
3020
|
+
}
|
|
3021
|
+
}
|
|
3022
|
+
if (getListener() && !isServer) {
|
|
3023
|
+
tracking = true;
|
|
3024
|
+
onCleanup(() => cached[4].count--);
|
|
3025
|
+
}
|
|
3026
|
+
if (cached && cached[0] && (isServer || intent2 === "native" || cached[4].count || Date.now() - cached[0] < PRELOAD_TIMEOUT)) {
|
|
3027
|
+
if (tracking) {
|
|
3028
|
+
cached[4].count++;
|
|
3029
|
+
cached[4][0]();
|
|
3030
|
+
}
|
|
3031
|
+
if (cached[3] === "preload" && intent2 !== "preload") {
|
|
3032
|
+
cached[0] = now;
|
|
3033
|
+
}
|
|
3034
|
+
let res2 = cached[1];
|
|
3035
|
+
if (intent2 !== "preload") {
|
|
3036
|
+
res2 = "then" in cached[1] ? cached[1].then(handleResponse(false), handleResponse(true)) : handleResponse(false)(cached[1]);
|
|
3037
|
+
!isServer && intent2 === "navigate" && startTransition(() => cached[4][1](cached[0]));
|
|
3038
|
+
}
|
|
3039
|
+
inPreloadFn2 && "then" in res2 && res2.catch(() => {
|
|
3040
|
+
});
|
|
3041
|
+
return res2;
|
|
3042
|
+
}
|
|
3043
|
+
let res;
|
|
3044
|
+
if (!isServer && sharedConfig.has && sharedConfig.has(key)) {
|
|
3045
|
+
res = sharedConfig.load(key);
|
|
3046
|
+
delete globalThis._$HY.r[key];
|
|
3047
|
+
} else res = fn(...args);
|
|
3048
|
+
if (cached) {
|
|
3049
|
+
cached[0] = now;
|
|
3050
|
+
cached[1] = res;
|
|
3051
|
+
cached[3] = intent2;
|
|
3052
|
+
!isServer && intent2 === "navigate" && startTransition(() => cached[4][1](cached[0]));
|
|
3053
|
+
} else {
|
|
3054
|
+
cache.set(key, cached = [now, res, , intent2, createSignal(now)]);
|
|
3055
|
+
cached[4].count = 0;
|
|
3056
|
+
}
|
|
3057
|
+
if (tracking) {
|
|
3058
|
+
cached[4].count++;
|
|
3059
|
+
cached[4][0]();
|
|
3060
|
+
}
|
|
3061
|
+
if (isServer) {
|
|
3062
|
+
const e = voidFn();
|
|
3063
|
+
if (e && e.router.dataOnly) return e.router.data[key] = res;
|
|
3064
|
+
}
|
|
3065
|
+
if (intent2 !== "preload") {
|
|
3066
|
+
res = "then" in res ? res.then(handleResponse(false), handleResponse(true)) : handleResponse(false)(res);
|
|
3067
|
+
}
|
|
3068
|
+
inPreloadFn2 && "then" in res && res.catch(() => {
|
|
3069
|
+
});
|
|
3070
|
+
if (isServer && sharedConfig.context && sharedConfig.context.async && !sharedConfig.context.noHydrate) {
|
|
3071
|
+
const e = voidFn();
|
|
3072
|
+
(!e || !e.serverOnly) && sharedConfig.context.serialize(key, res);
|
|
3073
|
+
}
|
|
3074
|
+
return res;
|
|
3075
|
+
function handleResponse(error) {
|
|
3076
|
+
return async (v) => {
|
|
3077
|
+
if (v instanceof Response) {
|
|
3078
|
+
const e = voidFn();
|
|
3079
|
+
if (e) {
|
|
3080
|
+
for (const [key2, value] of v.headers) {
|
|
3081
|
+
if (key2 == "set-cookie") e.response.headers.append("set-cookie", value);
|
|
3082
|
+
else e.response.headers.set(key2, value);
|
|
3083
|
+
}
|
|
3084
|
+
}
|
|
3085
|
+
const url = v.headers.get(LocationHeader);
|
|
3086
|
+
if (url !== null) {
|
|
3087
|
+
if (navigate && url.startsWith("/")) startTransition(() => {
|
|
3088
|
+
navigate(url, {
|
|
3089
|
+
replace: true
|
|
3090
|
+
});
|
|
3091
|
+
});
|
|
3092
|
+
else if (!isServer) window.location.href = url;
|
|
3093
|
+
else if (e) e.response.status = 302;
|
|
3094
|
+
return;
|
|
3095
|
+
}
|
|
3096
|
+
if (v.customBody) v = await v.customBody();
|
|
3097
|
+
}
|
|
3098
|
+
if (error) throw v;
|
|
3099
|
+
cached[2] = v;
|
|
3100
|
+
return v;
|
|
3101
|
+
};
|
|
3102
|
+
}
|
|
3103
|
+
};
|
|
3104
|
+
cachedFn.keyFor = (...args) => name + hashKey(args);
|
|
3105
|
+
cachedFn.key = name;
|
|
3106
|
+
return cachedFn;
|
|
3107
|
+
}
|
|
3108
|
+
query.get = (key) => {
|
|
3109
|
+
const cached = getCache().get(key);
|
|
3110
|
+
return cached[2];
|
|
3111
|
+
};
|
|
3112
|
+
query.set = (key, value) => {
|
|
3113
|
+
const cache = getCache();
|
|
3114
|
+
const now = Date.now();
|
|
3115
|
+
let cached = cache.get(key);
|
|
3116
|
+
if (cached) {
|
|
3117
|
+
cached[0] = now;
|
|
3118
|
+
cached[1] = Promise.resolve(value);
|
|
3119
|
+
cached[2] = value;
|
|
3120
|
+
cached[3] = "preload";
|
|
3121
|
+
} else {
|
|
3122
|
+
cache.set(key, cached = [now, Promise.resolve(value), value, "preload", createSignal(now)]);
|
|
3123
|
+
cached[4].count = 0;
|
|
3124
|
+
}
|
|
3125
|
+
};
|
|
3126
|
+
query.delete = (key) => getCache().delete(key);
|
|
3127
|
+
query.clear = () => getCache().clear();
|
|
3128
|
+
function matchKey(key, keys) {
|
|
3129
|
+
for (let k of keys) {
|
|
3130
|
+
if (k && key.startsWith(k)) return true;
|
|
3131
|
+
}
|
|
3132
|
+
return false;
|
|
3133
|
+
}
|
|
3134
|
+
function hashKey(args) {
|
|
3135
|
+
return JSON.stringify(args, (_, val) => isPlainObject(val) ? Object.keys(val).sort().reduce((result, key) => {
|
|
3136
|
+
result[key] = val[key];
|
|
3137
|
+
return result;
|
|
3138
|
+
}, {}) : val);
|
|
3139
|
+
}
|
|
3140
|
+
function isPlainObject(obj) {
|
|
3141
|
+
let proto;
|
|
3142
|
+
return obj != null && typeof obj === "object" && (!(proto = Object.getPrototypeOf(obj)) || proto === Object.prototype);
|
|
3143
|
+
}
|
|
3144
|
+
var _tmpl$ = /* @__PURE__ */ template(`<a>`);
|
|
3145
|
+
function A(props) {
|
|
3146
|
+
props = mergeProps({
|
|
3147
|
+
inactiveClass: "inactive",
|
|
3148
|
+
activeClass: "active"
|
|
3149
|
+
}, props);
|
|
3150
|
+
const [, rest] = splitProps(props, ["href", "state", "class", "activeClass", "inactiveClass", "end"]);
|
|
3151
|
+
const to = useResolvedPath(() => props.href);
|
|
3152
|
+
const href = useHref(to);
|
|
3153
|
+
const location = useLocation();
|
|
3154
|
+
const isActive = createMemo(() => {
|
|
3155
|
+
const to_ = to();
|
|
3156
|
+
if (to_ === void 0) return [false, false];
|
|
3157
|
+
const path = normalizePath(to_.split(/[?#]/, 1)[0]).toLowerCase();
|
|
3158
|
+
const loc = decodeURI(normalizePath(location.pathname).toLowerCase());
|
|
3159
|
+
return [props.end ? path === loc : loc.startsWith(path + "/") || loc === path, path === loc];
|
|
3160
|
+
});
|
|
3161
|
+
return (() => {
|
|
3162
|
+
var _el$ = _tmpl$();
|
|
3163
|
+
spread(_el$, mergeProps(rest, {
|
|
3164
|
+
get href() {
|
|
3165
|
+
return href() || props.href;
|
|
3166
|
+
},
|
|
3167
|
+
get state() {
|
|
3168
|
+
return JSON.stringify(props.state);
|
|
3169
|
+
},
|
|
3170
|
+
get classList() {
|
|
3171
|
+
return {
|
|
3172
|
+
...props.class && {
|
|
3173
|
+
[props.class]: true
|
|
3174
|
+
},
|
|
3175
|
+
[props.inactiveClass]: !isActive()[0],
|
|
3176
|
+
[props.activeClass]: isActive()[0],
|
|
3177
|
+
...rest.classList
|
|
3178
|
+
};
|
|
3179
|
+
},
|
|
3180
|
+
"link": "",
|
|
3181
|
+
get ["aria-current"]() {
|
|
3182
|
+
return isActive()[1] ? "page" : void 0;
|
|
3183
|
+
}
|
|
3184
|
+
}), false, false);
|
|
3185
|
+
return _el$;
|
|
3186
|
+
})();
|
|
3187
|
+
}
|
|
3188
|
+
|
|
3189
|
+
// src/components/SSModals.tsx
|
|
3190
|
+
var SSModalsContext = createContext();
|
|
3191
|
+
var modalCounter = 0;
|
|
3192
|
+
var nextModalId = () => `ss-modal-${modalCounter++}`;
|
|
3193
|
+
function useSSModals() {
|
|
3194
|
+
const context = useContext(SSModalsContext);
|
|
3195
|
+
if (!context) {
|
|
3196
|
+
throw new Error("useSSModals must be used within SSModalsProvider");
|
|
3197
|
+
}
|
|
3198
|
+
return context;
|
|
3199
|
+
}
|
|
3200
|
+
function DefaultModal(props) {
|
|
3201
|
+
const navigate = useNavigate();
|
|
3202
|
+
const location = useLocation();
|
|
3203
|
+
const [loading, process] = createLoading();
|
|
3204
|
+
const modalProps = () => props.config.modalProps?.({ hide: props.hide }) ?? {};
|
|
3205
|
+
const {
|
|
3206
|
+
primaryButtonText,
|
|
3207
|
+
secondaryButtonText,
|
|
3208
|
+
hideSecondaryButton,
|
|
3209
|
+
danger,
|
|
3210
|
+
...rest
|
|
3211
|
+
} = modalProps();
|
|
3212
|
+
return <SSModal
|
|
3213
|
+
open={props.visible()}
|
|
3214
|
+
onClose={props.hide}
|
|
3215
|
+
{...rest}
|
|
3216
|
+
footer={<>
|
|
3217
|
+
{!hideSecondaryButton && <SSButton class="secondary" onclick={props.hide}>
|
|
3218
|
+
{secondaryButtonText ?? "Abbrechen"}
|
|
3219
|
+
</SSButton>}
|
|
3220
|
+
<SSButton
|
|
3221
|
+
class={danger ? "danger" : void 0}
|
|
3222
|
+
onclick={() => process(
|
|
3223
|
+
() => props.config.onPrimaryAction?.({
|
|
3224
|
+
hide: props.hide,
|
|
3225
|
+
navigate,
|
|
3226
|
+
pathname: location.pathname
|
|
3227
|
+
}) ?? props.hide()
|
|
3228
|
+
)}
|
|
3229
|
+
disabled={loading()}
|
|
3230
|
+
>
|
|
3231
|
+
{primaryButtonText ?? "Weiter"}
|
|
3232
|
+
</SSButton>
|
|
3233
|
+
</>}
|
|
3234
|
+
>
|
|
3235
|
+
{props.config.content({ hide: props.hide })}
|
|
3236
|
+
</SSModal>;
|
|
3237
|
+
}
|
|
3238
|
+
function FormModal(props) {
|
|
3239
|
+
const navigate = useNavigate();
|
|
3240
|
+
const location = useLocation();
|
|
3241
|
+
return <SSForm
|
|
3242
|
+
onsubmit={(context) => props.config.onSubmit({
|
|
3243
|
+
hide: props.hide,
|
|
3244
|
+
context,
|
|
3245
|
+
navigate,
|
|
3246
|
+
pathname: location.pathname
|
|
3247
|
+
})}
|
|
3248
|
+
>
|
|
3249
|
+
<FormModalInner visible={props.visible} hide={props.hide} config={props.config} />
|
|
3250
|
+
</SSForm>;
|
|
3251
|
+
}
|
|
3252
|
+
function FormModalInner(props) {
|
|
3253
|
+
const context = SSForm.useContext();
|
|
3254
|
+
if (!context) return null;
|
|
3255
|
+
const modalProps = () => props.config.modalProps?.({ hide: props.hide, context }) ?? {};
|
|
3256
|
+
const {
|
|
3257
|
+
primaryButtonText,
|
|
3258
|
+
secondaryButtonText,
|
|
3259
|
+
hideSecondaryButton,
|
|
3260
|
+
danger,
|
|
3261
|
+
...rest
|
|
3262
|
+
} = modalProps();
|
|
3263
|
+
return <SSModal
|
|
3264
|
+
open={props.visible()}
|
|
3265
|
+
onClose={props.hide}
|
|
3266
|
+
{...rest}
|
|
3267
|
+
footer={<>
|
|
3268
|
+
{!hideSecondaryButton && <SSButton class="secondary" onclick={props.hide} disabled={context.loading()}>
|
|
3269
|
+
{secondaryButtonText ?? "Abbrechen"}
|
|
3270
|
+
</SSButton>}
|
|
3271
|
+
<SSButton
|
|
3272
|
+
class={danger ? "danger" : void 0}
|
|
3273
|
+
onclick={() => context.submit()}
|
|
3274
|
+
disabled={context.loading()}
|
|
3275
|
+
>
|
|
3276
|
+
{primaryButtonText ?? "Speichern"}
|
|
3277
|
+
</SSButton>
|
|
3278
|
+
</>}
|
|
3279
|
+
>
|
|
3280
|
+
{props.config.content({ hide: props.hide, context })}
|
|
3281
|
+
</SSModal>;
|
|
3282
|
+
}
|
|
3283
|
+
function SSModalsProvider(props) {
|
|
3284
|
+
const [modals, setModals] = createSignal([]);
|
|
3285
|
+
const modalsById = /* @__PURE__ */ new Map();
|
|
3286
|
+
const closeTimeouts = /* @__PURE__ */ new Map();
|
|
3287
|
+
const removeDelayMs = 220;
|
|
3288
|
+
const hide = (id) => {
|
|
3289
|
+
const modal = modalsById.get(id);
|
|
3290
|
+
if (!modal) return;
|
|
3291
|
+
modal.setVisible(false);
|
|
3292
|
+
const existing = closeTimeouts.get(id);
|
|
3293
|
+
if (existing) window.clearTimeout(existing);
|
|
3294
|
+
const timeout = window.setTimeout(() => {
|
|
3295
|
+
setModals((list) => list.filter((modal2) => modal2.id !== id));
|
|
3296
|
+
modalsById.delete(id);
|
|
3297
|
+
closeTimeouts.delete(id);
|
|
3298
|
+
}, removeDelayMs);
|
|
3299
|
+
closeTimeouts.set(id, timeout);
|
|
3300
|
+
};
|
|
3301
|
+
const show = (render) => {
|
|
3302
|
+
const id = nextModalId();
|
|
3303
|
+
const [visible, setVisible] = createSignal(true);
|
|
3304
|
+
const entry = { id, visible, setVisible, render };
|
|
3305
|
+
modalsById.set(id, entry);
|
|
3306
|
+
setModals((list) => [...list, entry]);
|
|
3307
|
+
return id;
|
|
3308
|
+
};
|
|
3309
|
+
const showDefault = (config) => {
|
|
3310
|
+
return show(({ hide: hide2, visible }) => <DefaultModal visible={visible} hide={hide2} config={config} />);
|
|
3311
|
+
};
|
|
3312
|
+
const showForm = (config) => {
|
|
3313
|
+
return show(({ hide: hide2, visible }) => <FormModal visible={visible} hide={hide2} config={config} />);
|
|
3314
|
+
};
|
|
3315
|
+
onCleanup(() => {
|
|
3316
|
+
closeTimeouts.forEach((timeout) => window.clearTimeout(timeout));
|
|
3317
|
+
closeTimeouts.clear();
|
|
3318
|
+
});
|
|
3319
|
+
return <SSModalsContext.Provider value={{ show, showDefault, showForm, hide }}>
|
|
3320
|
+
{props.children}
|
|
3321
|
+
|
|
3322
|
+
<For each={modals()}>
|
|
3323
|
+
{(modal) => {
|
|
3324
|
+
const hideModal = () => hide(modal.id);
|
|
3325
|
+
return modal.render({ id: modal.id, hide: hideModal, visible: modal.visible });
|
|
3326
|
+
}}
|
|
3327
|
+
</For>
|
|
3328
|
+
</SSModalsContext.Provider>;
|
|
3329
|
+
}
|
|
3330
|
+
|
|
3331
|
+
// src/components/SSShell.tsx
|
|
3332
|
+
var SSShellContext = createContext();
|
|
3333
|
+
function SSShell(props) {
|
|
3334
|
+
const drawerId = createUniqueId();
|
|
3335
|
+
const location = useLocation();
|
|
3336
|
+
const [hrefs, setHrefs] = createSignal([]);
|
|
3337
|
+
const closeDrawer = () => {
|
|
3338
|
+
const input = document.getElementById(drawerId);
|
|
3339
|
+
if (input) input.checked = false;
|
|
3340
|
+
};
|
|
3341
|
+
const registerHref = (href) => {
|
|
3342
|
+
setHrefs((prev) => prev.includes(href) ? prev : [...prev, href]);
|
|
3343
|
+
};
|
|
3344
|
+
const unregisterHref = (href) => {
|
|
3345
|
+
setHrefs((prev) => prev.filter((item) => item !== href));
|
|
3346
|
+
};
|
|
3347
|
+
const activeHref = createMemo(() => {
|
|
3348
|
+
const path = location.pathname;
|
|
3349
|
+
let best = null;
|
|
3350
|
+
for (const href of hrefs()) {
|
|
3351
|
+
if (!path.startsWith(href)) continue;
|
|
3352
|
+
if (!best || href.length > best.length) {
|
|
3353
|
+
best = href;
|
|
3354
|
+
}
|
|
3355
|
+
}
|
|
3356
|
+
return best;
|
|
3357
|
+
});
|
|
3358
|
+
return <SSShellContext.Provider value={{ closeDrawer, activeHref, registerHref, unregisterHref }}>
|
|
3359
|
+
<div class={`ss_shell ${props.class ?? ""}`} style={props.style}>
|
|
3360
|
+
<input id={drawerId} type="checkbox" class="ss_shell__drawer_toggle_input" />
|
|
3361
|
+
|
|
3362
|
+
<header class="ss_shell__header">
|
|
3363
|
+
<div class="ss_shell__header_left">
|
|
3364
|
+
<label
|
|
3365
|
+
for={drawerId}
|
|
3366
|
+
class="ss_shell__drawer_toggle ss_button ss_button--icon"
|
|
3367
|
+
aria-label="Navigation öffnen"
|
|
3368
|
+
role="button"
|
|
3369
|
+
tabindex="0"
|
|
3370
|
+
>
|
|
3371
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon icon-tabler icons-tabler-outline icon-tabler-menu-2"><path stroke="none" d="M0 0h24v24H0z" fill="none" /><path d="M4 6l16 0" /><path d="M4 12l16 0" /><path d="M4 18l16 0" /></svg>
|
|
3372
|
+
</label>
|
|
3373
|
+
<div class="ss_shell__title">{props.title}</div>
|
|
3374
|
+
</div>
|
|
3375
|
+
<div class="ss_shell__actions">{props.actions}</div>
|
|
3376
|
+
</header>
|
|
3377
|
+
|
|
3378
|
+
<div class="ss_shell__body">
|
|
3379
|
+
<nav class="ss_shell__nav" aria-label="Hauptnavigation">
|
|
3380
|
+
<div class="ss_shell__nav_inner">{props.nav}</div>
|
|
3381
|
+
</nav>
|
|
3382
|
+
<div class="ss_shell__main">{props.children}</div>
|
|
3383
|
+
<label for={drawerId} class="ss_shell__scrim" aria-label="Navigation schließen" />
|
|
3384
|
+
</div>
|
|
3385
|
+
</div>
|
|
3386
|
+
</SSShellContext.Provider>;
|
|
3387
|
+
}
|
|
3388
|
+
SSShell.Nav = function(props) {
|
|
3389
|
+
return <div class="ss_shell__nav_list">{props.children}</div>;
|
|
3390
|
+
};
|
|
3391
|
+
SSShell.NavLink = function(props) {
|
|
3392
|
+
const context = useContext(SSShellContext);
|
|
3393
|
+
onMount(() => context?.registerHref(props.href));
|
|
3394
|
+
onCleanup(() => context?.unregisterHref(props.href));
|
|
3395
|
+
const isActive = () => context?.activeHref() === props.href;
|
|
3396
|
+
return <a
|
|
3397
|
+
class="ss_shell__nav_item"
|
|
3398
|
+
classList={{ "ss_shell__nav_item--active": isActive() }}
|
|
3399
|
+
href={props.href}
|
|
3400
|
+
onclick={() => {
|
|
3401
|
+
props.onclick?.();
|
|
3402
|
+
context?.closeDrawer();
|
|
3403
|
+
}}
|
|
3404
|
+
>
|
|
3405
|
+
{props.icon && <span class="ss_shell__nav_icon">{props.icon}</span>}
|
|
3406
|
+
<span class="ss_shell__nav_label">{props.children}</span>
|
|
3407
|
+
</a>;
|
|
3408
|
+
};
|
|
3409
|
+
SSShell.NavAction = function(props) {
|
|
3410
|
+
const context = useContext(SSShellContext);
|
|
3411
|
+
return <button
|
|
3412
|
+
type="button"
|
|
3413
|
+
class="ss_shell__nav_item"
|
|
3414
|
+
onclick={() => {
|
|
3415
|
+
props.onclick();
|
|
3416
|
+
context?.closeDrawer();
|
|
3417
|
+
}}
|
|
3418
|
+
>
|
|
3419
|
+
{props.icon && <span class="ss_shell__nav_icon">{props.icon}</span>}
|
|
3420
|
+
<span class="ss_shell__nav_label">{props.children}</span>
|
|
3421
|
+
</button>;
|
|
3422
|
+
};
|
|
3423
|
+
SSShell.NavGroup = function(props) {
|
|
3424
|
+
return <details class="ss_shell__nav_group" open={props.initiallyExpanded}>
|
|
3425
|
+
<summary class="ss_shell__nav_group_header">
|
|
3426
|
+
{props.icon && <span class="ss_shell__nav_icon">{props.icon}</span>}
|
|
3427
|
+
<span class="ss_shell__nav_label">{props.title}</span>
|
|
3428
|
+
<span class="ss_shell__nav_group_chevron" aria-hidden="true">
|
|
3429
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="ss_shell__nav_group_chevron_svg"><path stroke="none" d="M0 0h24v24H0z" fill="none" /><path d="M9 6l6 6l-6 6" /></svg>
|
|
3430
|
+
</span>
|
|
3431
|
+
</summary>
|
|
3432
|
+
<div class="ss_shell__nav_group_items">{props.children}</div>
|
|
3433
|
+
</details>;
|
|
3434
|
+
};
|
|
3435
|
+
|
|
3436
|
+
// src/components/SSSurface.tsx
|
|
3437
|
+
function SSSurface(props) {
|
|
3438
|
+
return <div class={`ss_surface ${props.class ?? ""}`} style={props.style}>
|
|
3439
|
+
{props.children}
|
|
3440
|
+
</div>;
|
|
3441
|
+
}
|
|
3442
|
+
|
|
3443
|
+
// src/components/SSTile.tsx
|
|
3444
|
+
function SSTile(props) {
|
|
3445
|
+
return <div class={`ss_tile ${props.class ?? ""}`} style={props.style}>
|
|
3446
|
+
<div class="ss_tile__row">
|
|
3447
|
+
{props.icon && <span class="ss_tile__icon">{props.icon}</span>}
|
|
3448
|
+
<div class="ss_tile__content">
|
|
3449
|
+
{props.href ? <h5 class="ss_tile__title">
|
|
3450
|
+
<A class="ss_tile__link" href={props.href} onclick={props.onLinkClick}>
|
|
3451
|
+
{props.title}
|
|
3452
|
+
</A>
|
|
3453
|
+
</h5> : <h5 class="ss_tile__title">
|
|
3454
|
+
<span class="ss_tile__text">{props.title}</span>
|
|
3455
|
+
</h5>}
|
|
3456
|
+
{props.subtitle && <div class="ss_tile__subtitle">{props.subtitle}</div>}
|
|
3457
|
+
</div>
|
|
3458
|
+
{props.trailing && <div class="ss_tile__trailing">{props.trailing}</div>}
|
|
3459
|
+
</div>
|
|
3460
|
+
</div>;
|
|
3461
|
+
}
|
|
3462
|
+
function createSSTile(build) {
|
|
3463
|
+
return function(props) {
|
|
3464
|
+
const built = build(props.data);
|
|
3465
|
+
return <SSTile
|
|
3466
|
+
{...built}
|
|
3467
|
+
onLinkClick={props.onLinkClick ?? built.onLinkClick}
|
|
3468
|
+
href={props.noLink ? void 0 : built.href}
|
|
3469
|
+
icon={props.noIcon ? void 0 : built.icon}
|
|
3470
|
+
/>;
|
|
3471
|
+
};
|
|
3472
|
+
}
|
|
3473
|
+
export {
|
|
3474
|
+
SSButton,
|
|
3475
|
+
SSCallout,
|
|
3476
|
+
SSChip,
|
|
3477
|
+
SSDataTable,
|
|
3478
|
+
SSDropdown,
|
|
3479
|
+
SSExpandable,
|
|
3480
|
+
SSForm,
|
|
3481
|
+
SSHeader,
|
|
3482
|
+
SSModal,
|
|
3483
|
+
SSModalsProvider,
|
|
3484
|
+
SSShell,
|
|
3485
|
+
SSSurface,
|
|
3486
|
+
SSTile,
|
|
3487
|
+
createSSTile,
|
|
3488
|
+
useSSModals
|
|
3489
|
+
};
|