@ariakit/core 0.0.1 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintignore +6 -0
- package/CHANGELOG.md +24 -0
- package/checkbox/checkbox-store/package.json +7 -0
- package/cjs/__chunks/2YFRPUZP.cjs +30 -0
- package/cjs/__chunks/3BBA3Z5G.cjs +143 -0
- package/cjs/__chunks/3KP2MDG6.cjs +1491 -0
- package/cjs/__chunks/5D5Y5EI4.cjs +146 -0
- package/cjs/__chunks/7ZXWQTAY.cjs +71 -0
- package/cjs/__chunks/AZVDLKO3.cjs +286 -0
- package/cjs/__chunks/EFEGT32M.cjs +12 -0
- package/cjs/__chunks/EIDN2CWH.cjs +57 -0
- package/cjs/__chunks/GDZQUFNP.cjs +30 -0
- package/cjs/__chunks/NX5OHIMM.cjs +169 -0
- package/cjs/__chunks/OFNGELMA.cjs +182 -0
- package/cjs/checkbox/checkbox-store.cjs +27 -0
- package/cjs/checkbox/checkbox-store.d.ts +34 -0
- package/cjs/collection/collection-store.cjs +9 -0
- package/cjs/collection/collection-store.d.ts +65 -0
- package/cjs/combobox/combobox-store.cjs +163 -0
- package/cjs/combobox/combobox-store.d.ts +67 -0
- package/cjs/composite/composite-overflow-store.cjs +15 -0
- package/cjs/composite/composite-overflow-store.d.ts +10 -0
- package/cjs/composite/composite-store.cjs +11 -0
- package/cjs/composite/composite-store.d.ts +202 -0
- package/cjs/dialog/dialog-store.cjs +9 -0
- package/cjs/dialog/dialog-store.d.ts +10 -0
- package/cjs/disclosure/disclosure-store.cjs +8 -0
- package/cjs/disclosure/disclosure-store.d.ts +87 -0
- package/cjs/form/form-store.cjs +241 -0
- package/cjs/form/form-store.d.ts +236 -0
- package/cjs/form/types.cjs +1 -0
- package/cjs/form/types.d.ts +38 -0
- package/cjs/hovercard/hovercard-store.cjs +11 -0
- package/cjs/hovercard/hovercard-store.d.ts +45 -0
- package/cjs/index.cjs +5 -0
- package/cjs/index.d.ts +2 -0
- package/cjs/menu/menu-bar-store.cjs +27 -0
- package/cjs/menu/menu-bar-store.d.ts +10 -0
- package/cjs/menu/menu-store.cjs +108 -0
- package/cjs/menu/menu-store.d.ts +70 -0
- package/cjs/popover/popover-store.cjs +10 -0
- package/cjs/popover/popover-store.d.ts +150 -0
- package/cjs/radio/radio-store.cjs +41 -0
- package/cjs/radio/radio-store.d.ts +36 -0
- package/cjs/select/select-store.cjs +164 -0
- package/cjs/select/select-store.d.ts +87 -0
- package/cjs/tab/tab-store.cjs +126 -0
- package/cjs/tab/tab-store.d.ts +78 -0
- package/cjs/toolbar/toolbar-store.cjs +27 -0
- package/cjs/toolbar/toolbar-store.d.ts +21 -0
- package/cjs/tooltip/tooltip-store.cjs +98 -0
- package/cjs/tooltip/tooltip-store.d.ts +28 -0
- package/cjs/tsconfig.build.tsbuildinfo +1 -0
- package/cjs/utils/array.cjs +12 -0
- package/cjs/utils/array.d.ts +29 -0
- package/cjs/utils/dom.cjs +38 -0
- package/cjs/utils/dom.d.ts +105 -0
- package/cjs/utils/events.cjs +132 -0
- package/cjs/utils/events.d.ts +73 -0
- package/cjs/utils/focus.cjs +222 -0
- package/cjs/utils/focus.d.ts +117 -0
- package/cjs/utils/misc.cjs +40 -0
- package/cjs/utils/misc.d.ts +111 -0
- package/cjs/utils/platform.cjs +15 -0
- package/cjs/utils/platform.d.ts +20 -0
- package/cjs/utils/store.cjs +9 -0
- package/cjs/utils/store.d.ts +99 -0
- package/cjs/utils/types.cjs +1 -0
- package/cjs/utils/types.d.ts +72 -0
- package/collection/collection-store/package.json +7 -0
- package/combobox/combobox-store/package.json +7 -0
- package/composite/composite-overflow-store/package.json +7 -0
- package/composite/composite-store/package.json +7 -0
- package/dialog/dialog-store/package.json +7 -0
- package/disclosure/disclosure-store/package.json +7 -0
- package/esm/__chunks/5XEKIOCW.js +30 -0
- package/esm/__chunks/6U25WEDX.js +286 -0
- package/esm/__chunks/6UPCMUXT.js +1491 -0
- package/esm/__chunks/ADRUFBEO.js +12 -0
- package/esm/__chunks/DXA3K2FY.js +30 -0
- package/esm/__chunks/HCKYJLMC.js +71 -0
- package/esm/__chunks/KLKI3AIB.js +146 -0
- package/esm/__chunks/L7KN5AYP.js +169 -0
- package/esm/__chunks/RX3ZUQ6U.js +57 -0
- package/esm/__chunks/UOJSZ35L.js +143 -0
- package/esm/__chunks/UVCATTRC.js +182 -0
- package/esm/checkbox/checkbox-store.d.ts +34 -0
- package/esm/checkbox/checkbox-store.js +27 -0
- package/esm/collection/collection-store.d.ts +65 -0
- package/esm/collection/collection-store.js +9 -0
- package/esm/combobox/combobox-store.d.ts +67 -0
- package/esm/combobox/combobox-store.js +163 -0
- package/esm/composite/composite-overflow-store.d.ts +10 -0
- package/esm/composite/composite-overflow-store.js +15 -0
- package/esm/composite/composite-store.d.ts +202 -0
- package/esm/composite/composite-store.js +11 -0
- package/esm/dialog/dialog-store.d.ts +10 -0
- package/esm/dialog/dialog-store.js +9 -0
- package/esm/disclosure/disclosure-store.d.ts +87 -0
- package/esm/disclosure/disclosure-store.js +8 -0
- package/esm/form/form-store.d.ts +236 -0
- package/esm/form/form-store.js +241 -0
- package/esm/form/types.d.ts +38 -0
- package/esm/form/types.js +0 -0
- package/esm/hovercard/hovercard-store.d.ts +45 -0
- package/esm/hovercard/hovercard-store.js +11 -0
- package/esm/index.d.ts +2 -0
- package/esm/index.js +5 -0
- package/esm/menu/menu-bar-store.d.ts +10 -0
- package/esm/menu/menu-bar-store.js +27 -0
- package/esm/menu/menu-store.d.ts +70 -0
- package/esm/menu/menu-store.js +108 -0
- package/esm/popover/popover-store.d.ts +150 -0
- package/esm/popover/popover-store.js +10 -0
- package/esm/radio/radio-store.d.ts +36 -0
- package/esm/radio/radio-store.js +41 -0
- package/esm/select/select-store.d.ts +87 -0
- package/esm/select/select-store.js +164 -0
- package/esm/tab/tab-store.d.ts +78 -0
- package/esm/tab/tab-store.js +126 -0
- package/esm/toolbar/toolbar-store.d.ts +21 -0
- package/esm/toolbar/toolbar-store.js +27 -0
- package/esm/tooltip/tooltip-store.d.ts +28 -0
- package/esm/tooltip/tooltip-store.js +98 -0
- package/esm/tsconfig.build.tsbuildinfo +1 -0
- package/esm/utils/array.d.ts +29 -0
- package/esm/utils/array.js +12 -0
- package/esm/utils/dom.d.ts +105 -0
- package/esm/utils/dom.js +38 -0
- package/esm/utils/events.d.ts +73 -0
- package/esm/utils/events.js +132 -0
- package/esm/utils/focus.d.ts +117 -0
- package/esm/utils/focus.js +222 -0
- package/esm/utils/misc.d.ts +111 -0
- package/esm/utils/misc.js +40 -0
- package/esm/utils/platform.d.ts +20 -0
- package/esm/utils/platform.js +15 -0
- package/esm/utils/store.d.ts +99 -0
- package/esm/utils/store.js +9 -0
- package/esm/utils/types.d.ts +72 -0
- package/esm/utils/types.js +0 -0
- package/form/form-store/package.json +7 -0
- package/form/types/package.json +7 -0
- package/hovercard/hovercard-store/package.json +7 -0
- package/license +21 -0
- package/menu/menu-bar-store/package.json +7 -0
- package/menu/menu-store/package.json +7 -0
- package/package.json +137 -6
- package/popover/popover-store/package.json +7 -0
- package/radio/radio-store/package.json +7 -0
- package/select/select-store/package.json +7 -0
- package/tab/tab-store/package.json +7 -0
- package/toolbar/toolbar-store/package.json +7 -0
- package/tooltip/tooltip-store/package.json +7 -0
- package/tsconfig.build.json +4 -0
- package/utils/array/package.json +7 -0
- package/utils/dom/package.json +7 -0
- package/utils/events/package.json +7 -0
- package/utils/focus/package.json +7 -0
- package/utils/misc/package.json +7 -0
- package/utils/platform/package.json +7 -0
- package/utils/store/package.json +7 -0
- package/utils/types/package.json +7 -0
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
// src/utils/dom.ts
|
|
2
|
+
var canUseDOM = checkIsBrowser();
|
|
3
|
+
function checkIsBrowser() {
|
|
4
|
+
return typeof window !== "undefined" && !!window.document?.createElement;
|
|
5
|
+
}
|
|
6
|
+
function getDocument(node) {
|
|
7
|
+
return node ? node.ownerDocument || node : document;
|
|
8
|
+
}
|
|
9
|
+
function getWindow(node) {
|
|
10
|
+
return getDocument(node).defaultView || window;
|
|
11
|
+
}
|
|
12
|
+
function getActiveElement(node, activeDescendant = false) {
|
|
13
|
+
const { activeElement } = getDocument(node);
|
|
14
|
+
if (!activeElement?.nodeName) {
|
|
15
|
+
return null;
|
|
16
|
+
}
|
|
17
|
+
if (isFrame(activeElement) && activeElement.contentDocument) {
|
|
18
|
+
return getActiveElement(
|
|
19
|
+
activeElement.contentDocument.body,
|
|
20
|
+
activeDescendant
|
|
21
|
+
);
|
|
22
|
+
}
|
|
23
|
+
if (activeDescendant) {
|
|
24
|
+
const id = activeElement.getAttribute("aria-activedescendant");
|
|
25
|
+
if (id) {
|
|
26
|
+
const element = getDocument(activeElement).getElementById(id);
|
|
27
|
+
if (element) {
|
|
28
|
+
return element;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
return activeElement;
|
|
33
|
+
}
|
|
34
|
+
function contains(parent, child) {
|
|
35
|
+
return parent === child || parent.contains(child);
|
|
36
|
+
}
|
|
37
|
+
function isFrame(element) {
|
|
38
|
+
return element.tagName === "IFRAME";
|
|
39
|
+
}
|
|
40
|
+
function isButton(element) {
|
|
41
|
+
const tagName = element.tagName.toLowerCase();
|
|
42
|
+
if (tagName === "button")
|
|
43
|
+
return true;
|
|
44
|
+
if (tagName === "input" && element.type) {
|
|
45
|
+
return buttonInputTypes.indexOf(element.type) !== -1;
|
|
46
|
+
}
|
|
47
|
+
return false;
|
|
48
|
+
}
|
|
49
|
+
var buttonInputTypes = [
|
|
50
|
+
"button",
|
|
51
|
+
"color",
|
|
52
|
+
"file",
|
|
53
|
+
"image",
|
|
54
|
+
"reset",
|
|
55
|
+
"submit"
|
|
56
|
+
];
|
|
57
|
+
function matches(element, selectors) {
|
|
58
|
+
if ("matches" in element) {
|
|
59
|
+
return element.matches(selectors);
|
|
60
|
+
}
|
|
61
|
+
if ("msMatchesSelector" in element) {
|
|
62
|
+
return element.msMatchesSelector(selectors);
|
|
63
|
+
}
|
|
64
|
+
return element.webkitMatchesSelector(selectors);
|
|
65
|
+
}
|
|
66
|
+
function isVisible(element) {
|
|
67
|
+
const htmlElement = element;
|
|
68
|
+
return htmlElement.offsetWidth > 0 || htmlElement.offsetHeight > 0 || element.getClientRects().length > 0;
|
|
69
|
+
}
|
|
70
|
+
function closest(element, selectors) {
|
|
71
|
+
if ("closest" in element)
|
|
72
|
+
return element.closest(selectors);
|
|
73
|
+
do {
|
|
74
|
+
if (matches(element, selectors))
|
|
75
|
+
return element;
|
|
76
|
+
element = element.parentElement || element.parentNode;
|
|
77
|
+
} while (element !== null && element.nodeType === 1);
|
|
78
|
+
return null;
|
|
79
|
+
}
|
|
80
|
+
function isTextField(element) {
|
|
81
|
+
try {
|
|
82
|
+
const isTextInput = element instanceof HTMLInputElement && element.selectionStart !== null;
|
|
83
|
+
const isTextArea = element.tagName === "TEXTAREA";
|
|
84
|
+
return isTextInput || isTextArea || false;
|
|
85
|
+
} catch (error) {
|
|
86
|
+
return false;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
function getPopupRole(element, fallback) {
|
|
90
|
+
const allowedPopupRoles = ["dialog", "menu", "listbox", "tree", "grid"];
|
|
91
|
+
const role = element?.getAttribute("role");
|
|
92
|
+
if (role && allowedPopupRoles.indexOf(role) !== -1) {
|
|
93
|
+
return role;
|
|
94
|
+
}
|
|
95
|
+
return fallback;
|
|
96
|
+
}
|
|
97
|
+
function getPopupItemRole(element, fallback) {
|
|
98
|
+
const itemRoleByPopupRole = {
|
|
99
|
+
menu: "menuitem",
|
|
100
|
+
listbox: "option",
|
|
101
|
+
tree: "treeitem",
|
|
102
|
+
grid: "gridcell"
|
|
103
|
+
};
|
|
104
|
+
const popupRole = getPopupRole(element);
|
|
105
|
+
if (!popupRole)
|
|
106
|
+
return fallback;
|
|
107
|
+
const key = popupRole;
|
|
108
|
+
return itemRoleByPopupRole[key] ?? fallback;
|
|
109
|
+
}
|
|
110
|
+
function getTextboxSelection(element) {
|
|
111
|
+
let start = 0;
|
|
112
|
+
let end = 0;
|
|
113
|
+
if (isTextField(element)) {
|
|
114
|
+
start = element.selectionStart || 0;
|
|
115
|
+
end = element.selectionEnd || 0;
|
|
116
|
+
} else if (element.isContentEditable) {
|
|
117
|
+
const selection = getDocument(element).getSelection();
|
|
118
|
+
if (selection?.rangeCount && selection.anchorNode && contains(element, selection.anchorNode) && selection.focusNode && contains(element, selection.focusNode)) {
|
|
119
|
+
const range = selection.getRangeAt(0);
|
|
120
|
+
const nextRange = range.cloneRange();
|
|
121
|
+
nextRange.selectNodeContents(element);
|
|
122
|
+
nextRange.setEnd(range.startContainer, range.startOffset);
|
|
123
|
+
start = nextRange.toString().length;
|
|
124
|
+
nextRange.setEnd(range.endContainer, range.endOffset);
|
|
125
|
+
end = nextRange.toString().length;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
return { start, end };
|
|
129
|
+
}
|
|
130
|
+
function scrollIntoViewIfNeeded(element, arg) {
|
|
131
|
+
if (isPartiallyHidden(element) && "scrollIntoView" in element) {
|
|
132
|
+
element.scrollIntoView(arg);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
function getScrollingElement(element) {
|
|
136
|
+
if (!element)
|
|
137
|
+
return null;
|
|
138
|
+
if (element.clientHeight && element.scrollHeight > element.clientHeight) {
|
|
139
|
+
const { overflowY } = getComputedStyle(element);
|
|
140
|
+
const isScrollable = overflowY !== "visible" && overflowY !== "hidden";
|
|
141
|
+
if (isScrollable)
|
|
142
|
+
return element;
|
|
143
|
+
}
|
|
144
|
+
return getScrollingElement(element.parentElement) || document.scrollingElement || document.body;
|
|
145
|
+
}
|
|
146
|
+
function isPartiallyHidden(element) {
|
|
147
|
+
const elementRect = element.getBoundingClientRect();
|
|
148
|
+
const scroller = getScrollingElement(element);
|
|
149
|
+
if (!scroller)
|
|
150
|
+
return false;
|
|
151
|
+
const scrollerRect = scroller.getBoundingClientRect();
|
|
152
|
+
const isHTML = scroller.tagName === "HTML";
|
|
153
|
+
const scrollerTop = isHTML ? scrollerRect.top + scroller.scrollTop : scrollerRect.top;
|
|
154
|
+
const scrollerBottom = isHTML ? scroller.clientHeight : scrollerRect.bottom;
|
|
155
|
+
const scrollerLeft = isHTML ? scrollerRect.left + scroller.scrollLeft : scrollerRect.left;
|
|
156
|
+
const scrollerRight = isHTML ? scroller.clientWidth : scrollerRect.right;
|
|
157
|
+
const top = elementRect.top < scrollerTop;
|
|
158
|
+
const left = elementRect.left < scrollerLeft;
|
|
159
|
+
const bottom = elementRect.bottom > scrollerBottom;
|
|
160
|
+
const right = elementRect.right > scrollerRight;
|
|
161
|
+
return top || left || bottom || right;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
export {
|
|
165
|
+
canUseDOM,
|
|
166
|
+
getDocument,
|
|
167
|
+
getWindow,
|
|
168
|
+
getActiveElement,
|
|
169
|
+
contains,
|
|
170
|
+
isFrame,
|
|
171
|
+
isButton,
|
|
172
|
+
matches,
|
|
173
|
+
isVisible,
|
|
174
|
+
closest,
|
|
175
|
+
isTextField,
|
|
176
|
+
getPopupRole,
|
|
177
|
+
getPopupItemRole,
|
|
178
|
+
getTextboxSelection,
|
|
179
|
+
scrollIntoViewIfNeeded,
|
|
180
|
+
getScrollingElement,
|
|
181
|
+
isPartiallyHidden
|
|
182
|
+
};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { Store, StoreOptions, StoreProps } from "../utils/store.js";
|
|
2
|
+
import type { PickRequired, SetState, ToPrimitive } from "../utils/types.js";
|
|
3
|
+
type Value = boolean | string | number | Array<string | number>;
|
|
4
|
+
/**
|
|
5
|
+
* Creates a checkbox store.
|
|
6
|
+
*/
|
|
7
|
+
export declare function createCheckboxStore<T extends Value = Value>(props: PickRequired<CheckboxStoreProps<T>, "value" | "defaultValue">): CheckboxStore<T>;
|
|
8
|
+
export declare function createCheckboxStore(props?: CheckboxStoreProps): CheckboxStore;
|
|
9
|
+
export type CheckboxStoreValue = Value;
|
|
10
|
+
export interface CheckboxStoreState<T extends Value = Value> {
|
|
11
|
+
/**
|
|
12
|
+
* The checked state of the checkbox.
|
|
13
|
+
*/
|
|
14
|
+
value: ToPrimitive<T>;
|
|
15
|
+
}
|
|
16
|
+
export interface CheckboxStoreFunctions<T extends Value = Value> {
|
|
17
|
+
/**
|
|
18
|
+
* Sets the `value` state.
|
|
19
|
+
* @example
|
|
20
|
+
* store.setValue(true);
|
|
21
|
+
* store.setValue((value) => !value);
|
|
22
|
+
*/
|
|
23
|
+
setValue: SetState<CheckboxStoreState<T>["value"]>;
|
|
24
|
+
}
|
|
25
|
+
export interface CheckboxStoreOptions<T extends Value = Value> extends StoreOptions<CheckboxStoreState<T>, "value"> {
|
|
26
|
+
/**
|
|
27
|
+
* The default value of the checkbox.
|
|
28
|
+
* @default false
|
|
29
|
+
*/
|
|
30
|
+
defaultValue?: CheckboxStoreState<T>["value"];
|
|
31
|
+
}
|
|
32
|
+
export type CheckboxStoreProps<T extends Value = Value> = CheckboxStoreOptions<T> & StoreProps<CheckboxStoreState<T>>;
|
|
33
|
+
export type CheckboxStore<T extends Value = Value> = CheckboxStoreFunctions<T> & Store<CheckboxStoreState<T>>;
|
|
34
|
+
export {};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createStore
|
|
3
|
+
} from "../__chunks/UOJSZ35L.js";
|
|
4
|
+
import {
|
|
5
|
+
defaultValue
|
|
6
|
+
} from "../__chunks/KLKI3AIB.js";
|
|
7
|
+
|
|
8
|
+
// src/checkbox/checkbox-store.ts
|
|
9
|
+
function createCheckboxStore(props = {}) {
|
|
10
|
+
const syncState = props.store?.getState();
|
|
11
|
+
const initialState = {
|
|
12
|
+
value: defaultValue(
|
|
13
|
+
props.value,
|
|
14
|
+
syncState?.value,
|
|
15
|
+
props.defaultValue,
|
|
16
|
+
false
|
|
17
|
+
)
|
|
18
|
+
};
|
|
19
|
+
const checkbox = createStore(initialState, props.store);
|
|
20
|
+
return {
|
|
21
|
+
...checkbox,
|
|
22
|
+
setValue: (value) => checkbox.setState("value", value)
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
export {
|
|
26
|
+
createCheckboxStore
|
|
27
|
+
};
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import type { Store, StoreOptions, StoreProps } from "../utils/store.js";
|
|
2
|
+
import type { BivariantCallback } from "../utils/types.js";
|
|
3
|
+
type Item = {
|
|
4
|
+
id: string;
|
|
5
|
+
element?: HTMLElement | null;
|
|
6
|
+
};
|
|
7
|
+
/**
|
|
8
|
+
* Creates a collection store.
|
|
9
|
+
*/
|
|
10
|
+
export declare function createCollectionStore<T extends Item = Item>(props?: CollectionStoreProps<T>): CollectionStore<T>;
|
|
11
|
+
export type CollectionStoreItem = Item;
|
|
12
|
+
export interface CollectionStoreState<T extends Item = Item> {
|
|
13
|
+
/**
|
|
14
|
+
* Lists all the items with their meta data. This state is automatically
|
|
15
|
+
* updated when an item is registered or unregistered with the `registerItem`
|
|
16
|
+
* function.
|
|
17
|
+
*/
|
|
18
|
+
items: T[];
|
|
19
|
+
/**
|
|
20
|
+
* Lists all the items that are currently rendered. This state is
|
|
21
|
+
* automatically updated when an item is rendered or unrendered with the
|
|
22
|
+
* `renderItem` function. This state is also automatically sorted based on
|
|
23
|
+
* their DOM position.
|
|
24
|
+
*/
|
|
25
|
+
renderedItems: T[];
|
|
26
|
+
}
|
|
27
|
+
export interface CollectionStoreFunctions<T extends Item = Item> {
|
|
28
|
+
/**
|
|
29
|
+
* Registers an item in the collection. This function returns a cleanup
|
|
30
|
+
* function that unregisters the item.
|
|
31
|
+
* @param item The item to register.
|
|
32
|
+
* @example
|
|
33
|
+
* const unregisterItem = store.registerItem({ id: "item-1" });
|
|
34
|
+
* // on cleanup
|
|
35
|
+
* unregisterItem();
|
|
36
|
+
*/
|
|
37
|
+
registerItem: BivariantCallback<(item: T) => () => void>;
|
|
38
|
+
/**
|
|
39
|
+
* Renders an item in the collection. This function returns a cleanup function
|
|
40
|
+
* that unrenders the item.
|
|
41
|
+
* @param item The item to render.
|
|
42
|
+
* @example
|
|
43
|
+
* const unrenderItem = store.renderItem({ id: "item-1" });
|
|
44
|
+
* // on cleanup
|
|
45
|
+
* unrenderItem();
|
|
46
|
+
*/
|
|
47
|
+
renderItem: BivariantCallback<(item: T) => () => void>;
|
|
48
|
+
/**
|
|
49
|
+
* Gets an item by its id.
|
|
50
|
+
* @param id The id of the item.
|
|
51
|
+
* @example
|
|
52
|
+
* const item = store.item("item-1");
|
|
53
|
+
*/
|
|
54
|
+
item: (id: string | null | undefined) => T | null;
|
|
55
|
+
}
|
|
56
|
+
export interface CollectionStoreOptions<T extends Item = Item> extends StoreOptions<CollectionStoreState<T>, "items"> {
|
|
57
|
+
/**
|
|
58
|
+
* The defaut value for the `items` state.
|
|
59
|
+
* @default []
|
|
60
|
+
*/
|
|
61
|
+
defaultItems?: CollectionStoreState<T>["items"];
|
|
62
|
+
}
|
|
63
|
+
export type CollectionStoreProps<T extends Item = Item> = CollectionStoreOptions<T> & StoreProps<CollectionStoreState<T>>;
|
|
64
|
+
export type CollectionStore<T extends Item = Item> = CollectionStoreFunctions<T> & Store<CollectionStoreState<T>>;
|
|
65
|
+
export {};
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import type { CompositeStoreFunctions, CompositeStoreItem, CompositeStoreOptions, CompositeStoreState } from "../composite/composite-store.js";
|
|
2
|
+
import type { MenuStore } from "../menu/menu-store.js";
|
|
3
|
+
import type { PopoverStoreFunctions, PopoverStoreOptions, PopoverStoreState } from "../popover/popover-store.js";
|
|
4
|
+
import type { SelectStore } from "../select/select-store.js";
|
|
5
|
+
import type { Store, StoreOptions, StoreProps } from "../utils/store.js";
|
|
6
|
+
import type { SetState } from "../utils/types.js";
|
|
7
|
+
type Item = CompositeStoreItem & {
|
|
8
|
+
value?: string;
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* Creates a combobox store.
|
|
12
|
+
*/
|
|
13
|
+
export declare function createComboboxStore({ menu, select, ...props }?: ComboboxStoreProps): ComboboxStore;
|
|
14
|
+
export type ComboboxStoreItem = Item;
|
|
15
|
+
export interface ComboboxStoreState extends CompositeStoreState<Item>, PopoverStoreState {
|
|
16
|
+
/**
|
|
17
|
+
* @default true
|
|
18
|
+
*/
|
|
19
|
+
includesBaseElement: boolean;
|
|
20
|
+
/**
|
|
21
|
+
* The input value.
|
|
22
|
+
*/
|
|
23
|
+
value: string;
|
|
24
|
+
/**
|
|
25
|
+
* The value of the current active item.
|
|
26
|
+
*/
|
|
27
|
+
activeValue: string | undefined;
|
|
28
|
+
/**
|
|
29
|
+
* Whether to reset the value when the combobox popover is hidden.
|
|
30
|
+
*/
|
|
31
|
+
resetValueOnHide: boolean;
|
|
32
|
+
}
|
|
33
|
+
export interface ComboboxStoreFunctions extends CompositeStoreFunctions<Item>, PopoverStoreFunctions {
|
|
34
|
+
/**
|
|
35
|
+
* Sets the `value` state.
|
|
36
|
+
* @example
|
|
37
|
+
* store.setValue("Hello world");
|
|
38
|
+
* store.setValue((value) => value + "!");
|
|
39
|
+
*/
|
|
40
|
+
setValue: SetState<ComboboxStoreState["value"]>;
|
|
41
|
+
}
|
|
42
|
+
export interface ComboboxStoreOptions extends StoreOptions<ComboboxStoreState, "includesBaseElement" | "value" | "resetValueOnHide">, CompositeStoreOptions<Item>, PopoverStoreOptions {
|
|
43
|
+
/**
|
|
44
|
+
* @default null
|
|
45
|
+
*/
|
|
46
|
+
defaultActiveId?: CompositeStoreOptions<Item>["activeId"];
|
|
47
|
+
/**
|
|
48
|
+
* A reference to a menu store. This is used when combining the combobox with
|
|
49
|
+
* a menu (e.g., dropdown menu with a search input). The stores will share the
|
|
50
|
+
* same state.
|
|
51
|
+
*/
|
|
52
|
+
menu?: MenuStore;
|
|
53
|
+
/**
|
|
54
|
+
* A reference to a select store. This is used when combining the combobox
|
|
55
|
+
* with a select (e.g., select with a search input). The stores will share the
|
|
56
|
+
* same state.
|
|
57
|
+
*/
|
|
58
|
+
select?: SelectStore;
|
|
59
|
+
/**
|
|
60
|
+
* The combobox initial value.
|
|
61
|
+
* @default ""
|
|
62
|
+
*/
|
|
63
|
+
defaultValue?: ComboboxStoreState["value"];
|
|
64
|
+
}
|
|
65
|
+
export type ComboboxStoreProps = ComboboxStoreOptions & StoreProps<ComboboxStoreState>;
|
|
66
|
+
export type ComboboxStore = ComboboxStoreFunctions & Store<ComboboxStoreState>;
|
|
67
|
+
export {};
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createPopoverStore
|
|
3
|
+
} from "../__chunks/6UPCMUXT.js";
|
|
4
|
+
import "../__chunks/ADRUFBEO.js";
|
|
5
|
+
import "../__chunks/HCKYJLMC.js";
|
|
6
|
+
import {
|
|
7
|
+
createCompositeStore
|
|
8
|
+
} from "../__chunks/6U25WEDX.js";
|
|
9
|
+
import "../__chunks/L7KN5AYP.js";
|
|
10
|
+
import {
|
|
11
|
+
createStore,
|
|
12
|
+
mergeStore
|
|
13
|
+
} from "../__chunks/UOJSZ35L.js";
|
|
14
|
+
import {
|
|
15
|
+
defaultValue
|
|
16
|
+
} from "../__chunks/KLKI3AIB.js";
|
|
17
|
+
import {
|
|
18
|
+
isSafari,
|
|
19
|
+
isTouchDevice
|
|
20
|
+
} from "../__chunks/DXA3K2FY.js";
|
|
21
|
+
import "../__chunks/UVCATTRC.js";
|
|
22
|
+
import "../__chunks/5XEKIOCW.js";
|
|
23
|
+
|
|
24
|
+
// src/combobox/combobox-store.ts
|
|
25
|
+
var isSafariOnMobile = isSafari() && isTouchDevice();
|
|
26
|
+
function createComboboxStore({
|
|
27
|
+
menu,
|
|
28
|
+
select,
|
|
29
|
+
...props
|
|
30
|
+
} = {}) {
|
|
31
|
+
const store = mergeStore(
|
|
32
|
+
props.store,
|
|
33
|
+
menu?.omit(
|
|
34
|
+
"baseElement",
|
|
35
|
+
"arrowElement",
|
|
36
|
+
"anchorElement",
|
|
37
|
+
"contentElement",
|
|
38
|
+
"popoverElement",
|
|
39
|
+
"disclosureElement"
|
|
40
|
+
),
|
|
41
|
+
select?.omit(
|
|
42
|
+
"value",
|
|
43
|
+
"items",
|
|
44
|
+
"renderedItems",
|
|
45
|
+
"baseElement",
|
|
46
|
+
"arrowElement",
|
|
47
|
+
"anchorElement",
|
|
48
|
+
"contentElement",
|
|
49
|
+
"popoverElement",
|
|
50
|
+
"disclosureElement"
|
|
51
|
+
)
|
|
52
|
+
);
|
|
53
|
+
const syncState = store.getState();
|
|
54
|
+
const activeId = defaultValue(
|
|
55
|
+
props.activeId,
|
|
56
|
+
syncState.activeId,
|
|
57
|
+
props.defaultActiveId,
|
|
58
|
+
null
|
|
59
|
+
);
|
|
60
|
+
const composite = createCompositeStore({
|
|
61
|
+
...props,
|
|
62
|
+
store,
|
|
63
|
+
activeId,
|
|
64
|
+
includesBaseElement: defaultValue(
|
|
65
|
+
props.includesBaseElement,
|
|
66
|
+
syncState.includesBaseElement,
|
|
67
|
+
true
|
|
68
|
+
),
|
|
69
|
+
orientation: defaultValue(
|
|
70
|
+
props.orientation,
|
|
71
|
+
syncState.orientation,
|
|
72
|
+
"vertical"
|
|
73
|
+
),
|
|
74
|
+
focusLoop: defaultValue(props.focusLoop, syncState.focusLoop, true),
|
|
75
|
+
focusWrap: defaultValue(props.focusWrap, syncState.focusWrap, true),
|
|
76
|
+
virtualFocus: defaultValue(
|
|
77
|
+
props.virtualFocus,
|
|
78
|
+
syncState?.virtualFocus,
|
|
79
|
+
!isSafariOnMobile
|
|
80
|
+
)
|
|
81
|
+
});
|
|
82
|
+
const popover = createPopoverStore({
|
|
83
|
+
...props,
|
|
84
|
+
store,
|
|
85
|
+
placement: defaultValue(
|
|
86
|
+
props.placement,
|
|
87
|
+
syncState.placement,
|
|
88
|
+
"bottom-start"
|
|
89
|
+
)
|
|
90
|
+
});
|
|
91
|
+
const initialValue = defaultValue(
|
|
92
|
+
props.value,
|
|
93
|
+
syncState.value,
|
|
94
|
+
props.defaultValue,
|
|
95
|
+
""
|
|
96
|
+
);
|
|
97
|
+
const initialState = {
|
|
98
|
+
...composite.getState(),
|
|
99
|
+
...popover.getState(),
|
|
100
|
+
value: initialValue,
|
|
101
|
+
resetValueOnHide: defaultValue(
|
|
102
|
+
props.resetValueOnHide,
|
|
103
|
+
syncState.resetValueOnHide,
|
|
104
|
+
false
|
|
105
|
+
),
|
|
106
|
+
activeValue: syncState.activeValue
|
|
107
|
+
};
|
|
108
|
+
const combobox = createStore(initialState, composite, popover, store);
|
|
109
|
+
combobox.setup(
|
|
110
|
+
() => combobox.sync(
|
|
111
|
+
(state) => {
|
|
112
|
+
if (!state.resetValueOnHide)
|
|
113
|
+
return;
|
|
114
|
+
if (state.mounted)
|
|
115
|
+
return;
|
|
116
|
+
combobox.setState("value", initialValue);
|
|
117
|
+
},
|
|
118
|
+
["resetValueOnHide", "mounted"]
|
|
119
|
+
)
|
|
120
|
+
);
|
|
121
|
+
combobox.setup(
|
|
122
|
+
() => combobox.syncBatch(
|
|
123
|
+
(state) => {
|
|
124
|
+
if (state.mounted)
|
|
125
|
+
return;
|
|
126
|
+
combobox.setState("activeId", activeId);
|
|
127
|
+
combobox.setState("moves", 0);
|
|
128
|
+
},
|
|
129
|
+
["mounted"]
|
|
130
|
+
)
|
|
131
|
+
);
|
|
132
|
+
combobox.setup(
|
|
133
|
+
() => combobox.sync(
|
|
134
|
+
(state, prevState) => {
|
|
135
|
+
if (state.moves === prevState.moves) {
|
|
136
|
+
combobox.setState("activeValue", void 0);
|
|
137
|
+
}
|
|
138
|
+
},
|
|
139
|
+
["moves", "activeId"]
|
|
140
|
+
)
|
|
141
|
+
);
|
|
142
|
+
combobox.setup(
|
|
143
|
+
() => combobox.syncBatch(
|
|
144
|
+
(state, prev) => {
|
|
145
|
+
if (state.moves === prev.moves)
|
|
146
|
+
return;
|
|
147
|
+
const { activeId: activeId2 } = combobox.getState();
|
|
148
|
+
const activeItem = composite.item(activeId2);
|
|
149
|
+
combobox.setState("activeValue", activeItem?.value);
|
|
150
|
+
},
|
|
151
|
+
["moves", "renderedItems"]
|
|
152
|
+
)
|
|
153
|
+
);
|
|
154
|
+
return {
|
|
155
|
+
...popover,
|
|
156
|
+
...composite,
|
|
157
|
+
...combobox,
|
|
158
|
+
setValue: (value) => combobox.setState("value", value)
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
export {
|
|
162
|
+
createComboboxStore
|
|
163
|
+
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { PopoverStore, PopoverStoreFunctions, PopoverStoreOptions, PopoverStoreProps, PopoverStoreState } from "../popover/popover-store.js";
|
|
2
|
+
/**
|
|
3
|
+
* Creates a composite overflow store.
|
|
4
|
+
*/
|
|
5
|
+
export declare function createCompositeOverflowStore(props?: CompositeOverflowStoreProps): CompositeOverflowStore;
|
|
6
|
+
export type CompositeOverflowStoreState = PopoverStoreState;
|
|
7
|
+
export type CompositeOverflowStoreFunctions = PopoverStoreFunctions;
|
|
8
|
+
export type CompositeOverflowStoreOptions = PopoverStoreOptions;
|
|
9
|
+
export type CompositeOverflowStoreProps = PopoverStoreProps;
|
|
10
|
+
export type CompositeOverflowStore = PopoverStore;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createPopoverStore
|
|
3
|
+
} from "../__chunks/6UPCMUXT.js";
|
|
4
|
+
import "../__chunks/ADRUFBEO.js";
|
|
5
|
+
import "../__chunks/HCKYJLMC.js";
|
|
6
|
+
import "../__chunks/UOJSZ35L.js";
|
|
7
|
+
import "../__chunks/KLKI3AIB.js";
|
|
8
|
+
|
|
9
|
+
// src/composite/composite-overflow-store.ts
|
|
10
|
+
function createCompositeOverflowStore(props = {}) {
|
|
11
|
+
return createPopoverStore(props);
|
|
12
|
+
}
|
|
13
|
+
export {
|
|
14
|
+
createCompositeOverflowStore
|
|
15
|
+
};
|