lilact 0.2.1 → 0.2.2
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/lilact.development.min.js +198 -238
- package/dist/lilact.development.min.js.map +1 -1
- package/dist/lilact.production.min.js +8139 -1
- package/dist/lilact.production.min.js.map +1 -1
- package/docs/classes/accessories.ErrorBoundary.html +8 -8
- package/docs/classes/accessories.Suspense.html +7 -7
- package/docs/classes/components.Component.html +10 -10
- package/docs/classes/components.HTMLComponent.html +10 -10
- package/docs/classes/components.RootComponent.html +10 -10
- package/docs/functions/components.createComponent.html +1 -1
- package/docs/functions/components.createRoot.html +1 -1
- package/docs/functions/components.render.html +1 -1
- package/docs/functions/hooks.useActionState.html +3 -2
- package/docs/functions/hooks.useEffect.html +3 -2
- package/docs/functions/hooks.useImperativeHandle.html +1 -1
- package/docs/functions/hooks.useLayoutEffect.html +3 -2
- package/docs/functions/hooks.useLocalStorage.html +3 -2
- package/docs/functions/hooks.useMemo.html +3 -2
- package/docs/functions/hooks.useRef.html +3 -2
- package/docs/static/demos/pane.jsx +31 -0
- package/docs/static/index.html +1 -0
- package/docs/static/lilact.development.min.js +198 -238
- package/docs/static/lilact.production.min.js +8139 -1
- package/package.json +1 -1
- package/root/demos/pane.jsx +31 -0
- package/root/index.html +1 -0
- package/root/lilact.development.min.js +198 -238
- package/root/lilact.production.min.js +8139 -1
- package/src/components.jsx +4 -1
- package/src/hooks.jsx +15 -15
- package/src/misc.jsx +13 -1
- package/src/pane.jsx +207 -269
- package/webpack.config.js +1 -1
- package/docs/static/index 2.html +0 -95
- package/root/index 2.html +0 -95
package/package.json
CHANGED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
const { useRef, useState, ResizablePane } = Lilact;
|
|
2
|
+
|
|
3
|
+
module.exports = function Demo() {
|
|
4
|
+
const ref = useRef(null);
|
|
5
|
+
const [mode, setMode] = useState("horizontal");
|
|
6
|
+
const [position, setPosition] = useState(0.35);
|
|
7
|
+
|
|
8
|
+
return (
|
|
9
|
+
<>
|
|
10
|
+
<button onClick={() => ref.current?.setMode(ref.current?.getMode() === "horizontal" ? "vertical" : "horizontal")}>
|
|
11
|
+
Toggle mode
|
|
12
|
+
</button>
|
|
13
|
+
<button onClick={() => ref.current?.setPosition(0.5)}>Center</button>
|
|
14
|
+
|
|
15
|
+
<div style={{ height: "calc(100% - 2em)", width: "100% - 2em", border: "1px solid" }}>
|
|
16
|
+
<ResizablePane
|
|
17
|
+
ref={ref}
|
|
18
|
+
mode={mode}
|
|
19
|
+
position={position}
|
|
20
|
+
min={0.2}
|
|
21
|
+
max={0.8}
|
|
22
|
+
splitterSize={10}
|
|
23
|
+
onSizeChange={(p) => setPosition(p)}
|
|
24
|
+
>
|
|
25
|
+
<div style={{ padding: 12 }}>Left/Top</div>
|
|
26
|
+
<div style={{ padding: 12 }}>Right/Bottom</div>
|
|
27
|
+
</ResizablePane>
|
|
28
|
+
</div>
|
|
29
|
+
</>
|
|
30
|
+
);
|
|
31
|
+
}
|
package/root/index.html
CHANGED
|
@@ -160,6 +160,7 @@ function App()
|
|
|
160
160
|
{
|
|
161
161
|
const demos =[
|
|
162
162
|
['stopwatch.jsx', '( useState, useRef )'],
|
|
163
|
+
['pane.jsx', '( useRef, useState, ResizablePane )'],
|
|
163
164
|
['modal.jsx', '( useEffect, useRef, useState )'],
|
|
164
165
|
['actionstate.jsx', '( useActionState, useState )'],
|
|
165
166
|
['context.jsx', '( createContext, useContext, useState ), emotion:( css, cx )'],
|
|
@@ -1418,6 +1418,7 @@ __webpack_require__.d(misc_namespaceObject, {
|
|
|
1418
1418
|
isThenable: () => (isThenable),
|
|
1419
1419
|
isValidElement: () => (isValidElement),
|
|
1420
1420
|
layout_effects: () => (layout_effects),
|
|
1421
|
+
length_css_attributes_set: () => (length_css_attributes_set),
|
|
1421
1422
|
mapLocation: () => (mapLocation),
|
|
1422
1423
|
roots: () => (roots),
|
|
1423
1424
|
scanFunctionLabels: () => (scanFunctionLabels),
|
|
@@ -4628,7 +4629,19 @@ let events_set = new Set([
|
|
|
4628
4629
|
"onabort","oncanplay","oncanplaythrough","oncuechange","ondurationchange","onemptied","onended","onerror",
|
|
4629
4630
|
"onloadeddata","onloadedmetadata","onloadstart","onpause","onplay","onplaying","onprogress","onratechange",
|
|
4630
4631
|
"onseeked","onseeking","onstalled","onsuspend","ontimeupdate","onvolumechange","onwaiting",
|
|
4631
|
-
"ontoggle"
|
|
4632
|
+
"ontoggle",
|
|
4633
|
+
|
|
4634
|
+
"onpointerdown", "onpointerup", "onpointermove", "onpointercancel", "onpointerover", "onpointerout",
|
|
4635
|
+
"onpointerenter", "onpointerleave"
|
|
4636
|
+
])
|
|
4637
|
+
/** @ignore */
|
|
4638
|
+
let length_css_attributes_set = new Set([
|
|
4639
|
+
"width","height","minWidth","minHeight","maxWidth","maxHeight","top","right","bottom","left","margin",
|
|
4640
|
+
"marginTop","marginRight","marginBottom","marginLeft","padding","paddingTop","paddingRight","paddingBottom",
|
|
4641
|
+
"paddingLeft","borderWidth","borderTopWidth","borderRightWidth","borderBottomWidth","borderLeftWidth",
|
|
4642
|
+
"outlineWidth","fontSize","lineHeight","letterSpacing","wordSpacing","textIndent","borderRadius",
|
|
4643
|
+
"borderTopLeftRadius","borderTopRightRadius","borderBottomLeftRadius","borderBottomRightRadius",
|
|
4644
|
+
"columnGap","rowGap","gap"
|
|
4632
4645
|
])
|
|
4633
4646
|
|
|
4634
4647
|
|
|
@@ -5036,6 +5049,9 @@ class ComponentCore
|
|
|
5036
5049
|
this.event_detachers[al] = Lilact.addWrappedEventListener(this.element, al.substring(2), patch[a]);
|
|
5037
5050
|
}
|
|
5038
5051
|
else if(al==='style') {
|
|
5052
|
+
for(const x in patch[a]) {
|
|
5053
|
+
if(isFinite(patch[a][x])) patch[a][x]+='px';
|
|
5054
|
+
}
|
|
5039
5055
|
Object.assign(this.element.style, patch[a]);
|
|
5040
5056
|
}
|
|
5041
5057
|
else {
|
|
@@ -5052,7 +5068,7 @@ class ComponentCore
|
|
|
5052
5068
|
this.element.onsubmit = undefined;
|
|
5053
5069
|
}
|
|
5054
5070
|
|
|
5055
|
-
this.element.setAttribute('key', this.props.key);
|
|
5071
|
+
//this.element.setAttribute('key', this.props.key);
|
|
5056
5072
|
|
|
5057
5073
|
this.updateElementClass(patch);
|
|
5058
5074
|
}
|
|
@@ -5910,7 +5926,7 @@ function useTransition()
|
|
|
5910
5926
|
* @param {any} initialValue - Initial value used if nothing exists in localStorage.
|
|
5911
5927
|
* @returns {any} Stored state/result.
|
|
5912
5928
|
*/
|
|
5913
|
-
function useLocalStorage(key,
|
|
5929
|
+
function useLocalStorage(key, initialValue)
|
|
5914
5930
|
{
|
|
5915
5931
|
|
|
5916
5932
|
const hk = Lilact.useHook();
|
|
@@ -5923,8 +5939,8 @@ function useLocalStorage(key, default_val)
|
|
|
5923
5939
|
}
|
|
5924
5940
|
|
|
5925
5941
|
if(val===undefined) {
|
|
5926
|
-
if(typeof(
|
|
5927
|
-
val =
|
|
5942
|
+
if(typeof(initialValue)==='function') initialValue = initialValue();
|
|
5943
|
+
val = initialValue;
|
|
5928
5944
|
localStorage[key] = JSON.stringify(val);
|
|
5929
5945
|
}
|
|
5930
5946
|
|
|
@@ -5954,12 +5970,12 @@ function useLocalStorage(key, default_val)
|
|
|
5954
5970
|
* @param {any} initialValue - Initial ref value.
|
|
5955
5971
|
* @returns {Object} Ref object with `.current`.
|
|
5956
5972
|
*/
|
|
5957
|
-
function useRef(
|
|
5973
|
+
function useRef(initialValue = null)
|
|
5958
5974
|
{
|
|
5959
5975
|
const hk = Lilact.useHook();
|
|
5960
5976
|
|
|
5961
5977
|
if( Lilact.isEmpty(hk) ) {
|
|
5962
|
-
hk.current =
|
|
5978
|
+
hk.current = initialValue;
|
|
5963
5979
|
}
|
|
5964
5980
|
|
|
5965
5981
|
return hk;
|
|
@@ -5972,7 +5988,7 @@ function useRef(val = null)
|
|
|
5972
5988
|
* @param {Array<any>} [deps] - Dependency list.
|
|
5973
5989
|
* @returns {void}
|
|
5974
5990
|
*/
|
|
5975
|
-
function useLayoutEffect(
|
|
5991
|
+
function useLayoutEffect(effect, deps=undefined)
|
|
5976
5992
|
{
|
|
5977
5993
|
if( deps!==undefined && (typeof(deps)!=='object' || deps.constructor.name!=='Array') ) {
|
|
5978
5994
|
throw "layout effect dependencies must be an array or omitted.";
|
|
@@ -5989,7 +6005,7 @@ function useLayoutEffect(setup, deps=undefined)
|
|
|
5989
6005
|
}
|
|
5990
6006
|
|
|
5991
6007
|
hk.deps = deps;
|
|
5992
|
-
Lilact.layout_effects.add( ()=>{ hk.cleanup =
|
|
6008
|
+
Lilact.layout_effects.add( ()=>{ hk.cleanup = effect(); });
|
|
5993
6009
|
Lilact.current_component[0].component.forceUpdate();
|
|
5994
6010
|
}
|
|
5995
6011
|
|
|
@@ -6000,7 +6016,7 @@ function useLayoutEffect(setup, deps=undefined)
|
|
|
6000
6016
|
* @param {Array<any>} [deps] - Dependency list.
|
|
6001
6017
|
* @returns {void}
|
|
6002
6018
|
*/
|
|
6003
|
-
function useEffect(
|
|
6019
|
+
function useEffect(effect, deps=undefined)
|
|
6004
6020
|
{
|
|
6005
6021
|
if( deps!==undefined && (typeof(deps)!=='object' || deps.constructor.name!=='Array') ) {
|
|
6006
6022
|
throw "effect dependencies must be an array or omitted.";
|
|
@@ -6017,7 +6033,7 @@ function useEffect(setup, deps=[{}])
|
|
|
6017
6033
|
}
|
|
6018
6034
|
|
|
6019
6035
|
hk.deps = deps;
|
|
6020
|
-
Lilact.setTimeout( ()=>{ hk.cleanup =
|
|
6036
|
+
Lilact.setTimeout( ()=>{ hk.cleanup = effect(); }, 0 );
|
|
6021
6037
|
|
|
6022
6038
|
}
|
|
6023
6039
|
|
|
@@ -6028,7 +6044,7 @@ function useEffect(setup, deps=[{}])
|
|
|
6028
6044
|
* @param {Array<any>} deps - Dependency list.
|
|
6029
6045
|
* @returns {any} Memoized value.
|
|
6030
6046
|
*/
|
|
6031
|
-
function useMemo(
|
|
6047
|
+
function useMemo(factory,deps=undefined)
|
|
6032
6048
|
{
|
|
6033
6049
|
if( deps!==undefined && (typeof(deps)!=='object' || deps.constructor.name!=='Array') ) {
|
|
6034
6050
|
throw "memo dependencies must be an array or omitted.";
|
|
@@ -6041,7 +6057,7 @@ function useMemo(fn,deps=undefined)
|
|
|
6041
6057
|
}
|
|
6042
6058
|
|
|
6043
6059
|
hk.deps = deps;
|
|
6044
|
-
hk.value =
|
|
6060
|
+
hk.value = factory(hk.value);
|
|
6045
6061
|
|
|
6046
6062
|
return hk.value;
|
|
6047
6063
|
}
|
|
@@ -6053,14 +6069,14 @@ function useMemo(fn,deps=undefined)
|
|
|
6053
6069
|
* @param {any} initialState - Initial state for the hook.
|
|
6054
6070
|
* @returns {any} Hook result
|
|
6055
6071
|
*/
|
|
6056
|
-
function useActionState(fn,
|
|
6072
|
+
function useActionState(fn, initialState)
|
|
6057
6073
|
{
|
|
6058
6074
|
const hk = Lilact.useHook();
|
|
6059
6075
|
const [is_pending, tran_start_func] = Lilact.useTransition();
|
|
6060
6076
|
|
|
6061
6077
|
if( Lilact.isEmpty(hk) ) {
|
|
6062
6078
|
|
|
6063
|
-
hk.state =
|
|
6079
|
+
hk.state = initialState;
|
|
6064
6080
|
|
|
6065
6081
|
hk.form_action = (sub)=>{
|
|
6066
6082
|
event.preventDefault();
|
|
@@ -6189,7 +6205,7 @@ function forwardRef(render)
|
|
|
6189
6205
|
* Dependency list that controls when the exposed value is recalculated.
|
|
6190
6206
|
* @returns {void}
|
|
6191
6207
|
*/
|
|
6192
|
-
function useImperativeHandle(ref, factory, deps)
|
|
6208
|
+
function useImperativeHandle(ref, factory, deps=undefined)
|
|
6193
6209
|
{
|
|
6194
6210
|
if(deps!==undefined && ref?.deps!==undefined && Lilact.shallowEqual(deps, ref.deps)) return;
|
|
6195
6211
|
|
|
@@ -6200,7 +6216,7 @@ function useImperativeHandle(ref, factory, deps)
|
|
|
6200
6216
|
ref.current = {};
|
|
6201
6217
|
}
|
|
6202
6218
|
Object.assign( ref.current, factory(), 0 );
|
|
6203
|
-
});
|
|
6219
|
+
}, 0);
|
|
6204
6220
|
}
|
|
6205
6221
|
|
|
6206
6222
|
|
|
@@ -7716,9 +7732,11 @@ class Suspense extends Component
|
|
|
7716
7732
|
|
|
7717
7733
|
|
|
7718
7734
|
|
|
7719
|
-
|
|
7720
|
-
|
|
7721
|
-
|
|
7735
|
+
|
|
7736
|
+
const clamp = (n, min, max) => {
|
|
7737
|
+
if (!Number.isFinite(n)) return n;
|
|
7738
|
+
return Math.min(max, Math.max(min, n));
|
|
7739
|
+
};
|
|
7722
7740
|
|
|
7723
7741
|
/**
|
|
7724
7742
|
* ResizablePane
|
|
@@ -7732,248 +7750,190 @@ function clamp(n, min, max) {
|
|
|
7732
7750
|
* - Callback when size changes via onSizeChange
|
|
7733
7751
|
* - Children are rendered in two separate containers (no portals)
|
|
7734
7752
|
*/
|
|
7735
|
-
const ResizablePane = forwardRef(function
|
|
7736
|
-
|
|
7737
|
-
|
|
7738
|
-
|
|
7739
|
-
|
|
7740
|
-
|
|
7741
|
-
|
|
7742
|
-
|
|
7743
|
-
|
|
7744
|
-
|
|
7745
|
-
|
|
7746
|
-
|
|
7747
|
-
|
|
7748
|
-
|
|
7749
|
-
|
|
7750
|
-
|
|
7751
|
-
|
|
7752
|
-
ref
|
|
7753
|
+
const ResizablePane = forwardRef(function ResizablePane(
|
|
7754
|
+
{
|
|
7755
|
+
mode = "horizontal",
|
|
7756
|
+
position, // controlled: number | undefined/null
|
|
7757
|
+
defaultPosition = 0.5,
|
|
7758
|
+
min = 0.1,
|
|
7759
|
+
max = 0.9,
|
|
7760
|
+
splitterSize = 8,
|
|
7761
|
+
onSizeChange,
|
|
7762
|
+
style,
|
|
7763
|
+
className,
|
|
7764
|
+
leftPaneStyle,
|
|
7765
|
+
rightPaneStyle,
|
|
7766
|
+
splitterStyle,
|
|
7767
|
+
children,
|
|
7768
|
+
},
|
|
7769
|
+
ref
|
|
7753
7770
|
) {
|
|
7754
|
-
|
|
7755
|
-
|
|
7756
|
-
|
|
7757
|
-
|
|
7758
|
-
return clamp(start, min, max);
|
|
7759
|
-
});
|
|
7771
|
+
const containerRef = useRef(null);
|
|
7772
|
+
const panes = Children.toArray(children);
|
|
7773
|
+
const leftChild = panes[0] ?? null;
|
|
7774
|
+
const rightChild = panes[1] ?? null;
|
|
7760
7775
|
|
|
7761
|
-
|
|
7762
|
-
const draggingRef = useRef(false);
|
|
7776
|
+
const isControlled = position != null;
|
|
7763
7777
|
|
|
7764
|
-
|
|
7765
|
-
const leftChild = panes[0] ?? null;
|
|
7766
|
-
const rightChild = panes[1] ?? null;
|
|
7778
|
+
const [internalMode, setInternalMode] = useState(mode);
|
|
7767
7779
|
|
|
7768
|
-
|
|
7780
|
+
const [posUncontrolled, setPosUncontrolled] = useState(() =>
|
|
7781
|
+
clamp(
|
|
7782
|
+
position ?? defaultPosition,
|
|
7783
|
+
min,
|
|
7784
|
+
max
|
|
7785
|
+
)
|
|
7786
|
+
);
|
|
7769
7787
|
|
|
7770
|
-
|
|
7771
|
-
|
|
7772
|
-
|
|
7773
|
-
}, [mode]);
|
|
7788
|
+
useEffect(() => {
|
|
7789
|
+
if (mode != null) setInternalMode(mode);
|
|
7790
|
+
}, [mode]);
|
|
7774
7791
|
|
|
7775
|
-
|
|
7776
|
-
|
|
7777
|
-
|
|
7778
|
-
|
|
7779
|
-
|
|
7780
|
-
|
|
7781
|
-
const setPosition = (newPos) => {
|
|
7782
|
-
const next = clamp(newPos, min, max);
|
|
7783
|
-
if (position == null) setPos(next); // only update internal state if uncontrolled
|
|
7784
|
-
onSizeChange?.(next);
|
|
7785
|
-
};
|
|
7792
|
+
// keep internal position clamped if min/max change (uncontrolled only)
|
|
7793
|
+
useLayoutEffect(() => {
|
|
7794
|
+
if (isControlled) return;
|
|
7795
|
+
setPosUncontrolled((p) => clamp(p, min, max));
|
|
7796
|
+
}, [min, max, isControlled]);
|
|
7786
7797
|
|
|
7787
|
-
|
|
7788
|
-
const m = nextMode === "vertical" ? "vertical" : "horizontal";
|
|
7789
|
-
if (mode == null) setInternalMode(m);
|
|
7790
|
-
// If mode is controlled via prop, consumer should re-render with new prop.
|
|
7791
|
-
};
|
|
7798
|
+
const posResolved = isControlled ? clamp(position, min, max) : posUncontrolled;
|
|
7792
7799
|
|
|
7793
|
-
|
|
7794
|
-
|
|
7795
|
-
|
|
7796
|
-
|
|
7797
|
-
|
|
7798
|
-
getPosition: () => (position == null ? pos : clamp(position, min, max)),
|
|
7799
|
-
getMode: () => modeResolved,
|
|
7800
|
-
}),
|
|
7801
|
-
[pos, position, min, max, modeResolved, onSizeChange, mode]
|
|
7802
|
-
);
|
|
7800
|
+
const setPosition = (next) => {
|
|
7801
|
+
const clamped = clamp(next, min, max);
|
|
7802
|
+
if (!isControlled) setPosUncontrolled(clamped);
|
|
7803
|
+
onSizeChange?.(clamped);
|
|
7804
|
+
};
|
|
7803
7805
|
|
|
7804
|
-
|
|
7805
|
-
|
|
7806
|
-
if (!el) return;
|
|
7806
|
+
const draggingRef = useRef(false);
|
|
7807
|
+
const pointerIdRef = useRef(null);
|
|
7807
7808
|
|
|
7808
|
-
|
|
7809
|
-
|
|
7809
|
+
const updateFromClient = (clientX, clientY) => {
|
|
7810
|
+
const el = containerRef.current;
|
|
7811
|
+
if (!el) return;
|
|
7810
7812
|
|
|
7811
|
-
|
|
7812
|
-
const usable = rect.width;
|
|
7813
|
-
if (usable <= 0) return;
|
|
7814
|
-
next = (clientX - rect.left) / usable;
|
|
7815
|
-
} else {
|
|
7816
|
-
const usable = rect.height;
|
|
7817
|
-
if (usable <= 0) return;
|
|
7818
|
-
next = (clientY - rect.top) / usable;
|
|
7819
|
-
}
|
|
7820
|
-
setPosition(next);
|
|
7821
|
-
};
|
|
7813
|
+
const rect = el.getBoundingClientRect();
|
|
7822
7814
|
|
|
7823
|
-
|
|
7824
|
-
|
|
7825
|
-
|
|
7815
|
+
if (internalMode === "horizontal") {
|
|
7816
|
+
const usable = rect.width;
|
|
7817
|
+
if (!Number.isFinite(usable) || usable <= 0) return; // no jump on init
|
|
7818
|
+
const raw = (clientX - rect.left) / usable;
|
|
7819
|
+
if (!Number.isFinite(raw)) return;
|
|
7820
|
+
setPosition(raw);
|
|
7821
|
+
} else {
|
|
7822
|
+
const usable = rect.height;
|
|
7823
|
+
if (!Number.isFinite(usable) || usable <= 0) return; // no jump on init
|
|
7824
|
+
const raw = (clientY - rect.top) / usable;
|
|
7825
|
+
if (!Number.isFinite(raw)) return;
|
|
7826
|
+
setPosition(raw);
|
|
7827
|
+
}
|
|
7828
|
+
};
|
|
7826
7829
|
|
|
7827
|
-
|
|
7828
|
-
|
|
7829
|
-
|
|
7830
|
-
|
|
7831
|
-
|
|
7832
|
-
|
|
7830
|
+
// stable global listeners: only act while draggingRef.current === true
|
|
7831
|
+
useEffect(() => {
|
|
7832
|
+
const onMove = (e) => {
|
|
7833
|
+
if (!draggingRef.current) return;
|
|
7834
|
+
if (pointerIdRef.current != null && e.pointerId !== pointerIdRef.current) return;
|
|
7835
|
+
updateFromClient(e.clientX, e.clientY);
|
|
7836
|
+
};
|
|
7833
7837
|
|
|
7834
|
-
|
|
7835
|
-
|
|
7838
|
+
const stop = (e) => {
|
|
7839
|
+
if (!draggingRef.current) return;
|
|
7840
|
+
if (pointerIdRef.current != null && e.pointerId !== pointerIdRef.current) return;
|
|
7841
|
+
draggingRef.current = false;
|
|
7842
|
+
pointerIdRef.current = null;
|
|
7843
|
+
};
|
|
7836
7844
|
|
|
7837
|
-
|
|
7838
|
-
|
|
7839
|
-
|
|
7840
|
-
};
|
|
7845
|
+
window.addEventListener("pointermove", onMove, { passive: true });
|
|
7846
|
+
window.addEventListener("pointerup", stop, { passive: true });
|
|
7847
|
+
window.addEventListener("pointercancel", stop, { passive: true });
|
|
7841
7848
|
|
|
7842
|
-
|
|
7843
|
-
|
|
7844
|
-
|
|
7849
|
+
return () => {
|
|
7850
|
+
window.removeEventListener("pointermove", onMove);
|
|
7851
|
+
window.removeEventListener("pointerup", stop);
|
|
7852
|
+
window.removeEventListener("pointercancel", stop);
|
|
7853
|
+
};
|
|
7854
|
+
}, [internalMode]); // updateFromClient uses internalMode
|
|
7845
7855
|
|
|
7846
|
-
|
|
7847
|
-
|
|
7848
|
-
|
|
7849
|
-
if (!draggingRef.current) return;
|
|
7850
|
-
updateFromClientXorY(e.clientX, e.clientY);
|
|
7851
|
-
};
|
|
7852
|
-
const handleUp = () => stopDragging();
|
|
7856
|
+
const onPointerDown = (e) => {
|
|
7857
|
+
if (e.button != null && e.button !== 0) return;
|
|
7858
|
+
e.preventDefault();
|
|
7853
7859
|
|
|
7854
|
-
|
|
7855
|
-
|
|
7856
|
-
window.addEventListener("pointercancel", handleUp, { passive: true });
|
|
7860
|
+
draggingRef.current = true;
|
|
7861
|
+
pointerIdRef.current = e.pointerId;
|
|
7857
7862
|
|
|
7858
|
-
|
|
7859
|
-
|
|
7860
|
-
|
|
7861
|
-
window.removeEventListener("pointercancel", handleUp);
|
|
7862
|
-
};
|
|
7863
|
-
}, [modeResolved, min, max, position, onSizeChange]);
|
|
7863
|
+
try {
|
|
7864
|
+
e.currentTarget.setPointerCapture?.(e.pointerId);
|
|
7865
|
+
} catch {}
|
|
7864
7866
|
|
|
7865
|
-
|
|
7867
|
+
updateFromClient(e.clientX, e.clientY); // first update only if rect is sane
|
|
7868
|
+
};
|
|
7866
7869
|
|
|
7867
|
-
|
|
7868
|
-
|
|
7869
|
-
|
|
7870
|
-
// We set left/right as percentages and keep splitter fixed in px.
|
|
7871
|
-
return {
|
|
7872
|
-
left: `${posResolved * 100}%`,
|
|
7873
|
-
right: `calc(${100 - posResolved * 100}% - ${splitterSize}px)`,
|
|
7874
|
-
};
|
|
7875
|
-
}
|
|
7876
|
-
return {
|
|
7877
|
-
left: `${posResolved * 100}%`,
|
|
7878
|
-
right: `calc(${100 - posResolved * 100}% - ${splitterSize}px)`,
|
|
7879
|
-
};
|
|
7880
|
-
}, [modeResolved, posResolved, splitterSize]);
|
|
7881
|
-
|
|
7882
|
-
// Improve keyboard accessibility (arrow keys when handle is focused)
|
|
7883
|
-
const onSplitterKeyDown = (e) => {
|
|
7884
|
-
const step = 0.02;
|
|
7885
|
-
let delta = 0;
|
|
7886
|
-
if (modeResolved === "horizontal") {
|
|
7887
|
-
if (e.key === "ArrowLeft") delta = -step;
|
|
7888
|
-
if (e.key === "ArrowRight") delta = step;
|
|
7889
|
-
} else {
|
|
7890
|
-
if (e.key === "ArrowUp") delta = -step;
|
|
7891
|
-
if (e.key === "ArrowDown") delta = step;
|
|
7892
|
-
}
|
|
7893
|
-
if (delta !== 0) {
|
|
7894
|
-
e.preventDefault();
|
|
7895
|
-
setPosition(posResolved + delta);
|
|
7896
|
-
}
|
|
7897
|
-
};
|
|
7870
|
+
const onKeyDown = (e) => {
|
|
7871
|
+
const step = 0.02;
|
|
7872
|
+
let delta = 0;
|
|
7898
7873
|
|
|
7899
|
-
|
|
7900
|
-
|
|
7901
|
-
|
|
7902
|
-
|
|
7903
|
-
|
|
7904
|
-
|
|
7905
|
-
|
|
7906
|
-
width: "100%",
|
|
7907
|
-
height: "100%",
|
|
7908
|
-
overflow: "hidden",
|
|
7909
|
-
touchAction: "none",
|
|
7910
|
-
...(style || {}),
|
|
7911
|
-
flexDirection: modeResolved === "horizontal" ? "row" : "column",
|
|
7912
|
-
};
|
|
7874
|
+
if (internalMode === "horizontal") {
|
|
7875
|
+
if (e.key === "ArrowLeft") delta = -step;
|
|
7876
|
+
if (e.key === "ArrowRight") delta = step;
|
|
7877
|
+
} else {
|
|
7878
|
+
if (e.key === "ArrowUp") delta = -step;
|
|
7879
|
+
if (e.key === "ArrowDown") delta = step;
|
|
7880
|
+
}
|
|
7913
7881
|
|
|
7914
|
-
|
|
7915
|
-
|
|
7916
|
-
|
|
7917
|
-
|
|
7918
|
-
|
|
7919
|
-
overflow: "auto",
|
|
7920
|
-
...(leftPaneStyle || {}),
|
|
7921
|
-
}
|
|
7922
|
-
: {
|
|
7923
|
-
height: sizes.left,
|
|
7924
|
-
flex: `0 0 ${sizes.left}`,
|
|
7925
|
-
overflow: "auto",
|
|
7926
|
-
...(leftPaneStyle || {}),
|
|
7927
|
-
};
|
|
7928
|
-
|
|
7929
|
-
const rightPaneComputed =
|
|
7930
|
-
modeResolved === "horizontal"
|
|
7931
|
-
? {
|
|
7932
|
-
width: `calc(${100 - posResolved * 100}% - ${splitterSize}px)`,
|
|
7933
|
-
flex: `1 1 auto`,
|
|
7934
|
-
overflow: "auto",
|
|
7935
|
-
...(rightPaneStyle || {}),
|
|
7936
|
-
}
|
|
7937
|
-
: {
|
|
7938
|
-
height: `calc(${100 - posResolved * 100}% - ${splitterSize}px)`,
|
|
7939
|
-
flex: `1 1 auto`,
|
|
7940
|
-
overflow: "auto",
|
|
7941
|
-
...(rightPaneStyle || {}),
|
|
7942
|
-
};
|
|
7943
|
-
|
|
7944
|
-
const splitterComputed =
|
|
7945
|
-
modeResolved === "horizontal"
|
|
7946
|
-
? {
|
|
7947
|
-
width: `${splitterSize}px`,
|
|
7948
|
-
flex: `0 0 ${splitterSize}px`,
|
|
7949
|
-
cursor: "col-resize",
|
|
7950
|
-
background: "transparent",
|
|
7951
|
-
...(splitterStyle || {}),
|
|
7952
|
-
}
|
|
7953
|
-
: {
|
|
7954
|
-
height: `${splitterSize}px`,
|
|
7955
|
-
flex: `0 0 ${splitterSize}px`,
|
|
7956
|
-
cursor: "row-resize",
|
|
7957
|
-
background: "transparent",
|
|
7958
|
-
...(splitterStyle || {}),
|
|
7959
|
-
};
|
|
7960
|
-
|
|
7961
|
-
const dividerVisualStyle =
|
|
7962
|
-
modeResolved === "horizontal"
|
|
7963
|
-
? {
|
|
7964
|
-
height: "100%",
|
|
7965
|
-
width: "100%",
|
|
7966
|
-
background: "rgba(0,0,0,0.08)",
|
|
7967
|
-
}
|
|
7968
|
-
: {
|
|
7969
|
-
width: "100%",
|
|
7970
|
-
height: "100%",
|
|
7971
|
-
background: "rgba(0,0,0,0.08)",
|
|
7972
|
-
};
|
|
7882
|
+
if (delta !== 0) {
|
|
7883
|
+
e.preventDefault();
|
|
7884
|
+
setPosition(posResolved + delta);
|
|
7885
|
+
}
|
|
7886
|
+
};
|
|
7973
7887
|
|
|
7974
|
-
|
|
7975
|
-
|
|
7976
|
-
|
|
7888
|
+
const sizes = useMemo(() => {
|
|
7889
|
+
const leftPct = `${posResolved * 100}%`;
|
|
7890
|
+
const rightCalc = `calc(${100 - posResolved * 100}% - ${splitterSize}px)`;
|
|
7891
|
+
return { leftPct, rightCalc };
|
|
7892
|
+
}, [posResolved, splitterSize]);
|
|
7893
|
+
|
|
7894
|
+
const rootStyle = {
|
|
7895
|
+
display: "flex",
|
|
7896
|
+
width: "100%",
|
|
7897
|
+
height: "100%",
|
|
7898
|
+
overflow: "hidden",
|
|
7899
|
+
touchAction: "none",
|
|
7900
|
+
...(style || {}),
|
|
7901
|
+
flexDirection: internalMode === "horizontal" ? "row" : "column",
|
|
7902
|
+
};
|
|
7903
|
+
|
|
7904
|
+
const leftPaneComputed =
|
|
7905
|
+
internalMode === "horizontal"
|
|
7906
|
+
? { width: sizes.leftPct, flex: `0 0 ${sizes.leftPct}`, overflow: "auto", ...(leftPaneStyle || {}) }
|
|
7907
|
+
: { height: sizes.leftPct, flex: `0 0 ${sizes.leftPct}`, overflow: "auto", ...(leftPaneStyle || {}) };
|
|
7908
|
+
|
|
7909
|
+
const rightPaneComputed =
|
|
7910
|
+
internalMode === "horizontal"
|
|
7911
|
+
? { width: sizes.rightCalc, flex: "1 1 auto", overflow: "auto", ...(rightPaneStyle || {}) }
|
|
7912
|
+
: { height: sizes.rightCalc, flex: "1 1 auto", overflow: "auto", ...(rightPaneStyle || {}) };
|
|
7913
|
+
|
|
7914
|
+
const splitterComputed =
|
|
7915
|
+
internalMode === "horizontal"
|
|
7916
|
+
? { width: `${splitterSize}px`, height: '100%', flex: `0 0 ${splitterSize}px`, background: "rgba(0,0,0,0.08)", cursor: "col-resize", ...(splitterStyle || {}) }
|
|
7917
|
+
: { height: `${splitterSize}px`, width: '100%', flex: `0 0 ${splitterSize}px`, background: "rgba(0,0,0,0.08)", cursor: "row-resize", ...(splitterStyle || {}) };
|
|
7918
|
+
|
|
7919
|
+
const dividerVisualStyle =
|
|
7920
|
+
internalMode === "horizontal"
|
|
7921
|
+
? { height: "100%", width: "100%" }
|
|
7922
|
+
: { width: "100%", height: "100%" };
|
|
7923
|
+
|
|
7924
|
+
useImperativeHandle(ref, () => ({
|
|
7925
|
+
setPosition,
|
|
7926
|
+
setMode: (nextMode) => setInternalMode(nextMode === "vertical" ? "vertical" : "horizontal"),
|
|
7927
|
+
getPosition: () => posResolved,
|
|
7928
|
+
getMode: () => internalMode,
|
|
7929
|
+
}));
|
|
7930
|
+
|
|
7931
|
+
return (
|
|
7932
|
+
Lilact.createComponent( "div", { "ref": containerRef, "className": className, "style": rootStyle }, Lilact.createComponent( "div", { "style": leftPaneComputed }, leftChild ), Lilact.createComponent( "div", { "role": "separator", "aria-orientation": internalMode === "horizontal" ? "vertical" : "horizontal", "aria-valuemin": min, "aria-valuemax": max, "aria-valuenow": posResolved, "tabIndex": 0, "onPointerDown": onPointerDown, "onPointerCancel": () => {
|
|
7933
|
+
draggingRef.current = false;
|
|
7934
|
+
pointerIdRef.current = null;
|
|
7935
|
+
}, "onKeyDown": onKeyDown, "style": splitterComputed }, Lilact.createComponent( "div", { "style": dividerVisualStyle } ) ), Lilact.createComponent( "div", { "style": rightPaneComputed }, rightChild ) )
|
|
7936
|
+
);
|
|
7977
7937
|
});
|
|
7978
7938
|
|
|
7979
7939
|
|