@k2b/ui 0.11.0 → 0.13.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/README.md +1 -1
- package/dist/browser/content/FileView.js +203 -136
- package/dist/browser/content/FileView.js.map +1 -1
- package/dist/browser/content/PdfPreview.js +5 -2
- package/dist/browser/content/PdfPreview.js.map +1 -1
- package/dist/browser/content/markdown-title.js +52 -0
- package/dist/browser/content/markdown-title.js.map +1 -0
- package/dist/browser/feedback/InstallGuide.js +267 -0
- package/dist/browser/feedback/InstallGuide.js.map +1 -0
- package/dist/browser/feedback/announce.js +50 -0
- package/dist/browser/feedback/announce.js.map +1 -0
- package/dist/browser/feedback/dialog-core.js +82 -1
- package/dist/browser/feedback/dialog-core.js.map +1 -1
- package/dist/browser/feedback/index.js +4 -0
- package/dist/browser/feedback/index.js.map +1 -1
- package/dist/browser/feedback/install.js +99 -0
- package/dist/browser/feedback/install.js.map +1 -0
- package/dist/browser/feedback/prompts.js +29 -20
- package/dist/browser/feedback/prompts.js.map +1 -1
- package/dist/browser/feedback/theme-color.js +15 -0
- package/dist/browser/feedback/theme-color.js.map +1 -0
- package/dist/browser/feedback/toast.js +329 -122
- package/dist/browser/feedback/toast.js.map +1 -1
- package/dist/browser/inputs/DatePicker.js +263 -222
- package/dist/browser/inputs/DatePicker.js.map +1 -1
- package/dist/browser/inputs/MultiSelectInput.js +139 -105
- package/dist/browser/inputs/MultiSelectInput.js.map +1 -1
- package/dist/browser/inputs/NumberInput.js +209 -122
- package/dist/browser/inputs/NumberInput.js.map +1 -1
- package/dist/browser/inputs/QrScanner.js +164 -0
- package/dist/browser/inputs/QrScanner.js.map +1 -0
- package/dist/browser/inputs/Select.js +184 -92
- package/dist/browser/inputs/Select.js.map +1 -1
- package/dist/browser/inputs/index.js +1 -0
- package/dist/browser/inputs/index.js.map +1 -1
- package/dist/browser/intl/messages.js +90 -2
- package/dist/browser/intl/messages.js.map +1 -1
- package/dist/browser/layout/DetailPanel.js +2 -1
- package/dist/browser/layout/DetailPanel.js.map +1 -1
- package/dist/browser/layout/Discussion.js +2 -1
- package/dist/browser/layout/Discussion.js.map +1 -1
- package/dist/browser/layout/MobileShell.js +242 -0
- package/dist/browser/layout/MobileShell.js.map +1 -0
- package/dist/browser/layout/Navigation.js +1 -0
- package/dist/browser/layout/Navigation.js.map +1 -1
- package/dist/browser/layout/PanelDialog.js +1 -0
- package/dist/browser/layout/PanelDialog.js.map +1 -1
- package/dist/browser/layout/Settings.js +2 -2
- package/dist/browser/layout/Settings.js.map +1 -1
- package/dist/browser/layout/TabBar.js +65 -0
- package/dist/browser/layout/TabBar.js.map +1 -0
- package/dist/browser/layout/index.js +2 -0
- package/dist/browser/layout/index.js.map +1 -1
- package/dist/browser/surfaces/NoticeCard.js +55 -60
- package/dist/browser/surfaces/NoticeCard.js.map +1 -1
- package/dist/browser/surfaces/index.js +1 -1
- package/dist/browser/surfaces/index.js.map +1 -1
- package/dist/ssr/content/FileView.js +141 -81
- package/dist/ssr/content/FileView.js.map +1 -1
- package/dist/ssr/content/PdfPreview.js +4 -2
- package/dist/ssr/content/PdfPreview.js.map +1 -1
- package/dist/ssr/content/markdown-title.js +52 -0
- package/dist/ssr/content/markdown-title.js.map +1 -0
- package/dist/ssr/feedback/InstallGuide.js +201 -0
- package/dist/ssr/feedback/InstallGuide.js.map +1 -0
- package/dist/ssr/feedback/announce.js +50 -0
- package/dist/ssr/feedback/announce.js.map +1 -0
- package/dist/ssr/feedback/dialog-core.js +82 -1
- package/dist/ssr/feedback/dialog-core.js.map +1 -1
- package/dist/ssr/feedback/index.js +4 -0
- package/dist/ssr/feedback/index.js.map +1 -1
- package/dist/ssr/feedback/install.js +99 -0
- package/dist/ssr/feedback/install.js.map +1 -0
- package/dist/ssr/feedback/prompts.js +12 -2
- package/dist/ssr/feedback/prompts.js.map +1 -1
- package/dist/ssr/feedback/theme-color.js +15 -0
- package/dist/ssr/feedback/theme-color.js.map +1 -0
- package/dist/ssr/feedback/toast.js +329 -122
- package/dist/ssr/feedback/toast.js.map +1 -1
- package/dist/ssr/inputs/DatePicker.js +78 -52
- package/dist/ssr/inputs/DatePicker.js.map +1 -1
- package/dist/ssr/inputs/MultiSelectInput.js +52 -32
- package/dist/ssr/inputs/MultiSelectInput.js.map +1 -1
- package/dist/ssr/inputs/NumberInput.js +93 -40
- package/dist/ssr/inputs/NumberInput.js.map +1 -1
- package/dist/ssr/inputs/QrScanner.js +128 -0
- package/dist/ssr/inputs/QrScanner.js.map +1 -0
- package/dist/ssr/inputs/Select.js +108 -29
- package/dist/ssr/inputs/Select.js.map +1 -1
- package/dist/ssr/inputs/index.js +1 -0
- package/dist/ssr/inputs/index.js.map +1 -1
- package/dist/ssr/intl/messages.js +90 -2
- package/dist/ssr/intl/messages.js.map +1 -1
- package/dist/ssr/layout/DetailPanel.js +2 -1
- package/dist/ssr/layout/DetailPanel.js.map +1 -1
- package/dist/ssr/layout/Discussion.js +2 -1
- package/dist/ssr/layout/Discussion.js.map +1 -1
- package/dist/ssr/layout/MobileShell.js +211 -0
- package/dist/ssr/layout/MobileShell.js.map +1 -0
- package/dist/ssr/layout/Navigation.js +1 -0
- package/dist/ssr/layout/Navigation.js.map +1 -1
- package/dist/ssr/layout/PanelDialog.js +1 -0
- package/dist/ssr/layout/PanelDialog.js.map +1 -1
- package/dist/ssr/layout/Settings.js +2 -2
- package/dist/ssr/layout/Settings.js.map +1 -1
- package/dist/ssr/layout/TabBar.js +24 -0
- package/dist/ssr/layout/TabBar.js.map +1 -0
- package/dist/ssr/layout/index.js +2 -0
- package/dist/ssr/layout/index.js.map +1 -1
- package/dist/ssr/surfaces/NoticeCard.js +21 -30
- package/dist/ssr/surfaces/NoticeCard.js.map +1 -1
- package/dist/ssr/surfaces/index.js +1 -1
- package/dist/ssr/surfaces/index.js.map +1 -1
- package/dist/styles.css +1 -1
- package/dist/tabler.css +1 -1
- package/dist/types/content/FileView.d.ts +11 -1
- package/dist/types/content/markdown-title.d.ts +9 -0
- package/dist/types/feedback/InstallGuide.d.ts +26 -0
- package/dist/types/feedback/announce.d.ts +19 -0
- package/dist/types/feedback/dialog-core.d.ts +5 -0
- package/dist/types/feedback/index.d.ts +8 -1
- package/dist/types/feedback/install.d.ts +32 -0
- package/dist/types/feedback/prompts.d.ts +2 -0
- package/dist/types/feedback/theme-color.d.ts +6 -0
- package/dist/types/feedback/toast.d.ts +7 -0
- package/dist/types/inputs/DatePicker.d.ts +11 -2
- package/dist/types/inputs/MultiSelectInput.d.ts +5 -1
- package/dist/types/inputs/NumberInput.d.ts +14 -0
- package/dist/types/inputs/QrScanner.d.ts +20 -0
- package/dist/types/inputs/Select.d.ts +10 -0
- package/dist/types/inputs/index.d.ts +3 -1
- package/dist/types/intl/messages.d.ts +44 -0
- package/dist/types/layout/MobileShell.d.ts +40 -0
- package/dist/types/layout/Settings.d.ts +2 -2
- package/dist/types/layout/TabBar.d.ts +23 -0
- package/dist/types/layout/index.d.ts +4 -0
- package/dist/types/surfaces/NoticeCard.d.ts +4 -4
- package/dist/types/surfaces/index.d.ts +1 -1
- package/package.json +3 -2
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
import { template as _$template } from "solid-js/web";
|
|
2
|
+
import { setAttribute as _$setAttribute } from "solid-js/web";
|
|
3
|
+
import { className as _$className } from "solid-js/web";
|
|
4
|
+
import { effect as _$effect } from "solid-js/web";
|
|
5
|
+
import { getNextMarker as _$getNextMarker } from "solid-js/web";
|
|
6
|
+
import { createComponent as _$createComponent } from "solid-js/web";
|
|
7
|
+
import { getNextElement as _$getNextElement } from "solid-js/web";
|
|
8
|
+
import { insert as _$insert } from "solid-js/web";
|
|
9
|
+
import { memo as _$memo } from "solid-js/web";
|
|
10
|
+
import { use as _$use } from "solid-js/web";
|
|
11
|
+
var _tmpl$ = /*#__PURE__*/_$template(`<p class=k2b-qr-scanner__note>`),
|
|
12
|
+
_tmpl$2 = /*#__PURE__*/_$template(`<div><div class=k2b-qr-scanner__preview><video muted playsinline></video></div><p role=status></p><!$><!/>`);
|
|
13
|
+
import { timed } from "@k2b/stdlib/solid";
|
|
14
|
+
import { createSignal, onCleanup, onMount, Show } from "solid-js";
|
|
15
|
+
import { useUiMessages } from "../intl/messages";
|
|
16
|
+
/**
|
|
17
|
+
* qr-scanner turns every getUserMedia failure into the string "Camera not found.", so only the Permissions API can
|
|
18
|
+
* tell a refusal apart. Safari and Chrome expose the camera permission; elsewhere a refusal counts as unavailable.
|
|
19
|
+
*/
|
|
20
|
+
const cameraDenied = async () => {
|
|
21
|
+
try {
|
|
22
|
+
return (await navigator.permissions.query({
|
|
23
|
+
name: "camera"
|
|
24
|
+
})).state === "denied";
|
|
25
|
+
} catch {
|
|
26
|
+
return false;
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Scans a QR code with the rear camera. Each mount owns exactly one camera session, which stops when the scanner
|
|
32
|
+
* unmounts, the page is hidden, or a result is accepted. The scanning engine loads only when the scanner mounts.
|
|
33
|
+
* Decoded content is never logged.
|
|
34
|
+
*/
|
|
35
|
+
export function QrScanner(props) {
|
|
36
|
+
const messages = useUiMessages();
|
|
37
|
+
const [starting, setStarting] = createSignal(true);
|
|
38
|
+
const [invalid, setInvalid] = createSignal(false);
|
|
39
|
+
let lastRejected;
|
|
40
|
+
const resetRejected = timed.debounce(() => {
|
|
41
|
+
lastRejected = undefined;
|
|
42
|
+
}, 1000);
|
|
43
|
+
const resetFeedback = timed.debounce(() => setInvalid(false), 1500);
|
|
44
|
+
let video;
|
|
45
|
+
let scanner;
|
|
46
|
+
let closed = false;
|
|
47
|
+
/** The host has unmounted the scanner; it no longer hears about failures that finish later. */
|
|
48
|
+
let unmounted = false;
|
|
49
|
+
let cleanupMotion;
|
|
50
|
+
const destroy = () => {
|
|
51
|
+
closed = true;
|
|
52
|
+
cleanupMotion?.();
|
|
53
|
+
resetRejected.cancel();
|
|
54
|
+
resetFeedback.cancel();
|
|
55
|
+
// pause(true) stops existing tracks immediately; destroy also handles a still-pending permission request.
|
|
56
|
+
void scanner?.pause(true);
|
|
57
|
+
scanner?.destroy();
|
|
58
|
+
scanner = undefined;
|
|
59
|
+
};
|
|
60
|
+
const fail = async () => {
|
|
61
|
+
if (closed) return;
|
|
62
|
+
destroy();
|
|
63
|
+
const denied = await cameraDenied();
|
|
64
|
+
if (!unmounted) props.onError(denied ? "denied" : "unavailable");
|
|
65
|
+
};
|
|
66
|
+
onMount(() => {
|
|
67
|
+
const hidden = () => {
|
|
68
|
+
if (document.visibilityState !== "visible") props.onStop();
|
|
69
|
+
};
|
|
70
|
+
const leaving = () => props.onStop();
|
|
71
|
+
document.addEventListener("visibilitychange", hidden);
|
|
72
|
+
window.addEventListener("pagehide", leaving);
|
|
73
|
+
onCleanup(() => {
|
|
74
|
+
unmounted = true;
|
|
75
|
+
destroy();
|
|
76
|
+
document.removeEventListener("visibilitychange", hidden);
|
|
77
|
+
window.removeEventListener("pagehide", leaving);
|
|
78
|
+
});
|
|
79
|
+
void (async () => {
|
|
80
|
+
try {
|
|
81
|
+
const {
|
|
82
|
+
default: Engine
|
|
83
|
+
} = await import("qr-scanner");
|
|
84
|
+
if (closed || document.visibilityState !== "visible") return;
|
|
85
|
+
scanner = new Engine(video, result => {
|
|
86
|
+
if (closed) return;
|
|
87
|
+
// Rearm only after a full second without a decoded QR, not between individual frames.
|
|
88
|
+
resetRejected.debouncedFn();
|
|
89
|
+
if (result.data === lastRejected) return;
|
|
90
|
+
if (props.onResult(result.data)) {
|
|
91
|
+
destroy();
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
lastRejected = result.data;
|
|
95
|
+
setInvalid(true);
|
|
96
|
+
resetFeedback.debouncedFn();
|
|
97
|
+
}, {
|
|
98
|
+
preferredCamera: "environment",
|
|
99
|
+
highlightScanRegion: true,
|
|
100
|
+
// Empty frames are expected. Never log decoded content or frame data.
|
|
101
|
+
onDecodeError: error => {
|
|
102
|
+
if (closed || error === Engine.NO_QR_CODE_FOUND) return;
|
|
103
|
+
void fail();
|
|
104
|
+
}
|
|
105
|
+
});
|
|
106
|
+
const motion = matchMedia("(prefers-reduced-motion: reduce)");
|
|
107
|
+
const applyMotion = () => {
|
|
108
|
+
for (const animation of scanner?.$overlay?.getAnimations({
|
|
109
|
+
subtree: true
|
|
110
|
+
}) ?? []) {
|
|
111
|
+
if (motion.matches) animation.pause();else animation.play();
|
|
112
|
+
}
|
|
113
|
+
};
|
|
114
|
+
applyMotion();
|
|
115
|
+
motion.addEventListener("change", applyMotion);
|
|
116
|
+
cleanupMotion = () => motion.removeEventListener("change", applyMotion);
|
|
117
|
+
await scanner.start();
|
|
118
|
+
if (!closed) setStarting(false);
|
|
119
|
+
} catch {
|
|
120
|
+
await fail();
|
|
121
|
+
}
|
|
122
|
+
})();
|
|
123
|
+
});
|
|
124
|
+
return (() => {
|
|
125
|
+
var _el$ = _$getNextElement(_tmpl$2),
|
|
126
|
+
_el$2 = _el$.firstChild,
|
|
127
|
+
_el$3 = _el$2.firstChild,
|
|
128
|
+
_el$4 = _el$2.nextSibling,
|
|
129
|
+
_el$6 = _el$4.nextSibling,
|
|
130
|
+
[_el$7, _co$] = _$getNextMarker(_el$6.nextSibling);
|
|
131
|
+
var _ref$ = video;
|
|
132
|
+
typeof _ref$ === "function" ? _$use(_ref$, _el$3) : video = _el$3;
|
|
133
|
+
_$insert(_el$4, (() => {
|
|
134
|
+
var _c$ = _$memo(() => !!starting());
|
|
135
|
+
return () => _c$() ? messages().qrCameraStarting : props.instructions ?? messages().qrCameraInstructions;
|
|
136
|
+
})());
|
|
137
|
+
_$insert(_el$, _$createComponent(Show, {
|
|
138
|
+
get when() {
|
|
139
|
+
return !starting();
|
|
140
|
+
},
|
|
141
|
+
get children() {
|
|
142
|
+
var _el$5 = _$getNextElement(_tmpl$);
|
|
143
|
+
_$insert(_el$5, () => messages().qrCameraPrivacy);
|
|
144
|
+
return _el$5;
|
|
145
|
+
}
|
|
146
|
+
}), _el$7, _co$);
|
|
147
|
+
_$effect(_p$ => {
|
|
148
|
+
var _v$ = props.class ? `k2b-qr-scanner ${props.class}` : "k2b-qr-scanner",
|
|
149
|
+
_v$2 = invalid() || undefined,
|
|
150
|
+
_v$3 = messages().qrCameraPreview;
|
|
151
|
+
_v$ !== _p$.e && _$className(_el$, _p$.e = _v$);
|
|
152
|
+
_v$2 !== _p$.t && _$setAttribute(_el$2, "data-invalid", _p$.t = _v$2);
|
|
153
|
+
_v$3 !== _p$.a && _$setAttribute(_el$3, "aria-label", _p$.a = _v$3);
|
|
154
|
+
return _p$;
|
|
155
|
+
}, {
|
|
156
|
+
e: undefined,
|
|
157
|
+
t: undefined,
|
|
158
|
+
a: undefined
|
|
159
|
+
});
|
|
160
|
+
return _el$;
|
|
161
|
+
})();
|
|
162
|
+
}
|
|
163
|
+
export default QrScanner;
|
|
164
|
+
//# sourceMappingURL=QrScanner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":[],"sources":["inputs/QrScanner.tsx"],"sourcesContent":["import { timed } from \"@k2b/stdlib/solid\";\nimport type QrScannerEngine from \"qr-scanner\";\nimport { createSignal, type JSX, onCleanup, onMount, Show } from \"solid-js\";\nimport { useUiMessages } from \"../intl/messages\";\n\nexport type QrScannerError = \"denied\" | \"unavailable\";\n\nexport type QrScannerProps = {\n /** Decoded text is untrusted. Return `true` to accept it and stop the camera, `false` to reject it and keep scanning. */\n onResult: (text: string) => boolean;\n /** The page was hidden or left; unmount the scanner. */\n onStop: () => void;\n /** The camera could not start: access was denied, or there is no usable camera. Offer another way in. */\n onError: (reason: QrScannerError) => void;\n /** What to point the camera at. Defaults to a generic QR code hint. */\n instructions?: string;\n class?: string;\n};\n\n/**\n * qr-scanner turns every getUserMedia failure into the string \"Camera not found.\", so only the Permissions API can\n * tell a refusal apart. Safari and Chrome expose the camera permission; elsewhere a refusal counts as unavailable.\n */\nconst cameraDenied = async (): Promise<boolean> => {\n try {\n return (await navigator.permissions.query({ name: \"camera\" as PermissionName })).state === \"denied\";\n } catch {\n return false;\n }\n};\n\n/**\n * Scans a QR code with the rear camera. Each mount owns exactly one camera session, which stops when the scanner\n * unmounts, the page is hidden, or a result is accepted. The scanning engine loads only when the scanner mounts.\n * Decoded content is never logged.\n */\nexport function QrScanner(props: QrScannerProps): JSX.Element {\n const messages = useUiMessages();\n const [starting, setStarting] = createSignal(true);\n const [invalid, setInvalid] = createSignal(false);\n let lastRejected: string | undefined;\n const resetRejected = timed.debounce(() => {\n lastRejected = undefined;\n }, 1000);\n const resetFeedback = timed.debounce(() => setInvalid(false), 1500);\n let video!: HTMLVideoElement;\n let scanner: QrScannerEngine | undefined;\n let closed = false;\n /** The host has unmounted the scanner; it no longer hears about failures that finish later. */\n let unmounted = false;\n let cleanupMotion: (() => void) | undefined;\n const destroy = () => {\n closed = true;\n cleanupMotion?.();\n resetRejected.cancel();\n resetFeedback.cancel();\n // pause(true) stops existing tracks immediately; destroy also handles a still-pending permission request.\n void scanner?.pause(true);\n scanner?.destroy();\n scanner = undefined;\n };\n const fail = async () => {\n if (closed) return;\n destroy();\n const denied = await cameraDenied();\n if (!unmounted) props.onError(denied ? \"denied\" : \"unavailable\");\n };\n onMount(() => {\n const hidden = () => {\n if (document.visibilityState !== \"visible\") props.onStop();\n };\n const leaving = () => props.onStop();\n document.addEventListener(\"visibilitychange\", hidden);\n window.addEventListener(\"pagehide\", leaving);\n onCleanup(() => {\n unmounted = true;\n destroy();\n document.removeEventListener(\"visibilitychange\", hidden);\n window.removeEventListener(\"pagehide\", leaving);\n });\n void (async () => {\n try {\n const { default: Engine } = await import(\"qr-scanner\");\n if (closed || document.visibilityState !== \"visible\") return;\n scanner = new Engine(\n video,\n (result) => {\n if (closed) return;\n // Rearm only after a full second without a decoded QR, not between individual frames.\n resetRejected.debouncedFn();\n if (result.data === lastRejected) return;\n if (props.onResult(result.data)) {\n destroy();\n return;\n }\n lastRejected = result.data;\n setInvalid(true);\n resetFeedback.debouncedFn();\n },\n {\n preferredCamera: \"environment\",\n highlightScanRegion: true,\n // Empty frames are expected. Never log decoded content or frame data.\n onDecodeError: (error) => {\n if (closed || error === Engine.NO_QR_CODE_FOUND) return;\n void fail();\n },\n },\n );\n const motion = matchMedia(\"(prefers-reduced-motion: reduce)\");\n const applyMotion = () => {\n for (const animation of scanner?.$overlay?.getAnimations({ subtree: true }) ?? []) {\n if (motion.matches) animation.pause();\n else animation.play();\n }\n };\n applyMotion();\n motion.addEventListener(\"change\", applyMotion);\n cleanupMotion = () => motion.removeEventListener(\"change\", applyMotion);\n await scanner.start();\n if (!closed) setStarting(false);\n } catch {\n await fail();\n }\n })();\n });\n return (\n <div class={props.class ? `k2b-qr-scanner ${props.class}` : \"k2b-qr-scanner\"}>\n <div class=\"k2b-qr-scanner__preview\" data-invalid={invalid() || undefined}>\n {/* Live camera preview contains no prerecorded speech or audio. */}\n <video ref={video} muted playsinline aria-label={messages().qrCameraPreview} />\n </div>\n <p role=\"status\">{starting() ? messages().qrCameraStarting : (props.instructions ?? messages().qrCameraInstructions)}</p>\n <Show when={!starting()}>\n <p class=\"k2b-qr-scanner__note\">{messages().qrCameraPrivacy}</p>\n </Show>\n </div>\n );\n}\n\nexport default QrScanner;\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -21,19 +21,30 @@ var _tmpl$ = /*#__PURE__*/_$template(`<button type=button class="k2b-choice-cont
|
|
|
21
21
|
_tmpl$4 = /*#__PURE__*/_$template(`<div class=k2b-choice-toolbar><!$><!/><!$><!/>`),
|
|
22
22
|
_tmpl$5 = /*#__PURE__*/_$template(`<div class=k2b-choice-status><i class="ti ti-loader-2 k2b-spin"aria-hidden=true></i><span>`),
|
|
23
23
|
_tmpl$6 = /*#__PURE__*/_$template(`<div class=k2b-choice-control><button type=button class=k2b-choice-trigger role=combobox aria-haspopup=listbox><!$><!/><span class=k2b-choice-trigger__value></span><i aria-hidden=true></i></button><!$><!/><!$><!/><div popover=manual class=k2b-choice-popover role=group><!$><!/><!$><!/><div class=k2b-choice-options role=listbox><!$><!/><!$><!/><!$><!/>`),
|
|
24
|
-
_tmpl$7 = /*#__PURE__*/_$template(`<
|
|
25
|
-
_tmpl$8 = /*#__PURE__*/_$template(`<
|
|
26
|
-
_tmpl$9 = /*#__PURE__*/_$template(`<
|
|
27
|
-
_tmpl$0 = /*#__PURE__*/_$template(`<
|
|
28
|
-
_tmpl$1 = /*#__PURE__*/_$template(`<div class=k2b-choice-status>`),
|
|
29
|
-
_tmpl$10 = /*#__PURE__*/_$template(`<
|
|
30
|
-
_tmpl$11 = /*#__PURE__*/_$template(`<
|
|
24
|
+
_tmpl$7 = /*#__PURE__*/_$template(`<span class=k2b-choice-dot data-empty=true aria-hidden=true>`),
|
|
25
|
+
_tmpl$8 = /*#__PURE__*/_$template(`<i aria-hidden=true>`),
|
|
26
|
+
_tmpl$9 = /*#__PURE__*/_$template(`<span class=k2b-choice-dot aria-hidden=true>`),
|
|
27
|
+
_tmpl$0 = /*#__PURE__*/_$template(`<input type=hidden>`),
|
|
28
|
+
_tmpl$1 = /*#__PURE__*/_$template(`<div class=k2b-choice-status data-tone=danger><span></span><button type=button>`),
|
|
29
|
+
_tmpl$10 = /*#__PURE__*/_$template(`<div class=k2b-choice-status>`),
|
|
30
|
+
_tmpl$11 = /*#__PURE__*/_$template(`<button type=button class=k2b-choice-option role=option><!$><!/><span><strong></strong><!$><!/>`),
|
|
31
|
+
_tmpl$12 = /*#__PURE__*/_$template(`<small>`);
|
|
31
32
|
import { createMemo, createSignal, For, Show } from "solid-js";
|
|
32
33
|
import { createFieldMeta, Field, fieldControlAria } from "../internal/field";
|
|
33
34
|
import { useUiMessages } from "../intl/messages";
|
|
34
35
|
import { ChoiceGroups } from "./ChoiceGroups";
|
|
35
36
|
import { createChoiceLoader, createChoicePopover, filterChoiceOptions, nextEnabledChoiceIndex } from "./choice";
|
|
36
37
|
import { commitFieldValue, resolveMaybeAccessor } from "./field-contract";
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* `field` draws the boxed form control. `plain` shows the value as text for
|
|
41
|
+
* property rows: no box, no chevron, and a quiet surface on hover or while
|
|
42
|
+
* open. Its surface and hit area cover the nearest positioned ancestor, such as
|
|
43
|
+
* a `DescriptionList` row, so the whole row opens the picker.
|
|
44
|
+
*/
|
|
45
|
+
|
|
46
|
+
/** The list entry that clears a plain select. It cannot collide with a real option value. */
|
|
47
|
+
const CLEAR_VALUE = "\u0000k2b-select-clear";
|
|
37
48
|
const normalize = option => typeof option === "string" ? {
|
|
38
49
|
value: option,
|
|
39
50
|
label: option
|
|
@@ -75,6 +86,19 @@ export function Select(props) {
|
|
|
75
86
|
// Remote loaders filter server-side; a static list has to be filtered here or
|
|
76
87
|
// the search field would render but do nothing.
|
|
77
88
|
const options = createMemo(() => isAsync() || !props.searchable ? groupedOptions() : props.filterOptions ? [...props.filterOptions(groupedOptions(), query())] : filterChoiceOptions(groupedOptions(), query()));
|
|
89
|
+
const plain = () => props.appearance === "plain";
|
|
90
|
+
// A plain select has no room for a clear button beside its value, so
|
|
91
|
+
// clearing becomes the last list entry, named by the placeholder.
|
|
92
|
+
const clearOption = createMemo(() => plain() && props.clearable && !query() ? {
|
|
93
|
+
value: CLEAR_VALUE,
|
|
94
|
+
label: props.placeholder ?? messages().clearSelection
|
|
95
|
+
} : undefined);
|
|
96
|
+
const listOptions = createMemo(() => {
|
|
97
|
+
const clear = clearOption();
|
|
98
|
+
return clear && !loader.error() ? [...options(), clear] : options();
|
|
99
|
+
});
|
|
100
|
+
// Colour dots mark the options, so an empty plain value keeps the column with a hollow dot.
|
|
101
|
+
const emptyDot = () => plain() && !props.placeholderIcon && sourceOptions().some(option => option.color);
|
|
78
102
|
const selected = createMemo(() => {
|
|
79
103
|
const current = value();
|
|
80
104
|
if (current === null) return undefined;
|
|
@@ -85,29 +109,29 @@ export function Select(props) {
|
|
|
85
109
|
label: props.selectedLabel?.() ?? current
|
|
86
110
|
};
|
|
87
111
|
});
|
|
88
|
-
const hasClearAction = () => Boolean(props.clearable && selected() && !props.disabled);
|
|
112
|
+
const hasClearAction = () => Boolean(props.clearable && selected() && !props.disabled && !plain());
|
|
89
113
|
const accessibleLabel = () => props["aria-label"] ?? (typeof props.label === "string" ? undefined : props.placeholder ?? messages().selectOption);
|
|
90
114
|
const popover = createChoicePopover(() => Boolean(props.disabled));
|
|
91
|
-
const focusedOption = () =>
|
|
115
|
+
const focusedOption = () => listOptions()[focusedIndex()];
|
|
92
116
|
const focus = index => {
|
|
93
117
|
setFocusedIndex(index);
|
|
94
118
|
optionRefs[index]?.scrollIntoView({
|
|
95
119
|
block: "nearest"
|
|
96
120
|
});
|
|
97
121
|
};
|
|
98
|
-
const move = direction => focus(nextEnabledChoiceIndex(
|
|
122
|
+
const move = direction => focus(nextEnabledChoiceIndex(listOptions(), focusedIndex(), direction));
|
|
99
123
|
const chooseGroup = group => {
|
|
100
124
|
if (group === activeGroup()) return;
|
|
101
125
|
setSelectedGroup(group);
|
|
102
|
-
setFocusedIndex(nextEnabledChoiceIndex(
|
|
126
|
+
setFocusedIndex(nextEnabledChoiceIndex(listOptions(), -1, 1));
|
|
103
127
|
if (isAsync()) loader.load(query(), true);
|
|
104
128
|
};
|
|
105
129
|
const open = () => {
|
|
106
130
|
if (props.disabled) return;
|
|
107
131
|
setQuery("");
|
|
108
132
|
if (isAsync()) loader.load("", true);
|
|
109
|
-
const selectedIndex =
|
|
110
|
-
focus(selectedIndex >= 0 ? selectedIndex : nextEnabledChoiceIndex(
|
|
133
|
+
const selectedIndex = listOptions().findIndex(option => option.value === (value() ?? CLEAR_VALUE));
|
|
134
|
+
focus(selectedIndex >= 0 ? selectedIndex : nextEnabledChoiceIndex(listOptions(), -1, 1));
|
|
111
135
|
popover.show();
|
|
112
136
|
if (isSearchable()) queueMicrotask(() => searchRef?.focus());
|
|
113
137
|
};
|
|
@@ -123,6 +147,10 @@ export function Select(props) {
|
|
|
123
147
|
const select = option => {
|
|
124
148
|
if (option.disabled) return;
|
|
125
149
|
close(true);
|
|
150
|
+
if (option.value === CLEAR_VALUE) {
|
|
151
|
+
commitFieldValue(props, null);
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
126
154
|
setCache({
|
|
127
155
|
...cache(),
|
|
128
156
|
[option.value]: option
|
|
@@ -224,25 +252,54 @@ export function Select(props) {
|
|
|
224
252
|
}), false, true);
|
|
225
253
|
_$insert(_el$2, _$createComponent(Show, {
|
|
226
254
|
get when() {
|
|
227
|
-
return selected()
|
|
255
|
+
return selected();
|
|
228
256
|
},
|
|
229
257
|
get fallback() {
|
|
230
258
|
return _$createComponent(Show, {
|
|
231
259
|
get when() {
|
|
232
|
-
return
|
|
260
|
+
return props.placeholderIcon;
|
|
261
|
+
},
|
|
262
|
+
get fallback() {
|
|
263
|
+
return _$createComponent(Show, {
|
|
264
|
+
get when() {
|
|
265
|
+
return emptyDot();
|
|
266
|
+
},
|
|
267
|
+
get children() {
|
|
268
|
+
return _$getNextElement(_tmpl$7);
|
|
269
|
+
}
|
|
270
|
+
});
|
|
233
271
|
},
|
|
234
272
|
children: icon => (() => {
|
|
235
|
-
var _el$
|
|
236
|
-
_$effect(() => _$className(_el$
|
|
237
|
-
return _el$
|
|
273
|
+
var _el$36 = _$getNextElement(_tmpl$8);
|
|
274
|
+
_$effect(() => _$className(_el$36, `${icon()} k2b-choice-trigger__placeholder-icon`));
|
|
275
|
+
return _el$36;
|
|
238
276
|
})()
|
|
239
277
|
});
|
|
240
278
|
},
|
|
241
|
-
children
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
279
|
+
get children() {
|
|
280
|
+
return _$createComponent(Show, {
|
|
281
|
+
get when() {
|
|
282
|
+
return selected()?.color;
|
|
283
|
+
},
|
|
284
|
+
get fallback() {
|
|
285
|
+
return _$createComponent(Show, {
|
|
286
|
+
get when() {
|
|
287
|
+
return selected()?.icon;
|
|
288
|
+
},
|
|
289
|
+
children: icon => (() => {
|
|
290
|
+
var _el$37 = _$getNextElement(_tmpl$8);
|
|
291
|
+
_$effect(() => _$className(_el$37, icon()));
|
|
292
|
+
return _el$37;
|
|
293
|
+
})()
|
|
294
|
+
});
|
|
295
|
+
},
|
|
296
|
+
children: color => (() => {
|
|
297
|
+
var _el$38 = _$getNextElement(_tmpl$9);
|
|
298
|
+
_$effect(_$p => _$setStyleProperty(_el$38, "background-color", color()));
|
|
299
|
+
return _el$38;
|
|
300
|
+
})()
|
|
301
|
+
});
|
|
302
|
+
}
|
|
246
303
|
}), _el$6, _co$);
|
|
247
304
|
_$insert(_el$3, () => selected()?.label ?? props.placeholder ?? messages().select);
|
|
248
305
|
_$insert(_el$, _$createComponent(Show, {
|
|
@@ -250,10 +307,10 @@ export function Select(props) {
|
|
|
250
307
|
return props.name;
|
|
251
308
|
},
|
|
252
309
|
children: name => (() => {
|
|
253
|
-
var _el$
|
|
254
|
-
_$effect(() => _$setAttribute(_el$
|
|
255
|
-
_$effect(() => _$setProperty(_el$
|
|
256
|
-
return _el$
|
|
310
|
+
var _el$39 = _$getNextElement(_tmpl$0);
|
|
311
|
+
_$effect(() => _$setAttribute(_el$39, "name", name()));
|
|
312
|
+
_$effect(() => _$setProperty(_el$39, "value", value() ?? ""));
|
|
313
|
+
return _el$39;
|
|
257
314
|
})()
|
|
258
315
|
}), _el$32, _co$9);
|
|
259
316
|
_$insert(_el$, _$createComponent(Show, {
|
|
@@ -367,14 +424,14 @@ export function Select(props) {
|
|
|
367
424
|
return loader.error();
|
|
368
425
|
},
|
|
369
426
|
children: message => (() => {
|
|
370
|
-
var _el$
|
|
371
|
-
_el$
|
|
372
|
-
_el$
|
|
373
|
-
_$insert(_el$
|
|
374
|
-
_$addEventListener(_el$
|
|
375
|
-
_$insert(_el$
|
|
427
|
+
var _el$40 = _$getNextElement(_tmpl$1),
|
|
428
|
+
_el$41 = _el$40.firstChild,
|
|
429
|
+
_el$42 = _el$41.nextSibling;
|
|
430
|
+
_$insert(_el$41, message);
|
|
431
|
+
_$addEventListener(_el$42, "click", loader.retry, true);
|
|
432
|
+
_$insert(_el$42, () => messages().retry);
|
|
376
433
|
_$runHydrationEvents();
|
|
377
|
-
return _el$
|
|
434
|
+
return _el$40;
|
|
378
435
|
})()
|
|
379
436
|
}), _el$22, _co$4);
|
|
380
437
|
_$insert(_el$17, _$createComponent(Show, {
|
|
@@ -391,7 +448,7 @@ export function Select(props) {
|
|
|
391
448
|
}), _el$24, _co$5);
|
|
392
449
|
_$insert(_el$17, _$createComponent(For, {
|
|
393
450
|
get each() {
|
|
394
|
-
return _$memo(() => !!loader.error())() ? [] :
|
|
451
|
+
return _$memo(() => !!loader.error())() ? [] : listOptions();
|
|
395
452
|
},
|
|
396
453
|
get fallback() {
|
|
397
454
|
return _$createComponent(Show, {
|
|
@@ -399,95 +456,129 @@ export function Select(props) {
|
|
|
399
456
|
return _$memo(() => !!!loader.loading())() && !loader.error();
|
|
400
457
|
},
|
|
401
458
|
get children() {
|
|
402
|
-
var _el$
|
|
403
|
-
_$insert(_el$
|
|
459
|
+
var _el$43 = _$getNextElement(_tmpl$10);
|
|
460
|
+
_$insert(_el$43, (() => {
|
|
404
461
|
var _c$ = _$memo(() => !!isSearchable());
|
|
405
462
|
return () => _c$() ? messages().noResults : messages().noOptions;
|
|
406
463
|
})());
|
|
407
|
-
return _el$
|
|
464
|
+
return _el$43;
|
|
408
465
|
}
|
|
409
466
|
});
|
|
410
467
|
},
|
|
411
468
|
children: (option, index) => (() => {
|
|
412
|
-
var _el$
|
|
413
|
-
_el$
|
|
414
|
-
[_el$
|
|
415
|
-
_el$
|
|
416
|
-
_el$
|
|
417
|
-
_el$
|
|
418
|
-
[_el$
|
|
419
|
-
_el$
|
|
420
|
-
_el$
|
|
421
|
-
_$use(element => optionRefs[index()] = element, _el$
|
|
422
|
-
_$insert(_el$
|
|
469
|
+
var _el$44 = _$getNextElement(_tmpl$11),
|
|
470
|
+
_el$49 = _el$44.firstChild,
|
|
471
|
+
[_el$50, _co$10] = _$getNextMarker(_el$49.nextSibling),
|
|
472
|
+
_el$45 = _el$50.nextSibling,
|
|
473
|
+
_el$46 = _el$45.firstChild,
|
|
474
|
+
_el$47 = _el$46.nextSibling,
|
|
475
|
+
[_el$48, _co$1] = _$getNextMarker(_el$47.nextSibling);
|
|
476
|
+
_el$44.$$click = () => select(option);
|
|
477
|
+
_el$44.$$pointermove = () => focus(index());
|
|
478
|
+
_$use(element => optionRefs[index()] = element, _el$44);
|
|
479
|
+
_$insert(_el$44, _$createComponent(Show, {
|
|
423
480
|
get when() {
|
|
424
|
-
return option.
|
|
481
|
+
return option.value === CLEAR_VALUE;
|
|
425
482
|
},
|
|
426
483
|
get fallback() {
|
|
427
484
|
return _$createComponent(Show, {
|
|
428
485
|
get when() {
|
|
429
|
-
return option.
|
|
486
|
+
return option.color;
|
|
430
487
|
},
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
488
|
+
get fallback() {
|
|
489
|
+
return _$createComponent(Show, {
|
|
490
|
+
get when() {
|
|
491
|
+
return option.icon;
|
|
492
|
+
},
|
|
493
|
+
children: icon => (() => {
|
|
494
|
+
var _el$51 = _$getNextElement(_tmpl$8);
|
|
495
|
+
_$effect(() => _$className(_el$51, icon()));
|
|
496
|
+
return _el$51;
|
|
497
|
+
})()
|
|
498
|
+
});
|
|
499
|
+
},
|
|
500
|
+
children: color => (() => {
|
|
501
|
+
var _el$52 = _$getNextElement(_tmpl$9);
|
|
502
|
+
_$effect(_$p => _$setStyleProperty(_el$52, "background-color", color()));
|
|
503
|
+
return _el$52;
|
|
435
504
|
})()
|
|
436
505
|
});
|
|
437
506
|
},
|
|
438
|
-
children
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
507
|
+
get children() {
|
|
508
|
+
return _$createComponent(Show, {
|
|
509
|
+
get when() {
|
|
510
|
+
return props.placeholderIcon;
|
|
511
|
+
},
|
|
512
|
+
get fallback() {
|
|
513
|
+
return _$createComponent(Show, {
|
|
514
|
+
get when() {
|
|
515
|
+
return emptyDot();
|
|
516
|
+
},
|
|
517
|
+
get children() {
|
|
518
|
+
return _$getNextElement(_tmpl$7);
|
|
519
|
+
}
|
|
520
|
+
});
|
|
521
|
+
},
|
|
522
|
+
children: icon => (() => {
|
|
523
|
+
var _el$54 = _$getNextElement(_tmpl$8);
|
|
524
|
+
_$effect(() => _$className(_el$54, icon()));
|
|
525
|
+
return _el$54;
|
|
526
|
+
})()
|
|
527
|
+
});
|
|
528
|
+
}
|
|
529
|
+
}), _el$50, _co$10);
|
|
530
|
+
_$insert(_el$46, () => option.label);
|
|
531
|
+
_$insert(_el$45, _$createComponent(Show, {
|
|
446
532
|
get when() {
|
|
447
533
|
return option.description;
|
|
448
534
|
},
|
|
449
535
|
children: description => (() => {
|
|
450
|
-
var _el$
|
|
451
|
-
_$insert(_el$
|
|
452
|
-
return _el$
|
|
536
|
+
var _el$55 = _$getNextElement(_tmpl$12);
|
|
537
|
+
_$insert(_el$55, description);
|
|
538
|
+
return _el$55;
|
|
453
539
|
})()
|
|
454
|
-
}), _el$
|
|
540
|
+
}), _el$48, _co$1);
|
|
455
541
|
_$effect(_p$ => {
|
|
456
|
-
var _v$
|
|
457
|
-
_v$
|
|
458
|
-
_v$
|
|
459
|
-
_v$
|
|
460
|
-
_v$
|
|
461
|
-
|
|
462
|
-
_v$11 !== _p$.
|
|
463
|
-
_v$12 !== _p$.
|
|
464
|
-
_v$13 !== _p$.
|
|
465
|
-
_v$14 !== _p$.
|
|
542
|
+
var _v$11 = `${listboxId}-${index()}`,
|
|
543
|
+
_v$12 = option.label,
|
|
544
|
+
_v$13 = option.value === (value() ?? CLEAR_VALUE),
|
|
545
|
+
_v$14 = index() === focusedIndex() ? "true" : undefined,
|
|
546
|
+
_v$15 = option.value === CLEAR_VALUE ? "true" : undefined,
|
|
547
|
+
_v$16 = option.disabled;
|
|
548
|
+
_v$11 !== _p$.e && _$setAttribute(_el$44, "id", _p$.e = _v$11);
|
|
549
|
+
_v$12 !== _p$.t && _$setAttribute(_el$44, "aria-label", _p$.t = _v$12);
|
|
550
|
+
_v$13 !== _p$.a && _$setAttribute(_el$44, "aria-selected", _p$.a = _v$13);
|
|
551
|
+
_v$14 !== _p$.o && _$setAttribute(_el$44, "data-focused", _p$.o = _v$14);
|
|
552
|
+
_v$15 !== _p$.i && _$setAttribute(_el$44, "data-clear", _p$.i = _v$15);
|
|
553
|
+
_v$16 !== _p$.n && _$setProperty(_el$44, "disabled", _p$.n = _v$16);
|
|
466
554
|
return _p$;
|
|
467
555
|
}, {
|
|
468
556
|
e: undefined,
|
|
469
557
|
t: undefined,
|
|
470
558
|
a: undefined,
|
|
471
559
|
o: undefined,
|
|
472
|
-
i: undefined
|
|
560
|
+
i: undefined,
|
|
561
|
+
n: undefined
|
|
473
562
|
});
|
|
474
563
|
_$runHydrationEvents();
|
|
475
|
-
return _el$
|
|
564
|
+
return _el$44;
|
|
476
565
|
})()
|
|
477
566
|
}), _el$26, _co$6);
|
|
478
567
|
_$effect(_p$ => {
|
|
479
|
-
var _v$6 =
|
|
480
|
-
_v$7 =
|
|
481
|
-
_v$8 =
|
|
482
|
-
_v$9 =
|
|
483
|
-
_v$0 =
|
|
484
|
-
_v$1 = activeView()
|
|
485
|
-
|
|
486
|
-
_v$
|
|
487
|
-
_v$
|
|
488
|
-
_v$
|
|
489
|
-
_v$
|
|
490
|
-
_v$
|
|
568
|
+
var _v$6 = props.appearance ?? "field",
|
|
569
|
+
_v$7 = error() ? "true" : undefined,
|
|
570
|
+
_v$8 = selected() ? undefined : "true",
|
|
571
|
+
_v$9 = `${popover.open() ? props.activeIcon ?? "ti ti-chevron-up" : props.icon ?? "ti ti-chevron-down"} k2b-choice-trigger__chevron`,
|
|
572
|
+
_v$0 = typeof props.label === "string" ? props.label : props["aria-label"] ?? messages().options,
|
|
573
|
+
_v$1 = activeView(),
|
|
574
|
+
_v$10 = activeView() === "grid" ? props.gridSize ?? "md" : undefined;
|
|
575
|
+
_v$6 !== _p$.e && _$setAttribute(_el$, "data-appearance", _p$.e = _v$6);
|
|
576
|
+
_v$7 !== _p$.t && _$setAttribute(_el$, "data-invalid", _p$.t = _v$7);
|
|
577
|
+
_v$8 !== _p$.a && _$setAttribute(_el$3, "data-placeholder", _p$.a = _v$8);
|
|
578
|
+
_v$9 !== _p$.o && _$className(_el$4, _p$.o = _v$9);
|
|
579
|
+
_v$0 !== _p$.i && _$setAttribute(_el$8, "aria-label", _p$.i = _v$0);
|
|
580
|
+
_v$1 !== _p$.n && _$setAttribute(_el$17, "data-view", _p$.n = _v$1);
|
|
581
|
+
_v$10 !== _p$.s && _$setAttribute(_el$17, "data-grid-size", _p$.s = _v$10);
|
|
491
582
|
return _p$;
|
|
492
583
|
}, {
|
|
493
584
|
e: undefined,
|
|
@@ -495,7 +586,8 @@ export function Select(props) {
|
|
|
495
586
|
a: undefined,
|
|
496
587
|
o: undefined,
|
|
497
588
|
i: undefined,
|
|
498
|
-
n: undefined
|
|
589
|
+
n: undefined,
|
|
590
|
+
s: undefined
|
|
499
591
|
});
|
|
500
592
|
_$runHydrationEvents();
|
|
501
593
|
return _el$;
|