@jsenv/navi 0.27.51 → 0.27.53
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/jsenv_navi.js +166 -166
- package/dist/jsenv_navi.js.map +22 -18
- package/package.json +1 -1
package/dist/jsenv_navi.js
CHANGED
|
@@ -22459,7 +22459,7 @@ const useUIStateController = (
|
|
|
22459
22459
|
const currentUIState = uiStateController.uiState;
|
|
22460
22460
|
const stateIsTheSame = compareTwoJsValues(newUIState, currentUIState);
|
|
22461
22461
|
if (stateIsTheSame) {
|
|
22462
|
-
if (controlType === "button") {
|
|
22462
|
+
if (controlType === "button" || controlType === "link") {
|
|
22463
22463
|
if (!isInternalEvent(e)) {
|
|
22464
22464
|
uiStateController.onUIAction(e);
|
|
22465
22465
|
}
|
|
@@ -23071,6 +23071,9 @@ const useUIGroupStateController = (
|
|
|
23071
23071
|
if (childUIStateController.controlType === "button") {
|
|
23072
23072
|
return false;
|
|
23073
23073
|
}
|
|
23074
|
+
if (childUIStateController.controlType === "link") {
|
|
23075
|
+
return false;
|
|
23076
|
+
}
|
|
23074
23077
|
return true;
|
|
23075
23078
|
};
|
|
23076
23079
|
|
|
@@ -23367,6 +23370,9 @@ const useUIGroupStateController = (
|
|
|
23367
23370
|
if (childUIStateController.controlType === "button") {
|
|
23368
23371
|
continue;
|
|
23369
23372
|
}
|
|
23373
|
+
if (childUIStateController.controlType === "link") {
|
|
23374
|
+
continue;
|
|
23375
|
+
}
|
|
23370
23376
|
childUIStateController.clearUIState(propagateDownClearEvent);
|
|
23371
23377
|
}
|
|
23372
23378
|
onChange(e, { notifyExternal: true });
|
|
@@ -23465,6 +23471,9 @@ const useUIFacadeStateController = (props, realUIStateController) => {
|
|
|
23465
23471
|
if (childController.controlType === "button") {
|
|
23466
23472
|
return false;
|
|
23467
23473
|
}
|
|
23474
|
+
if (childController.controlType === "link") {
|
|
23475
|
+
return false;
|
|
23476
|
+
}
|
|
23468
23477
|
if (childController.controlType === "facade") {
|
|
23469
23478
|
return false;
|
|
23470
23479
|
}
|
|
@@ -32091,8 +32100,12 @@ const getNowHoursRoundedToStep = (stepMinutes, offsetMinutes = 0) => {
|
|
|
32091
32100
|
return `${String(h).padStart(2, "0")}:${String(m).padStart(2, "0")}`;
|
|
32092
32101
|
};
|
|
32093
32102
|
|
|
32094
|
-
// Maps validity type names → navi input type names
|
|
32103
|
+
// Maps validity type names → navi input type names.
|
|
32104
|
+
// Numeric signal types must not fall through to the native type="number"
|
|
32105
|
+
// (which adds spinner buttons and has poor UX) — they map to navi_number instead.
|
|
32095
32106
|
const VALIDITY_TYPE_TO_INPUT_TYPE = {
|
|
32107
|
+
number: "navi_number",
|
|
32108
|
+
integer: "navi_number",
|
|
32096
32109
|
percentage: "navi_percentage",
|
|
32097
32110
|
};
|
|
32098
32111
|
|
|
@@ -35497,7 +35510,7 @@ const Dialog = props => {
|
|
|
35497
35510
|
focusedBeforeOpen
|
|
35498
35511
|
});
|
|
35499
35512
|
};
|
|
35500
|
-
const close = e => {
|
|
35513
|
+
const close = (e, detail = {}) => {
|
|
35501
35514
|
debugPopup(`"${e.type}" on ${getElementSignature(e.target)} -> closeDialog`);
|
|
35502
35515
|
const dialogEl = ref.current;
|
|
35503
35516
|
markAutofocusRestoreOnClose(dialogEl);
|
|
@@ -35505,7 +35518,8 @@ const Dialog = props => {
|
|
|
35505
35518
|
cleanup();
|
|
35506
35519
|
openedRef.current = false;
|
|
35507
35520
|
dispatchCustomEvent(dialogEl, "navi_close", {
|
|
35508
|
-
event: e
|
|
35521
|
+
event: e,
|
|
35522
|
+
...detail
|
|
35509
35523
|
});
|
|
35510
35524
|
};
|
|
35511
35525
|
const onRequestOpen = (e, {
|
|
@@ -35522,7 +35536,7 @@ const Dialog = props => {
|
|
|
35522
35536
|
anchor
|
|
35523
35537
|
});
|
|
35524
35538
|
};
|
|
35525
|
-
const onRequestClose = e => {
|
|
35539
|
+
const onRequestClose = (e, detail = {}) => {
|
|
35526
35540
|
const dialogEl = ref.current;
|
|
35527
35541
|
if (!dialogEl) {
|
|
35528
35542
|
return;
|
|
@@ -35540,15 +35554,15 @@ const Dialog = props => {
|
|
|
35540
35554
|
denied = false;
|
|
35541
35555
|
}
|
|
35542
35556
|
};
|
|
35543
|
-
closeRequestHandler(e, closePermission);
|
|
35557
|
+
closeRequestHandler(e, closePermission, detail);
|
|
35544
35558
|
if (denied) {
|
|
35545
35559
|
closePermission.allow = () => {
|
|
35546
|
-
close(e);
|
|
35560
|
+
close(e, detail);
|
|
35547
35561
|
};
|
|
35548
35562
|
return;
|
|
35549
35563
|
}
|
|
35550
35564
|
}
|
|
35551
|
-
close(e);
|
|
35565
|
+
close(e, detail);
|
|
35552
35566
|
};
|
|
35553
35567
|
return jsx(Box, {
|
|
35554
35568
|
...rest,
|
|
@@ -35562,7 +35576,9 @@ const Dialog = props => {
|
|
|
35562
35576
|
// The <dialog> element covers the full viewport; clicking the backdrop
|
|
35563
35577
|
// hits the dialog itself (not any child). Close when that happens.
|
|
35564
35578
|
if (!pointerTrap && e.button === 0 && e.target === ref.current) {
|
|
35565
|
-
onRequestClose(e
|
|
35579
|
+
onRequestClose(e, {
|
|
35580
|
+
isClickOutside: true
|
|
35581
|
+
});
|
|
35566
35582
|
}
|
|
35567
35583
|
},
|
|
35568
35584
|
onCancel: e => {
|
|
@@ -35722,7 +35738,7 @@ const Popover = props => {
|
|
|
35722
35738
|
focusedBeforeOpen
|
|
35723
35739
|
});
|
|
35724
35740
|
};
|
|
35725
|
-
const close = e => {
|
|
35741
|
+
const close = (e, detail = {}) => {
|
|
35726
35742
|
debugPopup(e, `closePopover()`);
|
|
35727
35743
|
const popoverEl = ref.current;
|
|
35728
35744
|
markAutofocusRestoreOnClose(popoverEl);
|
|
@@ -35731,7 +35747,8 @@ const Popover = props => {
|
|
|
35731
35747
|
openedRef.current = false;
|
|
35732
35748
|
setOpened(false);
|
|
35733
35749
|
dispatchCustomEvent(popoverEl, "navi_close", {
|
|
35734
|
-
event: e
|
|
35750
|
+
event: e,
|
|
35751
|
+
...detail
|
|
35735
35752
|
});
|
|
35736
35753
|
};
|
|
35737
35754
|
const onRequestOpen = (e, {
|
|
@@ -35748,7 +35765,7 @@ const Popover = props => {
|
|
|
35748
35765
|
anchor
|
|
35749
35766
|
});
|
|
35750
35767
|
};
|
|
35751
|
-
const onRequestClose = e => {
|
|
35768
|
+
const onRequestClose = (e, detail = {}) => {
|
|
35752
35769
|
const popoverEl = ref.current;
|
|
35753
35770
|
if (!popoverEl) {
|
|
35754
35771
|
return;
|
|
@@ -35766,15 +35783,15 @@ const Popover = props => {
|
|
|
35766
35783
|
denied = false;
|
|
35767
35784
|
}
|
|
35768
35785
|
};
|
|
35769
|
-
closeRequestHandler(e, closePermission);
|
|
35786
|
+
closeRequestHandler(e, closePermission, detail);
|
|
35770
35787
|
if (denied) {
|
|
35771
35788
|
closePermission.allow = () => {
|
|
35772
|
-
close(e);
|
|
35789
|
+
close(e, detail);
|
|
35773
35790
|
};
|
|
35774
35791
|
return;
|
|
35775
35792
|
}
|
|
35776
35793
|
}
|
|
35777
|
-
close(e);
|
|
35794
|
+
close(e, detail);
|
|
35778
35795
|
};
|
|
35779
35796
|
return jsxs(Box, {
|
|
35780
35797
|
id: id,
|
|
@@ -35806,7 +35823,9 @@ const Popover = props => {
|
|
|
35806
35823
|
e.preventDefault();
|
|
35807
35824
|
return;
|
|
35808
35825
|
}
|
|
35809
|
-
onRequestClose(e
|
|
35826
|
+
onRequestClose(e, {
|
|
35827
|
+
isClickOutside: true
|
|
35828
|
+
});
|
|
35810
35829
|
}
|
|
35811
35830
|
}), children]
|
|
35812
35831
|
});
|
|
@@ -35823,7 +35842,7 @@ installImportMetaCssBuild(import.meta);const css$p = /* css */`
|
|
|
35823
35842
|
min-width: var(--anchor-width, 0px);
|
|
35824
35843
|
max-width: 95vw;
|
|
35825
35844
|
/* max-height covers the placeholder + list; the list scrolls internally */
|
|
35826
|
-
max-height: var(--space-available, 95dvh);
|
|
35845
|
+
max-height: min(var(--picker-popup-max-height, 300px), var(--space-available, 95dvh));
|
|
35827
35846
|
margin: 0;
|
|
35828
35847
|
padding: 0;
|
|
35829
35848
|
background: var(--picker-background-color);
|
|
@@ -35915,8 +35934,12 @@ installImportMetaCssBuild(import.meta);const css$p = /* css */`
|
|
|
35915
35934
|
/* dialog */
|
|
35916
35935
|
&[aria-haspopup="dialog"] {
|
|
35917
35936
|
.navi_picker_dialog {
|
|
35937
|
+
--dialog-max-width: 95dvw;
|
|
35938
|
+
--dialog-max-height: 95dvh;
|
|
35939
|
+
|
|
35918
35940
|
min-width: var(--anchor-width, 0px);
|
|
35919
|
-
max-
|
|
35941
|
+
max-width: var(--dialog-max-width);
|
|
35942
|
+
max-height: var(--dialog-max-height);
|
|
35920
35943
|
padding: 0;
|
|
35921
35944
|
background: var(--picker-background-color);
|
|
35922
35945
|
border: var(--picker-border-width) solid var(--x-picker-border-color);
|
|
@@ -35930,6 +35953,13 @@ installImportMetaCssBuild(import.meta);const css$p = /* css */`
|
|
|
35930
35953
|
cursor: default; /* Reset pointer cursor within the select */
|
|
35931
35954
|
/* overscroll-behavior: contain; */
|
|
35932
35955
|
|
|
35956
|
+
&[data-expand-x] {
|
|
35957
|
+
width: var(--dialog-max-width);
|
|
35958
|
+
}
|
|
35959
|
+
&[data-expand-y] {
|
|
35960
|
+
height: var(--dialog-max-height);
|
|
35961
|
+
}
|
|
35962
|
+
|
|
35933
35963
|
&[open] {
|
|
35934
35964
|
display: flex;
|
|
35935
35965
|
flex-direction: column;
|
|
@@ -36071,15 +36101,9 @@ const PickerCustom = props => {
|
|
|
36071
36101
|
expandedRef.current = expanded;
|
|
36072
36102
|
const valueAtOpenRef = useRef(null);
|
|
36073
36103
|
const activeElementAtOpenRef = useRef(null);
|
|
36074
|
-
// Tracks whether a uiAction has occurred since the last close denial.
|
|
36075
|
-
// true = no pending denial (initial state, or user has interacted since)
|
|
36076
|
-
// false = close was denied and user hasn't interacted yet
|
|
36077
|
-
// When false, a second close attempt is treated as cancel.
|
|
36078
|
-
const uiActionSinceDeniedRef = useRef(true);
|
|
36079
36104
|
const onOpen = e => {
|
|
36080
36105
|
expandedRef.current = true;
|
|
36081
36106
|
setExpanded(true);
|
|
36082
|
-
uiActionSinceDeniedRef.current = true;
|
|
36083
36107
|
const focusedBeforeOpen = e.detail.focusedBeforeOpen;
|
|
36084
36108
|
activeElementAtOpenRef.current = focusedBeforeOpen;
|
|
36085
36109
|
debugFocus(e, "picked opened, store element focused", focusedBeforeOpen);
|
|
@@ -36185,44 +36209,29 @@ const PickerCustom = props => {
|
|
|
36185
36209
|
}
|
|
36186
36210
|
});
|
|
36187
36211
|
},
|
|
36188
|
-
// Intercept uiAction to detect user interaction after a close denial.
|
|
36189
36212
|
"uiAction": (v, e) => {
|
|
36190
|
-
uiActionSinceDeniedRef.current = true;
|
|
36191
36213
|
uiActionProp?.(v, e);
|
|
36192
36214
|
},
|
|
36193
36215
|
children
|
|
36194
36216
|
});
|
|
36195
36217
|
Object.assign(popupProps, {
|
|
36196
|
-
closeRequestHandler: (requestCloseEvent, closePermission
|
|
36218
|
+
closeRequestHandler: (requestCloseEvent, closePermission, {
|
|
36219
|
+
isClickOutside
|
|
36220
|
+
} = {}) => {
|
|
36197
36221
|
const cancelEvent = findEvent(requestCloseEvent, eInChain => eInChain.type === "navi_request_close" && eInChain.detail.isCancel);
|
|
36198
|
-
const isCancel = Boolean(cancelEvent);
|
|
36199
|
-
const pickerEl = ref.current;
|
|
36200
|
-
const inputEl = getPickerInput(pickerEl);
|
|
36201
|
-
const valueAtOpen = valueAtOpenRef.current;
|
|
36222
|
+
const isCancel = isClickOutside || Boolean(cancelEvent);
|
|
36202
36223
|
if (isCancel) {
|
|
36203
|
-
|
|
36224
|
+
const pickerEl = ref.current;
|
|
36225
|
+
const inputEl = getPickerInput(pickerEl);
|
|
36226
|
+
const valueAtOpen = valueAtOpenRef.current;
|
|
36227
|
+
debugPopup(requestCloseEvent, `picker cancel, restoring value at open ${JSON.stringify(valueAtOpen)}`);
|
|
36204
36228
|
dispatchRequestSetUIState(inputEl, valueAtOpen, {
|
|
36205
36229
|
event: requestCloseEvent
|
|
36206
36230
|
});
|
|
36207
36231
|
return;
|
|
36208
36232
|
}
|
|
36209
|
-
|
|
36210
|
-
|
|
36211
|
-
// treat this re-attempt as a cancel so they are not trapped.
|
|
36212
|
-
if (!uiActionSinceDeniedRef.current) {
|
|
36213
|
-
debugPopup(requestCloseEvent, `picker close was denied and user did not interact, treating re-attempt as cancel (restoring ${JSON.stringify(valueAtOpen)})`);
|
|
36214
|
-
uiActionSinceDeniedRef.current = true;
|
|
36215
|
-
dispatchRequestSetUIState(inputEl, valueAtOpen, {
|
|
36216
|
-
event: requestCloseEvent
|
|
36217
|
-
});
|
|
36218
|
-
return;
|
|
36219
|
-
}
|
|
36220
|
-
const valueAtClose = getPickerInputUIState(pickerEl);
|
|
36221
|
-
if (compareTwoJsValues(valueAtClose, valueAtOpen)) {
|
|
36222
|
-
debugPopup(requestCloseEvent, `picker closed with same value as when it opened (${JSON.stringify(valueAtClose)}), no action dispatched`);
|
|
36223
|
-
return;
|
|
36224
|
-
}
|
|
36225
|
-
debugPopup(requestCloseEvent, `picker attempt to close with value (${JSON.stringify(valueAtClose)}) wait for picker action to close picker`);
|
|
36233
|
+
const pickerEl = ref.current;
|
|
36234
|
+
const inputEl = getPickerInput(pickerEl);
|
|
36226
36235
|
dispatchRequestAction(inputEl, {
|
|
36227
36236
|
event: requestCloseEvent,
|
|
36228
36237
|
name: "picker close",
|
|
@@ -36233,10 +36242,8 @@ const PickerCustom = props => {
|
|
|
36233
36242
|
// user sees what is wrong, even if the picker has no action prop.
|
|
36234
36243
|
reportOnInvalid: true,
|
|
36235
36244
|
onInvalid: () => {
|
|
36236
|
-
uiActionSinceDeniedRef.current = false;
|
|
36237
36245
|
closePermission.deny();
|
|
36238
|
-
}
|
|
36239
|
-
allowed: () => {}
|
|
36246
|
+
}
|
|
36240
36247
|
});
|
|
36241
36248
|
},
|
|
36242
36249
|
onnavi_open: e => {
|
|
@@ -36318,10 +36325,16 @@ const PickerCustom = props => {
|
|
|
36318
36325
|
Object.assign(pickerProps, {
|
|
36319
36326
|
eventReactionDefinitions: {
|
|
36320
36327
|
mouseDown: e => {
|
|
36328
|
+
const popupEl = popupRef.current;
|
|
36329
|
+
if (popupEl && popupEl.contains(e.target)) {
|
|
36330
|
+
return null;
|
|
36331
|
+
}
|
|
36321
36332
|
if (expandedRef.current) {
|
|
36322
36333
|
return {
|
|
36323
36334
|
name: "mousedown to close picker",
|
|
36324
|
-
allowed: () => requestClose(e
|
|
36335
|
+
allowed: () => requestClose(e, {
|
|
36336
|
+
isCancel: true
|
|
36337
|
+
})
|
|
36325
36338
|
};
|
|
36326
36339
|
}
|
|
36327
36340
|
return {
|
|
@@ -36334,6 +36347,10 @@ const PickerCustom = props => {
|
|
|
36334
36347
|
};
|
|
36335
36348
|
},
|
|
36336
36349
|
click: e => {
|
|
36350
|
+
const popupEl = popupRef.current;
|
|
36351
|
+
if (popupEl && popupEl.contains(e.target)) {
|
|
36352
|
+
return null;
|
|
36353
|
+
}
|
|
36337
36354
|
// When a label is clicked it transfers focus to the select
|
|
36338
36355
|
// in that case we want to open it (otherwise we have already opened on mousedown interaction)
|
|
36339
36356
|
return {
|
|
@@ -36352,40 +36369,6 @@ const PickerCustom = props => {
|
|
|
36352
36369
|
}
|
|
36353
36370
|
}
|
|
36354
36371
|
});
|
|
36355
|
-
Object.assign(popupProps, {
|
|
36356
|
-
onMouseDown: e => {
|
|
36357
|
-
if (e.button !== 0) {
|
|
36358
|
-
return;
|
|
36359
|
-
}
|
|
36360
|
-
// mousedown inside popover should not bubble to the select (would re-open it if that mousedown closes it)
|
|
36361
|
-
debugPopup(e, `"mousedown" received on popup -> prevent bubbling to picker (e.stopPropagation())`);
|
|
36362
|
-
e.stopPropagation();
|
|
36363
|
-
},
|
|
36364
|
-
onClick: e => {
|
|
36365
|
-
if (e.button !== 0) {
|
|
36366
|
-
return;
|
|
36367
|
-
}
|
|
36368
|
-
// click inside popover should not bubble to the picker (would re-open it if that click closes it)
|
|
36369
|
-
debugPopup(e, `"click" received on popup -> prevent bubbling to picker (e.stopPropagation())`);
|
|
36370
|
-
e.stopPropagation();
|
|
36371
|
-
// Here we can't preventDefault because the click might be needed to check a radio for instance.
|
|
36372
|
-
// As a result we have to let it go through which means it could trigger form submission
|
|
36373
|
-
// but we've put type="button" on the picker to ensure it can't submit the form
|
|
36374
|
-
// so browser won't submit eventual form for clicks inside the popover/dialog
|
|
36375
|
-
// e.preventDefault();
|
|
36376
|
-
},
|
|
36377
|
-
onKeyDown: e => {
|
|
36378
|
-
// some keys pressed inside popover should not reach the picker button
|
|
36379
|
-
// (like enter that would try to request action of closest form otherwise for instance)
|
|
36380
|
-
if (e.key === "Enter") {
|
|
36381
|
-
debugPopup(e, `"enter" received on popup -> prevent bubbling to picker (e.stopPropagation())`);
|
|
36382
|
-
e.stopPropagation();
|
|
36383
|
-
// preventDefault prevents the browser from dispatching a "click" on the
|
|
36384
|
-
// picker button when focus moves to it synchronously during enterEffect
|
|
36385
|
-
e.preventDefault();
|
|
36386
|
-
}
|
|
36387
|
-
}
|
|
36388
|
-
});
|
|
36389
36372
|
}
|
|
36390
36373
|
}
|
|
36391
36374
|
if (mode === "popover") {
|
|
@@ -36444,7 +36427,8 @@ const PickerContentInsidePopover = props => {
|
|
|
36444
36427
|
category: "interaction",
|
|
36445
36428
|
allowed: () => {
|
|
36446
36429
|
dispatchCustomEvent(popoverEl, "navi_request_close", {
|
|
36447
|
-
event: e
|
|
36430
|
+
event: e,
|
|
36431
|
+
isCancel: true
|
|
36448
36432
|
});
|
|
36449
36433
|
}
|
|
36450
36434
|
});
|
|
@@ -36470,7 +36454,8 @@ const PickerContentInsidePopover = props => {
|
|
|
36470
36454
|
}
|
|
36471
36455
|
const popupEl = popupProps.ref.current;
|
|
36472
36456
|
dispatchCustomEvent(popupEl, "navi_request_close", {
|
|
36473
|
-
event: e
|
|
36457
|
+
event: e,
|
|
36458
|
+
isCancel: true
|
|
36474
36459
|
});
|
|
36475
36460
|
},
|
|
36476
36461
|
children: props.trigger
|
|
@@ -36485,8 +36470,13 @@ const PickerContentInsideDialog = props => {
|
|
|
36485
36470
|
children,
|
|
36486
36471
|
scrollTrap,
|
|
36487
36472
|
pointerTrap,
|
|
36473
|
+
dialogExpand,
|
|
36474
|
+
dialogExpandX,
|
|
36475
|
+
dialogExpandY,
|
|
36488
36476
|
...rest
|
|
36489
36477
|
} = props;
|
|
36478
|
+
const expandX = dialogExpand || dialogExpandX;
|
|
36479
|
+
const expandY = dialogExpand || dialogExpandY;
|
|
36490
36480
|
return jsx(Next, {
|
|
36491
36481
|
"aria-haspopup": "dialog",
|
|
36492
36482
|
...rest,
|
|
@@ -36497,6 +36487,8 @@ const PickerContentInsideDialog = props => {
|
|
|
36497
36487
|
pointerTrap: pointerTrap,
|
|
36498
36488
|
centerInVisualViewport: true,
|
|
36499
36489
|
autoFocus: "fallback",
|
|
36490
|
+
"data-expand-x": expandX ? "" : undefined,
|
|
36491
|
+
"data-expand-y": expandY ? "" : undefined,
|
|
36500
36492
|
children: children
|
|
36501
36493
|
})
|
|
36502
36494
|
});
|
|
@@ -37613,10 +37605,6 @@ installImportMetaCssBuild(import.meta);const css$n = /* css */`
|
|
|
37613
37605
|
}
|
|
37614
37606
|
}
|
|
37615
37607
|
|
|
37616
|
-
fieldset.navi_list_container[navi-selectable] {
|
|
37617
|
-
margin: 0; /* Reset margin that might come from fieldset */
|
|
37618
|
-
padding: 0; /* Reset padding that might come from fieldset */
|
|
37619
|
-
}
|
|
37620
37608
|
.navi_list_container[navi-selectable] {
|
|
37621
37609
|
&[data-callout] {
|
|
37622
37610
|
--x-list-border-color: var(--callout-color);
|
|
@@ -37860,7 +37848,6 @@ const ListSelectable = props => {
|
|
|
37860
37848
|
setCurrentId(initialEl.id);
|
|
37861
37849
|
}, []);
|
|
37862
37850
|
const listVnode = jsx(Next, {
|
|
37863
|
-
as: "fieldset",
|
|
37864
37851
|
"navi-selectable": "",
|
|
37865
37852
|
"navi-has-selected-background": selectedIndicator === "backgroundColor" ? "" : undefined,
|
|
37866
37853
|
...listControlRootProps,
|
|
@@ -38269,9 +38256,10 @@ installImportMetaCssBuild(import.meta);const ListItemTrackerContext = createCont
|
|
|
38269
38256
|
const GroupItemTrackerContext = createContext(null);
|
|
38270
38257
|
const PendingScrollRefContext = createContext(null);
|
|
38271
38258
|
// Controls how List.Item behaves when match=false (set via List searchNoMatchMode prop):
|
|
38272
|
-
// "remove"
|
|
38259
|
+
// "remove" — remove from DOM (default)
|
|
38273
38260
|
// "invisible_and_inert" — keep in DOM, invisible and non-interactive (preserves layout, no content visible)
|
|
38274
38261
|
// "muted" — keep in DOM, visible but opacified and still interactive
|
|
38262
|
+
// "below" — keep in DOM, fully visible, pushed below matching items via CSS order
|
|
38275
38263
|
const SearchNoMatchModeContext = createContext("remove");
|
|
38276
38264
|
|
|
38277
38265
|
// When total rendered items exceeds renderBudget, a render window [start, end)
|
|
@@ -38298,7 +38286,6 @@ const css$m = /* css */`
|
|
|
38298
38286
|
--list-border-width: 1px;
|
|
38299
38287
|
--list-border-color: light-dark(#ccc, #555);
|
|
38300
38288
|
--list-background-color: light-dark(#fff, #1e1e1e);
|
|
38301
|
-
--list-max-height: 220px;
|
|
38302
38289
|
}
|
|
38303
38290
|
.navi_list_item {
|
|
38304
38291
|
--list-item-padding-x-default: 0px;
|
|
@@ -38369,8 +38356,8 @@ const css$m = /* css */`
|
|
|
38369
38356
|
.navi_list_scroll_container {
|
|
38370
38357
|
width: inherit;
|
|
38371
38358
|
min-width: inherit;
|
|
38372
|
-
max-width: inherit;
|
|
38373
|
-
max-height: var(--list-max-height);
|
|
38359
|
+
max-width: var(--list-max-width, inherit);
|
|
38360
|
+
max-height: var(--list-max-height, inherit);
|
|
38374
38361
|
overflow: auto;
|
|
38375
38362
|
overscroll-behavior: inherit; /* inherit select behavior */
|
|
38376
38363
|
}
|
|
@@ -38378,6 +38365,12 @@ const css$m = /* css */`
|
|
|
38378
38365
|
&[data-expand-x] {
|
|
38379
38366
|
width: 100%;
|
|
38380
38367
|
}
|
|
38368
|
+
&[data-expand-y] {
|
|
38369
|
+
--list-max-height: none;
|
|
38370
|
+
}
|
|
38371
|
+
&[navi-nothing-to-display] {
|
|
38372
|
+
display: none;
|
|
38373
|
+
}
|
|
38381
38374
|
&[popover] {
|
|
38382
38375
|
position: absolute;
|
|
38383
38376
|
inset: unset;
|
|
@@ -38494,6 +38487,8 @@ const css$m = /* css */`
|
|
|
38494
38487
|
/* background: pink; */
|
|
38495
38488
|
}
|
|
38496
38489
|
&[data-horizontal] {
|
|
38490
|
+
--list-max-height: none;
|
|
38491
|
+
|
|
38497
38492
|
.navi_list_virtual_filler {
|
|
38498
38493
|
width: var(--size-to-fill, 0px);
|
|
38499
38494
|
height: 100%;
|
|
@@ -38643,8 +38638,8 @@ const ListUI = props => {
|
|
|
38643
38638
|
children,
|
|
38644
38639
|
popover,
|
|
38645
38640
|
expandX,
|
|
38641
|
+
expandY,
|
|
38646
38642
|
expand,
|
|
38647
|
-
maxHeight,
|
|
38648
38643
|
onListVisibleItemsChange,
|
|
38649
38644
|
virtualItemSize,
|
|
38650
38645
|
lockSize,
|
|
@@ -38709,6 +38704,12 @@ const ListUI = props => {
|
|
|
38709
38704
|
const getItemById = itemId => {
|
|
38710
38705
|
return tracker.itemsSignal.peek().find(item => item.id === itemId);
|
|
38711
38706
|
};
|
|
38707
|
+
const noMatchCount = tracker.noMatchCountSignal.value;
|
|
38708
|
+
const itemCount = tracker.countSignal.value;
|
|
38709
|
+
const allNoMatch = noMatchCount > 0 && noMatchCount === itemCount;
|
|
38710
|
+
const fallbackDisabled = fallback !== undefined && !fallback;
|
|
38711
|
+
const searchFallbackDisabled = searchFallback !== undefined && !searchFallback;
|
|
38712
|
+
const nothingToDisplay = allNoMatch && searchFallbackDisabled && searchNoMatchMode === "remove" || itemCount === 0 && fallbackDisabled;
|
|
38712
38713
|
return jsx(Box, {
|
|
38713
38714
|
...rest,
|
|
38714
38715
|
ref: ref,
|
|
@@ -38716,9 +38717,12 @@ const ListUI = props => {
|
|
|
38716
38717
|
popover: popover,
|
|
38717
38718
|
"data-horizontal": horizontal ? "" : undefined,
|
|
38718
38719
|
"data-expand-x": expandX || expand ? "" : undefined,
|
|
38720
|
+
"data-expand-y": expandY || expand ? "" : undefined,
|
|
38719
38721
|
expandX: expandX,
|
|
38722
|
+
expandY: expandY,
|
|
38720
38723
|
expand: expand,
|
|
38721
|
-
|
|
38724
|
+
"navi-zero-match": allNoMatch ? "" : undefined,
|
|
38725
|
+
"navi-nothing-to-display": nothingToDisplay ? "" : undefined,
|
|
38722
38726
|
styleCSSVars: LIST_STYLE_CSS_VARS,
|
|
38723
38727
|
pseudoClasses: LIST_PSEUDO_CLASSES,
|
|
38724
38728
|
hasChildUsingForwardedProps: true,
|
|
@@ -38743,6 +38747,7 @@ const ListUI = props => {
|
|
|
38743
38747
|
searchNoMatchMode: searchNoMatchMode,
|
|
38744
38748
|
separator: separator,
|
|
38745
38749
|
expandX: expandX,
|
|
38750
|
+
expandY: expandY,
|
|
38746
38751
|
expand: expand,
|
|
38747
38752
|
horizontal: horizontal,
|
|
38748
38753
|
spacing: spacing,
|
|
@@ -38764,41 +38769,32 @@ const ListFirstResolver = props => {
|
|
|
38764
38769
|
...props
|
|
38765
38770
|
});
|
|
38766
38771
|
};
|
|
38772
|
+
|
|
38767
38773
|
/**
|
|
38768
38774
|
* List — generic virtualized scroll container.
|
|
38769
|
-
*
|
|
38770
|
-
*
|
|
38771
|
-
*
|
|
38772
|
-
*
|
|
38773
|
-
*
|
|
38774
|
-
*
|
|
38775
|
-
*
|
|
38776
|
-
*
|
|
38777
|
-
*
|
|
38778
|
-
*
|
|
38779
|
-
*
|
|
38780
|
-
*
|
|
38781
|
-
*
|
|
38782
|
-
*
|
|
38783
|
-
*
|
|
38784
|
-
*
|
|
38785
|
-
*
|
|
38786
|
-
*
|
|
38787
|
-
*
|
|
38788
|
-
*
|
|
38789
|
-
*
|
|
38790
|
-
*
|
|
38791
|
-
*
|
|
38792
|
-
* searchNoMatchMode — controls how List.Item behaves when match=false (default "remove"):
|
|
38793
|
-
* "remove" — remove from DOM
|
|
38794
|
-
* "invisible_and_inert" — keep in DOM, invisible and non-interactive (preserves layout)
|
|
38795
|
-
* "muted" — keep in DOM, visible but opacified and still interactive
|
|
38796
|
-
* separator — element or function(index, { previousItem, currentItem }) inserted between visible items.
|
|
38797
|
-
* lockSize — captures the container's dimensions on first render so filtering
|
|
38798
|
-
* cannot collapse the layout (sets min-width/min-height).
|
|
38799
|
-
* horizontal — lays items out in a row instead of a column.
|
|
38800
|
-
* spacing — gap between items (forwarded to Box spacing prop).
|
|
38801
|
-
* ...rest — forwarded to the outer container <Box>.
|
|
38775
|
+
* Items must use <List.Item> to participate in tracking.
|
|
38776
|
+
*
|
|
38777
|
+
* @type {import("ignore:preact").FunctionComponent<{
|
|
38778
|
+
* selectable?: boolean,
|
|
38779
|
+
* action?: (value: any) => void,
|
|
38780
|
+
* uiAction?: (value: any) => void,
|
|
38781
|
+
* popover?: boolean,
|
|
38782
|
+
* renderBudget?: number,
|
|
38783
|
+
* virtualItemSize?: number,
|
|
38784
|
+
* fallback?: import("ignore:preact").ComponentChildren,
|
|
38785
|
+
* searchFallback?: import("ignore:preact").ComponentChildren,
|
|
38786
|
+
* searchText?: string,
|
|
38787
|
+
* searchNoMatchMode?: "remove" | "invisible_and_inert" | "muted" | "below",
|
|
38788
|
+
* separator?: boolean | import("ignore:preact").ComponentChildren,
|
|
38789
|
+
* lockSize?: boolean,
|
|
38790
|
+
* horizontal?: boolean,
|
|
38791
|
+
* spacing?: string,
|
|
38792
|
+
* expandX?: boolean,
|
|
38793
|
+
* expandY?: boolean,
|
|
38794
|
+
* expand?: boolean,
|
|
38795
|
+
* children?: import("ignore:preact").ComponentChildren,
|
|
38796
|
+
* [key: string]: any,
|
|
38797
|
+
* }>}
|
|
38802
38798
|
*/
|
|
38803
38799
|
const List = createComponentResolver([ListFirstResolver, ListSelectableResolver, ListUI]);
|
|
38804
38800
|
const ListContent = ({
|
|
@@ -38808,6 +38804,7 @@ const ListContent = ({
|
|
|
38808
38804
|
searchNoMatchMode,
|
|
38809
38805
|
separator,
|
|
38810
38806
|
expandX,
|
|
38807
|
+
expandY,
|
|
38811
38808
|
expand,
|
|
38812
38809
|
horizontal,
|
|
38813
38810
|
spacing,
|
|
@@ -38829,6 +38826,7 @@ const ListContent = ({
|
|
|
38829
38826
|
margin: "0"
|
|
38830
38827
|
}) : separator,
|
|
38831
38828
|
expandX: expandX || expand,
|
|
38829
|
+
expandY: expandY || expand,
|
|
38832
38830
|
horizontal: horizontal,
|
|
38833
38831
|
spacing: spacing,
|
|
38834
38832
|
...listProps,
|
|
@@ -38844,6 +38842,7 @@ const ListContent = ({
|
|
|
38844
38842
|
};
|
|
38845
38843
|
const LIST_STYLE_CSS_VARS = {
|
|
38846
38844
|
maxHeight: "--list-max-height",
|
|
38845
|
+
maxWidth: "--list-max-width",
|
|
38847
38846
|
borderColor: "--list-border-color",
|
|
38848
38847
|
borderRadius: "--list-border-radius",
|
|
38849
38848
|
borderWidth: "--list-border-width"
|
|
@@ -39262,7 +39261,6 @@ const UnorderedList = ({
|
|
|
39262
39261
|
return jsxs(Box, {
|
|
39263
39262
|
as: "ul",
|
|
39264
39263
|
flex: horizontal ? "x" : "y",
|
|
39265
|
-
flexWrap: true,
|
|
39266
39264
|
...rest,
|
|
39267
39265
|
spacing: spacing,
|
|
39268
39266
|
baseClassName: "navi_list",
|
|
@@ -40694,38 +40692,6 @@ installImportMetaCssBuild(import.meta);const css$i = /* css */`
|
|
|
40694
40692
|
}
|
|
40695
40693
|
}
|
|
40696
40694
|
`;
|
|
40697
|
-
|
|
40698
|
-
/**
|
|
40699
|
-
* A button-like trigger that opens a picker when clicked.
|
|
40700
|
-
*
|
|
40701
|
-
* Use the `type` prop to choose what kind of picker to open:
|
|
40702
|
-
* "date" — calendar day
|
|
40703
|
-
* "month" — year + month
|
|
40704
|
-
* "week" — ISO week
|
|
40705
|
-
* "time" — hours + minutes
|
|
40706
|
-
* "datetime" — date + time
|
|
40707
|
-
* "color" — color chooser
|
|
40708
|
-
* "hour" — fixed time slots (derived from min/max/step)
|
|
40709
|
-
*
|
|
40710
|
-
* When `children` are provided, the picker opens a popover or dialog instead
|
|
40711
|
-
* of the browser-native picker. On small screens a dialog is used automatically;
|
|
40712
|
-
* on larger screens a popover is used. Pass `mode="dialog"` or `mode="popover"`
|
|
40713
|
-
* to force one. The children are rendered inside the popup.
|
|
40714
|
-
*
|
|
40715
|
-
* Props:
|
|
40716
|
-
* type — picker variant (see above)
|
|
40717
|
-
* value — controlled value
|
|
40718
|
-
* uiAction — called with the new value when the user picks one
|
|
40719
|
-
* name — form field name
|
|
40720
|
-
* placeholder — shown when no value is selected
|
|
40721
|
-
* required — marks the field as required
|
|
40722
|
-
* min — minimum allowed value; accepts a Date or a raw string
|
|
40723
|
-
* max — maximum allowed value; accepts a Date or a raw string
|
|
40724
|
-
* step — step interval
|
|
40725
|
-
* disabled — disables the picker
|
|
40726
|
-
* children — content to display inside the popup (enables popover/dialog mode)
|
|
40727
|
-
* mode — "popover" or "dialog"; auto-detected from screen size when omitted
|
|
40728
|
-
*/
|
|
40729
40695
|
const PickerButton = props => {
|
|
40730
40696
|
import.meta.css = [css$i, "@jsenv/navi/src/control/picker/picker.jsx"];
|
|
40731
40697
|
if (typeof props.maxLines === "string") {
|
|
@@ -40983,6 +40949,40 @@ const PickerFirstResolver = props => {
|
|
|
40983
40949
|
...props
|
|
40984
40950
|
});
|
|
40985
40951
|
};
|
|
40952
|
+
|
|
40953
|
+
/**
|
|
40954
|
+
* Button-like trigger that opens a picker (native or custom popup) when clicked.
|
|
40955
|
+
*
|
|
40956
|
+
* Without `children`, opens the browser-native picker for the given `type`.
|
|
40957
|
+
* With `children`, opens a popover (desktop) or dialog (mobile) containing the children.
|
|
40958
|
+
* Pass `mode="popover"` or `mode="dialog"` to override the automatic choice.
|
|
40959
|
+
*
|
|
40960
|
+
* @type {import("ignore:preact").FunctionComponent<{
|
|
40961
|
+
* type?: "date" | "month" | "week" | "time" | "datetime" | "color" | "hour" | "navi_time" | "navi_number" | "navi_percentage",
|
|
40962
|
+
* value?: any,
|
|
40963
|
+
* defaultValue?: any,
|
|
40964
|
+
* name?: string,
|
|
40965
|
+
* placeholder?: import("ignore:preact").ComponentChildren,
|
|
40966
|
+
* required?: boolean,
|
|
40967
|
+
* min?: Date | string | number,
|
|
40968
|
+
* max?: Date | string | number,
|
|
40969
|
+
* step?: string | number,
|
|
40970
|
+
* disabled?: boolean,
|
|
40971
|
+
* readOnly?: boolean,
|
|
40972
|
+
* uiAction?: (value: any, event: Event) => void,
|
|
40973
|
+
* action?: (value: any, event: Event) => void,
|
|
40974
|
+
* children?: import("ignore:preact").ComponentChildren,
|
|
40975
|
+
* mode?: "popover" | "dialog",
|
|
40976
|
+
* variant?: "icon" | "headless",
|
|
40977
|
+
* icon?: import("ignore:preact").ComponentChildren,
|
|
40978
|
+
* maxLines?: number,
|
|
40979
|
+
* dialogExpand?: boolean,
|
|
40980
|
+
* dialogExpandX?: boolean,
|
|
40981
|
+
* dialogExpandY?: boolean,
|
|
40982
|
+
* ref?: import("ignore:preact").RefObject<HTMLElement>,
|
|
40983
|
+
* [key: string]: any,
|
|
40984
|
+
* }>}
|
|
40985
|
+
*/
|
|
40986
40986
|
const Picker = createComponentResolver([PickerFirstResolver, PickerPresetResolver, PickerCustomResolver, PickerTypeResolver, PickerButton]);
|
|
40987
40987
|
Picker.UI = PickerDefaultUI;
|
|
40988
40988
|
Picker.UI.Date = PickerDateUI;
|