@octanejs/base-ui 0.1.10 → 0.1.14

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@octanejs/base-ui",
3
- "version": "0.1.10",
3
+ "version": "0.1.14",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "engines": {
@@ -38,22 +38,22 @@
38
38
  "./*": "./src/*.ts"
39
39
  },
40
40
  "dependencies": {
41
- "@floating-ui/utils": "^0.2.11",
41
+ "@floating-ui/utils": "^0.2.12",
42
42
  "aria-hidden": "^1.2.6",
43
43
  "tabbable": "^6.5.0",
44
- "@octanejs/floating-ui": "0.1.11"
44
+ "@octanejs/floating-ui": "0.1.15"
45
45
  },
46
46
  "peerDependencies": {
47
- "octane": "0.1.12"
47
+ "octane": "0.1.16"
48
48
  },
49
49
  "devDependencies": {
50
50
  "@base-ui/react": "^1.6.0",
51
- "@tsrx/react": "^0.2.44",
51
+ "@tsrx/react": "^0.2.50",
52
52
  "esbuild": "^0.28.1",
53
- "react": "^19.2.0",
54
- "react-dom": "^19.2.0",
55
- "vitest": "^4.1.9",
56
- "octane": "0.1.12"
53
+ "react": "^19.2.7",
54
+ "react-dom": "^19.2.7",
55
+ "vitest": "^4.1.10",
56
+ "octane": "0.1.16"
57
57
  },
58
58
  "scripts": {
59
59
  "test": "vitest run"
package/src/slider.ts CHANGED
@@ -12,6 +12,8 @@
12
12
  // React hydration-warning no-op). With the default `center` alignment, thumb/indicator positions
13
13
  // are pure math (`valueToPercent`), so mount and keyboard interaction render identically without
14
14
  // layout (pointer drag needs real layout — inert in jsdom, so not differential-covered).
15
+ // Edge-aligned visibility uses octane's real server/hydration snapshot; the
16
+ // React-specific pre-hydration script is not needed for that snapshot contract.
15
17
  import {
16
18
  createContext,
17
19
  createElement,
@@ -1016,7 +1018,7 @@ function SliderIndicator(componentProps: any): any {
1016
1018
  const { render, className, style: styleProp, ref, ...elementProps } = componentProps;
1017
1019
  const { indicatorPosition, inset, max, min, orientation, renderBeforeHydration, state, values } =
1018
1020
  useSliderRootContext();
1019
- const isHydrating = useIsHydrating();
1021
+ const isHydrating = useIsHydrating(subSlot(slot, 'hydrating'));
1020
1022
  const vertical = orientation === 'vertical';
1021
1023
  const range = values.length > 1;
1022
1024
 
@@ -1180,7 +1182,7 @@ function SliderThumb(componentProps: any): any {
1180
1182
  undefined,
1181
1183
  subSlot(slot, 'posPct'),
1182
1184
  );
1183
- const isHydrating = useIsHydrating();
1185
+ const isHydrating = useIsHydrating(subSlot(slot, 'hydrating'));
1184
1186
 
1185
1187
  const safeLastUsedThumbIndex =
1186
1188
  lastUsedThumbIndex >= 0 && lastUsedThumbIndex < sliderValues.length ? lastUsedThumbIndex : -1;
@@ -57,9 +57,7 @@ export interface UseDismissProps {
57
57
  | (() => PressType | { mouse: PressType; touch: PressType })
58
58
  | undefined;
59
59
  bubbles?:
60
- | boolean
61
- | { escapeKey?: boolean | undefined; outsidePress?: boolean | undefined }
62
- | undefined;
60
+ boolean | { escapeKey?: boolean | undefined; outsidePress?: boolean | undefined } | undefined;
63
61
  externalTree?: FloatingTreeStore | undefined;
64
62
  }
65
63
 
@@ -2,11 +2,7 @@
2
2
  export type Direction = -1 | 1;
3
3
 
4
4
  export type DirectionalChangeReason =
5
- | 'increment-press'
6
- | 'decrement-press'
7
- | 'wheel'
8
- | 'scrub'
9
- | 'keyboard';
5
+ 'increment-press' | 'decrement-press' | 'wheel' | 'scrub' | 'keyboard';
10
6
 
11
7
  export interface ChangeEventCustomProperties {
12
8
  direction?: Direction;
@@ -38,11 +38,11 @@ export const pressableTriggerOpenStateMapping: StateAttributesMapping<{ open: bo
38
38
  },
39
39
  };
40
40
 
41
- export const popupStateMapping: StateAttributesMapping<{ open: boolean; anchorHidden: boolean }> = {
41
+ export const popupStateMapping = {
42
42
  open(value: boolean) {
43
43
  return value ? POPUP_OPEN_HOOK : POPUP_CLOSED_HOOK;
44
44
  },
45
45
  anchorHidden(value: boolean) {
46
46
  return value ? ANCHOR_HIDDEN_HOOK : null;
47
47
  },
48
- };
48
+ } satisfies StateAttributesMapping<{ open: boolean; anchorHidden: boolean }>;
@@ -1,9 +1,26 @@
1
- // Ported from .base-ui/packages/react/src/utils/useIsHydrating.ts. React drives this via
2
- // `useSyncExternalStore` (server snapshot `true`, client snapshot `false`) so the first client
3
- // paint of a hydrated tree matches the server, then flips to `false`. octane's binding renders
4
- // client-only in these tests, so a fresh mount is never hydrating — returns `false`. It only
5
- // gates the `thumbAlignment: 'edge'` pre-hydration visibility path (inert for the default
6
- // `center` alignment).
7
- export function useIsHydrating(): boolean {
1
+ // Ported from Base UI's useIsHydrating: the server snapshot must also be used
2
+ // for the first hydration render so layout-dependent slider styles are adopted
3
+ // before the client snapshot makes the hydrated controls visible.
4
+ import { useSyncExternalStore } from 'octane';
5
+
6
+ import { S, splitSlot, subSlot } from '../internal';
7
+
8
+ function subscribe(): () => void {
9
+ return () => {};
10
+ }
11
+
12
+ function getSnapshot(): boolean {
8
13
  return false;
9
14
  }
15
+
16
+ function getServerSnapshot(): boolean {
17
+ return true;
18
+ }
19
+
20
+ export function useIsHydrating(): boolean;
21
+ export function useIsHydrating(slot: symbol | undefined): boolean;
22
+ export function useIsHydrating(...args: unknown[]): boolean {
23
+ const [, slotArg] = splitSlot(args);
24
+ const slot = slotArg ?? S('useIsHydrating');
25
+ return useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot, subSlot(slot, 'store'));
26
+ }
@@ -27,8 +27,7 @@ import { mergeProps, mergePropsN, mergeClassNames } from './mergeProps';
27
27
  const EMPTY_OBJECT: Record<string, any> = {};
28
28
 
29
29
  export type RenderProp<State> =
30
- | ((props: Record<string, any>, state: State) => any)
31
- | any /* element descriptor */;
30
+ ((props: Record<string, any>, state: State) => any) | any; /* element descriptor */
32
31
 
33
32
  export interface UseRenderElementComponentProps<State> {
34
33
  className?: string | ((state: State) => string | undefined);