@octanejs/base-ui 0.1.1 → 0.1.3
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 +7 -1
- package/package.json +12 -4
- package/src/alert-dialog.ts +47 -0
- package/src/checkbox.ts +7 -16
- package/src/dialog.ts +859 -0
- package/src/field.ts +4 -30
- package/src/index.ts +3 -0
- package/src/number-field.ts +8 -45
- package/src/popover.ts +1205 -0
- package/src/radio.ts +3 -24
- package/src/slider.ts +4 -5
- package/src/switch.ts +4 -30
- package/src/utils/InternalBackdrop.ts +28 -0
- package/src/utils/adaptiveOriginMiddleware.ts +82 -0
- package/src/utils/closePart.ts +61 -0
- package/src/utils/constants.ts +9 -0
- package/src/utils/createChangeEventDetails.ts +7 -0
- package/src/utils/dom.ts +9 -0
- package/src/utils/empty.ts +7 -0
- package/src/utils/floating/FloatingFocusManager.ts +833 -0
- package/src/utils/floating/FloatingPortal.ts +268 -0
- package/src/utils/floating/FloatingRootStore.ts +127 -0
- package/src/utils/floating/FloatingTree.ts +70 -0
- package/src/utils/floating/FloatingTreeStore.ts +22 -0
- package/src/utils/floating/FocusGuard.ts +34 -0
- package/src/utils/floating/composite.ts +20 -0
- package/src/utils/floating/constants.ts +8 -0
- package/src/utils/floating/createAttribute.ts +4 -0
- package/src/utils/floating/createEventEmitter.ts +20 -0
- package/src/utils/floating/element.ts +54 -0
- package/src/utils/floating/enqueueFocus.ts +38 -0
- package/src/utils/floating/event.ts +53 -0
- package/src/utils/floating/getEmptyRootContext.ts +19 -0
- package/src/utils/floating/markOthers.ts +197 -0
- package/src/utils/floating/nodes.ts +31 -0
- package/src/utils/floating/tabbable.ts +260 -0
- package/src/utils/floating/types.ts +57 -0
- package/src/utils/floating/useClick.ts +174 -0
- package/src/utils/floating/useDismiss.ts +641 -0
- package/src/utils/floating/useFloating.ts +198 -0
- package/src/utils/floating/useFloatingRootContext.ts +81 -0
- package/src/utils/floating/useHoverFloatingInteraction.ts +12 -0
- package/src/utils/floating/useHoverReferenceInteraction.ts +17 -0
- package/src/utils/floating/useSyncedFloatingRootContext.ts +93 -0
- package/src/utils/getDisabledMountTransitionStyles.ts +12 -0
- package/src/utils/hideMiddleware.ts +22 -0
- package/src/utils/inertValue.ts +5 -0
- package/src/utils/mergeCleanups.ts +13 -0
- package/src/utils/platform.ts +46 -2
- package/src/utils/popupStateMapping.ts +48 -0
- package/src/utils/popups/index.ts +4 -0
- package/src/utils/popups/popupStoreUtils.ts +484 -0
- package/src/utils/popups/popupTriggerMap.ts +62 -0
- package/src/utils/popups/store.ts +147 -0
- package/src/utils/popups/useTriggerFocusGuards.ts +73 -0
- package/src/utils/store/ReactStore.ts +168 -0
- package/src/utils/store/Store.ts +84 -0
- package/src/utils/store/createSelector.ts +66 -0
- package/src/utils/store/useStore.ts +49 -0
- package/src/utils/useAnchorPositioning.ts +581 -0
- package/src/utils/useAnchoredPopupScrollLock.ts +50 -0
- package/src/utils/useAnimationFrame.ts +28 -5
- package/src/utils/useEnhancedClickHandler.ts +47 -0
- package/src/utils/useOnFirstRender.ts +11 -0
- package/src/utils/useOpenInteractionType.ts +32 -0
- package/src/utils/usePositioner.ts +48 -0
- package/src/utils/useScrollLock.ts +253 -0
package/README.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# @octanejs/base-ui
|
|
2
2
|
|
|
3
3
|
[Base UI](https://base-ui.com) (`@base-ui/react`) ported to the
|
|
4
|
-
[octane](https://github.com/octanejs/octane)
|
|
4
|
+
[octane](https://github.com/octanejs/octane) UI framework — headless, accessible, unstyled
|
|
5
5
|
UI primitives.
|
|
6
6
|
|
|
7
7
|
Alpha, in progress. Ported at full fidelity from the pinned `mui/base-ui` source
|
|
@@ -31,3 +31,9 @@ Every component takes Base UI's universal composition props — `render` (a JSX
|
|
|
31
31
|
- **ref-as-prop.** No `forwardRef`; `ref` is a normal prop (React-19 shape).
|
|
32
32
|
- **`className` composition** follows octane's `normalizeClass` at the apply site; the
|
|
33
33
|
`render`-prop merge concatenates strings exactly like Base UI.
|
|
34
|
+
|
|
35
|
+
## Status
|
|
36
|
+
|
|
37
|
+
Current scope, known divergences, and verification status are tracked in the
|
|
38
|
+
generated [bindings status table](../../docs/bindings-status.md), sourced from
|
|
39
|
+
this package's [`status.json`](./status.json).
|
package/package.json
CHANGED
|
@@ -1,8 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@octanejs/base-ui",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
|
+
"octane": {
|
|
7
|
+
"hookSlots": {
|
|
8
|
+
"manual": [
|
|
9
|
+
"src"
|
|
10
|
+
]
|
|
11
|
+
}
|
|
12
|
+
},
|
|
6
13
|
"description": "Base UI (@base-ui/react) for the octane renderer — headless, accessible, unstyled UI primitives ported from base-ui.com at full fidelity.",
|
|
7
14
|
"author": {
|
|
8
15
|
"name": "Dominic Gannaway",
|
|
@@ -28,14 +35,15 @@
|
|
|
28
35
|
"./*": "./src/*.ts"
|
|
29
36
|
},
|
|
30
37
|
"dependencies": {
|
|
38
|
+
"@floating-ui/utils": "^0.2.11",
|
|
31
39
|
"aria-hidden": "^1.2.6",
|
|
32
40
|
"tabbable": "^6.5.0",
|
|
33
|
-
"@octanejs/floating-ui": "0.1.
|
|
34
|
-
"octane": "0.1.
|
|
41
|
+
"@octanejs/floating-ui": "0.1.4",
|
|
42
|
+
"octane": "0.1.5"
|
|
35
43
|
},
|
|
36
44
|
"devDependencies": {
|
|
37
45
|
"@base-ui/react": "^1.6.0",
|
|
38
|
-
"@tsrx/react": "^0.2.
|
|
46
|
+
"@tsrx/react": "^0.2.37",
|
|
39
47
|
"esbuild": "^0.28.1",
|
|
40
48
|
"react": "^19.2.0",
|
|
41
49
|
"react-dom": "^19.2.0",
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
// Ported from .base-ui/packages/react/src/alert-dialog/ (v1.6.0). AlertDialog is a thin variant of
|
|
2
|
+
// Dialog: the Root delegates to Dialog's `useRenderDialogRoot` with the `'alert-dialog'` mode (which
|
|
3
|
+
// forces `modal: true`, `disablePointerDismissal: true`, `role: 'alertdialog'`), and every other part
|
|
4
|
+
// — Trigger, Portal, Backdrop, Popup, Title, Description, Close — is literally Dialog's part reused.
|
|
5
|
+
// The handle extends `DialogHandle`, enforcing the alert-dialog invariants on its store.
|
|
6
|
+
import { useRenderDialogRoot, DialogHandle, DialogStore, Dialog } from './dialog';
|
|
7
|
+
|
|
8
|
+
const alertDialogState = {
|
|
9
|
+
modal: true,
|
|
10
|
+
disablePointerDismissal: true,
|
|
11
|
+
role: 'alertdialog',
|
|
12
|
+
} as const;
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* A handle to control an Alert Dialog imperatively and to associate detached triggers with it.
|
|
16
|
+
*/
|
|
17
|
+
export class AlertDialogHandle<Payload> extends DialogHandle<Payload> {
|
|
18
|
+
constructor(store?: DialogStore<Payload>) {
|
|
19
|
+
const alertDialogStore = store ?? new DialogStore<Payload>(alertDialogState as any);
|
|
20
|
+
super(alertDialogStore);
|
|
21
|
+
|
|
22
|
+
if (store) {
|
|
23
|
+
// Supplied stores may have been created as plain dialogs; enforce alert-dialog state.
|
|
24
|
+
this.store.update(alertDialogState as any);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export function createAlertDialogHandle<Payload>(): AlertDialogHandle<Payload> {
|
|
30
|
+
return new AlertDialogHandle<Payload>();
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function AlertDialogRoot<Payload>(props: any): any {
|
|
34
|
+
return useRenderDialogRoot<Payload>(props, 'alert-dialog');
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export const AlertDialog = {
|
|
38
|
+
Root: AlertDialogRoot,
|
|
39
|
+
Trigger: Dialog.Trigger,
|
|
40
|
+
Portal: Dialog.Portal,
|
|
41
|
+
Backdrop: Dialog.Backdrop,
|
|
42
|
+
Popup: Dialog.Popup,
|
|
43
|
+
Title: Dialog.Title,
|
|
44
|
+
Description: Dialog.Description,
|
|
45
|
+
Close: Dialog.Close,
|
|
46
|
+
createHandle: createAlertDialogHandle,
|
|
47
|
+
};
|
package/src/checkbox.ts
CHANGED
|
@@ -4,10 +4,11 @@
|
|
|
4
4
|
//
|
|
5
5
|
// A checkbox renders a `<span role="checkbox">` + a hidden `<input type="checkbox">`, with an
|
|
6
6
|
// optional `<Checkbox.Indicator>` (transition-mounted). octane adaptations mirror Switch:
|
|
7
|
-
// native events (no `.nativeEvent`); the
|
|
8
|
-
//
|
|
9
|
-
//
|
|
10
|
-
// parent-checkbox branches stay dormant until CheckboxGroup lands
|
|
7
|
+
// native events (no `.nativeEvent`); the hidden input takes the live `checked` prop (octane
|
|
8
|
+
// inputs are CONTROLLED exactly like React's) with native click dispatch;
|
|
9
|
+
// `input.indeterminate` set imperatively as a property (it has no attribute). The
|
|
10
|
+
// CheckboxGroup / parent-checkbox branches stay dormant until CheckboxGroup lands
|
|
11
|
+
// (groupContext undefined).
|
|
11
12
|
import {
|
|
12
13
|
createContext,
|
|
13
14
|
createElement,
|
|
@@ -225,9 +226,6 @@ function CheckboxRoot(props: CheckboxRootProps): any {
|
|
|
225
226
|
subSlot(slot, 'checked'),
|
|
226
227
|
);
|
|
227
228
|
|
|
228
|
-
// octane: reflect the INITIAL checked as the `checked` ATTRIBUTE (see Switch).
|
|
229
|
-
const initialCheckedRef = useRef(checked, subSlot(slot, 'initialChecked'));
|
|
230
|
-
|
|
231
229
|
const computedChecked = isGroupedWithParent ? Boolean(groupChecked) : checked;
|
|
232
230
|
const computedIndeterminate = isGroupedWithParent
|
|
233
231
|
? groupIndeterminate || indeterminate
|
|
@@ -289,19 +287,13 @@ function CheckboxRoot(props: CheckboxRootProps): any {
|
|
|
289
287
|
subSlot(slot, 'ariaLabelledBy'),
|
|
290
288
|
);
|
|
291
289
|
|
|
292
|
-
//
|
|
293
|
-
// React's controlled input (property-only, never a `checked` attribute beyond the initial).
|
|
290
|
+
// `indeterminate` has no attribute — set the property imperatively (per Base UI).
|
|
294
291
|
useLayoutEffect(
|
|
295
292
|
() => {
|
|
296
293
|
const input = inputRef.current;
|
|
297
294
|
if (!input) {
|
|
298
295
|
return;
|
|
299
296
|
}
|
|
300
|
-
const setNativeChecked = Object.getOwnPropertyDescriptor(
|
|
301
|
-
ownerWindow(input).HTMLInputElement.prototype,
|
|
302
|
-
'checked',
|
|
303
|
-
)?.set;
|
|
304
|
-
setNativeChecked?.call(input, checked);
|
|
305
297
|
input.indeterminate = computedIndeterminate;
|
|
306
298
|
if (checked) {
|
|
307
299
|
setFilled(true);
|
|
@@ -327,8 +319,7 @@ function CheckboxRoot(props: CheckboxRootProps): any {
|
|
|
327
319
|
|
|
328
320
|
const inputProps: Record<string, any> = mergeProps(
|
|
329
321
|
{
|
|
330
|
-
|
|
331
|
-
checked: initialCheckedRef.current || undefined,
|
|
322
|
+
checked,
|
|
332
323
|
disabled,
|
|
333
324
|
form,
|
|
334
325
|
name: parent ? undefined : name,
|