@jsenv/navi 0.29.443 → 0.29.444
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/dev/jsenv_navi.js +57 -16
- package/dist/dev/jsenv_navi.js.map +6 -6
- package/dist/jsenv_navi.js +45 -15
- package/dist/jsenv_navi.js.map +6 -6
- package/docs/AI_INSTRUCTIONS.md +6 -4
- package/docs/actions.md +6 -2
- package/docs/control_value.md +28 -8
- package/package.json +1 -1
package/dist/jsenv_navi.js
CHANGED
|
@@ -6281,6 +6281,10 @@ const CONTROL_PROP_SET = new Set([
|
|
|
6281
6281
|
"charGuard",
|
|
6282
6282
|
"maxLengthGuard",
|
|
6283
6283
|
|
|
6284
|
+
// A checkbox that is a yes/no: `true` checked, `false` unchecked, instead of
|
|
6285
|
+
// HTML's value-or-nothing (see resolveEmptyUIState).
|
|
6286
|
+
"boolean",
|
|
6287
|
+
|
|
6284
6288
|
// This control answers for itself: it registers into no group, no form and no
|
|
6285
6289
|
// picker around it (see useUIStateController). It belongs here rather than
|
|
6286
6290
|
// being deleted off `props` where it is read: props is the vnode's own object
|
|
@@ -42149,6 +42153,14 @@ const useUIStateController = (
|
|
|
42149
42153
|
return ownUIState || parentUIState;
|
|
42150
42154
|
})
|
|
42151
42155
|
: ownUIStateSignal;
|
|
42156
|
+
// What the control is worth, which its action is bound to: what it
|
|
42157
|
+
// holds, or its own empty when it holds nothing. Apart from
|
|
42158
|
+
// uiStateSignal because unchecked is `undefined` there (the DOM reads any
|
|
42159
|
+
// other value as checked), while a yes/no unchecked is worth `false`.
|
|
42160
|
+
const emptyUIStateSignal = signal(emptyUIState);
|
|
42161
|
+
const valueSignal = computed(() =>
|
|
42162
|
+
uiStateOrEmpty(uiStateSignal.value, emptyUIStateSignal.value),
|
|
42163
|
+
);
|
|
42152
42164
|
|
|
42153
42165
|
// The two-way half of a bound `signal` prop: setting it re-renders and
|
|
42154
42166
|
// re-syncs via state_prop_change, but with the same value → guarded as a
|
|
@@ -42197,6 +42209,7 @@ const useUIStateController = (
|
|
|
42197
42209
|
// travel command ended up carrying a picker's selection: see
|
|
42198
42210
|
// resolveCommandValue in commands.js.
|
|
42199
42211
|
ownUIStateSignal,
|
|
42212
|
+
valueSignal,
|
|
42200
42213
|
value: controlInfo.value,
|
|
42201
42214
|
// The suggestion this control started on — what tells a field showing
|
|
42202
42215
|
// its default from one carrying an answer (see isUIStateHeld).
|
|
@@ -42256,7 +42269,11 @@ const useUIStateController = (
|
|
|
42256
42269
|
}
|
|
42257
42270
|
s.uiActionInternal?.(currentUIState, e);
|
|
42258
42271
|
if (s.uiAction) {
|
|
42259
|
-
|
|
42272
|
+
const value = uiStateOrEmpty(
|
|
42273
|
+
currentUIState,
|
|
42274
|
+
controller.emptyUIState,
|
|
42275
|
+
);
|
|
42276
|
+
s.uiAction(value, e);
|
|
42260
42277
|
}
|
|
42261
42278
|
if (skipCommand) ; else {
|
|
42262
42279
|
const command = controller.controlHostProps.command;
|
|
@@ -42743,6 +42760,7 @@ const useUIStateController = (
|
|
|
42743
42760
|
return {
|
|
42744
42761
|
controller,
|
|
42745
42762
|
parentUiStateSignalHolder,
|
|
42763
|
+
emptyUIStateSignal,
|
|
42746
42764
|
...liveValues(),
|
|
42747
42765
|
};
|
|
42748
42766
|
},
|
|
@@ -42864,6 +42882,7 @@ const useUIStateController = (
|
|
|
42864
42882
|
);
|
|
42865
42883
|
scope.parentUiStateSignalHolder.value =
|
|
42866
42884
|
parentUIStateController?.uiStateSignal ?? null;
|
|
42885
|
+
scope.emptyUIStateSignal.value = emptyUIState;
|
|
42867
42886
|
|
|
42868
42887
|
const { controller } = scope;
|
|
42869
42888
|
const controllerRef = controller.ref;
|
|
@@ -43074,14 +43093,11 @@ const keptAndNamedChildUIStates = (children, fallbackState, kept) => {
|
|
|
43074
43093
|
const readNamedChildUIStates = (children, { warnNameless }) => {
|
|
43075
43094
|
const values = {};
|
|
43076
43095
|
for (const child of children) {
|
|
43077
|
-
const { name
|
|
43096
|
+
const { name } = child;
|
|
43078
43097
|
// A control holding nothing writes its own empty, not a hole: the key is in
|
|
43079
43098
|
// the object either way, and what is read from it keeps the shape the
|
|
43080
43099
|
// reader was promised (see resolveEmptyUIState).
|
|
43081
|
-
const uiState =
|
|
43082
|
-
child.uiState === undefined && emptyUIState !== undefined
|
|
43083
|
-
? emptyUIState
|
|
43084
|
-
: child.uiState;
|
|
43100
|
+
const uiState = uiStateOrEmpty(child.uiState, child.emptyUIState);
|
|
43085
43101
|
if (!name) {
|
|
43086
43102
|
if (isNamelessGrouping(child, uiState)) {
|
|
43087
43103
|
Object.assign(
|
|
@@ -44413,11 +44429,10 @@ const useUIFacadeStateController = (props, realUIStateController) => {
|
|
|
44413
44429
|
// whose last item was unselected holds [], the same thing clearing it
|
|
44414
44430
|
// leaves — not a value that changes type on its owner the moment it
|
|
44415
44431
|
// empties.
|
|
44416
|
-
const
|
|
44417
|
-
|
|
44418
|
-
|
|
44419
|
-
|
|
44420
|
-
: child.uiState;
|
|
44432
|
+
const uiStateToAdopt = uiStateOrEmpty(
|
|
44433
|
+
child.uiState,
|
|
44434
|
+
s.realUIStateController.emptyUIState,
|
|
44435
|
+
);
|
|
44421
44436
|
s.realUIStateController.setUIState(uiStateToAdopt, propagateUpEvent);
|
|
44422
44437
|
updatingRef.current = false;
|
|
44423
44438
|
},
|
|
@@ -44657,8 +44672,9 @@ const resolveEmptyUIState = (props, controlType) => {
|
|
|
44657
44672
|
if (controlType === "input" && props.type === "checkbox") {
|
|
44658
44673
|
// A checkbox is a member of a set, the way HTML has it: checked it sends
|
|
44659
44674
|
// its value ("on" by default), unchecked it sends nothing at all. Only one
|
|
44660
|
-
//
|
|
44661
|
-
|
|
44675
|
+
// declared `boolean` is a yes/no, and a yes/no nobody said yes to is
|
|
44676
|
+
// `false`.
|
|
44677
|
+
return props.boolean ? false : undefined;
|
|
44662
44678
|
}
|
|
44663
44679
|
const stateShape = props["navi-state-shape"];
|
|
44664
44680
|
if (stateShape === "array") {
|
|
@@ -44670,6 +44686,15 @@ const resolveEmptyUIState = (props, controlType) => {
|
|
|
44670
44686
|
return undefined;
|
|
44671
44687
|
};
|
|
44672
44688
|
|
|
44689
|
+
// What a control holding `uiState` is worth: its own empty when it holds
|
|
44690
|
+
// nothing, so the reader gets the shape it was promised.
|
|
44691
|
+
const uiStateOrEmpty = (uiState, emptyUIState) => {
|
|
44692
|
+
if (uiState === undefined && emptyUIState !== undefined) {
|
|
44693
|
+
return emptyUIState;
|
|
44694
|
+
}
|
|
44695
|
+
return uiState;
|
|
44696
|
+
};
|
|
44697
|
+
|
|
44673
44698
|
// What a cleared control shows: its own empty, kept in the shape it was holding.
|
|
44674
44699
|
const resolveClearedUIState = (controller) => {
|
|
44675
44700
|
const { controlType, props } = controller;
|
|
@@ -44904,7 +44929,7 @@ const useControlProps = (props, {
|
|
|
44904
44929
|
// of a form would re-render at each change of any of its fields.
|
|
44905
44930
|
// eslint-disable-next-line no-unused-expressions
|
|
44906
44931
|
uiStateController.ownUIStateSignal.value;
|
|
44907
|
-
const boundAction = useAction(props.action, uiStateController.
|
|
44932
|
+
const boundAction = useAction(props.action, uiStateController.valueSignal);
|
|
44908
44933
|
const [controlRootProps, controlHostProps] = useInteractiveProps(props, {
|
|
44909
44934
|
uiStateController,
|
|
44910
44935
|
boundAction,
|
|
@@ -56981,7 +57006,12 @@ const css$M = /* css */`@layer navi {
|
|
|
56981
57006
|
const InputCheckbox = props => {
|
|
56982
57007
|
const defaultRef = useRef();
|
|
56983
57008
|
props.ref = props.ref || defaultRef;
|
|
56984
|
-
|
|
57009
|
+
useRef(false);
|
|
57010
|
+
if (props.boolean) {
|
|
57011
|
+
props.value = true;
|
|
57012
|
+
} else if (props.value === undefined) {
|
|
57013
|
+
props.value = "on";
|
|
57014
|
+
}
|
|
56985
57015
|
if (props.headless) {
|
|
56986
57016
|
return jsx(InputCheckboxHeadless, {
|
|
56987
57017
|
...props,
|