@quaffui/quaff 1.0.0-alpha2 → 1.0.0-beta12
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 +2 -0
- package/dist/classes/QScrollObserver.svelte.d.ts +4 -4
- package/dist/classes/QScrollObserver.svelte.js +26 -13
- package/dist/components/avatar/QAvatar.svelte +4 -0
- package/dist/components/avatar/QAvatar.svelte.d.ts +4 -14
- package/dist/components/breadcrumbs/QBreadcrumbs.scss +9 -5
- package/dist/components/breadcrumbs/QBreadcrumbs.svelte +46 -16
- package/dist/components/breadcrumbs/QBreadcrumbs.svelte.d.ts +24 -12
- package/dist/components/breadcrumbs/QBreadcrumbsEl.scss +22 -3
- package/dist/components/breadcrumbs/QBreadcrumbsEl.svelte +50 -38
- package/dist/components/breadcrumbs/QBreadcrumbsEl.svelte.d.ts +4 -14
- package/dist/components/breadcrumbs/props.d.ts +4 -4
- package/dist/components/button/QBtn.scss +3 -1
- package/dist/components/button/QBtn.svelte +38 -22
- package/dist/components/button/QBtn.svelte.d.ts +4 -14
- package/dist/components/button/props.d.ts +9 -2
- package/dist/components/card/QCard.svelte +9 -5
- package/dist/components/card/QCard.svelte.d.ts +4 -14
- package/dist/components/card/QCardActions.svelte +4 -0
- package/dist/components/card/QCardActions.svelte.d.ts +4 -14
- package/dist/components/card/QCardSection.svelte +2 -0
- package/dist/components/card/QCardSection.svelte.d.ts +4 -14
- package/dist/components/checkbox/QCheckbox.svelte +6 -4
- package/dist/components/checkbox/QCheckbox.svelte.d.ts +4 -14
- package/dist/components/checkbox/props.d.ts +1 -1
- package/dist/components/chip/QChip.scss +3 -1
- package/dist/components/chip/QChip.svelte +24 -14
- package/dist/components/chip/QChip.svelte.d.ts +4 -14
- package/dist/components/codeBlock/QCodeBlock.svelte +8 -0
- package/dist/components/codeBlock/QCodeBlock.svelte.d.ts +4 -14
- package/dist/components/dialog/QDialog.scss +17 -0
- package/dist/components/dialog/QDialog.svelte +34 -9
- package/dist/components/dialog/QDialog.svelte.d.ts +8 -21
- package/dist/components/drawer/QDrawer.scss +2 -2
- package/dist/components/drawer/QDrawer.svelte +124 -69
- package/dist/components/drawer/QDrawer.svelte.d.ts +8 -21
- package/dist/components/drawer/props.d.ts +3 -3
- package/dist/components/expansion-item/QExpansionItem.scss +59 -0
- package/dist/components/expansion-item/QExpansionItem.svelte +319 -0
- package/dist/components/expansion-item/QExpansionItem.svelte.d.ts +8 -0
- package/dist/components/expansion-item/docs.d.ts +2 -0
- package/dist/components/expansion-item/docs.js +17 -0
- package/dist/components/expansion-item/props.d.ts +129 -0
- package/dist/components/expansion-item/props.js +1 -0
- package/dist/components/footer/QFooter.scss +1 -1
- package/dist/components/footer/QFooter.svelte +32 -28
- package/dist/components/footer/QFooter.svelte.d.ts +4 -14
- package/dist/components/header/QHeader.scss +1 -1
- package/dist/components/header/QHeader.svelte +41 -33
- package/dist/components/header/QHeader.svelte.d.ts +4 -14
- package/dist/components/icon/QIcon.svelte +6 -4
- package/dist/components/icon/QIcon.svelte.d.ts +4 -14
- package/dist/components/index.d.ts +3 -1
- package/dist/components/index.js +3 -1
- package/dist/components/input/QInput.svelte +139 -17
- package/dist/components/input/QInput.svelte.d.ts +4 -14
- package/dist/components/input/docs.js +2 -2
- package/dist/components/input/mask.d.ts +10 -0
- package/dist/components/input/mask.js +204 -0
- package/dist/components/input/props.d.ts +37 -4
- package/dist/components/layout/QLayout.svelte +248 -93
- package/dist/components/layout/QLayout.svelte.d.ts +67 -15
- package/dist/components/layout/props.d.ts +1 -1
- package/dist/components/list/QItem.scss +7 -4
- package/dist/components/list/QItem.svelte +44 -24
- package/dist/components/list/QItem.svelte.d.ts +17 -13
- package/dist/components/list/QItemSection.scss +24 -3
- package/dist/components/list/QItemSection.svelte +19 -21
- package/dist/components/list/QItemSection.svelte.d.ts +4 -14
- package/dist/components/list/QList.scss +17 -4
- package/dist/components/list/QList.svelte +30 -8
- package/dist/components/list/QList.svelte.d.ts +17 -13
- package/dist/components/list/props.d.ts +3 -3
- package/dist/components/menu/QMenu.scss +37 -0
- package/dist/components/menu/QMenu.svelte +314 -0
- package/dist/components/menu/QMenu.svelte.d.ts +8 -0
- package/dist/components/menu/docs.d.ts +2 -0
- package/dist/components/menu/docs.js +27 -0
- package/dist/components/menu/props.d.ts +48 -0
- package/dist/components/menu/props.js +1 -0
- package/dist/components/progress/QCircularProgress.svelte +17 -14
- package/dist/components/progress/QCircularProgress.svelte.d.ts +4 -14
- package/dist/components/progress/QLinearProgress.svelte +15 -15
- package/dist/components/progress/QLinearProgress.svelte.d.ts +4 -14
- package/dist/components/radio/QRadio.svelte +6 -4
- package/dist/components/radio/QRadio.svelte.d.ts +4 -14
- package/dist/components/radio/props.d.ts +1 -1
- package/dist/components/railbar/QRailbar.scss +1 -1
- package/dist/components/railbar/QRailbar.svelte +36 -35
- package/dist/components/railbar/QRailbar.svelte.d.ts +4 -14
- package/dist/components/select/QSelect.svelte +316 -102
- package/dist/components/select/QSelect.svelte.d.ts +4 -14
- package/dist/components/select/filter.d.ts +13 -0
- package/dist/components/select/filter.js +73 -0
- package/dist/components/select/index.scss +28 -27
- package/dist/components/select/option.d.ts +9 -0
- package/dist/components/select/option.js +59 -0
- package/dist/components/select/props.d.ts +40 -7
- package/dist/components/separator/QSeparator.scss +2 -0
- package/dist/components/separator/QSeparator.svelte +9 -8
- package/dist/components/separator/QSeparator.svelte.d.ts +4 -14
- package/dist/components/switch/QSwitch.scss +12 -6
- package/dist/components/switch/QSwitch.svelte +7 -1
- package/dist/components/switch/QSwitch.svelte.d.ts +4 -14
- package/dist/components/table/QTable.svelte +31 -19
- package/dist/components/table/QTable.svelte.d.ts +4 -14
- package/dist/components/table/index.scss +1 -1
- package/dist/components/tabs/QTab.scss +2 -0
- package/dist/components/tabs/QTab.svelte +19 -22
- package/dist/components/tabs/QTab.svelte.d.ts +4 -14
- package/dist/components/tabs/QTabs.svelte +59 -32
- package/dist/components/tabs/QTabs.svelte.d.ts +18 -18
- package/dist/components/toolbar/QToolbar.svelte +2 -0
- package/dist/components/toolbar/QToolbar.svelte.d.ts +4 -14
- package/dist/components/toolbar/QToolbarTitle.svelte +2 -0
- package/dist/components/toolbar/QToolbarTitle.svelte.d.ts +4 -14
- package/dist/components/tooltip/QTooltip.svelte +48 -38
- package/dist/components/tooltip/QTooltip.svelte.d.ts +29 -17
- package/dist/components/tooltip/QTooltipBase.svelte +18 -8
- package/dist/components/tooltip/QTooltipBase.svelte.d.ts +4 -14
- package/dist/composables/index.d.ts +2 -0
- package/dist/composables/index.js +2 -0
- package/dist/composables/useColor.d.ts +1 -0
- package/dist/composables/useColor.js +19 -0
- package/dist/composables/useRevealScrollObserver.svelte.d.ts +9 -0
- package/dist/composables/useRevealScrollObserver.svelte.js +25 -0
- package/dist/composables/useRouterLink.d.ts +3 -2
- package/dist/composables/useRouterLink.js +2 -2
- package/dist/css/_components.scss +2 -0
- package/dist/css/classes/_grid.scss +12 -1
- package/dist/css/index.css +1 -1
- package/dist/css/mixins/_design.scss +1 -1
- package/dist/css/mixins/_field.scss +3 -2
- package/dist/css/mixins/_table.scss +1 -1
- package/dist/css/mixins/_toolbar.scss +1 -1
- package/dist/css/shared/q-field.scss +7 -6
- package/dist/css/theme/_page.scss +8 -6
- package/dist/css/theme/_reset.scss +2 -1
- package/dist/helpers/clickOutside.js +5 -4
- package/dist/helpers/ripple.js +5 -6
- package/dist/helpers/version.d.ts +1 -1
- package/dist/helpers/version.js +1 -1
- package/dist/{components/private/ContextReseter.svelte → internal/ContextResetter.svelte} +2 -3
- package/dist/internal/ContextResetter.svelte.d.ts +8 -0
- package/dist/{components/private → internal}/QIconSnippet.svelte +2 -2
- package/dist/internal/QIconSnippet.svelte.d.ts +10 -0
- package/dist/utils/context.d.ts +49 -32
- package/dist/utils/context.js +82 -33
- package/dist/utils/dom.d.ts +6 -0
- package/dist/utils/dom.js +33 -0
- package/dist/utils/events.d.ts +0 -24
- package/dist/utils/events.js +0 -24
- package/package.json +44 -38
- package/dist/classes/QContext.svelte.d.ts +0 -42
- package/dist/classes/QContext.svelte.js +0 -63
- package/dist/components/avatar/docs.props.d.ts +0 -3
- package/dist/components/avatar/docs.props.js +0 -87
- package/dist/components/breadcrumbs/docs.props.d.ts +0 -5
- package/dist/components/breadcrumbs/docs.props.js +0 -144
- package/dist/components/button/docs.props.d.ts +0 -3
- package/dist/components/button/docs.props.js +0 -227
- package/dist/components/card/docs.props.d.ts +0 -7
- package/dist/components/card/docs.props.js +0 -89
- package/dist/components/checkbox/docs.props.d.ts +0 -3
- package/dist/components/checkbox/docs.props.js +0 -41
- package/dist/components/chip/docs.props.d.ts +0 -3
- package/dist/components/chip/docs.props.js +0 -137
- package/dist/components/codeBlock/docs.props.d.ts +0 -3
- package/dist/components/codeBlock/docs.props.js +0 -83
- package/dist/components/dialog/docs.props.d.ts +0 -3
- package/dist/components/dialog/docs.props.js +0 -65
- package/dist/components/drawer/docs.props.d.ts +0 -3
- package/dist/components/drawer/docs.props.js +0 -149
- package/dist/components/footer/docs.props.d.ts +0 -3
- package/dist/components/footer/docs.props.js +0 -65
- package/dist/components/header/docs.props.d.ts +0 -7
- package/dist/components/header/docs.props.js +0 -131
- package/dist/components/icon/docs.props.d.ts +0 -3
- package/dist/components/icon/docs.props.js +0 -107
- package/dist/components/input/docs.props.d.ts +0 -3
- package/dist/components/input/docs.props.js +0 -162
- package/dist/components/layout/docs.props.d.ts +0 -3
- package/dist/components/layout/docs.props.js +0 -81
- package/dist/components/list/docs.props.d.ts +0 -11
- package/dist/components/list/docs.props.js +0 -434
- package/dist/components/private/ContextReseter.svelte.d.ts +0 -14
- package/dist/components/private/QApi.svelte +0 -296
- package/dist/components/private/QApi.svelte.d.ts +0 -14
- package/dist/components/private/QDocs.svelte +0 -155
- package/dist/components/private/QDocs.svelte.d.ts +0 -14
- package/dist/components/private/QDocsSection.svelte +0 -62
- package/dist/components/private/QDocsSection.svelte.d.ts +0 -14
- package/dist/components/private/QIconSnippet.svelte.d.ts +0 -14
- package/dist/components/private/index.d.ts +0 -6
- package/dist/components/private/index.js +0 -6
- package/dist/components/progress/docs.props.d.ts +0 -5
- package/dist/components/progress/docs.props.js +0 -314
- package/dist/components/radio/docs.props.d.ts +0 -3
- package/dist/components/radio/docs.props.js +0 -53
- package/dist/components/railbar/docs.props.d.ts +0 -3
- package/dist/components/railbar/docs.props.js +0 -47
- package/dist/components/select/docs.props.d.ts +0 -3
- package/dist/components/select/docs.props.js +0 -198
- package/dist/components/separator/docs.props.d.ts +0 -5
- package/dist/components/separator/docs.props.js +0 -196
- package/dist/components/switch/docs.props.d.ts +0 -3
- package/dist/components/switch/docs.props.js +0 -119
- package/dist/components/table/docs.props.d.ts +0 -3
- package/dist/components/table/docs.props.js +0 -94
- package/dist/components/tabs/docs.props.d.ts +0 -5
- package/dist/components/tabs/docs.props.js +0 -86
- package/dist/components/toolbar/docs.props.d.ts +0 -5
- package/dist/components/toolbar/docs.props.js +0 -68
- package/dist/components/tooltip/docs.props.d.ts +0 -3
- package/dist/components/tooltip/docs.props.js +0 -77
- package/dist/utils/types.json +0 -31
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { QLayoutCtxName } from "../../utils";
|
|
5
|
-
import type { QLayoutProps } from "../layout/props";
|
|
6
|
-
import type { DrawerContext } from "../layout/QLayout.svelte";
|
|
2
|
+
import { onMount } from "svelte";
|
|
3
|
+
import { leftRailbarCtx, rightRailbarCtx } from "../layout/QLayout.svelte";
|
|
7
4
|
import type { QRailbarProps } from "./props";
|
|
8
5
|
|
|
6
|
+
// #region: --- Props
|
|
9
7
|
let {
|
|
10
8
|
width = 88,
|
|
11
9
|
side = "left",
|
|
@@ -13,50 +11,53 @@
|
|
|
13
11
|
children,
|
|
14
12
|
...props
|
|
15
13
|
}: QRailbarProps = $props();
|
|
14
|
+
// #endregion: --- Props
|
|
16
15
|
|
|
17
|
-
|
|
18
|
-
const layoutView = getContext<{ value: NonNullable<QLayoutProps["view"]> }>(
|
|
19
|
-
QLayoutCtxName.view,
|
|
20
|
-
);
|
|
21
|
-
|
|
16
|
+
// #region: --- Non-reactive variables
|
|
22
17
|
let railbarEl: HTMLElement;
|
|
18
|
+
// #endregion: --- Non-reactive variables
|
|
23
19
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
}
|
|
30
|
-
});
|
|
31
|
-
|
|
32
|
-
onDestroy(() => {
|
|
33
|
-
untrack(() => railbarCtx)?.updateEntries({
|
|
34
|
-
width: 0,
|
|
35
|
-
takesSpace: false,
|
|
36
|
-
ready: false,
|
|
37
|
-
});
|
|
38
|
-
});
|
|
39
|
-
|
|
40
|
-
$effect.pre(() => {
|
|
41
|
-
untrack(() => railbarCtx)?.updateEntries({
|
|
42
|
-
width,
|
|
43
|
-
takesSpace: railbarEl?.style.display !== "none" || false,
|
|
44
|
-
ready: true,
|
|
45
|
-
});
|
|
46
|
-
});
|
|
20
|
+
// #region: --- Derived values
|
|
21
|
+
const railbarCtxToUse = $derived(
|
|
22
|
+
side === "left" ? leftRailbarCtx : rightRailbarCtx,
|
|
23
|
+
);
|
|
24
|
+
const railbarCtx = $derived(railbarCtxToUse.get());
|
|
47
25
|
|
|
48
26
|
const offsetTop = $derived.by(() => {
|
|
49
27
|
const charPos = side === "left" ? 0 : 2;
|
|
50
|
-
return
|
|
28
|
+
return railbarCtx?.view.charAt(charPos) === "h";
|
|
51
29
|
});
|
|
52
30
|
const offsetBottom = $derived.by(() => {
|
|
53
31
|
const charPos = side === "left" ? 8 : 10;
|
|
54
|
-
return
|
|
32
|
+
return railbarCtx?.view.charAt(charPos) === "f";
|
|
55
33
|
});
|
|
56
34
|
|
|
57
35
|
const railbarWidthStyle = $derived(`--${side}-railbar-width: ${width}px`);
|
|
58
36
|
|
|
59
37
|
const style = $derived(`${railbarWidthStyle};${props.style ?? ""}`);
|
|
38
|
+
// #endregion: --- Derived values
|
|
39
|
+
|
|
40
|
+
// #region: --- Lifecycle
|
|
41
|
+
onMount(() => {
|
|
42
|
+
railbarCtxToUse.updateEntries({
|
|
43
|
+
width,
|
|
44
|
+
takesSpace: railbarEl.style.display !== "none" || false,
|
|
45
|
+
ready: true,
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
setTimeout(() => {
|
|
49
|
+
railbarEl.style.transition = "top 0.3s, bottom 0.3s, transform 0.3s";
|
|
50
|
+
}, 100);
|
|
51
|
+
|
|
52
|
+
return () => {
|
|
53
|
+
railbarCtxToUse.updateEntries({
|
|
54
|
+
width: 0,
|
|
55
|
+
takesSpace: false,
|
|
56
|
+
ready: false,
|
|
57
|
+
});
|
|
58
|
+
};
|
|
59
|
+
});
|
|
60
|
+
// #endregion: --- Lifecycle
|
|
60
61
|
</script>
|
|
61
62
|
|
|
62
63
|
<nav
|
|
@@ -1,14 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
declare const
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
[evt: string]: CustomEvent<any>;
|
|
6
|
-
};
|
|
7
|
-
slots: {};
|
|
8
|
-
};
|
|
9
|
-
type QRailbarProps_ = typeof __propDef.props;
|
|
10
|
-
export { QRailbarProps_ as QRailbarProps };
|
|
11
|
-
export type QRailbarEvents = typeof __propDef.events;
|
|
12
|
-
export type QRailbarSlots = typeof __propDef.slots;
|
|
13
|
-
export default class QRailbar extends SvelteComponentTyped<QRailbarProps_, QRailbarEvents, QRailbarSlots> {
|
|
14
|
-
}
|
|
1
|
+
import type { QRailbarProps } from "./props";
|
|
2
|
+
declare const QRailbar: import("svelte").Component<QRailbarProps, {}, "">;
|
|
3
|
+
type QRailbar = ReturnType<typeof QRailbar>;
|
|
4
|
+
export default QRailbar;
|
|
@@ -1,21 +1,30 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
import { onDestroy,
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
2
|
+
import { onDestroy, tick } from "svelte";
|
|
3
|
+
import { QIcon, QItem, QItemSection, QList, QMenu } from "../..";
|
|
4
|
+
import { isActivationKey, type QEvent } from "../../utils";
|
|
5
|
+
import {
|
|
6
|
+
createFilterRunner,
|
|
7
|
+
getFilteredOptions,
|
|
8
|
+
getInputValue,
|
|
9
|
+
} from "./filter";
|
|
10
|
+
import {
|
|
11
|
+
doValuesMatch,
|
|
12
|
+
getDisplayValue,
|
|
13
|
+
getInitialOptionIndex,
|
|
14
|
+
getNextValue,
|
|
15
|
+
getOptionLabel,
|
|
16
|
+
normalizeOptionIndex,
|
|
17
|
+
} from "./option";
|
|
18
|
+
import type { QSelectOption, QSelectProps } from "./props";
|
|
11
19
|
|
|
12
20
|
type QSelectEvent<T> = QEvent<T, HTMLDivElement>;
|
|
13
21
|
|
|
22
|
+
// #region: --- Props
|
|
14
23
|
let {
|
|
15
24
|
options,
|
|
16
25
|
multiple = false,
|
|
17
26
|
dense = false,
|
|
18
|
-
|
|
27
|
+
disabled = false,
|
|
19
28
|
error = false,
|
|
20
29
|
errorMessage = undefined,
|
|
21
30
|
filled = false,
|
|
@@ -24,124 +33,296 @@
|
|
|
24
33
|
outlined = false,
|
|
25
34
|
rounded = false,
|
|
26
35
|
displayValue,
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
36
|
+
emitValue = false,
|
|
37
|
+
useInput = false,
|
|
38
|
+
filterable = false,
|
|
39
|
+
inputDebounce = 300,
|
|
40
|
+
noOptionText = "No options",
|
|
41
|
+
onFilter,
|
|
42
|
+
before,
|
|
43
|
+
prepend,
|
|
44
|
+
append,
|
|
45
|
+
after,
|
|
31
46
|
value = $bindable(),
|
|
32
47
|
...props
|
|
33
48
|
}: QSelectProps = $props();
|
|
49
|
+
// #endregion: --- Props
|
|
34
50
|
|
|
35
|
-
|
|
51
|
+
// #region: --- Non-reactive variables
|
|
52
|
+
const id = $props.id();
|
|
53
|
+
const listboxId = `q-select__listbox-${id}`;
|
|
54
|
+
// #endregion: --- Non-reactive variables
|
|
36
55
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
56
|
+
// #region: --- Reactive variables
|
|
57
|
+
let isFocused = $state(false);
|
|
58
|
+
|
|
59
|
+
let menuTarget = $state<HTMLLabelElement>();
|
|
60
|
+
let isMenuOpen = $state(false);
|
|
61
|
+
let focusedOptionIndex = $state(-1);
|
|
62
|
+
let snippetPrependWidth = $state(0);
|
|
63
|
+
let searchValue = $state("");
|
|
64
|
+
let isSearching = $state(false);
|
|
65
|
+
// #endregion: --- Reactive variables
|
|
66
|
+
|
|
67
|
+
const filterRunner = createFilterRunner({
|
|
68
|
+
onAbort: resetFocusedOption,
|
|
69
|
+
onDone: focusFirstOption,
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
// #region: --- Derived values
|
|
73
|
+
const currentDisplayValue = $derived(
|
|
74
|
+
getDisplayValue(value, options, multiple, displayValue),
|
|
75
|
+
);
|
|
76
|
+
|
|
77
|
+
const hasDisplayValue = $derived(
|
|
78
|
+
currentDisplayValue !== "" && currentDisplayValue !== undefined,
|
|
79
|
+
);
|
|
80
|
+
const isActive = $derived(hasDisplayValue || isFocused || isMenuOpen);
|
|
81
|
+
|
|
82
|
+
const visibleOptions = $derived(
|
|
83
|
+
getFilteredOptions(options, searchValue, useInput, filterable, !!onFilter),
|
|
84
|
+
);
|
|
85
|
+
const inputValue = $derived(
|
|
86
|
+
getInputValue(currentDisplayValue, searchValue, useInput, isSearching),
|
|
87
|
+
);
|
|
88
|
+
|
|
89
|
+
const isOptionSelectedByIndex = $derived(visibleOptions.map(isSelected));
|
|
90
|
+
const activeOptionId = $derived(
|
|
91
|
+
isMenuOpen && focusedOptionIndex >= 0
|
|
92
|
+
? getOptionId(focusedOptionIndex)
|
|
93
|
+
: undefined,
|
|
94
|
+
);
|
|
95
|
+
// #endregion: --- Derived values
|
|
96
|
+
|
|
97
|
+
// #region: --- Effects
|
|
98
|
+
$effect(() => {
|
|
99
|
+
if (disabled) {
|
|
100
|
+
isMenuOpen = false;
|
|
40
101
|
}
|
|
102
|
+
});
|
|
41
103
|
|
|
42
|
-
|
|
43
|
-
|
|
104
|
+
$effect(() => {
|
|
105
|
+
if (!isMenuOpen) {
|
|
106
|
+
focusedOptionIndex = -1;
|
|
107
|
+
resetSearch();
|
|
44
108
|
}
|
|
109
|
+
});
|
|
45
110
|
|
|
46
|
-
|
|
111
|
+
$effect(() => {
|
|
112
|
+
if (focusedOptionIndex >= visibleOptions.length) {
|
|
113
|
+
focusedOptionIndex = visibleOptions.length
|
|
114
|
+
? visibleOptions.length - 1
|
|
115
|
+
: -1;
|
|
116
|
+
}
|
|
47
117
|
});
|
|
118
|
+
// #endregion: --- Effects
|
|
48
119
|
|
|
49
|
-
|
|
120
|
+
onDestroy(filterRunner.clear);
|
|
50
121
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
122
|
+
// #region: --- Functions
|
|
123
|
+
function handleMousedown() {
|
|
124
|
+
if (disabled) {
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
55
127
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
128
|
+
if (useInput) {
|
|
129
|
+
void showMenu();
|
|
130
|
+
} else if (isMenuOpen) {
|
|
131
|
+
hideMenu();
|
|
132
|
+
} else {
|
|
133
|
+
void showMenu();
|
|
134
|
+
}
|
|
60
135
|
}
|
|
61
136
|
|
|
62
137
|
function handleFocus(e: QSelectEvent<FocusEvent>) {
|
|
63
|
-
|
|
64
|
-
if (!wasClicked) {
|
|
65
|
-
isMenuOpen = true;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
wasClicked = false;
|
|
138
|
+
isFocused = true;
|
|
69
139
|
props.onfocus?.(e);
|
|
70
140
|
}
|
|
71
141
|
|
|
72
142
|
function handleBlur(e: QSelectEvent<FocusEvent>) {
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
if (!multiple && !preventClose) {
|
|
76
|
-
isMenuOpen = false;
|
|
77
|
-
}
|
|
78
|
-
preventClose = false;
|
|
143
|
+
isFocused = false;
|
|
79
144
|
props.onblur?.(e);
|
|
80
145
|
}
|
|
81
146
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
147
|
+
function handleKeydown(e: QSelectEvent<KeyboardEvent>) {
|
|
148
|
+
if (disabled) {
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
85
151
|
|
|
86
|
-
|
|
152
|
+
const isSelectKey = useInput ? e.code === "Enter" : isActivationKey(e);
|
|
87
153
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
? (value as QSelectMultipleValue).includes(optionValue)
|
|
92
|
-
: value === optionValue;
|
|
93
|
-
}
|
|
154
|
+
if (isSelectKey) {
|
|
155
|
+
e.preventDefault();
|
|
156
|
+
e.stopPropagation();
|
|
94
157
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
158
|
+
if (isMenuOpen && focusedOptionIndex !== -1) {
|
|
159
|
+
selectOption(visibleOptions[focusedOptionIndex]);
|
|
160
|
+
} else if (isMenuOpen) {
|
|
161
|
+
hideMenu();
|
|
162
|
+
} else {
|
|
163
|
+
void showMenu();
|
|
164
|
+
}
|
|
165
|
+
} else if (e.code === "ArrowDown" || e.code === "ArrowUp") {
|
|
166
|
+
e.preventDefault();
|
|
167
|
+
e.stopPropagation();
|
|
168
|
+
moveFocusedOption(e.code === "ArrowDown" ? 1 : -1);
|
|
169
|
+
} else if (!useInput && (e.code === "Home" || e.code === "End")) {
|
|
170
|
+
e.preventDefault();
|
|
171
|
+
e.stopPropagation();
|
|
172
|
+
|
|
173
|
+
if (!isMenuOpen) {
|
|
174
|
+
isMenuOpen = true;
|
|
175
|
+
}
|
|
98
176
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
(entry) => entry === optionValue,
|
|
177
|
+
void setFocusedOptionIndex(
|
|
178
|
+
e.code === "Home" ? 0 : visibleOptions.length - 1,
|
|
102
179
|
);
|
|
180
|
+
} else if (e.code === "Escape" && isMenuOpen) {
|
|
181
|
+
e.preventDefault();
|
|
182
|
+
e.stopPropagation();
|
|
183
|
+
hideMenu();
|
|
184
|
+
} else if (e.code === "Tab") {
|
|
185
|
+
hideMenu();
|
|
186
|
+
}
|
|
103
187
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
value as QSelectMultipleValue
|
|
107
|
-
).filter((val) => val !== optionValue);
|
|
108
|
-
} else {
|
|
109
|
-
(value as QSelectMultipleValue) = [
|
|
110
|
-
...(value as QSelectMultipleValue),
|
|
111
|
-
optionValue,
|
|
112
|
-
];
|
|
113
|
-
}
|
|
188
|
+
props.onkeydown?.(e);
|
|
189
|
+
}
|
|
114
190
|
|
|
191
|
+
function handleInput(e: Event) {
|
|
192
|
+
if (!useInput) {
|
|
115
193
|
return;
|
|
116
194
|
}
|
|
117
195
|
|
|
118
|
-
|
|
196
|
+
searchValue = (e.currentTarget as HTMLInputElement).value;
|
|
197
|
+
isSearching = true;
|
|
198
|
+
|
|
199
|
+
if (!isMenuOpen) {
|
|
200
|
+
void showMenu(0);
|
|
201
|
+
} else {
|
|
202
|
+
void setFocusedOptionIndex(0);
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
filterRunner.schedule(searchValue, getExternalFilter(), inputDebounce);
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
async function showMenu(optionIndex = getInitialFocusedOptionIndex()) {
|
|
209
|
+
isMenuOpen = true;
|
|
210
|
+
await setFocusedOptionIndex(optionIndex);
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
function hideMenu() {
|
|
119
214
|
isMenuOpen = false;
|
|
215
|
+
focusedOptionIndex = -1;
|
|
120
216
|
}
|
|
121
217
|
|
|
122
|
-
function
|
|
123
|
-
if (
|
|
124
|
-
|
|
218
|
+
function moveFocusedOption(offset: number) {
|
|
219
|
+
if (!visibleOptions.length) {
|
|
220
|
+
return;
|
|
125
221
|
}
|
|
222
|
+
|
|
223
|
+
if (!isMenuOpen) {
|
|
224
|
+
void showMenu(getInitialFocusedOptionIndex(offset));
|
|
225
|
+
return;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
const baseIndex =
|
|
229
|
+
focusedOptionIndex === -1
|
|
230
|
+
? getInitialFocusedOptionIndex(offset)
|
|
231
|
+
: focusedOptionIndex;
|
|
232
|
+
|
|
233
|
+
void setFocusedOptionIndex(baseIndex + offset);
|
|
126
234
|
}
|
|
127
235
|
|
|
128
|
-
|
|
129
|
-
if (
|
|
130
|
-
|
|
236
|
+
function getInitialFocusedOptionIndex(direction = 1) {
|
|
237
|
+
if (!visibleOptions.length) {
|
|
238
|
+
return -1;
|
|
131
239
|
}
|
|
132
|
-
});
|
|
133
240
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
241
|
+
return getInitialOptionIndex(visibleOptions, isSelected, direction);
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
async function setFocusedOptionIndex(optionIndex: number) {
|
|
245
|
+
focusedOptionIndex = normalizeOptionIndex(
|
|
246
|
+
optionIndex,
|
|
247
|
+
visibleOptions.length,
|
|
248
|
+
);
|
|
249
|
+
|
|
250
|
+
await tick();
|
|
251
|
+
scrollFocusedOptionIntoView();
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
function resetFocusedOption() {
|
|
255
|
+
focusedOptionIndex = -1;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
function focusFirstOption() {
|
|
259
|
+
return setFocusedOptionIndex(0);
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
function scrollFocusedOptionIntoView() {
|
|
263
|
+
if (focusedOptionIndex === -1) {
|
|
264
|
+
return;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
document
|
|
268
|
+
.getElementById(getOptionId(focusedOptionIndex))
|
|
269
|
+
?.scrollIntoView({ block: "nearest" });
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
function getOptionId(optionIndex: number) {
|
|
273
|
+
return `${listboxId}__option-${optionIndex}`;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
function isSelected(option: QSelectOption) {
|
|
277
|
+
return multiple
|
|
278
|
+
? Array.isArray(value) && value.some((opt) => doValuesMatch(opt, option))
|
|
279
|
+
: doValuesMatch(value as QSelectOption, option);
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
function handleOptionMousedown(evt: MouseEvent) {
|
|
283
|
+
evt.preventDefault();
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
function handleOptionClick(
|
|
287
|
+
evt: MouseEvent,
|
|
288
|
+
option: QSelectOption,
|
|
289
|
+
optionIndex: number,
|
|
290
|
+
) {
|
|
291
|
+
evt.preventDefault();
|
|
292
|
+
focusedOptionIndex = optionIndex;
|
|
293
|
+
selectOption(option);
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
function selectOption(option: QSelectOption) {
|
|
297
|
+
value = getNextValue(value, option, multiple, emitValue);
|
|
298
|
+
|
|
299
|
+
if (multiple) {
|
|
300
|
+
resetSearch();
|
|
301
|
+
return;
|
|
137
302
|
}
|
|
138
|
-
|
|
303
|
+
|
|
304
|
+
hideMenu();
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
function resetSearch() {
|
|
308
|
+
if (!isSearching && !searchValue) {
|
|
309
|
+
return;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
searchValue = "";
|
|
313
|
+
isSearching = false;
|
|
314
|
+
filterRunner.schedule("", getExternalFilter(), inputDebounce);
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
function getExternalFilter() {
|
|
318
|
+
return useInput ? onFilter : undefined;
|
|
319
|
+
}
|
|
320
|
+
// #endregion: --- Functions
|
|
139
321
|
|
|
140
322
|
// q-field here, q-select in classes
|
|
141
323
|
</script>
|
|
142
324
|
|
|
143
325
|
<div
|
|
144
|
-
bind:this={wrapper}
|
|
145
326
|
{...props}
|
|
146
327
|
class={[
|
|
147
328
|
"q-field",
|
|
@@ -153,14 +334,15 @@
|
|
|
153
334
|
filled && "q-field--filled",
|
|
154
335
|
(outlined || rounded) && "q-field--has-border",
|
|
155
336
|
dense && "q-field--dense",
|
|
156
|
-
|
|
157
|
-
|
|
337
|
+
isActive && "q-field--active",
|
|
338
|
+
isFocused && "q-field--focus",
|
|
158
339
|
label && "q-field--label",
|
|
159
340
|
!!append && "q-field--snippet-append",
|
|
160
341
|
!!prepend && "q-field--snippet-prepend",
|
|
161
|
-
|
|
342
|
+
disabled && "q-field--disabled",
|
|
162
343
|
error && "q-field--error",
|
|
163
344
|
(hint || (error && errorMessage)) && "q-field--bottom-space",
|
|
345
|
+
useInput && "q-field--use-input",
|
|
164
346
|
]}
|
|
165
347
|
style:--snippet-prepend-width="{snippetPrependWidth}px"
|
|
166
348
|
data-quaff
|
|
@@ -172,7 +354,7 @@
|
|
|
172
354
|
{/if}
|
|
173
355
|
|
|
174
356
|
<div class="q-field__inner">
|
|
175
|
-
<label class="q-field__wrapper">
|
|
357
|
+
<label bind:this={menuTarget} class="q-field__wrapper">
|
|
176
358
|
{#if prepend}
|
|
177
359
|
<div
|
|
178
360
|
class="q-field__snippet-prepend"
|
|
@@ -184,14 +366,24 @@
|
|
|
184
366
|
|
|
185
367
|
<input
|
|
186
368
|
class="q-field__input"
|
|
187
|
-
value={
|
|
369
|
+
value={inputValue}
|
|
188
370
|
placeholder=""
|
|
371
|
+
role="combobox"
|
|
372
|
+
aria-autocomplete={useInput ? "list" : "none"}
|
|
373
|
+
aria-controls={listboxId}
|
|
374
|
+
aria-expanded={isMenuOpen}
|
|
375
|
+
aria-haspopup="listbox"
|
|
376
|
+
aria-label={label}
|
|
377
|
+
aria-activedescendant={activeOptionId}
|
|
378
|
+
aria-readonly={useInput ? undefined : "true"}
|
|
189
379
|
onfocus={handleFocus}
|
|
190
380
|
onblur={handleBlur}
|
|
381
|
+
oninput={handleInput}
|
|
191
382
|
onmousedown={handleMousedown}
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
383
|
+
onkeydown={handleKeydown}
|
|
384
|
+
{disabled}
|
|
385
|
+
tabindex={disabled === true ? -1 : 0}
|
|
386
|
+
readonly={!useInput}
|
|
195
387
|
/>
|
|
196
388
|
|
|
197
389
|
<span class="q-field__label">{label}</span>
|
|
@@ -204,23 +396,45 @@
|
|
|
204
396
|
? 'q-select__arrow-toggle--has-append'
|
|
205
397
|
: ''}"
|
|
206
398
|
name={`arrow_drop_${isMenuOpen ? "up" : "down"}`}
|
|
399
|
+
onmousedown={handleMousedown}
|
|
207
400
|
/>
|
|
208
401
|
</div>
|
|
209
402
|
</label>
|
|
210
403
|
|
|
211
|
-
<
|
|
212
|
-
{
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
404
|
+
<QMenu
|
|
405
|
+
bind:value={isMenuOpen}
|
|
406
|
+
target={menuTarget}
|
|
407
|
+
fit
|
|
408
|
+
autoClose={!multiple}
|
|
409
|
+
class="q-select__menu"
|
|
410
|
+
id={listboxId}
|
|
411
|
+
role="listbox"
|
|
412
|
+
aria-multiselectable={multiple ? "true" : undefined}
|
|
413
|
+
>
|
|
414
|
+
<QList dense>
|
|
415
|
+
{#each visibleOptions as option, idx (idx)}
|
|
416
|
+
<QItem
|
|
417
|
+
clickable
|
|
418
|
+
active={isOptionSelectedByIndex[idx]}
|
|
419
|
+
activeClass="q-select__option--selected"
|
|
420
|
+
class="q-select__option {focusedOptionIndex === idx
|
|
421
|
+
? 'q-select__option--focused'
|
|
422
|
+
: ''}"
|
|
423
|
+
id={getOptionId(idx)}
|
|
424
|
+
role="option"
|
|
425
|
+
tabindex={-1}
|
|
426
|
+
aria-selected={isOptionSelectedByIndex[idx] ? "true" : "false"}
|
|
427
|
+
onmousedown={handleOptionMousedown}
|
|
428
|
+
onmousemove={() => (focusedOptionIndex = idx)}
|
|
429
|
+
onclick={(e) => handleOptionClick(e, option, idx)}
|
|
430
|
+
>
|
|
431
|
+
<QItemSection>{getOptionLabel(option, options)}</QItemSection>
|
|
432
|
+
</QItem>
|
|
433
|
+
{:else}
|
|
434
|
+
<div class="q-select__no-option">{noOptionText}</div>
|
|
435
|
+
{/each}
|
|
436
|
+
</QList>
|
|
437
|
+
</QMenu>
|
|
224
438
|
|
|
225
439
|
{#if error && errorMessage}
|
|
226
440
|
<div class="q-field__error">{errorMessage}</div>
|
|
@@ -1,14 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
declare const
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
[evt: string]: CustomEvent<any>;
|
|
6
|
-
};
|
|
7
|
-
slots: {};
|
|
8
|
-
};
|
|
9
|
-
type QSelectProps_ = typeof __propDef.props;
|
|
10
|
-
export { QSelectProps_ as QSelectProps };
|
|
11
|
-
export type QSelectEvents = typeof __propDef.events;
|
|
12
|
-
export type QSelectSlots = typeof __propDef.slots;
|
|
13
|
-
export default class QSelect extends SvelteComponentTyped<QSelectProps_, QSelectEvents, QSelectSlots> {
|
|
14
|
-
}
|
|
1
|
+
import type { QSelectProps } from "./props";
|
|
2
|
+
declare const QSelect: import("svelte").Component<QSelectProps, {}, "value">;
|
|
3
|
+
type QSelect = ReturnType<typeof QSelect>;
|
|
4
|
+
export default QSelect;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { QSelectOption, QSelectProps } from "./props";
|
|
2
|
+
type QSelectOnFilter = QSelectProps["onFilter"];
|
|
3
|
+
type FilterRunnerOptions = {
|
|
4
|
+
onAbort: () => void;
|
|
5
|
+
onDone: () => void | Promise<void>;
|
|
6
|
+
};
|
|
7
|
+
export declare function getFilteredOptions(options: QSelectOption[], search: string, useInput: boolean, filterable: boolean, hasExternalFilter: boolean): QSelectOption[];
|
|
8
|
+
export declare function getInputValue(currentDisplayValue: string | number, search: string, useInput: boolean, isSearching: boolean): string | number;
|
|
9
|
+
export declare function createFilterRunner({ onAbort, onDone }: FilterRunnerOptions): {
|
|
10
|
+
clear: () => void;
|
|
11
|
+
schedule: (search: string, onFilter: QSelectOnFilter, debounce?: number) => void;
|
|
12
|
+
};
|
|
13
|
+
export {};
|