@jsenv/navi 0.16.51 → 0.16.52
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 +64 -49
- package/dist/jsenv_navi.js.map +6 -4
- package/package.json +1 -1
package/dist/jsenv_navi.js
CHANGED
|
@@ -4570,54 +4570,6 @@ const isProps = (value) => {
|
|
|
4570
4570
|
return value !== null && typeof value === "object";
|
|
4571
4571
|
};
|
|
4572
4572
|
|
|
4573
|
-
/**
|
|
4574
|
-
* Creates a signal that stays synchronized with an external value,
|
|
4575
|
-
* only updating the signal when the value actually changes.
|
|
4576
|
-
*
|
|
4577
|
-
* This hook solves a common reactive UI pattern where:
|
|
4578
|
-
* 1. A signal controls a UI element (like an input field)
|
|
4579
|
-
* 2. The UI element can be modified by user interaction
|
|
4580
|
-
* 3. When the external "source of truth" changes, it should take precedence
|
|
4581
|
-
*
|
|
4582
|
-
* @param {any} value - The external value to sync with (the "source of truth")
|
|
4583
|
-
* @param {any} [initialValue] - Optional initial value for the signal (defaults to value)
|
|
4584
|
-
* @returns {Signal} A signal that tracks the external value but allows temporary local changes
|
|
4585
|
-
*
|
|
4586
|
-
* @example
|
|
4587
|
-
* const FileNameEditor = ({ file }) => {
|
|
4588
|
-
* // Signal stays in sync with file.name, but allows user editing
|
|
4589
|
-
* const nameSignal = useSignalSync(file.name);
|
|
4590
|
-
*
|
|
4591
|
-
* return (
|
|
4592
|
-
* <Editable
|
|
4593
|
-
* valueSignal={nameSignal} // User can edit this
|
|
4594
|
-
* action={renameFileAction} // Saves changes
|
|
4595
|
-
* />
|
|
4596
|
-
* );
|
|
4597
|
-
* };
|
|
4598
|
-
*
|
|
4599
|
-
* // Scenario:
|
|
4600
|
-
* // 1. file.name = "doc.txt", nameSignal.value = "doc.txt"
|
|
4601
|
-
* // 2. User types "report" -> nameSignal.value = "report.txt"
|
|
4602
|
-
* // 3. External update: file.name = "shared-doc.txt"
|
|
4603
|
-
* // 4. Next render: nameSignal.value = "shared-doc.txt" (model wins!)
|
|
4604
|
-
*
|
|
4605
|
-
*/
|
|
4606
|
-
|
|
4607
|
-
const useSignalSync = (value, initialValue = value) => {
|
|
4608
|
-
const signal = useSignal(initialValue);
|
|
4609
|
-
const previousValueRef = useRef(value);
|
|
4610
|
-
|
|
4611
|
-
// Only update signal when external value actually changes
|
|
4612
|
-
// This preserves user input between external changes
|
|
4613
|
-
if (previousValueRef.current !== value) {
|
|
4614
|
-
previousValueRef.current = value;
|
|
4615
|
-
signal.value = value; // Model takes precedence
|
|
4616
|
-
}
|
|
4617
|
-
|
|
4618
|
-
return signal;
|
|
4619
|
-
};
|
|
4620
|
-
|
|
4621
4573
|
const addIntoArray = (array, ...valuesToAdd) => {
|
|
4622
4574
|
if (valuesToAdd.length === 1) {
|
|
4623
4575
|
const [valueToAdd] = valuesToAdd;
|
|
@@ -4680,6 +4632,69 @@ const removeFromArray = (array, ...valuesToRemove) => {
|
|
|
4680
4632
|
return hasRemovedValues ? arrayWithoutTheseValues : array;
|
|
4681
4633
|
};
|
|
4682
4634
|
|
|
4635
|
+
const useArraySignalMembership = (arraySignal, id) => {
|
|
4636
|
+
const array = arraySignal.value;
|
|
4637
|
+
const found = array.includes(id);
|
|
4638
|
+
return [
|
|
4639
|
+
found,
|
|
4640
|
+
(enabled) => {
|
|
4641
|
+
if (enabled) {
|
|
4642
|
+
arraySignal.value = addIntoArray(array, id);
|
|
4643
|
+
} else {
|
|
4644
|
+
arraySignal.value = removeFromArray(array, id);
|
|
4645
|
+
}
|
|
4646
|
+
},
|
|
4647
|
+
];
|
|
4648
|
+
};
|
|
4649
|
+
|
|
4650
|
+
/**
|
|
4651
|
+
* Creates a signal that stays synchronized with an external value,
|
|
4652
|
+
* only updating the signal when the value actually changes.
|
|
4653
|
+
*
|
|
4654
|
+
* This hook solves a common reactive UI pattern where:
|
|
4655
|
+
* 1. A signal controls a UI element (like an input field)
|
|
4656
|
+
* 2. The UI element can be modified by user interaction
|
|
4657
|
+
* 3. When the external "source of truth" changes, it should take precedence
|
|
4658
|
+
*
|
|
4659
|
+
* @param {any} value - The external value to sync with (the "source of truth")
|
|
4660
|
+
* @param {any} [initialValue] - Optional initial value for the signal (defaults to value)
|
|
4661
|
+
* @returns {Signal} A signal that tracks the external value but allows temporary local changes
|
|
4662
|
+
*
|
|
4663
|
+
* @example
|
|
4664
|
+
* const FileNameEditor = ({ file }) => {
|
|
4665
|
+
* // Signal stays in sync with file.name, but allows user editing
|
|
4666
|
+
* const nameSignal = useSignalSync(file.name);
|
|
4667
|
+
*
|
|
4668
|
+
* return (
|
|
4669
|
+
* <Editable
|
|
4670
|
+
* valueSignal={nameSignal} // User can edit this
|
|
4671
|
+
* action={renameFileAction} // Saves changes
|
|
4672
|
+
* />
|
|
4673
|
+
* );
|
|
4674
|
+
* };
|
|
4675
|
+
*
|
|
4676
|
+
* // Scenario:
|
|
4677
|
+
* // 1. file.name = "doc.txt", nameSignal.value = "doc.txt"
|
|
4678
|
+
* // 2. User types "report" -> nameSignal.value = "report.txt"
|
|
4679
|
+
* // 3. External update: file.name = "shared-doc.txt"
|
|
4680
|
+
* // 4. Next render: nameSignal.value = "shared-doc.txt" (model wins!)
|
|
4681
|
+
*
|
|
4682
|
+
*/
|
|
4683
|
+
|
|
4684
|
+
const useSignalSync = (value, initialValue = value) => {
|
|
4685
|
+
const signal = useSignal(initialValue);
|
|
4686
|
+
const previousValueRef = useRef(value);
|
|
4687
|
+
|
|
4688
|
+
// Only update signal when external value actually changes
|
|
4689
|
+
// This preserves user input between external changes
|
|
4690
|
+
if (previousValueRef.current !== value) {
|
|
4691
|
+
previousValueRef.current = value;
|
|
4692
|
+
signal.value = value; // Model takes precedence
|
|
4693
|
+
}
|
|
4694
|
+
|
|
4695
|
+
return signal;
|
|
4696
|
+
};
|
|
4697
|
+
|
|
4683
4698
|
/**
|
|
4684
4699
|
* Picks the best initial value from three options using a simple priority system.
|
|
4685
4700
|
*
|
|
@@ -28509,5 +28524,5 @@ const UserSvg = () => jsx("svg", {
|
|
|
28509
28524
|
})
|
|
28510
28525
|
});
|
|
28511
28526
|
|
|
28512
|
-
export { ActionRenderer, ActiveKeyboardShortcuts, Address, BadgeCount, Box, Button, ButtonCopyToClipboard, Caption, CheckSvg, Checkbox, CheckboxList, Code, Col, Colgroup, ConstructionSvg, Details, DialogLayout, Editable, ErrorBoundaryContext, ExclamationSvg, EyeClosedSvg, EyeSvg, Form, Group, HeartSvg, HomeSvg, Icon, Image, Input, Label, Link, LinkAnchorSvg, LinkBlankTargetSvg, MessageBox, Paragraph, Radio, RadioList, Route, RouteLink, Routes, RowNumberCol, RowNumberTableCell, SINGLE_SPACE_CONSTRAINT, SVGMaskOverlay, SearchSvg, Select, SelectionContext, Separator, SettingsSvg, StarSvg, SummaryMarker, Svg, Tab, TabList, Table, TableCell, Tbody, Text, Thead, Title, Tr, UITransition, UserSvg, ViewportLayout, actionIntegratedVia, addCustomMessage, clearAllRoutes, compareTwoJsValues, createAction, createAvailableConstraint, createRequestCanceller, createSelectionKeyboardShortcuts, enableDebugActions, enableDebugOnDocumentLoading, forwardActionRequested, installCustomConstraintValidation, isCellSelected, isColumnSelected, isRowSelected, localStorageSignal, navBack, navForward, navTo, openCallout, rawUrlPart, reload, removeCustomMessage, requestAction, rerunActions, resource, setBaseUrl, setupRoutes, stateSignal, stopLoad, stringifyTableSelectionValue, updateActions, useActionData, useActionStatus, useCalloutClose, useCellsAndColumns, useConstraintValidityState, useDependenciesDiff, useDocumentResource, useDocumentState, useDocumentUrl, useEditionController, useFocusGroup, useKeyboardShortcuts, useMatchingRouteInfo, useNavState$1 as useNavState, useRouteStatus, useRunOnMount, useSelectableElement, useSelectionController, useSignalSync, useStateArray, useTitleLevel, useUrlSearchParam, valueInLocalStorage };
|
|
28527
|
+
export { ActionRenderer, ActiveKeyboardShortcuts, Address, BadgeCount, Box, Button, ButtonCopyToClipboard, Caption, CheckSvg, Checkbox, CheckboxList, Code, Col, Colgroup, ConstructionSvg, Details, DialogLayout, Editable, ErrorBoundaryContext, ExclamationSvg, EyeClosedSvg, EyeSvg, Form, Group, HeartSvg, HomeSvg, Icon, Image, Input, Label, Link, LinkAnchorSvg, LinkBlankTargetSvg, MessageBox, Paragraph, Radio, RadioList, Route, RouteLink, Routes, RowNumberCol, RowNumberTableCell, SINGLE_SPACE_CONSTRAINT, SVGMaskOverlay, SearchSvg, Select, SelectionContext, Separator, SettingsSvg, StarSvg, SummaryMarker, Svg, Tab, TabList, Table, TableCell, Tbody, Text, Thead, Title, Tr, UITransition, UserSvg, ViewportLayout, actionIntegratedVia, addCustomMessage, clearAllRoutes, compareTwoJsValues, createAction, createAvailableConstraint, createRequestCanceller, createSelectionKeyboardShortcuts, enableDebugActions, enableDebugOnDocumentLoading, forwardActionRequested, installCustomConstraintValidation, isCellSelected, isColumnSelected, isRowSelected, localStorageSignal, navBack, navForward, navTo, openCallout, rawUrlPart, reload, removeCustomMessage, requestAction, rerunActions, resource, setBaseUrl, setupRoutes, stateSignal, stopLoad, stringifyTableSelectionValue, updateActions, useActionData, useActionStatus, useArraySignalMembership, useCalloutClose, useCellsAndColumns, useConstraintValidityState, useDependenciesDiff, useDocumentResource, useDocumentState, useDocumentUrl, useEditionController, useFocusGroup, useKeyboardShortcuts, useMatchingRouteInfo, useNavState$1 as useNavState, useRouteStatus, useRunOnMount, useSelectableElement, useSelectionController, useSignalSync, useStateArray, useTitleLevel, useUrlSearchParam, valueInLocalStorage };
|
|
28513
28528
|
//# sourceMappingURL=jsenv_navi.js.map
|