bits-ui 2.17.2 → 2.18.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/dist/bits/menubar/components/menubar-menu.svelte +1 -2
- package/dist/bits/pin-input/components/pin-input.svelte +5 -0
- package/dist/bits/pin-input/components/pin-input.svelte.d.ts +1 -1
- package/dist/bits/pin-input/pin-input.svelte.d.ts +1 -0
- package/dist/bits/pin-input/pin-input.svelte.js +10 -10
- package/dist/bits/pin-input/types.d.ts +6 -0
- package/dist/bits/select/components/select-value.svelte +48 -0
- package/dist/bits/select/components/select-value.svelte.d.ts +4 -0
- package/dist/bits/select/exports.d.ts +2 -1
- package/dist/bits/select/exports.js +1 -0
- package/dist/bits/select/select.svelte.d.ts +24 -0
- package/dist/bits/select/select.svelte.js +85 -0
- package/dist/bits/select/types.d.ts +22 -1
- package/dist/bits/utilities/dismissible-layer/use-dismissable-layer.svelte.js +3 -2
- package/dist/bits/utilities/popper-layer/popper-layer-inner.svelte +1 -3
- package/dist/bits/utilities/presence-layer/presence-layer.svelte +4 -5
- package/package.json +1 -1
|
@@ -25,6 +25,5 @@
|
|
|
25
25
|
_internal_variant="menubar"
|
|
26
26
|
{...restProps}
|
|
27
27
|
_internal_should_skip_exit_animation={() =>
|
|
28
|
-
menuState.root.skipExitAnimationForMenuValue === menuState.opts.value.current
|
|
29
|
-
}
|
|
28
|
+
menuState.root.skipExitAnimationForMenuValue === menuState.opts.value.current}
|
|
30
29
|
/>
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
id = createId(uid),
|
|
12
12
|
inputId = `${createId(uid)}-input`,
|
|
13
13
|
ref = $bindable(null),
|
|
14
|
+
inputRef = $bindable(null),
|
|
14
15
|
maxlength = 6,
|
|
15
16
|
textalign = "left",
|
|
16
17
|
pattern,
|
|
@@ -33,6 +34,10 @@
|
|
|
33
34
|
() => ref,
|
|
34
35
|
(v) => (ref = v)
|
|
35
36
|
),
|
|
37
|
+
inputRef: boxWith(
|
|
38
|
+
() => inputRef,
|
|
39
|
+
(v) => (inputRef = v)
|
|
40
|
+
),
|
|
36
41
|
inputId: boxWith(() => inputId),
|
|
37
42
|
autocomplete: boxWith(() => autocomplete),
|
|
38
43
|
maxLength: boxWith(() => maxlength),
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import type { PinInputRootProps } from "../types.js";
|
|
2
|
-
declare const PinInput: import("svelte").Component<PinInputRootProps, {}, "value" | "ref">;
|
|
2
|
+
declare const PinInput: import("svelte").Component<PinInputRootProps, {}, "value" | "inputRef" | "ref">;
|
|
3
3
|
type PinInput = ReturnType<typeof PinInput>;
|
|
4
4
|
export default PinInput;
|
|
@@ -6,6 +6,7 @@ export declare const REGEXP_ONLY_CHARS = "^[a-zA-Z]+$";
|
|
|
6
6
|
export declare const REGEXP_ONLY_DIGITS_AND_CHARS = "^[a-zA-Z0-9]+$";
|
|
7
7
|
interface PinInputRootStateOpts extends WithRefOpts, WritableBoxedValues<{
|
|
8
8
|
value: string;
|
|
9
|
+
inputRef: HTMLInputElement | null;
|
|
9
10
|
}>, ReadableBoxedValues<{
|
|
10
11
|
inputId: string;
|
|
11
12
|
disabled: boolean;
|
|
@@ -33,9 +33,8 @@ export class PinInputRootState {
|
|
|
33
33
|
}
|
|
34
34
|
opts;
|
|
35
35
|
attachment;
|
|
36
|
-
|
|
36
|
+
inputAttachment;
|
|
37
37
|
#isHoveringInput = $state(false);
|
|
38
|
-
inputAttachment = attachRef(this.#inputRef);
|
|
39
38
|
#isFocused = simpleBox(false);
|
|
40
39
|
#mirrorSelectionStart = $state(null);
|
|
41
40
|
#mirrorSelectionEnd = $state(null);
|
|
@@ -58,6 +57,7 @@ export class PinInputRootState {
|
|
|
58
57
|
constructor(opts) {
|
|
59
58
|
this.opts = opts;
|
|
60
59
|
this.attachment = attachRef(this.opts.ref);
|
|
60
|
+
this.inputAttachment = attachRef(this.opts.inputRef);
|
|
61
61
|
this.domContext = new DOMContext(opts.ref);
|
|
62
62
|
this.#initialLoad = {
|
|
63
63
|
value: this.opts.value,
|
|
@@ -66,13 +66,13 @@ export class PinInputRootState {
|
|
|
66
66
|
};
|
|
67
67
|
this.#pwmb = usePasswordManagerBadge({
|
|
68
68
|
containerRef: this.opts.ref,
|
|
69
|
-
inputRef: this
|
|
69
|
+
inputRef: this.opts.inputRef,
|
|
70
70
|
isFocused: this.#isFocused,
|
|
71
71
|
pushPasswordManagerStrategy: this.opts.pushPasswordManagerStrategy,
|
|
72
72
|
domContext: this.domContext,
|
|
73
73
|
});
|
|
74
74
|
onMount(() => {
|
|
75
|
-
const input = this
|
|
75
|
+
const input = this.opts.inputRef.current;
|
|
76
76
|
const container = this.opts.ref.current;
|
|
77
77
|
if (!input || !container)
|
|
78
78
|
return;
|
|
@@ -107,9 +107,9 @@ export class PinInputRootState {
|
|
|
107
107
|
resizeObserver.disconnect();
|
|
108
108
|
};
|
|
109
109
|
});
|
|
110
|
-
watch([() => this.opts.value.current, () => this
|
|
110
|
+
watch([() => this.opts.value.current, () => this.opts.inputRef.current], () => {
|
|
111
111
|
syncTimeouts(() => {
|
|
112
|
-
const input = this
|
|
112
|
+
const input = this.opts.inputRef.current;
|
|
113
113
|
if (!input)
|
|
114
114
|
return;
|
|
115
115
|
// forcefully remove :autofill state
|
|
@@ -213,7 +213,7 @@ export class PinInputRootState {
|
|
|
213
213
|
}
|
|
214
214
|
}
|
|
215
215
|
#onDocumentSelectionChange = () => {
|
|
216
|
-
const input = this
|
|
216
|
+
const input = this.opts.inputRef.current;
|
|
217
217
|
const container = this.opts.ref.current;
|
|
218
218
|
if (!input || !container)
|
|
219
219
|
return;
|
|
@@ -260,7 +260,7 @@ export class PinInputRootState {
|
|
|
260
260
|
}
|
|
261
261
|
}
|
|
262
262
|
if (start !== -1 && end !== -1 && start !== end) {
|
|
263
|
-
this
|
|
263
|
+
this.opts.inputRef.current?.setSelectionRange(start, end, direction);
|
|
264
264
|
}
|
|
265
265
|
}
|
|
266
266
|
// finally update the state
|
|
@@ -289,7 +289,7 @@ export class PinInputRootState {
|
|
|
289
289
|
this.opts.value.current = newValue;
|
|
290
290
|
};
|
|
291
291
|
onfocus = (_) => {
|
|
292
|
-
const input = this
|
|
292
|
+
const input = this.opts.inputRef.current;
|
|
293
293
|
if (input) {
|
|
294
294
|
const start = Math.min(input.value.length, this.opts.maxLength.current - 1);
|
|
295
295
|
const end = input.value.length;
|
|
@@ -300,7 +300,7 @@ export class PinInputRootState {
|
|
|
300
300
|
this.#isFocused.current = true;
|
|
301
301
|
};
|
|
302
302
|
onpaste = (e) => {
|
|
303
|
-
const input = this
|
|
303
|
+
const input = this.opts.inputRef.current;
|
|
304
304
|
if (!input)
|
|
305
305
|
return;
|
|
306
306
|
const getNewValue = (finalContent) => {
|
|
@@ -52,6 +52,12 @@ export type PinInputRootPropsWithoutHTML = Omit<WithChild<{
|
|
|
52
52
|
* Optionally provide an ID to apply to the hidden input element.
|
|
53
53
|
*/
|
|
54
54
|
inputId?: string;
|
|
55
|
+
/**
|
|
56
|
+
* The underlying hidden `<input>` element. Bind to call `focus()`, read selection, etc.
|
|
57
|
+
*
|
|
58
|
+
* @bindable
|
|
59
|
+
*/
|
|
60
|
+
inputRef?: HTMLInputElement | null;
|
|
55
61
|
/**
|
|
56
62
|
* The children snippet used to render the individual cells.
|
|
57
63
|
*/
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { boxWith, mergeProps } from "svelte-toolbelt";
|
|
3
|
+
import { SelectValueState } from "../select.svelte.js";
|
|
4
|
+
import type { SelectValueProps } from "../types.js";
|
|
5
|
+
import { createId } from "../../../internal/create-id.js";
|
|
6
|
+
|
|
7
|
+
const uid = $props.id();
|
|
8
|
+
|
|
9
|
+
let {
|
|
10
|
+
ref = $bindable(null),
|
|
11
|
+
id = createId(uid),
|
|
12
|
+
placeholder,
|
|
13
|
+
child,
|
|
14
|
+
children,
|
|
15
|
+
...restProps
|
|
16
|
+
}: SelectValueProps = $props();
|
|
17
|
+
|
|
18
|
+
const valueState = SelectValueState.create({
|
|
19
|
+
id: boxWith(() => id),
|
|
20
|
+
ref: boxWith(
|
|
21
|
+
() => ref,
|
|
22
|
+
(v) => (ref = v)
|
|
23
|
+
),
|
|
24
|
+
placeholder: boxWith(() => placeholder),
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
const mergedProps = $derived(mergeProps(restProps, valueState.props));
|
|
28
|
+
</script>
|
|
29
|
+
|
|
30
|
+
{#if child}
|
|
31
|
+
{@render child({ props: mergedProps, ...valueState.snippetProps })}
|
|
32
|
+
{:else}
|
|
33
|
+
<span {...mergedProps}>
|
|
34
|
+
{#if children}
|
|
35
|
+
{@render children?.(valueState.snippetProps)}
|
|
36
|
+
{:else if valueState.snippetProps.selection.type === "single"}
|
|
37
|
+
{valueState.snippetProps.selection.selected?.label ?? placeholder}
|
|
38
|
+
{:else if valueState.snippetProps.selection.type === "multiple" && valueState.snippetProps.selection.selected}
|
|
39
|
+
{valueState.snippetProps.selection.selected.length > 0
|
|
40
|
+
? valueState.snippetProps.selection.selected
|
|
41
|
+
.map((selected) => selected.label)
|
|
42
|
+
.join(", ")
|
|
43
|
+
: placeholder}
|
|
44
|
+
{:else}
|
|
45
|
+
{placeholder}
|
|
46
|
+
{/if}
|
|
47
|
+
</span>
|
|
48
|
+
{/if}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export { default as Root } from "./components/select.svelte";
|
|
2
|
+
export { default as Value } from "./components/select-value.svelte";
|
|
2
3
|
export { default as Content } from "./components/select-content.svelte";
|
|
3
4
|
export { default as ContentStatic } from "./components/select-content-static.svelte";
|
|
4
5
|
export { default as Item } from "./components/select-item.svelte";
|
|
@@ -9,4 +10,4 @@ export { default as Portal } from "../utilities/portal/portal.svelte";
|
|
|
9
10
|
export { default as Viewport } from "./components/select-viewport.svelte";
|
|
10
11
|
export { default as ScrollUpButton } from "./components/select-scroll-up-button.svelte";
|
|
11
12
|
export { default as ScrollDownButton } from "./components/select-scroll-down-button.svelte";
|
|
12
|
-
export type { SelectRootProps as RootProps, SelectContentProps as ContentProps, SelectContentStaticProps as ContentStaticProps, SelectItemProps as ItemProps, SelectGroupProps as GroupProps, SelectGroupHeadingProps as GroupHeadingProps, SelectTriggerProps as TriggerProps, SelectViewportProps as ViewportProps, SelectScrollUpButtonProps as ScrollUpButtonProps, SelectScrollDownButtonProps as ScrollDownButtonProps, SelectPortalProps as PortalProps, } from "./types.js";
|
|
13
|
+
export type { SelectRootProps as RootProps, SelectValueProps as ValueProps, SelectContentProps as ContentProps, SelectContentStaticProps as ContentStaticProps, SelectItemProps as ItemProps, SelectGroupProps as GroupProps, SelectGroupHeadingProps as GroupHeadingProps, SelectTriggerProps as TriggerProps, SelectViewportProps as ViewportProps, SelectScrollUpButtonProps as ScrollUpButtonProps, SelectScrollDownButtonProps as ScrollDownButtonProps, SelectPortalProps as PortalProps, } from "./types.js";
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export { default as Root } from "./components/select.svelte";
|
|
2
|
+
export { default as Value } from "./components/select-value.svelte";
|
|
2
3
|
export { default as Content } from "./components/select-content.svelte";
|
|
3
4
|
export { default as ContentStatic } from "./components/select-content-static.svelte";
|
|
4
5
|
export { default as Item } from "./components/select-item.svelte";
|
|
@@ -2,6 +2,7 @@ import { Previous } from "runed";
|
|
|
2
2
|
import { DOMContext, type ReadableBoxedValues, type WritableBoxedValues, type Box } from "svelte-toolbelt";
|
|
3
3
|
import type { BitsEvent, BitsFocusEvent, BitsKeyboardEvent, BitsMouseEvent, BitsPointerEvent, OnChangeFn, WithRefOpts, RefAttachment } from "../../internal/types.js";
|
|
4
4
|
import { PresenceManager } from "../../internal/presence-manager.svelte.js";
|
|
5
|
+
import type { SelectValueSnippetProps } from "./types.js";
|
|
5
6
|
export declare const INTERACTION_KEYS: string[];
|
|
6
7
|
export declare const FIRST_KEYS: string[];
|
|
7
8
|
export declare const LAST_KEYS: string[];
|
|
@@ -36,6 +37,7 @@ declare abstract class SelectBaseRootState {
|
|
|
36
37
|
contentPresence: PresenceManager;
|
|
37
38
|
viewportNode: HTMLElement | null;
|
|
38
39
|
triggerNode: HTMLElement | null;
|
|
40
|
+
valueNode: HTMLElement | null;
|
|
39
41
|
valueId: string;
|
|
40
42
|
highlightedNode: HTMLElement | null;
|
|
41
43
|
readonly highlightedValue: string | null;
|
|
@@ -51,6 +53,11 @@ declare abstract class SelectBaseRootState {
|
|
|
51
53
|
getCandidateNodes(): HTMLElement[];
|
|
52
54
|
setHighlightedToFirstCandidate(initial?: boolean): void;
|
|
53
55
|
getNodeByValue(value: string): HTMLElement | null;
|
|
56
|
+
/**
|
|
57
|
+
* Resolves the display label for a value: `items` entry when present, otherwise the
|
|
58
|
+
* mounted item's `data-label` or its text content.
|
|
59
|
+
*/
|
|
60
|
+
getLabelForValue(value: string): string;
|
|
54
61
|
setOpen(open: boolean): void;
|
|
55
62
|
toggleOpen(): void;
|
|
56
63
|
handleOpen(): void;
|
|
@@ -112,6 +119,23 @@ export declare class SelectRootState {
|
|
|
112
119
|
static create(props: SelectRootStateOpts): SelectRoot;
|
|
113
120
|
}
|
|
114
121
|
type SelectRoot = SelectSingleRootState | SelectMultipleRootState;
|
|
122
|
+
type SelectValueStateProps = WithRefOpts<ReadableBoxedValues<{
|
|
123
|
+
placeholder: string | null | undefined;
|
|
124
|
+
}>>;
|
|
125
|
+
export declare class SelectValueState {
|
|
126
|
+
static create(opts: SelectValueStateProps): SelectValueState;
|
|
127
|
+
readonly root: SelectRoot;
|
|
128
|
+
readonly opts: SelectValueStateProps;
|
|
129
|
+
readonly attachment: RefAttachment;
|
|
130
|
+
constructor(opts: SelectValueStateProps, root: SelectRoot);
|
|
131
|
+
setValue(value: string | string[]): void;
|
|
132
|
+
readonly snippetProps: SelectValueSnippetProps;
|
|
133
|
+
readonly props: {
|
|
134
|
+
id: string;
|
|
135
|
+
"data-placeholder": string | undefined;
|
|
136
|
+
"data-select-value": string;
|
|
137
|
+
};
|
|
138
|
+
}
|
|
115
139
|
interface SelectInputStateOpts extends WithRefOpts, ReadableBoxedValues<{
|
|
116
140
|
clearOnDeselect: boolean;
|
|
117
141
|
}> {
|
|
@@ -11,6 +11,7 @@ import { getFloatingContentCSSVars } from "../../internal/floating-svelte/floati
|
|
|
11
11
|
import { DataTypeahead } from "../../internal/data-typeahead.svelte.js";
|
|
12
12
|
import { DOMTypeahead } from "../../internal/dom-typeahead.svelte.js";
|
|
13
13
|
import { PresenceManager } from "../../internal/presence-manager.svelte.js";
|
|
14
|
+
import { DEV } from "esm-env";
|
|
14
15
|
// prettier-ignore
|
|
15
16
|
export const INTERACTION_KEYS = [kbd.ARROW_LEFT, kbd.ESCAPE, kbd.ARROW_RIGHT, kbd.SHIFT, kbd.CAPS_LOCK, kbd.CONTROL, kbd.ALT, kbd.META, kbd.ENTER, kbd.F1, kbd.F2, kbd.F3, kbd.F4, kbd.F5, kbd.F6, kbd.F7, kbd.F8, kbd.F9, kbd.F10, kbd.F11, kbd.F12];
|
|
16
17
|
export const FIRST_KEYS = [kbd.ARROW_DOWN, kbd.PAGE_UP, kbd.HOME];
|
|
@@ -48,6 +49,7 @@ class SelectBaseRootState {
|
|
|
48
49
|
contentPresence;
|
|
49
50
|
viewportNode = $state(null);
|
|
50
51
|
triggerNode = $state(null);
|
|
52
|
+
valueNode = $state(null);
|
|
51
53
|
valueId = $state("");
|
|
52
54
|
highlightedNode = $state(null);
|
|
53
55
|
highlightedValue = $derived.by(() => {
|
|
@@ -127,6 +129,25 @@ class SelectBaseRootState {
|
|
|
127
129
|
const candidateNodes = this.getCandidateNodes();
|
|
128
130
|
return candidateNodes.find((node) => node.dataset.value === value) ?? null;
|
|
129
131
|
}
|
|
132
|
+
/**
|
|
133
|
+
* Resolves the display label for a value: `items` entry when present, otherwise the
|
|
134
|
+
* mounted item's `data-label` or its text content.
|
|
135
|
+
*/
|
|
136
|
+
getLabelForValue(value) {
|
|
137
|
+
if (value === "")
|
|
138
|
+
return "";
|
|
139
|
+
const fromItems = this.opts.items.current.find((item) => item.value === value)?.label;
|
|
140
|
+
if (fromItems !== undefined)
|
|
141
|
+
return fromItems;
|
|
142
|
+
const node = this.getNodeByValue(value);
|
|
143
|
+
if (node) {
|
|
144
|
+
const dataLabel = node.getAttribute("data-label");
|
|
145
|
+
if (dataLabel !== null && dataLabel !== "")
|
|
146
|
+
return dataLabel;
|
|
147
|
+
return node.textContent?.trim() ?? value;
|
|
148
|
+
}
|
|
149
|
+
return value;
|
|
150
|
+
}
|
|
130
151
|
setOpen(open) {
|
|
131
152
|
this.opts.open.current = open;
|
|
132
153
|
}
|
|
@@ -269,6 +290,70 @@ export class SelectRootState {
|
|
|
269
290
|
return SelectRootContext.set(rootState);
|
|
270
291
|
}
|
|
271
292
|
}
|
|
293
|
+
export class SelectValueState {
|
|
294
|
+
static create(opts) {
|
|
295
|
+
return new SelectValueState(opts, SelectRootContext.get());
|
|
296
|
+
}
|
|
297
|
+
root;
|
|
298
|
+
opts;
|
|
299
|
+
attachment;
|
|
300
|
+
constructor(opts, root) {
|
|
301
|
+
this.root = root;
|
|
302
|
+
this.opts = opts;
|
|
303
|
+
this.attachment = attachRef(opts.ref, (v) => (this.root.valueNode = v));
|
|
304
|
+
this.setValue = this.setValue.bind(this);
|
|
305
|
+
}
|
|
306
|
+
setValue(value) {
|
|
307
|
+
if (this.root.isMulti && !Array.isArray(value)) {
|
|
308
|
+
if (DEV)
|
|
309
|
+
throw new Error(`Expected an array of strings passed to \`setValue\` got ${typeof value}.`);
|
|
310
|
+
return;
|
|
311
|
+
}
|
|
312
|
+
if (!this.root.isMulti && typeof value !== "string") {
|
|
313
|
+
if (DEV)
|
|
314
|
+
throw new Error(`Expected a string passed to \`setValue\` got ${typeof value}.`);
|
|
315
|
+
return;
|
|
316
|
+
}
|
|
317
|
+
this.root.opts.value.current = value;
|
|
318
|
+
}
|
|
319
|
+
// this way consumers get type narrowing for the value on `type`
|
|
320
|
+
snippetProps = $derived.by(() => {
|
|
321
|
+
if (this.root.isMulti) {
|
|
322
|
+
return {
|
|
323
|
+
selection: {
|
|
324
|
+
type: "multiple",
|
|
325
|
+
selected: this.root.opts.value.current.length > 0
|
|
326
|
+
? this.root.opts.value.current.map((value) => ({
|
|
327
|
+
value,
|
|
328
|
+
label: this.root.getLabelForValue(value),
|
|
329
|
+
}))
|
|
330
|
+
: [],
|
|
331
|
+
setValue: this.setValue,
|
|
332
|
+
},
|
|
333
|
+
placeholder: this.opts.placeholder.current ?? null,
|
|
334
|
+
disabled: this.root.opts.disabled.current,
|
|
335
|
+
};
|
|
336
|
+
}
|
|
337
|
+
const value = this.root.opts.value.current;
|
|
338
|
+
return {
|
|
339
|
+
selection: {
|
|
340
|
+
type: "single",
|
|
341
|
+
selected: value !== ""
|
|
342
|
+
? { value, label: value === "" ? "" : this.root.getLabelForValue(value) }
|
|
343
|
+
: undefined,
|
|
344
|
+
setValue: this.setValue,
|
|
345
|
+
},
|
|
346
|
+
placeholder: this.opts.placeholder.current ?? null,
|
|
347
|
+
disabled: this.root.opts.disabled.current,
|
|
348
|
+
};
|
|
349
|
+
});
|
|
350
|
+
props = $derived.by(() => ({
|
|
351
|
+
id: this.opts.id.current,
|
|
352
|
+
"data-placeholder": this.root.hasValue ? undefined : "",
|
|
353
|
+
"data-select-value": "",
|
|
354
|
+
...this.attachment,
|
|
355
|
+
}));
|
|
356
|
+
}
|
|
272
357
|
export class SelectInputState {
|
|
273
358
|
static create(opts) {
|
|
274
359
|
return new SelectInputState(opts, SelectRootContext.get());
|
|
@@ -2,7 +2,7 @@ import type { Expand } from "svelte-toolbelt";
|
|
|
2
2
|
import type { PortalProps } from "../utilities/portal/types.js";
|
|
3
3
|
import type { PopperLayerProps, PopperLayerStaticProps } from "../utilities/popper-layer/types.js";
|
|
4
4
|
import type { ArrowProps, ArrowPropsWithoutHTML } from "../utilities/arrow/types.js";
|
|
5
|
-
import type { BitsPrimitiveButtonAttributes, BitsPrimitiveDivAttributes } from "../../shared/attributes.js";
|
|
5
|
+
import type { BitsPrimitiveButtonAttributes, BitsPrimitiveDivAttributes, BitsPrimitiveSpanAttributes } from "../../shared/attributes.js";
|
|
6
6
|
import type { OnChangeFn, WithChild, WithChildNoChildrenSnippetProps, WithChildren, Without } from "../../internal/types.js";
|
|
7
7
|
import type { FloatingContentSnippetProps, StaticContentSnippetProps } from "../../shared/types.js";
|
|
8
8
|
import type { HTMLInputAttributes } from "svelte/elements";
|
|
@@ -124,6 +124,27 @@ export type SelectSingleRootProps = SelectBaseRootPropsWithoutHTML & SelectSingl
|
|
|
124
124
|
export type SelectMultipleRootProps = SelectBaseRootPropsWithoutHTML & SelectMultipleRootPropsWithoutHTML & Without<BitsPrimitiveDivAttributes, SelectMultipleRootPropsWithoutHTML | SelectBaseRootPropsWithoutHTML>;
|
|
125
125
|
export type SelectRootPropsWithoutHTML = SelectBaseRootPropsWithoutHTML & (SelectSingleRootPropsWithoutHTML | SelectMultipleRootPropsWithoutHTML);
|
|
126
126
|
export type SelectRootProps = SelectRootPropsWithoutHTML;
|
|
127
|
+
export type SelectValueSnippetProps = {
|
|
128
|
+
selection: {
|
|
129
|
+
type: "single";
|
|
130
|
+
selected?: {
|
|
131
|
+
value: string;
|
|
132
|
+
label: string;
|
|
133
|
+
};
|
|
134
|
+
setValue: (value: string) => void;
|
|
135
|
+
} | {
|
|
136
|
+
type: "multiple";
|
|
137
|
+
selected: {
|
|
138
|
+
value: string;
|
|
139
|
+
label: string;
|
|
140
|
+
}[];
|
|
141
|
+
setValue: (value: string[]) => void;
|
|
142
|
+
};
|
|
143
|
+
placeholder: string | null;
|
|
144
|
+
disabled: boolean;
|
|
145
|
+
};
|
|
146
|
+
export type SelectValuePropsWithoutHTML = WithChild<{}, SelectValueSnippetProps>;
|
|
147
|
+
export type SelectValueProps = SelectValuePropsWithoutHTML & Without<BitsPrimitiveSpanAttributes, SelectValuePropsWithoutHTML>;
|
|
127
148
|
export type _SharedSelectContentProps = {
|
|
128
149
|
/**
|
|
129
150
|
* Whether or not to loop through the items when navigating with the keyboard.
|
|
@@ -194,8 +194,9 @@ function isValidEvent(e, node) {
|
|
|
194
194
|
const nodeIsContextMenu = Boolean(node.closest(`[${CONTEXT_MENU_CONTENT_ATTR}]`));
|
|
195
195
|
if ("button" in e && e.button > 0 && !targetIsContextMenuTrigger)
|
|
196
196
|
return false;
|
|
197
|
-
if ("button" in e && e.button === 0 && targetIsContextMenuTrigger)
|
|
198
|
-
return
|
|
197
|
+
if ("button" in e && e.button === 0 && targetIsContextMenuTrigger && nodeIsContextMenu) {
|
|
198
|
+
return true;
|
|
199
|
+
}
|
|
199
200
|
if (targetIsContextMenuTrigger && nodeIsContextMenu)
|
|
200
201
|
return false;
|
|
201
202
|
const ownerDocument = getOwnerDocument(target);
|
|
@@ -54,9 +54,7 @@
|
|
|
54
54
|
} = $props();
|
|
55
55
|
|
|
56
56
|
const resolvedPreventScroll = $derived(preventScroll ?? true);
|
|
57
|
-
const effectiveStrategy = $derived(
|
|
58
|
-
strategy ?? (resolvedPreventScroll ? "fixed" : "absolute")
|
|
59
|
-
);
|
|
57
|
+
const effectiveStrategy = $derived(strategy ?? (resolvedPreventScroll ? "fixed" : "absolute"));
|
|
60
58
|
</script>
|
|
61
59
|
|
|
62
60
|
<PopperContent
|
|
@@ -12,9 +12,8 @@
|
|
|
12
12
|
</script>
|
|
13
13
|
|
|
14
14
|
{#if forceMount || open || presenceState.isPresent}
|
|
15
|
-
{@render
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
})}
|
|
15
|
+
{@render presence?.({
|
|
16
|
+
present: presenceState.isPresent,
|
|
17
|
+
transitionStatus: presenceState.transitionStatus,
|
|
18
|
+
})}
|
|
20
19
|
{/if}
|