@plaudit/gutenberg-api-extensions 2.79.0 → 2.80.0
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/blocks/MoveError.js +10 -0
- package/dist/blocks/MoveError.js.map +1 -0
- package/{build → dist}/blocks/PathError.js +7 -3
- package/dist/blocks/PathError.js.map +1 -0
- package/{build → dist}/blocks/SNPFlexibleItemsListComponent.d.ts +1 -1
- package/dist/blocks/SNPFlexibleItemsListComponent.js +18 -0
- package/dist/blocks/SNPFlexibleItemsListComponent.js.map +1 -0
- package/{build → dist}/blocks/SNPGroupComponent.d.ts +2 -2
- package/dist/blocks/SNPGroupComponent.js +20 -0
- package/dist/blocks/SNPGroupComponent.js.map +1 -0
- package/{build → dist}/blocks/SNPListComponent.d.ts +1 -1
- package/dist/blocks/SNPListComponent.js +18 -0
- package/dist/blocks/SNPListComponent.js.map +1 -0
- package/dist/blocks/SNPTreeContext.js +14 -0
- package/dist/blocks/SNPTreeContext.js.map +1 -0
- package/dist/blocks/basic-custom-block-bindings-support.js +157 -0
- package/dist/blocks/basic-custom-block-bindings-support.js.map +1 -0
- package/dist/blocks/common-native-property-constructors.d.ts +13 -0
- package/{build → dist}/blocks/common-native-property-constructors.js +105 -151
- package/dist/blocks/common-native-property-constructors.js.map +1 -0
- package/{build → dist}/blocks/conditions.js +12 -7
- package/dist/blocks/conditions.js.map +1 -0
- package/dist/blocks/csnp-api.d.ts +166 -0
- package/dist/blocks/csnp-api.js +74 -0
- package/dist/blocks/csnp-api.js.map +1 -0
- package/{build → dist}/blocks/data-controller-manager.js +4 -1
- package/dist/blocks/data-controller-manager.js.map +1 -0
- package/{build → dist}/blocks/data-controller.js +74 -70
- package/dist/blocks/data-controller.js.map +1 -0
- package/{build → dist}/blocks/hooks/built-in-suspendable-option-protocols/select.js +14 -11
- package/dist/blocks/hooks/built-in-suspendable-option-protocols/select.js.map +1 -0
- package/{build → dist}/blocks/hooks/built-in-suspendable-option-protocols/settings.js +9 -6
- package/dist/blocks/hooks/built-in-suspendable-option-protocols/settings.js.map +1 -0
- package/{build → dist}/blocks/hooks/useSuspendableOptions.d.ts +1 -1
- package/{build → dist}/blocks/hooks/useSuspendableOptions.js +30 -23
- package/dist/blocks/hooks/useSuspendableOptions.js.map +1 -0
- package/dist/blocks/index.js +35 -0
- package/dist/blocks/index.js.map +1 -0
- package/{build → dist}/blocks/layered-styles-api.d.ts +2 -2
- package/{build → dist}/blocks/layered-styles-api.js +10 -6
- package/dist/blocks/layered-styles-api.js.map +1 -0
- package/{build → dist}/blocks/layered-styles-impl.js +14 -9
- package/dist/blocks/layered-styles-impl.js.map +1 -0
- package/{build → dist}/blocks/layout/LaidOutProperty.d.ts +1 -2
- package/dist/blocks/layout/LaidOutProperty.js +47 -0
- package/dist/blocks/layout/LaidOutProperty.js.map +1 -0
- package/dist/blocks/layout/LaidOutPropertyRow.js +15 -0
- package/dist/blocks/layout/LaidOutPropertyRow.js.map +1 -0
- package/{build → dist}/blocks/layout/NodeContext.d.ts +2 -2
- package/dist/blocks/layout/NodeContext.js +44 -0
- package/dist/blocks/layout/NodeContext.js.map +1 -0
- package/dist/blocks/layout/PanelRoot.js +29 -0
- package/dist/blocks/layout/PanelRoot.js.map +1 -0
- package/{build → dist}/blocks/layout/TabsRoot.js +16 -13
- package/dist/blocks/layout/TabsRoot.js.map +1 -0
- package/dist/blocks/layout/ToolsPanelContext.js +23 -0
- package/dist/blocks/layout/ToolsPanelContext.js.map +1 -0
- package/dist/blocks/shared-exportable-types.js +3 -0
- package/dist/blocks/shared-internal-types.js +3 -0
- package/{build → dist}/blocks/simple-block.d.ts +1 -1
- package/dist/blocks/simple-block.js +45 -0
- package/dist/blocks/simple-block.js.map +1 -0
- package/{build → dist}/blocks/simple-native-property-api.d.ts +1 -1
- package/{build → dist}/blocks/simple-native-property-api.js +16 -10
- package/dist/blocks/simple-native-property-api.js.map +1 -0
- package/{build → dist}/blocks/simple-native-property-impl.js +60 -55
- package/dist/blocks/simple-native-property-impl.js.map +1 -0
- package/{build → dist}/blocks/simple-native-property-internal-shared.js +6 -2
- package/dist/blocks/simple-native-property-internal-shared.js.map +1 -0
- package/{build → dist}/blocks/snp-api.d.ts +1 -0
- package/dist/blocks/snp-api.js +7 -0
- package/dist/blocks/snp-api.js.map +1 -0
- package/{build → dist}/blocks/snp-data-store.js +8 -4
- package/dist/blocks/snp-data-store.js.map +1 -0
- package/{build → dist}/blocks/utilities.d.ts +1 -1
- package/dist/blocks/utilities.js +79 -0
- package/dist/blocks/utilities.js.map +1 -0
- package/{build → dist}/controls/AsynchronousFormTokenField.d.ts +1 -1
- package/dist/controls/AsynchronousFormTokenField.js +36 -0
- package/dist/controls/AsynchronousFormTokenField.js.map +1 -0
- package/{build → dist}/controls/BaseSortableItemsControl.d.ts +3 -3
- package/dist/controls/BaseSortableItemsControl.js +25 -0
- package/dist/controls/BaseSortableItemsControl.js.map +1 -0
- package/{build → dist}/controls/ExtendedFormTokenField.d.ts +3 -3
- package/dist/controls/ExtendedFormTokenField.js +64 -0
- package/dist/controls/ExtendedFormTokenField.js.map +1 -0
- package/dist/controls/ExtendedPostPicker.js +28 -0
- package/dist/controls/ExtendedPostPicker.js.map +1 -0
- package/dist/controls/ExtendedRadioControl.d.ts +12 -0
- package/dist/controls/ExtendedRadioControl.js +33 -0
- package/dist/controls/ExtendedRadioControl.js.map +1 -0
- package/{build → dist}/controls/ExtendedTaxonomyPicker.d.ts +1 -1
- package/dist/controls/ExtendedTaxonomyPicker.js +71 -0
- package/dist/controls/ExtendedTaxonomyPicker.js.map +1 -0
- package/{build → dist}/controls/ExtendedTermPicker.d.ts +1 -1
- package/dist/controls/ExtendedTermPicker.js +33 -0
- package/dist/controls/ExtendedTermPicker.js.map +1 -0
- package/dist/controls/ExtendedTextareaControl.d.ts +12 -0
- package/{build → dist}/controls/ExtendedTextareaControl.js +15 -12
- package/dist/controls/ExtendedTextareaControl.js.map +1 -0
- package/dist/controls/ExtendedUserPicker.js +28 -0
- package/dist/controls/ExtendedUserPicker.js.map +1 -0
- package/{build → dist}/controls/FullSizeToggleControl.d.ts +6 -4
- package/dist/controls/FullSizeToggleControl.js +110 -0
- package/dist/controls/FullSizeToggleControl.js.map +1 -0
- package/{build → dist}/controls/ImageControl.d.ts +1 -1
- package/dist/controls/ImageControl.js +81 -0
- package/dist/controls/ImageControl.js.map +1 -0
- package/{build → dist}/controls/InspectorPanel.d.ts +4 -3
- package/dist/controls/InspectorPanel.js +29 -0
- package/dist/controls/InspectorPanel.js.map +1 -0
- package/{build → dist}/controls/LazySuggestionsComboboxControl.d.ts +5 -1
- package/dist/controls/LazySuggestionsComboboxControl.js +32 -0
- package/dist/controls/LazySuggestionsComboboxControl.js.map +1 -0
- package/{build → dist}/controls/MultiSelectControl.d.ts +1 -1
- package/dist/controls/MultiSelectControl.js +33 -0
- package/dist/controls/MultiSelectControl.js.map +1 -0
- package/{build → dist}/controls/PickOne.d.ts +1 -1
- package/dist/controls/PickOne.js +54 -0
- package/dist/controls/PickOne.js.map +1 -0
- package/{build → dist}/controls/PromisableComponent.d.ts +2 -2
- package/{build → dist}/controls/PromisableComponent.js +14 -11
- package/dist/controls/PromisableComponent.js.map +1 -0
- package/{build → dist}/controls/ProperLinkControl.d.ts +1 -1
- package/dist/controls/ProperLinkControl.js +59 -0
- package/dist/controls/ProperLinkControl.js.map +1 -0
- package/dist/controls/SimpleToggle.js +11 -0
- package/dist/controls/SimpleToggle.js.map +1 -0
- package/dist/controls/SortableFlexibleItemsControl.js +18 -0
- package/dist/controls/SortableFlexibleItemsControl.js.map +1 -0
- package/dist/controls/SortableItemsControl.js +15 -0
- package/dist/controls/SortableItemsControl.js.map +1 -0
- package/{build → dist}/controls/basicNumericallyIdedItemPicker.d.ts +1 -1
- package/dist/controls/basicNumericallyIdedItemPicker.js +37 -0
- package/dist/controls/basicNumericallyIdedItemPicker.js.map +1 -0
- package/{build → dist}/controls/hooks/useImprovedTokenManager.d.ts +7 -5
- package/{build → dist}/controls/hooks/useImprovedTokenManager.js +21 -15
- package/dist/controls/hooks/useImprovedTokenManager.js.map +1 -0
- package/{build → dist}/controls/hooks/useMultiSingleConversionLayer.d.ts +1 -1
- package/dist/controls/hooks/useMultiSingleConversionLayer.js +14 -0
- package/dist/controls/hooks/useMultiSingleConversionLayer.js.map +1 -0
- package/dist/controls/hooks/useNonRenderingCounter.js +9 -0
- package/dist/controls/hooks/useNonRenderingCounter.js.map +1 -0
- package/{build → dist}/controls/hooks/useOutputMemoizingFilter.js +7 -4
- package/dist/controls/hooks/useOutputMemoizingFilter.js.map +1 -0
- package/{build → dist}/controls/hooks/useSortableItemsModel.js +14 -11
- package/dist/controls/hooks/useSortableItemsModel.js.map +1 -0
- package/{build → dist}/controls/hooks/useSuggestions.js +16 -13
- package/dist/controls/hooks/useSuggestions.js.map +1 -0
- package/{build → dist}/controls/hooks/useTokenManager.d.ts +5 -3
- package/{build → dist}/controls/hooks/useTokenManager.js +37 -34
- package/dist/controls/hooks/useTokenManager.js.map +1 -0
- package/dist/controls/index.js +41 -0
- package/dist/controls/index.js.map +1 -0
- package/{build → dist}/controls/shared.js +18 -8
- package/dist/controls/shared.js.map +1 -0
- package/dist/controls/types.js +3 -0
- package/dist/editor/post-featured-image.js +125 -0
- package/dist/editor/post-featured-image.js.map +1 -0
- package/dist/editor/simple-gutenberg-endpoints-api.js +26 -0
- package/dist/editor/simple-gutenberg-endpoints-api.js.map +1 -0
- package/{build → dist}/editor/simple-gutenberg-endpoints-impl.js +24 -17
- package/dist/editor/simple-gutenberg-endpoints-impl.js.map +1 -0
- package/dist/index.js +39 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/gutenberg-api-extensions-state/custom-block-bindings-support-logic.js +27 -0
- package/dist/lib/gutenberg-api-extensions-state/custom-block-bindings-support-logic.js.map +1 -0
- package/{build → dist}/lib/gutenberg-api-extensions-state/general-logic.js +12 -8
- package/dist/lib/gutenberg-api-extensions-state/general-logic.js.map +1 -0
- package/{build → dist}/lib/gutenberg-api-extensions-state/layered-block-styles-logic.js +10 -6
- package/dist/lib/gutenberg-api-extensions-state/layered-block-styles-logic.js.map +1 -0
- package/{build → dist}/lib/gutenberg-api-extensions-state/snp-logic.js +33 -26
- package/dist/lib/gutenberg-api-extensions-state/snp-logic.js.map +1 -0
- package/{build → dist}/lib/gutenberg-api-extensions-state.d.ts +2 -2
- package/dist/lib/gutenberg-api-extensions-state.js +52 -0
- package/dist/lib/gutenberg-api-extensions-state.js.map +1 -0
- package/{build → dist}/lib/helpers.d.ts +3 -3
- package/{build → dist}/lib/helpers.js +13 -6
- package/dist/lib/helpers.js.map +1 -0
- package/dist/lib/plaudit-icons/column-1.js +6 -0
- package/dist/lib/plaudit-icons/column-1.js.map +1 -0
- package/dist/lib/plaudit-icons/column-2.js +6 -0
- package/dist/lib/plaudit-icons/column-2.js.map +1 -0
- package/dist/lib/plaudit-icons/column-3.js +6 -0
- package/dist/lib/plaudit-icons/column-3.js.map +1 -0
- package/dist/lib/plaudit-icons/placement-center.js +6 -0
- package/dist/lib/plaudit-icons/placement-center.js.map +1 -0
- package/dist/lib/plaudit-icons/placement-end.js +6 -0
- package/dist/lib/plaudit-icons/placement-end.js.map +1 -0
- package/dist/lib/plaudit-icons/placement-start.js +6 -0
- package/dist/lib/plaudit-icons/placement-start.js.map +1 -0
- package/dist/lib/plaudit-icons/placement-stretch.js +6 -0
- package/dist/lib/plaudit-icons/placement-stretch.js.map +1 -0
- package/dist/lib/plaudit-icons/plaudit-icon.js +6 -0
- package/dist/lib/plaudit-icons/plaudit-icon.js.map +1 -0
- package/dist/lib/plaudit-icons/reusable-block-marker.js +6 -0
- package/{build → dist}/lib/plaudit-icons/reusable-block-marker.js.map +1 -1
- package/dist/lib/plaudit-icons.js +29 -0
- package/dist/lib/plaudit-icons.js.map +1 -0
- package/{build → dist}/lib/suspense/promise-handlers.js +16 -7
- package/dist/lib/suspense/promise-handlers.js.map +1 -0
- package/{build → dist}/lib/suspense.d.ts +2 -2
- package/dist/lib/suspense.js +31 -0
- package/dist/lib/suspense.js.map +1 -0
- package/{build → dist}/lib/useful-types.d.ts +4 -1
- package/dist/lib/useful-types.js +11 -0
- package/dist/lib/useful-types.js.map +1 -0
- package/package.json +22 -30
- package/src/blocks/MoveError.ts +7 -0
- package/src/blocks/PathError.ts +18 -0
- package/src/blocks/SNPFlexibleItemsListComponent.tsx +30 -0
- package/src/blocks/SNPGroupComponent.tsx +38 -0
- package/src/blocks/SNPListComponent.tsx +25 -0
- package/src/blocks/SNPTreeContext.tsx +13 -0
- package/src/blocks/basic-custom-block-bindings-support.tsx +243 -0
- package/src/blocks/common-native-property-constructors.tsx +877 -0
- package/src/blocks/conditions.ts +260 -0
- package/src/blocks/csnp-api.ts +214 -0
- package/src/blocks/data-controller-manager.ts +50 -0
- package/src/blocks/data-controller.ts +736 -0
- package/src/blocks/hooks/built-in-suspendable-option-protocols/select.ts +51 -0
- package/src/blocks/hooks/built-in-suspendable-option-protocols/settings.ts +70 -0
- package/src/blocks/hooks/useSuspendableOptions.ts +123 -0
- package/src/blocks/index.ts +20 -0
- package/src/blocks/layered-styles-api.ts +142 -0
- package/src/blocks/layered-styles-impl.ts +94 -0
- package/src/blocks/layout/LaidOutProperty.tsx +72 -0
- package/src/blocks/layout/LaidOutPropertyRow.tsx +22 -0
- package/src/blocks/layout/NodeContext.tsx +54 -0
- package/src/blocks/layout/PanelRoot.tsx +33 -0
- package/src/blocks/layout/TabsRoot.tsx +56 -0
- package/src/blocks/layout/ToolsPanelContext.tsx +22 -0
- package/src/blocks/shared-exportable-types.ts +6 -0
- package/src/blocks/shared-internal-types.ts +18 -0
- package/src/blocks/simple-block.tsx +74 -0
- package/src/blocks/simple-native-property-api.ts +170 -0
- package/src/blocks/simple-native-property-impl.tsx +329 -0
- package/src/blocks/simple-native-property-internal-shared.ts +46 -0
- package/src/blocks/snp-api.ts +5 -0
- package/src/blocks/snp-data-store.ts +66 -0
- package/src/blocks/utilities.ts +80 -0
- package/src/controls/AsynchronousFormTokenField.tsx +85 -0
- package/src/controls/BaseSortableItemsControl.tsx +84 -0
- package/src/controls/ExtendedFormTokenField.tsx +121 -0
- package/src/controls/ExtendedPostPicker.ts +57 -0
- package/src/controls/ExtendedRadioControl.tsx +107 -0
- package/src/controls/ExtendedTaxonomyPicker.tsx +100 -0
- package/src/controls/ExtendedTermPicker.tsx +62 -0
- package/src/controls/ExtendedTextareaControl.tsx +65 -0
- package/src/controls/ExtendedUserPicker.ts +56 -0
- package/src/controls/FullSizeToggleControl.tsx +94 -0
- package/src/controls/ImageControl.tsx +143 -0
- package/src/controls/InspectorPanel.tsx +37 -0
- package/src/controls/LazySuggestionsComboboxControl.tsx +62 -0
- package/src/controls/MultiSelectControl.tsx +59 -0
- package/src/controls/PickOne.tsx +84 -0
- package/src/controls/PromisableComponent.tsx +56 -0
- package/src/controls/ProperLinkControl.tsx +93 -0
- package/src/controls/SimpleToggle.tsx +9 -0
- package/src/controls/SortableFlexibleItemsControl.tsx +35 -0
- package/src/controls/SortableItemsControl.tsx +18 -0
- package/src/controls/basicNumericallyIdedItemPicker.tsx +76 -0
- package/src/controls/hooks/useImprovedTokenManager.ts +157 -0
- package/src/controls/hooks/useMultiSingleConversionLayer.ts +17 -0
- package/src/controls/hooks/useNonRenderingCounter.ts +6 -0
- package/src/controls/hooks/useOutputMemoizingFilter.ts +16 -0
- package/src/controls/hooks/useSortableItemsModel.ts +196 -0
- package/src/controls/hooks/useSuggestions.ts +91 -0
- package/src/controls/hooks/useTokenManager.ts +177 -0
- package/{build/controls/index.js → src/controls/index.ts} +3 -2
- package/src/controls/shared.ts +50 -0
- package/src/controls/types.ts +18 -0
- package/src/editor/post-featured-image.tsx +161 -0
- package/src/editor/simple-gutenberg-endpoints-api.ts +31 -0
- package/src/editor/simple-gutenberg-endpoints-impl.ts +119 -0
- package/src/index.ts +32 -0
- package/src/lib/gutenberg-api-extensions-state/custom-block-bindings-support-logic.ts +34 -0
- package/src/lib/gutenberg-api-extensions-state/general-logic.ts +41 -0
- package/src/lib/gutenberg-api-extensions-state/layered-block-styles-logic.ts +42 -0
- package/src/lib/gutenberg-api-extensions-state/snp-logic.ts +240 -0
- package/src/lib/gutenberg-api-extensions-state.ts +69 -0
- package/src/lib/helpers.ts +114 -0
- package/src/lib/plaudit-icons/column-1.tsx +6 -0
- package/src/lib/plaudit-icons/column-2.tsx +6 -0
- package/src/lib/plaudit-icons/column-3.tsx +6 -0
- package/src/lib/plaudit-icons/placement-center.tsx +3 -0
- package/src/lib/plaudit-icons/placement-end.tsx +3 -0
- package/src/lib/plaudit-icons/placement-start.tsx +3 -0
- package/src/lib/plaudit-icons/placement-stretch.tsx +3 -0
- package/src/lib/plaudit-icons/plaudit-icon.tsx +4 -0
- package/src/lib/plaudit-icons/reusable-block-marker.tsx +3 -0
- package/{build/lib/plaudit-icons.js → src/lib/plaudit-icons.ts} +1 -1
- package/src/lib/suspense/promise-handlers.ts +72 -0
- package/src/lib/suspense.tsx +18 -0
- package/src/lib/useful-types.ts +65 -0
- package/build/blocks/MoveError.js +0 -6
- package/build/blocks/MoveError.js.map +0 -1
- package/build/blocks/PathError.js.map +0 -1
- package/build/blocks/SNPFlexibleItemsListComponent.js +0 -15
- package/build/blocks/SNPFlexibleItemsListComponent.js.map +0 -1
- package/build/blocks/SNPGroupComponent.js +0 -17
- package/build/blocks/SNPGroupComponent.js.map +0 -1
- package/build/blocks/SNPListComponent.js +0 -15
- package/build/blocks/SNPListComponent.js.map +0 -1
- package/build/blocks/SNPTreeContext.js +0 -10
- package/build/blocks/SNPTreeContext.js.map +0 -1
- package/build/blocks/basic-custom-block-bindings-support.js +0 -150
- package/build/blocks/basic-custom-block-bindings-support.js.map +0 -1
- package/build/blocks/common-native-property-constructors.d.ts +0 -208
- package/build/blocks/common-native-property-constructors.js.map +0 -1
- package/build/blocks/conditions.js.map +0 -1
- package/build/blocks/data-controller-manager.js.map +0 -1
- package/build/blocks/data-controller.js.map +0 -1
- package/build/blocks/hooks/built-in-suspendable-option-protocols/select.js.map +0 -1
- package/build/blocks/hooks/built-in-suspendable-option-protocols/settings.js.map +0 -1
- package/build/blocks/hooks/useSuspendableOptions.js.map +0 -1
- package/build/blocks/index.js +0 -15
- package/build/blocks/index.js.map +0 -1
- package/build/blocks/layered-styles-api.js.map +0 -1
- package/build/blocks/layered-styles-impl.js.map +0 -1
- package/build/blocks/layout/LaidOutProperty.js +0 -44
- package/build/blocks/layout/LaidOutProperty.js.map +0 -1
- package/build/blocks/layout/LaidOutPropertyRow.js +0 -12
- package/build/blocks/layout/LaidOutPropertyRow.js.map +0 -1
- package/build/blocks/layout/NodeContext.js +0 -37
- package/build/blocks/layout/NodeContext.js.map +0 -1
- package/build/blocks/layout/PanelRoot.js +0 -26
- package/build/blocks/layout/PanelRoot.js.map +0 -1
- package/build/blocks/layout/TabsRoot.js.map +0 -1
- package/build/blocks/layout/ToolsPanelContext.js +0 -18
- package/build/blocks/layout/ToolsPanelContext.js.map +0 -1
- package/build/blocks/shared-exportable-types.js +0 -2
- package/build/blocks/shared-internal-types.js +0 -2
- package/build/blocks/simple-block.js +0 -41
- package/build/blocks/simple-block.js.map +0 -1
- package/build/blocks/simple-native-property-api.js.map +0 -1
- package/build/blocks/simple-native-property-impl.js.map +0 -1
- package/build/blocks/simple-native-property-internal-shared.js.map +0 -1
- package/build/blocks/snp-api.js +0 -2
- package/build/blocks/snp-api.js.map +0 -1
- package/build/blocks/snp-data-store.js.map +0 -1
- package/build/blocks/utilities.js +0 -67
- package/build/blocks/utilities.js.map +0 -1
- package/build/controls/AsynchronousFormTokenField.js +0 -32
- package/build/controls/AsynchronousFormTokenField.js.map +0 -1
- package/build/controls/BaseSortableItemsControl.js +0 -22
- package/build/controls/BaseSortableItemsControl.js.map +0 -1
- package/build/controls/ExtendedFormTokenField.js +0 -58
- package/build/controls/ExtendedFormTokenField.js.map +0 -1
- package/build/controls/ExtendedPostPicker.js +0 -22
- package/build/controls/ExtendedPostPicker.js.map +0 -1
- package/build/controls/ExtendedRadioControl.d.ts +0 -10
- package/build/controls/ExtendedRadioControl.js +0 -30
- package/build/controls/ExtendedRadioControl.js.map +0 -1
- package/build/controls/ExtendedTaxonomyPicker.js +0 -68
- package/build/controls/ExtendedTaxonomyPicker.js.map +0 -1
- package/build/controls/ExtendedTermPicker.js +0 -27
- package/build/controls/ExtendedTermPicker.js.map +0 -1
- package/build/controls/ExtendedTextareaControl.d.ts +0 -14
- package/build/controls/ExtendedTextareaControl.js.map +0 -1
- package/build/controls/ExtendedUserPicker.js +0 -22
- package/build/controls/ExtendedUserPicker.js.map +0 -1
- package/build/controls/FullSizeToggleControl.js +0 -70
- package/build/controls/FullSizeToggleControl.js.map +0 -1
- package/build/controls/ImageControl.js +0 -76
- package/build/controls/ImageControl.js.map +0 -1
- package/build/controls/InspectorPanel.js +0 -26
- package/build/controls/InspectorPanel.js.map +0 -1
- package/build/controls/LazySuggestionsComboboxControl.js +0 -29
- package/build/controls/LazySuggestionsComboboxControl.js.map +0 -1
- package/build/controls/MultiSelectControl.js +0 -30
- package/build/controls/MultiSelectControl.js.map +0 -1
- package/build/controls/PickOne.js +0 -48
- package/build/controls/PickOne.js.map +0 -1
- package/build/controls/PromisableComponent.js.map +0 -1
- package/build/controls/ProperLinkControl.js +0 -56
- package/build/controls/ProperLinkControl.js.map +0 -1
- package/build/controls/SimpleToggle.js +0 -8
- package/build/controls/SimpleToggle.js.map +0 -1
- package/build/controls/SortableFlexibleItemsControl.js +0 -15
- package/build/controls/SortableFlexibleItemsControl.js.map +0 -1
- package/build/controls/SortableItemsControl.js +0 -12
- package/build/controls/SortableItemsControl.js.map +0 -1
- package/build/controls/basicNumericallyIdedItemPicker.js +0 -34
- package/build/controls/basicNumericallyIdedItemPicker.js.map +0 -1
- package/build/controls/hooks/useImprovedTokenManager.js.map +0 -1
- package/build/controls/hooks/useMultiSingleConversionLayer.js +0 -11
- package/build/controls/hooks/useMultiSingleConversionLayer.js.map +0 -1
- package/build/controls/hooks/useNonRenderingCounter.js +0 -6
- package/build/controls/hooks/useNonRenderingCounter.js.map +0 -1
- package/build/controls/hooks/useOutputMemoizingFilter.js.map +0 -1
- package/build/controls/hooks/useSortableItemsModel.js.map +0 -1
- package/build/controls/hooks/useSuggestions.js.map +0 -1
- package/build/controls/hooks/useTokenManager.js.map +0 -1
- package/build/controls/index.js.map +0 -1
- package/build/controls/shared.js.map +0 -1
- package/build/controls/types.js +0 -2
- package/build/editor/post-featured-image.js +0 -122
- package/build/editor/post-featured-image.js.map +0 -1
- package/build/editor/simple-gutenberg-endpoints-api.js +0 -22
- package/build/editor/simple-gutenberg-endpoints-api.js.map +0 -1
- package/build/editor/simple-gutenberg-endpoints-impl.js.map +0 -1
- package/build/index.js +0 -22
- package/build/index.js.map +0 -1
- package/build/lib/gutenberg-api-extensions-state/custom-block-bindings-support-logic.js +0 -23
- package/build/lib/gutenberg-api-extensions-state/custom-block-bindings-support-logic.js.map +0 -1
- package/build/lib/gutenberg-api-extensions-state/general-logic.js.map +0 -1
- package/build/lib/gutenberg-api-extensions-state/layered-block-styles-logic.js.map +0 -1
- package/build/lib/gutenberg-api-extensions-state/snp-logic.js.map +0 -1
- package/build/lib/gutenberg-api-extensions-state.js +0 -48
- package/build/lib/gutenberg-api-extensions-state.js.map +0 -1
- package/build/lib/helpers.js.map +0 -1
- package/build/lib/plaudit-icons/column-1.js +0 -3
- package/build/lib/plaudit-icons/column-1.js.map +0 -1
- package/build/lib/plaudit-icons/column-2.js +0 -3
- package/build/lib/plaudit-icons/column-2.js.map +0 -1
- package/build/lib/plaudit-icons/column-3.js +0 -3
- package/build/lib/plaudit-icons/column-3.js.map +0 -1
- package/build/lib/plaudit-icons/placement-center.js +0 -3
- package/build/lib/plaudit-icons/placement-center.js.map +0 -1
- package/build/lib/plaudit-icons/placement-end.js +0 -3
- package/build/lib/plaudit-icons/placement-end.js.map +0 -1
- package/build/lib/plaudit-icons/placement-start.js +0 -3
- package/build/lib/plaudit-icons/placement-start.js.map +0 -1
- package/build/lib/plaudit-icons/placement-stretch.js +0 -3
- package/build/lib/plaudit-icons/placement-stretch.js.map +0 -1
- package/build/lib/plaudit-icons/plaudit-icon.js +0 -3
- package/build/lib/plaudit-icons/plaudit-icon.js.map +0 -1
- package/build/lib/plaudit-icons/reusable-block-marker.js +0 -3
- package/build/lib/plaudit-icons.js.map +0 -1
- package/build/lib/suspense/promise-handlers.js.map +0 -1
- package/build/lib/suspense.js +0 -14
- package/build/lib/suspense.js.map +0 -1
- package/build/lib/useful-types.js +0 -7
- package/build/lib/useful-types.js.map +0 -1
- /package/{build → dist}/blocks/MoveError.d.ts +0 -0
- /package/{build → dist}/blocks/PathError.d.ts +0 -0
- /package/{build → dist}/blocks/SNPTreeContext.d.ts +0 -0
- /package/{build → dist}/blocks/basic-custom-block-bindings-support.d.ts +0 -0
- /package/{build → dist}/blocks/conditions.d.ts +0 -0
- /package/{build → dist}/blocks/data-controller-manager.d.ts +0 -0
- /package/{build → dist}/blocks/data-controller.d.ts +0 -0
- /package/{build → dist}/blocks/hooks/built-in-suspendable-option-protocols/select.d.ts +0 -0
- /package/{build → dist}/blocks/hooks/built-in-suspendable-option-protocols/settings.d.ts +0 -0
- /package/{build → dist}/blocks/index.d.ts +0 -0
- /package/{build → dist}/blocks/layered-styles-impl.d.ts +0 -0
- /package/{build → dist}/blocks/layout/LaidOutPropertyRow.d.ts +0 -0
- /package/{build → dist}/blocks/layout/PanelRoot.d.ts +0 -0
- /package/{build → dist}/blocks/layout/TabsRoot.d.ts +0 -0
- /package/{build → dist}/blocks/layout/ToolsPanelContext.d.ts +0 -0
- /package/{build → dist}/blocks/shared-exportable-types.d.ts +0 -0
- /package/{build → dist}/blocks/shared-exportable-types.js.map +0 -0
- /package/{build → dist}/blocks/shared-internal-types.d.ts +0 -0
- /package/{build → dist}/blocks/shared-internal-types.js.map +0 -0
- /package/{build → dist}/blocks/simple-native-property-impl.d.ts +0 -0
- /package/{build → dist}/blocks/simple-native-property-internal-shared.d.ts +0 -0
- /package/{build → dist}/blocks/snp-data-store.d.ts +0 -0
- /package/{build → dist}/controls/ExtendedPostPicker.d.ts +0 -0
- /package/{build → dist}/controls/ExtendedUserPicker.d.ts +0 -0
- /package/{build → dist}/controls/SimpleToggle.d.ts +0 -0
- /package/{build → dist}/controls/SortableFlexibleItemsControl.d.ts +0 -0
- /package/{build → dist}/controls/SortableItemsControl.d.ts +0 -0
- /package/{build → dist}/controls/hooks/useNonRenderingCounter.d.ts +0 -0
- /package/{build → dist}/controls/hooks/useOutputMemoizingFilter.d.ts +0 -0
- /package/{build → dist}/controls/hooks/useSortableItemsModel.d.ts +0 -0
- /package/{build → dist}/controls/hooks/useSuggestions.d.ts +0 -0
- /package/{build → dist}/controls/index.d.ts +0 -0
- /package/{build → dist}/controls/shared.d.ts +0 -0
- /package/{build → dist}/controls/types.d.ts +0 -0
- /package/{build → dist}/controls/types.js.map +0 -0
- /package/{build → dist}/editor/post-featured-image.d.ts +0 -0
- /package/{build → dist}/editor/simple-gutenberg-endpoints-api.d.ts +0 -0
- /package/{build → dist}/editor/simple-gutenberg-endpoints-impl.d.ts +0 -0
- /package/{build → dist}/index.d.ts +0 -0
- /package/{build → dist}/lib/gutenberg-api-extensions-state/custom-block-bindings-support-logic.d.ts +0 -0
- /package/{build → dist}/lib/gutenberg-api-extensions-state/general-logic.d.ts +0 -0
- /package/{build → dist}/lib/gutenberg-api-extensions-state/layered-block-styles-logic.d.ts +0 -0
- /package/{build → dist}/lib/gutenberg-api-extensions-state/snp-logic.d.ts +0 -0
- /package/{build → dist}/lib/plaudit-icons/column-1.d.ts +0 -0
- /package/{build → dist}/lib/plaudit-icons/column-2.d.ts +0 -0
- /package/{build → dist}/lib/plaudit-icons/column-3.d.ts +0 -0
- /package/{build → dist}/lib/plaudit-icons/placement-center.d.ts +0 -0
- /package/{build → dist}/lib/plaudit-icons/placement-end.d.ts +0 -0
- /package/{build → dist}/lib/plaudit-icons/placement-start.d.ts +0 -0
- /package/{build → dist}/lib/plaudit-icons/placement-stretch.d.ts +0 -0
- /package/{build → dist}/lib/plaudit-icons/plaudit-icon.d.ts +0 -0
- /package/{build → dist}/lib/plaudit-icons/reusable-block-marker.d.ts +0 -0
- /package/{build → dist}/lib/plaudit-icons.d.ts +0 -0
- /package/{build → dist}/lib/suspense/promise-handlers.d.ts +0 -0
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import {Button, SelectControl} from "@wordpress/components";
|
|
2
|
+
import {useCallback, useState} from "@wordpress/element";
|
|
3
|
+
|
|
4
|
+
import {BaseSortableItemsControl, type BaseSortableItemsControlProps} from "./BaseSortableItemsControl";
|
|
5
|
+
import type {NonEmptyArray} from "../lib/useful-types";
|
|
6
|
+
import type {FlexibleItem} from "./types";
|
|
7
|
+
|
|
8
|
+
import type {ReactNode} from "react";
|
|
9
|
+
|
|
10
|
+
type SortableFlexibleItemsControlSpecificProps<T extends string> = {
|
|
11
|
+
availableTypes: NonEmptyArray<{label: string, value: T}>,
|
|
12
|
+
emptyValueBuilder: (type: T) => FlexibleItem<T>
|
|
13
|
+
};
|
|
14
|
+
export type SortableFlexibleItemsControl<T extends string> = Omit<BaseSortableItemsControlProps<FlexibleItem<T>>, 'buttonsArea'>&SortableFlexibleItemsControlSpecificProps<T>;
|
|
15
|
+
export function SortableFlexibleItemsControl<T extends string>({availableTypes, emptyValueBuilder, ...baseProps}: SortableFlexibleItemsControl<T>) {
|
|
16
|
+
const buttonsArea = useCallback<BaseSortableItemsControlProps<FlexibleItem<T>>['buttonsArea']>(
|
|
17
|
+
// Unfortunately, the typedefs for React memo components don't allow us to properly check the emptyValueBuilder function
|
|
18
|
+
args => <ButtonsArea {...args} availableTypes={availableTypes} emptyValueBuilder={emptyValueBuilder} />, [availableTypes, emptyValueBuilder]);
|
|
19
|
+
return <BaseSortableItemsControl {...baseProps} buttonsArea={buttonsArea} />;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
type ButtonsAreaProps<T extends string> = Parameters<BaseSortableItemsControlProps<FlexibleItem<T>>['buttonsArea']>[0]&SortableFlexibleItemsControlSpecificProps<T>;
|
|
23
|
+
function ButtonsArea<T extends string>({addHandler, disabled, availableTypes, emptyValueBuilder}: ButtonsAreaProps<T>): ReactNode {
|
|
24
|
+
const [selectedType, setSelectedType] = useState(availableTypes[0].value);
|
|
25
|
+
return <div className="plaudit-sortable-items-buttons flexible-items">
|
|
26
|
+
<Button icon="insert" disabled={disabled} onClick={() => addHandler(emptyValueBuilder(selectedType))}>Add</Button>
|
|
27
|
+
<SelectControl
|
|
28
|
+
label="Type"
|
|
29
|
+
hideLabelFromVision={true}
|
|
30
|
+
value={selectedType}
|
|
31
|
+
options={availableTypes}
|
|
32
|
+
onChange={setSelectedType}
|
|
33
|
+
/>
|
|
34
|
+
</div>;
|
|
35
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import {Button} from "@wordpress/components";
|
|
2
|
+
import {useCallback} from "@wordpress/element";
|
|
3
|
+
|
|
4
|
+
import {BaseSortableItemsControl, type BaseSortableItemsControlProps} from "./BaseSortableItemsControl";
|
|
5
|
+
|
|
6
|
+
export type SortableItemsControlProps<D> = Omit<BaseSortableItemsControlProps<D>, 'buttonsArea'|'emptyValue'>&{emptyValue: D, addRowText?: string};
|
|
7
|
+
export function SortableItemsControl<D>({emptyValue, addRowText, ...baseProps}: SortableItemsControlProps<D>) {
|
|
8
|
+
const buttonsArea = useCallback<BaseSortableItemsControlProps<D>['buttonsArea']>(
|
|
9
|
+
args => <ButtonsArea {...args} emptyValue={emptyValue} addRowText={addRowText} />, [emptyValue, addRowText]);
|
|
10
|
+
return <BaseSortableItemsControl {...baseProps} buttonsArea={buttonsArea} emptyValue={emptyValue} />;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
type ButtonsAreaProps<D = any> = Parameters<BaseSortableItemsControlProps<D>['buttonsArea']>[0]&{emptyValue: D, addRowText?: string};
|
|
14
|
+
function ButtonsArea<D>({addHandler, disabled, emptyValue, addRowText}: ButtonsAreaProps<D>) {
|
|
15
|
+
return <div className="plaudit-sortable-items-buttons">
|
|
16
|
+
<Button icon="insert" disabled={disabled} onClick={() => addHandler(typeof emptyValue === 'object' ? {...emptyValue} : emptyValue)}>{addRowText ?? "Add Row"}</Button>
|
|
17
|
+
</div>
|
|
18
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import {select as dataSelect} from "@wordpress/data";
|
|
2
|
+
import {useCallback} from "@wordpress/element";
|
|
3
|
+
|
|
4
|
+
import type {SNPControlSlots} from "../blocks";
|
|
5
|
+
import {ExtendedFormTokenField, unpackDisplayedTokenText, ValidationState} from "./ExtendedFormTokenField";
|
|
6
|
+
import {isNumeric} from "./shared";
|
|
7
|
+
import type {TokenItem} from "../lib/useful-types";
|
|
8
|
+
|
|
9
|
+
import type {ReactNode} from "react";
|
|
10
|
+
|
|
11
|
+
type BasicNumericallyIdedItemPickerPropsBase = {
|
|
12
|
+
label?: string;
|
|
13
|
+
help?: ReactNode;
|
|
14
|
+
placeholder?: string;
|
|
15
|
+
}&Partial<Pick<SNPControlSlots, 'Messages'>>;
|
|
16
|
+
type BasicNumericallyIdedItemPickerPropsSingle = BasicNumericallyIdedItemPickerPropsBase&{
|
|
17
|
+
onChange(value: string): void;
|
|
18
|
+
value?: string;
|
|
19
|
+
multiple: false;
|
|
20
|
+
};
|
|
21
|
+
type BasicNumericallyIdedItemPickerPropsMultiple = BasicNumericallyIdedItemPickerPropsBase&{
|
|
22
|
+
onChange(value: string[]): void;
|
|
23
|
+
value?: string[];
|
|
24
|
+
multiple?: true|undefined;
|
|
25
|
+
};
|
|
26
|
+
export type BasicNumericallyIdedItemPickerProps = BasicNumericallyIdedItemPickerPropsSingle|BasicNumericallyIdedItemPickerPropsMultiple;
|
|
27
|
+
|
|
28
|
+
export function basicNumericallyIdedItemPicker(props: BasicNumericallyIdedItemPickerProps, endpoint: string, queryProps: {[key: string]: any}) {
|
|
29
|
+
const {multiple, value, ...remainder} = props;
|
|
30
|
+
|
|
31
|
+
const suggestionQuery = useCallback((input: string, select: typeof dataSelect) => {
|
|
32
|
+
return select('plaudit/simple-gutenberg-apis')
|
|
33
|
+
.get(endpoint + "-options", {search: input, ...queryProps}) as TokenItem[]|undefined;
|
|
34
|
+
}, [queryProps]);
|
|
35
|
+
const validationQuery = useCallback((idsBeingValidated: string[], select: typeof dataSelect) => {
|
|
36
|
+
return (select('plaudit/simple-gutenberg-apis')
|
|
37
|
+
.get(endpoint + "-validation", {ids: idsBeingValidated.join(','), ...queryProps}) as TokenItem[]|undefined);
|
|
38
|
+
}, [queryProps]);
|
|
39
|
+
|
|
40
|
+
if (props.multiple === false) {
|
|
41
|
+
return <ExtendedFormTokenField
|
|
42
|
+
{...remainder}
|
|
43
|
+
value={props.value}
|
|
44
|
+
multiple={false}
|
|
45
|
+
onChange={props.onChange}
|
|
46
|
+
stringToTokenConverter={makeTokenFromSuggestion}
|
|
47
|
+
suggestionQuery={suggestionQuery}
|
|
48
|
+
validationQuery={validationQuery}
|
|
49
|
+
validator={validator}
|
|
50
|
+
/>;
|
|
51
|
+
} else {
|
|
52
|
+
return <ExtendedFormTokenField
|
|
53
|
+
{...remainder}
|
|
54
|
+
value={props.value}
|
|
55
|
+
multiple={true}
|
|
56
|
+
onChange={props.onChange}
|
|
57
|
+
stringToTokenConverter={makeTokenFromSuggestion}
|
|
58
|
+
suggestionQuery={suggestionQuery}
|
|
59
|
+
validationQuery={validationQuery}
|
|
60
|
+
validator={validator}
|
|
61
|
+
/>;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function makeTokenFromSuggestion(token: string): TokenItem {
|
|
66
|
+
if (isNumeric(token)) {
|
|
67
|
+
return {value: token, status: ValidationState.Validating};
|
|
68
|
+
} else {
|
|
69
|
+
const {value, title} = unpackDisplayedTokenText(token);
|
|
70
|
+
return {value, status: isNumeric(value) ? ValidationState.Validating : ValidationState.Invalid, title};
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function validator(token: string) {
|
|
75
|
+
return /\(#([0-9]+)\)$/.exec(token)?.[1] !== undefined;
|
|
76
|
+
}
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
import {useSelect} from "@wordpress/data";
|
|
2
|
+
import type {MapSelect} from "@wordpress/data/types";
|
|
3
|
+
import {useEffect, useMemo, useRef, useState} from "@wordpress/element";
|
|
4
|
+
|
|
5
|
+
import type {TokenItem} from "../../lib/useful-types";
|
|
6
|
+
|
|
7
|
+
export function packDisplayTokenText(token: TokenItem) {
|
|
8
|
+
return `${token.title || token.value} (#${token.value})`;
|
|
9
|
+
}
|
|
10
|
+
export function unpackDisplayedTokenText(token: string) {
|
|
11
|
+
const result = /(.+) \(#([^)]+)\)$/.exec(token);
|
|
12
|
+
return {title: result?.[1], value: result?.[2] ?? token};
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
// The strange values correspond to the literals that are expected by TokenItem.status, which allows the assignment code to be cleaner
|
|
16
|
+
export const enum ValidationState {
|
|
17
|
+
Valid = 'success',
|
|
18
|
+
Invalid = 'error',
|
|
19
|
+
Validating = 'validating'
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export type TokenManagementCallbacks = {
|
|
23
|
+
validationQuery(tokens: string[], ...args: Parameters<MapSelect>): TokenItem[]|undefined;
|
|
24
|
+
suggestionQuery(input: string, ...args: Parameters<MapSelect>): TokenItem[]|undefined;
|
|
25
|
+
stringToTokenConverter(suggestion: string): TokenItem;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
type ImprovedTokenManagerReturnType = {
|
|
29
|
+
currentTokens: TokenItem[];
|
|
30
|
+
isValidating: boolean;
|
|
31
|
+
updateComponentValue: (value: (((prevState: (string | TokenItem)[]) => (string|TokenItem)[])|(string|TokenItem)[])) => void;
|
|
32
|
+
tokenStatusCache: Map<TokenItem["value"], TokenItem["status"]>
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
export function useImprovedTokenManager(
|
|
36
|
+
initialValue: (string|TokenItem)[]|undefined,
|
|
37
|
+
writeBackingValue: (value: TokenItem[]) => void,
|
|
38
|
+
validationQuery: TokenManagementCallbacks['validationQuery'],
|
|
39
|
+
makeTokenFromString: TokenManagementCallbacks['stringToTokenConverter'],
|
|
40
|
+
tokenTitleCache: Map<TokenItem['value'], TokenItem['title']>
|
|
41
|
+
): ImprovedTokenManagerReturnType {
|
|
42
|
+
const [componentValue, updateComponentValue] = useState<(string|TokenItem)[]>(
|
|
43
|
+
() => initialValue?.map(item => typeof item === 'string' ? makeTokenFromString(item) : item) ?? []);
|
|
44
|
+
|
|
45
|
+
const tokenStatusCacheRef = useRef<Map<TokenItem['value'], TokenItem['status']>|undefined>(undefined);
|
|
46
|
+
if (tokenStatusCacheRef.current === undefined) {
|
|
47
|
+
tokenStatusCacheRef.current = new Map();
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const convertedTokens = useTokenConverter(componentValue, makeTokenFromString, tokenStatusCacheRef.current);
|
|
51
|
+
const {isValidating, validatedTokens} = useTokenValidator(convertedTokens, validationQuery, tokenStatusCacheRef.current)
|
|
52
|
+
const titledTokens = useTokenTitleApplier(validatedTokens, tokenTitleCache);
|
|
53
|
+
|
|
54
|
+
useEffect(() => {
|
|
55
|
+
if (!isValidating) {
|
|
56
|
+
writeBackingValue(titledTokens);
|
|
57
|
+
}
|
|
58
|
+
}, [titledTokens, isValidating]);
|
|
59
|
+
|
|
60
|
+
return {currentTokens: titledTokens, isValidating, updateComponentValue, tokenStatusCache: tokenStatusCacheRef.current};
|
|
61
|
+
}
|
|
62
|
+
function syncTokenTitles(token: TokenItem, cache: Map<TokenItem['value'], TokenItem['title']>): TokenItem {
|
|
63
|
+
return {...token, title: cache.get(token.value) ?? addTokenTitleToCache(token, cache) ?? packDisplayTokenText(token)};
|
|
64
|
+
}
|
|
65
|
+
function addTokenTitleToCache(token: TokenItem, cache: Map<TokenItem['value'], TokenItem['title']>) {
|
|
66
|
+
let label = token.title?.trim();
|
|
67
|
+
if (!label) {
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
const valueSuffix = `(#${token.value})`;
|
|
71
|
+
if (label.endsWith(valueSuffix)) {
|
|
72
|
+
label = label.substring(0, label.length - valueSuffix.length).trim();
|
|
73
|
+
}
|
|
74
|
+
const res = `${label.length > 30 ? `${label.substring(0, 30).trim()}…` : label} ${valueSuffix}`;
|
|
75
|
+
cache.set(token.value, res);
|
|
76
|
+
return res;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
function isAllValidTokens(arr: (string|TokenItem)[]): arr is (Omit<TokenItem, 'title'|'status'>&Required<Pick<TokenItem, 'title'|'status'>>)[] {
|
|
80
|
+
return arr.every(token => typeof token !== 'string' && token.status !== undefined && token.status !== ValidationState.Validating && token.title !== undefined);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function useTokenConverter(
|
|
84
|
+
componentValue: (string|TokenItem)[], makeTokenFromString: (token: string) => TokenItem, tokenStatusCache: Map<TokenItem['value'], TokenItem['status']>
|
|
85
|
+
) {
|
|
86
|
+
const priorComponentValue = useRef<(string|TokenItem)[]>([]);
|
|
87
|
+
const alreadyConvertedTokens = useRef<TokenItem[]>([]);
|
|
88
|
+
if (priorComponentValue.current === componentValue) {
|
|
89
|
+
return alreadyConvertedTokens.current;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
const newlyConvertedTokens = isAllValidTokens(componentValue) ? componentValue
|
|
93
|
+
: componentValue.map(token => {
|
|
94
|
+
if (typeof token === 'string') {
|
|
95
|
+
const res = makeTokenFromString(token);
|
|
96
|
+
if (res.status === undefined) {
|
|
97
|
+
res.status = tokenStatusCache.get(res.value);
|
|
98
|
+
}
|
|
99
|
+
return res;
|
|
100
|
+
} else {
|
|
101
|
+
if (token.status === undefined || token.status === ValidationState.Validating) {
|
|
102
|
+
token.status = tokenStatusCache.get(token.value);
|
|
103
|
+
}
|
|
104
|
+
return token;
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
const convertedTokens = alreadyConvertedTokens.current;
|
|
109
|
+
if (newlyConvertedTokens.length !== convertedTokens.length) {
|
|
110
|
+
priorComponentValue.current = componentValue;
|
|
111
|
+
alreadyConvertedTokens.current = newlyConvertedTokens;
|
|
112
|
+
return newlyConvertedTokens;
|
|
113
|
+
}
|
|
114
|
+
for (let i = 0; i < newlyConvertedTokens.length; i++) {
|
|
115
|
+
if (newlyConvertedTokens[i]?.value !== convertedTokens[i]?.value || newlyConvertedTokens[i]?.status !== convertedTokens[i]?.status) {
|
|
116
|
+
priorComponentValue.current = componentValue;
|
|
117
|
+
alreadyConvertedTokens.current = newlyConvertedTokens;
|
|
118
|
+
return newlyConvertedTokens;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
return convertedTokens;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
function useTokenValidator(
|
|
125
|
+
convertedTokens: TokenItem[], validationQuery: TokenManagementCallbacks['validationQuery'], tokenStatusCache: Map<TokenItem['value'], TokenItem['status']>
|
|
126
|
+
) {
|
|
127
|
+
const [statusUpdatedConvertedTokens, statusUpdatedConvertedTokenValues] = useMemo(() => {
|
|
128
|
+
const res = convertedTokens
|
|
129
|
+
.map(token => {
|
|
130
|
+
return (token.status === undefined || token.status === ValidationState.Validating) && tokenStatusCache.has(token.value)
|
|
131
|
+
? {...token, status: tokenStatusCache.get(token.value)} : token;
|
|
132
|
+
});
|
|
133
|
+
return [res, res.map(token => token.value)];
|
|
134
|
+
}, [convertedTokens, tokenStatusCache]);
|
|
135
|
+
|
|
136
|
+
return useSelect((select, registry) => {
|
|
137
|
+
if (statusUpdatedConvertedTokens.some(token => token.status === undefined || token.status === ValidationState.Validating)) {
|
|
138
|
+
const res = validationQuery(statusUpdatedConvertedTokenValues, select, registry);
|
|
139
|
+
if (res !== undefined) {
|
|
140
|
+
const validTokens = new Map(res.map(token => [token.value, token]));
|
|
141
|
+
const validatedTokens = convertedTokens.map(token => validTokens.get(token.value) ?? {...token, status: ValidationState.Invalid});
|
|
142
|
+
for (const token of validatedTokens) {
|
|
143
|
+
tokenStatusCache.set(token.value, token.status);
|
|
144
|
+
}
|
|
145
|
+
return {validatedTokens: res, isValidating: false};
|
|
146
|
+
} else {
|
|
147
|
+
return {validatedTokens: statusUpdatedConvertedTokens, isValidating: true};
|
|
148
|
+
}
|
|
149
|
+
} else {
|
|
150
|
+
return {validatedTokens: statusUpdatedConvertedTokens, isValidating: false};
|
|
151
|
+
}
|
|
152
|
+
}, [convertedTokens, statusUpdatedConvertedTokens, statusUpdatedConvertedTokenValues, validationQuery, tokenStatusCache]);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
function useTokenTitleApplier(convertedTokens: TokenItem[], tokenTitleCache: Map<TokenItem['value'], TokenItem['title']>) {
|
|
156
|
+
return useMemo(() => convertedTokens.map(token => syncTokenTitles(token, tokenTitleCache)), [convertedTokens, tokenTitleCache]);
|
|
157
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import {useCallback, useMemo} from "@wordpress/element";
|
|
2
|
+
|
|
3
|
+
import type {TokenItem} from "../../lib/useful-types";
|
|
4
|
+
|
|
5
|
+
export type ValueConverter = [string[], (value: TokenItem[]) => void];
|
|
6
|
+
export function useMultiSingleConversionLayer(
|
|
7
|
+
value: string|string[]|undefined, onChange: ((tokens: string[]) => void)|((token: string) => void),
|
|
8
|
+
makeTokenFromSuggestion: (suggestion: string) => TokenItem, multiple = true
|
|
9
|
+
): ValueConverter {
|
|
10
|
+
return [
|
|
11
|
+
useMemo(() => value === undefined ? [] : (Array.isArray(value) ? value : [value]), [value]),
|
|
12
|
+
useCallback(tokens => {
|
|
13
|
+
const bareTokens = tokens.filter(token => token.status === 'success').map(token => token.value);
|
|
14
|
+
onChange((multiple ? bareTokens : bareTokens[0]) as any);
|
|
15
|
+
}, [onChange, makeTokenFromSuggestion, multiple])
|
|
16
|
+
];
|
|
17
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import {useCallback, useRef} from "@wordpress/element";
|
|
2
|
+
|
|
3
|
+
export function useOutputMemoizingFilter<A extends any[], R>(filter: (...args: A) => R, externals?: any[]): typeof filter {
|
|
4
|
+
const existingState = useRef<undefined|[typeof filter, A, R]>(undefined);
|
|
5
|
+
const memoizedFilter = useCallback((...args: A): R => {
|
|
6
|
+
if (existingState.current !== undefined && existingState.current[0] === memoizedFilter
|
|
7
|
+
&& (existingState.current[1] === args || args.every((a, i) => existingState.current![1][i] === a))
|
|
8
|
+
) {
|
|
9
|
+
return existingState.current[2];
|
|
10
|
+
}
|
|
11
|
+
const res = filter(...args);
|
|
12
|
+
existingState.current = [memoizedFilter, args, res];
|
|
13
|
+
return res;
|
|
14
|
+
}, externals ? [filter, ...externals] : [filter]);
|
|
15
|
+
return memoizedFilter;
|
|
16
|
+
}
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
import {useEffect, useMemo, useState} from "@wordpress/element";
|
|
2
|
+
|
|
3
|
+
import {Immer} from "immer";
|
|
4
|
+
import {clone} from "../../lib/helpers";
|
|
5
|
+
|
|
6
|
+
type Listeners<D> = {
|
|
7
|
+
onAdd?: (index: number, value: D) => void,
|
|
8
|
+
onChange?: (value: D[]) => void,
|
|
9
|
+
onRemove?: (index: number) => void,
|
|
10
|
+
onReorder?: (oldIndex: number, newIndex: number) => void
|
|
11
|
+
};
|
|
12
|
+
type SortableItemsModelArgs<D> = Listeners<D>&{
|
|
13
|
+
emptyValue?: D,
|
|
14
|
+
value?: D[]
|
|
15
|
+
}
|
|
16
|
+
export type SortableItemsModelKey = ReturnType<typeof crypto.randomUUID>;
|
|
17
|
+
export type KeyedValue<D> = {value: D, key: SortableItemsModelKey};
|
|
18
|
+
export type KeyedValues<D> = KeyedValue<D>[];
|
|
19
|
+
type ActionDefs<D> = {
|
|
20
|
+
add(args: {index?: number, value: D}): void,
|
|
21
|
+
remove(args: {key: SortableItemsModelKey}): void,
|
|
22
|
+
move(args: {oldIndex: number, newIndex: number}): void,
|
|
23
|
+
change(args: {value: D, index: number}): void,
|
|
24
|
+
|
|
25
|
+
commit(args: {keyedValues: KeyedValues<D>}): void,
|
|
26
|
+
refresh(args: {listeners: Listeners<D>, value?: D[]}): void
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
type State<D> = {
|
|
30
|
+
listeners: Listeners<D>,
|
|
31
|
+
keyedValues: KeyedValues<D>,
|
|
32
|
+
value?: D[] // This is only used to avoid updating keyedValues on refresh wherever possible
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
export type IndexedItemActions<D> = {
|
|
36
|
+
add(value: D): void,
|
|
37
|
+
remove(): void,
|
|
38
|
+
moveUp(): void,
|
|
39
|
+
moveDown(): void,
|
|
40
|
+
change(value: D): void
|
|
41
|
+
};
|
|
42
|
+
export type IndexedItemActionsMaker<D> = (index: number, key: SortableItemsModelKey) => IndexedItemActions<D>;
|
|
43
|
+
|
|
44
|
+
type Actions<D> = {add(value: D, index?: number): void, commit(keyedValues: KeyedValues<D>): void, makeIndexedItemActions: IndexedItemActionsMaker<D>};
|
|
45
|
+
export function useSortableItemsModel<D>(args: SortableItemsModelArgs<D>) {
|
|
46
|
+
const {mutators, state} = usePseudoReducerBasedStateManagement<D>(args);
|
|
47
|
+
|
|
48
|
+
const {emptyValue} = args;
|
|
49
|
+
// We use a separate memo for the actions because dispatch should change significantly less-often than state
|
|
50
|
+
const actions = useMemo<Actions<D>>(() => {
|
|
51
|
+
return ({
|
|
52
|
+
add: (value: D, index?: number) => {
|
|
53
|
+
mutators.add({value, index});
|
|
54
|
+
},
|
|
55
|
+
commit: (keyedValues: KeyedValues<D>) => {
|
|
56
|
+
mutators.commit({keyedValues});
|
|
57
|
+
},
|
|
58
|
+
addEmptyValue: emptyValue !== undefined && emptyValue !== null ? (index?: number) => {
|
|
59
|
+
mutators.add({value: typeof emptyValue === 'object' ? {...emptyValue} : emptyValue, index});
|
|
60
|
+
} : undefined,
|
|
61
|
+
makeIndexedItemActions(index: number, key: SortableItemsModelKey) {
|
|
62
|
+
return useMemo(() => ({
|
|
63
|
+
add: (value: D) => {
|
|
64
|
+
mutators.add({value, index});
|
|
65
|
+
},
|
|
66
|
+
remove: () => {
|
|
67
|
+
mutators.remove({key});
|
|
68
|
+
},
|
|
69
|
+
moveUp: () => {
|
|
70
|
+
mutators.move({oldIndex: index, newIndex: index - 1});
|
|
71
|
+
},
|
|
72
|
+
moveDown: () => {
|
|
73
|
+
mutators.move({oldIndex: index, newIndex: index + 1});
|
|
74
|
+
},
|
|
75
|
+
change: (value: D) => {
|
|
76
|
+
mutators.change({value, index});
|
|
77
|
+
}
|
|
78
|
+
}), [index, key, mutators]);
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
}, [emptyValue, mutators]);
|
|
82
|
+
|
|
83
|
+
return {...actions, keyedValues: state.keyedValues};
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function swap<T>(value: T[], newIndex: number, oldIndex: number): T[] {
|
|
87
|
+
const splicedValue = [...value];
|
|
88
|
+
if (newIndex > oldIndex) {
|
|
89
|
+
splicedValue.splice(newIndex + 1, 0, splicedValue[oldIndex]!);
|
|
90
|
+
splicedValue.splice(oldIndex, 1);
|
|
91
|
+
} else {
|
|
92
|
+
splicedValue.splice(newIndex, 0, ...splicedValue.splice(oldIndex, 1));
|
|
93
|
+
}
|
|
94
|
+
return splicedValue;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
function usePseudoReducerBasedStateManagement<D>({value, onAdd, onChange, onRemove, onReorder}: SortableItemsModelArgs<D>) {
|
|
98
|
+
const [state, setState] = useState<State<D>>({keyedValues: [], listeners: {}});
|
|
99
|
+
|
|
100
|
+
const mutators = useMemo<ActionDefs<D>>(() => {
|
|
101
|
+
return {
|
|
102
|
+
add({value, index}) {
|
|
103
|
+
const newItemIndex = index ?? state.value?.length ?? 0;
|
|
104
|
+
const newValue = state.value?.toSpliced(newItemIndex, 0, value) ?? [value];
|
|
105
|
+
onAdd?.(newItemIndex, value);
|
|
106
|
+
onChange?.(newValue);
|
|
107
|
+
setState({
|
|
108
|
+
...state,
|
|
109
|
+
value: newValue,
|
|
110
|
+
keyedValues: state.keyedValues.toSpliced(newItemIndex, 0, {value: value, key: crypto.randomUUID()})
|
|
111
|
+
});
|
|
112
|
+
},
|
|
113
|
+
remove({key}) {
|
|
114
|
+
const actionIndex = state.keyedValues?.findIndex(({key: k}) => k === key) ?? -1;
|
|
115
|
+
if (actionIndex === -1) {
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
const newValue = state.value?.toSpliced(actionIndex, 1) ?? [];
|
|
119
|
+
onRemove?.(actionIndex);
|
|
120
|
+
onChange?.(newValue);
|
|
121
|
+
setState({
|
|
122
|
+
...state,
|
|
123
|
+
value: newValue,
|
|
124
|
+
keyedValues: state.keyedValues.toSpliced(actionIndex, 1)
|
|
125
|
+
});
|
|
126
|
+
},
|
|
127
|
+
move({oldIndex, newIndex}) {
|
|
128
|
+
if (newIndex === oldIndex) {
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
const newValue = swap(state.value ?? [], newIndex, oldIndex);
|
|
132
|
+
const changesStart = Math.min(newIndex, oldIndex);
|
|
133
|
+
newValue.splice(changesStart, newValue.length, ...newValue.slice(changesStart).map(v => clone(v)));
|
|
134
|
+
onReorder?.(oldIndex, newIndex);
|
|
135
|
+
onChange?.(newValue);
|
|
136
|
+
setState({
|
|
137
|
+
...state,
|
|
138
|
+
value: newValue,
|
|
139
|
+
keyedValues: swap(state.keyedValues, newIndex, oldIndex).map(({key}, i) => ({
|
|
140
|
+
value: newValue[i]!,
|
|
141
|
+
key
|
|
142
|
+
}))
|
|
143
|
+
});
|
|
144
|
+
},
|
|
145
|
+
change({value, index}) {
|
|
146
|
+
const newValue = (state.value ?? []).toSpliced(index, 1, value);
|
|
147
|
+
onChange?.(newValue);
|
|
148
|
+
setState({
|
|
149
|
+
...state,
|
|
150
|
+
value: newValue,
|
|
151
|
+
keyedValues: state.keyedValues.toSpliced(index, 1, {...state.keyedValues[index]!, value})
|
|
152
|
+
});
|
|
153
|
+
},
|
|
154
|
+
commit({keyedValues}) {
|
|
155
|
+
const newValue = keyedValues.map(({value}) => value);
|
|
156
|
+
onChange?.(newValue);
|
|
157
|
+
setState({
|
|
158
|
+
...state,
|
|
159
|
+
value: newValue,
|
|
160
|
+
keyedValues
|
|
161
|
+
});
|
|
162
|
+
},
|
|
163
|
+
refresh(args) {
|
|
164
|
+
const prevState = state;
|
|
165
|
+
setState((new Immer({autoFreeze: false})).produce(prevState, (draft: State<D>) => {
|
|
166
|
+
for (const [key, value] of Object.entries(args.listeners) as [keyof Listeners<D>, any][]) {
|
|
167
|
+
draft.listeners[key] = value;
|
|
168
|
+
}
|
|
169
|
+
if (prevState.value !== args.value) {
|
|
170
|
+
draft.value = args.value;
|
|
171
|
+
if (args.value !== undefined) {
|
|
172
|
+
if (args.value.length !== prevState.keyedValues.length) {
|
|
173
|
+
draft.keyedValues = args.value.map((v, i) => {
|
|
174
|
+
return {
|
|
175
|
+
value: v,
|
|
176
|
+
key: prevState.keyedValues[i] !== undefined && prevState.keyedValues[i].value === v ? prevState.keyedValues[i].key : crypto.randomUUID()
|
|
177
|
+
};
|
|
178
|
+
});
|
|
179
|
+
} else {
|
|
180
|
+
for (let i = 0; i < args.value.length; i++) {
|
|
181
|
+
draft.keyedValues[i]!.value = args.value[i]!;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
}));
|
|
187
|
+
}
|
|
188
|
+
};
|
|
189
|
+
}, [state, onAdd, onChange, onRemove, onReorder]);
|
|
190
|
+
|
|
191
|
+
useEffect(() => {
|
|
192
|
+
mutators.refresh({listeners: {onAdd, onChange, onRemove, onReorder}, value});
|
|
193
|
+
}, [value, onAdd, onChange, onRemove, onReorder, mutators]);
|
|
194
|
+
|
|
195
|
+
return {mutators, state};
|
|
196
|
+
}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import {useCallback, useEffect, useRef, useState} from "@wordpress/element";
|
|
2
|
+
|
|
3
|
+
import {useNonRenderingCounter} from "./useNonRenderingCounter";
|
|
4
|
+
|
|
5
|
+
import {useReducer} from "react";
|
|
6
|
+
|
|
7
|
+
type UseSuggestionsArgs<T> = {
|
|
8
|
+
expandOnFocus?: boolean,
|
|
9
|
+
getOption?: (value?: string) => Promise<T|undefined>,
|
|
10
|
+
getSuggestions(filterValue: string): Promise<T[]>
|
|
11
|
+
};
|
|
12
|
+
type SuggestionState<T> = {
|
|
13
|
+
hasLoadingError: boolean,
|
|
14
|
+
suggestions: T[],
|
|
15
|
+
requestId: number
|
|
16
|
+
};
|
|
17
|
+
function useSimpleDebouncer(delay: number) {
|
|
18
|
+
const timerId = useRef<ReturnType<typeof window['setTimeout']>|undefined>(undefined);
|
|
19
|
+
return useCallback((action: () => void) => {
|
|
20
|
+
if (timerId.current !== undefined) {
|
|
21
|
+
clearTimeout(timerId.current);
|
|
22
|
+
}
|
|
23
|
+
timerId.current = setTimeout(() => {
|
|
24
|
+
timerId.current = undefined;
|
|
25
|
+
action();
|
|
26
|
+
}, delay);
|
|
27
|
+
}, [timerId]);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export function useSuggestions<T>(initialValue: string|null|undefined, {expandOnFocus, getOption, getSuggestions}: UseSuggestionsArgs<T>) {
|
|
31
|
+
const suggestionRequestDebouncer = useSimpleDebouncer(200);
|
|
32
|
+
const [requestId, nextRequestId] = useNonRenderingCounter();
|
|
33
|
+
const [isLoading, setIsLoading] = useState(false);
|
|
34
|
+
const [latestSuggestions, dispatchSuggestionsUpdate] = useReducer(useSuggestionSuggestionUpdateReducer<T>,
|
|
35
|
+
{hasLoadingError: false, requestId: 0, suggestions: []});
|
|
36
|
+
const [input, setInput] = useState(initialValue ?? "");
|
|
37
|
+
|
|
38
|
+
useEffect(() => {
|
|
39
|
+
const myRequestId = nextRequestId();
|
|
40
|
+
if (getOption === undefined) {
|
|
41
|
+
dispatchSuggestionsUpdate({hasLoadingError: false, suggestions: [], requestId: myRequestId});
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
if (!expandOnFocus && input.length < 2) {
|
|
45
|
+
dispatchSuggestionsUpdate({hasLoadingError: false, suggestions: [], requestId: myRequestId});
|
|
46
|
+
} else {
|
|
47
|
+
setIsLoading(true);
|
|
48
|
+
getOption(input)
|
|
49
|
+
.then(option => dispatchSuggestionsUpdate({hasLoadingError: false, suggestions: option ? [option] : [], requestId: myRequestId}))
|
|
50
|
+
.catch(err => {
|
|
51
|
+
dispatchSuggestionsUpdate({hasLoadingError: true, suggestions: [], requestId: myRequestId});
|
|
52
|
+
console.error("An error occurred while loading options:", err);
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
}, [expandOnFocus, getOption]);
|
|
56
|
+
|
|
57
|
+
useEffect(() => {
|
|
58
|
+
const myRequestId = nextRequestId();
|
|
59
|
+
if (!expandOnFocus && input.length < 2) {
|
|
60
|
+
dispatchSuggestionsUpdate({hasLoadingError: false, suggestions: [], requestId: myRequestId});
|
|
61
|
+
} else {
|
|
62
|
+
const myRequestId = nextRequestId();
|
|
63
|
+
setIsLoading(true);
|
|
64
|
+
suggestionRequestDebouncer(() => {
|
|
65
|
+
getSuggestions(input)
|
|
66
|
+
.then(suggestions => dispatchSuggestionsUpdate({hasLoadingError: false, suggestions, requestId: myRequestId}))
|
|
67
|
+
.catch(err => {
|
|
68
|
+
dispatchSuggestionsUpdate({hasLoadingError: true, suggestions: [], requestId: myRequestId});
|
|
69
|
+
console.error("An error occurred while loading options:", err);
|
|
70
|
+
});
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
}, [input, suggestionRequestDebouncer]);
|
|
74
|
+
|
|
75
|
+
// This is a separate useEffect hook because we don't necessarily want to update the rendered state when a new request is sent out.
|
|
76
|
+
useEffect(() => setIsLoading(latestSuggestions.requestId < requestId.current), [latestSuggestions.requestId]);
|
|
77
|
+
|
|
78
|
+
return {
|
|
79
|
+
hasLoadingError: latestSuggestions.hasLoadingError, isInitializing: latestSuggestions.requestId === 0, isLoading,
|
|
80
|
+
input, setInput, suggestions: latestSuggestions.suggestions
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
function useSuggestionSuggestionUpdateReducer<T>(state: SuggestionState<T>, action: SuggestionState<T>): SuggestionState<T> {
|
|
84
|
+
if (action.requestId <= state.requestId) {
|
|
85
|
+
return state;
|
|
86
|
+
}
|
|
87
|
+
if (action.hasLoadingError) {
|
|
88
|
+
return {hasLoadingError: true, requestId: action.requestId, suggestions: [...state.suggestions]};
|
|
89
|
+
}
|
|
90
|
+
return action;
|
|
91
|
+
}
|