@plaudit/gutenberg-api-extensions 2.79.0 → 2.80.1
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 -4
- 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 +23 -31
- 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 +120 -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 +156 -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 +113 -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,51 @@
|
|
|
1
|
+
import {useSuspenseSelect} from "@wordpress/data";
|
|
2
|
+
import {useMemo} from "@wordpress/element";
|
|
3
|
+
import {addFilter} from "@wordpress/hooks";
|
|
4
|
+
|
|
5
|
+
import {produce} from "immer";
|
|
6
|
+
|
|
7
|
+
import {useNodeContext} from "../../layout/NodeContext";
|
|
8
|
+
|
|
9
|
+
export default function() {
|
|
10
|
+
addFilter(
|
|
11
|
+
'plaudit.gutenbergApiExtensions.simpleNativeProperties.suspendableOptions.resolve',
|
|
12
|
+
'plaudit/gutenberg-api-extensions/simple-native-properties/suspendable-options',
|
|
13
|
+
(options: unknown | undefined, selectorInfo: URL, {attributes}: { attributes: Record<string, any> | null }) => {
|
|
14
|
+
if (options !== undefined || selectorInfo.protocol !== "select:") {
|
|
15
|
+
return options;
|
|
16
|
+
}
|
|
17
|
+
const nodeContext = useNodeContext("get contextual options");
|
|
18
|
+
const trimmedAttributes = useMemo(() => {
|
|
19
|
+
if (selectorInfo.searchParams.has("attributes")) {
|
|
20
|
+
if (attributes === null) {
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
return produce(attributes, draft => {
|
|
24
|
+
let current = draft;
|
|
25
|
+
for (const p of nodeContext.path.slice(0, nodeContext.path.length - 1)) {
|
|
26
|
+
if (typeof p === 'string') {
|
|
27
|
+
current = current.p;
|
|
28
|
+
} else {
|
|
29
|
+
current = current[p];
|
|
30
|
+
}
|
|
31
|
+
if (current === undefined) {
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
const lastItem = nodeContext.path[nodeContext.path.length - 1]!;
|
|
36
|
+
if (typeof lastItem === 'string') {
|
|
37
|
+
delete current[lastItem];
|
|
38
|
+
} else {
|
|
39
|
+
current.splice(lastItem, 1);
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
} else {
|
|
43
|
+
return undefined;
|
|
44
|
+
}
|
|
45
|
+
}, [attributes, nodeContext]);
|
|
46
|
+
return useSuspenseSelect(select => {
|
|
47
|
+
return (select(selectorInfo.hostname + selectorInfo.pathname) as any).get(selectorInfo.username, trimmedAttributes);
|
|
48
|
+
}, [selectorInfo, trimmedAttributes]);
|
|
49
|
+
}, 100_000
|
|
50
|
+
);
|
|
51
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import {useSettings} from "@wordpress/block-editor";
|
|
2
|
+
import {addFilter} from "@wordpress/hooks";
|
|
3
|
+
|
|
4
|
+
export default function() {
|
|
5
|
+
addFilter(
|
|
6
|
+
'plaudit.gutenbergApiExtensions.simpleNativeProperties.suspendableOptions.resolve',
|
|
7
|
+
'plaudit/gutenberg-api-extensions/simple-native-properties/suspendable-options',
|
|
8
|
+
(options: unknown | undefined, selectorInfo: URL) => {
|
|
9
|
+
return options === undefined && selectorInfo.protocol === "settings:" ? useSettings(selectorInfo.hostname)[0] : options;
|
|
10
|
+
}, 100_000
|
|
11
|
+
);
|
|
12
|
+
|
|
13
|
+
addFilter(
|
|
14
|
+
'plaudit.gutenbergApiExtensions.simpleNativeProperties.suspendableOptions.postProcess',
|
|
15
|
+
'plaudit/gutenberg-api-extensions/simple-native-properties/suspendable-options',
|
|
16
|
+
(options: unknown, selectorInfo: URL) => {
|
|
17
|
+
if (selectorInfo.protocol !== "settings:") {
|
|
18
|
+
return options;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
if (!Array.isArray(options)) {
|
|
22
|
+
console.error(`The "settings" protocol for CSNPs only supports array-formatted values. ${selectorInfo} did not resolve to an array`);
|
|
23
|
+
return [];
|
|
24
|
+
}
|
|
25
|
+
const valueTransformer = getValueTransformer(selectorInfo);
|
|
26
|
+
return options
|
|
27
|
+
.filter((s): s is { name: string, slug: string } & ({ value: string | number, icon?: string } | { color: string }) => {
|
|
28
|
+
if (typeof s === 'object' && s && typeof s["name"] === 'string' && typeof s["slug"] === 'string') {
|
|
29
|
+
if (typeof s["value"] === 'string' || typeof s["value"] === 'number') {
|
|
30
|
+
if ("color" in s) {
|
|
31
|
+
console.error("Encountered an invalid setting value:", s);
|
|
32
|
+
return false;
|
|
33
|
+
}
|
|
34
|
+
} else if (typeof s["color"] !== 'string' || "value" in s) {
|
|
35
|
+
console.error("Encountered an invalid setting value:", s);
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
return true;
|
|
39
|
+
}
|
|
40
|
+
return false;
|
|
41
|
+
})
|
|
42
|
+
.map(s => {
|
|
43
|
+
const {slug, name: label, ...rest} = s;
|
|
44
|
+
return {...rest, value: valueTransformer(slug), label};
|
|
45
|
+
});
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
function getValueTransformer(selectorInfo: URL): (value: string) => string {
|
|
49
|
+
const valuePattern = getValuePatternAccountingForLegacyCode(selectorInfo);
|
|
50
|
+
if (!valuePattern) {
|
|
51
|
+
return value => value;
|
|
52
|
+
}
|
|
53
|
+
if (!valuePattern.includes("$slug")) {
|
|
54
|
+
throw new Error("Value patterns provided to the \"settings\" protocol MUST include '$slug'");
|
|
55
|
+
}
|
|
56
|
+
return value => valuePattern.replaceAll("$slug", value);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function getValuePatternAccountingForLegacyCode(selectorInfo: URL) {
|
|
60
|
+
const res = selectorInfo.searchParams.get("value-pattern") || selectorInfo.searchParams.get("valuePattern");
|
|
61
|
+
if (!res) {
|
|
62
|
+
for (const key of selectorInfo.searchParams.keys()) {
|
|
63
|
+
if (key.includes("$slug")) {
|
|
64
|
+
return key;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
return res;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import {useSelect} from "@wordpress/data";
|
|
2
|
+
import {useMemo} from "@wordpress/element";
|
|
3
|
+
import {applyFilters} from "@wordpress/hooks";
|
|
4
|
+
|
|
5
|
+
import type {CSNPConfig, PromisablePickableOptions, SuspendablePromisablePickableOptions} from "../csnp-api";
|
|
6
|
+
import type {PickableOptions} from "../../controls";
|
|
7
|
+
import {useNodeContext} from "../layout/NodeContext";
|
|
8
|
+
import {isPromise, use} from "../../lib/suspense/promise-handlers";
|
|
9
|
+
import {blockEditorStore} from "../utilities";
|
|
10
|
+
|
|
11
|
+
type RefablePromisablePickableOptions<T> = T extends {options: PromisablePickableOptions<infer V, infer T>} ? PickableOptions<V, T> : never;
|
|
12
|
+
export function isSuspendableOptions<V extends string|number, T extends object = {}>(thing: PromisablePickableOptions<V, T>|string): thing is SuspendablePromisablePickableOptions {
|
|
13
|
+
return typeof thing === 'string' || thing instanceof URL;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
type ExcavateMapSelect<T> = T extends (...args: any[]) => any ? T : never;
|
|
17
|
+
export function useSuspendableOptions<T extends CSNPConfig&{options: PromisablePickableOptions<any>}>(config: T): RefablePromisablePickableOptions<T> {
|
|
18
|
+
const rawOptions = isPromise(config.options) ? use(config.options) : config.options;
|
|
19
|
+
if (isSuspendableOptions(rawOptions)) {
|
|
20
|
+
const selectorInfo = toSuspendableOptionsURI(rawOptions);
|
|
21
|
+
const nodeContext = useNodeContext("get contextual options");
|
|
22
|
+
const blockClientId = nodeContext.dataController.blockClientId;
|
|
23
|
+
|
|
24
|
+
const usesBlockAttributes = applyFilters('plaudit.gutenbergApiExtensions.simpleNativeProperties.suspendableOptions.usesBlockAttributes',
|
|
25
|
+
selectorInfo.searchParams.has("attributes"), selectorInfo, blockClientId);
|
|
26
|
+
|
|
27
|
+
// This if/else statement is present because actually passing attributes through to the selectors represents a SEVERE relative performance hit.
|
|
28
|
+
// At a minimum, it causes at leat one additional full execution pass, and, due to how data can be cached, that pass is almost guaranteed to turn into at least one full render.
|
|
29
|
+
let mapSelect: (...args: Parameters<ExcavateMapSelect<Parameters<typeof useSelect>[0]>>) => [Record<string, any>|null, string|null];
|
|
30
|
+
if (usesBlockAttributes) {
|
|
31
|
+
mapSelect = wrappedSelect => {
|
|
32
|
+
const selected = wrappedSelect(blockEditorStore);
|
|
33
|
+
return [selected.getBlockAttributes(blockClientId), selected.getBlockName(blockClientId)];
|
|
34
|
+
};
|
|
35
|
+
} else {
|
|
36
|
+
mapSelect = wrappedSelect => [null, wrappedSelect(blockEditorStore).getBlockName(blockClientId)];
|
|
37
|
+
}
|
|
38
|
+
const [attributes, blockName] = useSelect(mapSelect, [blockClientId]);
|
|
39
|
+
|
|
40
|
+
const potentiallyPromisedOptions = applyFilters('plaudit.gutenbergApiExtensions.simpleNativeProperties.suspendableOptions.resolve',
|
|
41
|
+
undefined, selectorInfo, {attributes, blockName});
|
|
42
|
+
if (potentiallyPromisedOptions === undefined) {
|
|
43
|
+
throw new Error(`Encountered an unsupported suspendable option request: ${rawOptions}`);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// selectorInfo is guaranteed to be valid by virtue of the checks performed while getting the handler
|
|
47
|
+
const options = potentiallyPromisedOptions && typeof potentiallyPromisedOptions === 'object' && 'then' in potentiallyPromisedOptions
|
|
48
|
+
? use(potentiallyPromisedOptions as Promise<unknown>) : potentiallyPromisedOptions;
|
|
49
|
+
|
|
50
|
+
return useMemo(() => {
|
|
51
|
+
return applyFilters('plaudit.gutenbergApiExtensions.simpleNativeProperties.suspendableOptions.postProcess', options, selectorInfo, {attributes, blockName});
|
|
52
|
+
}, [options, selectorInfo, attributes, blockName]) as RefablePromisablePickableOptions<T>;
|
|
53
|
+
} else {
|
|
54
|
+
return rawOptions as RefablePromisablePickableOptions<T>;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export type SuspendableOptionsHandler = (selectorInfo: URL, params: {attributes: Record<string, any>|null, blockName: string|null}) => any;
|
|
59
|
+
|
|
60
|
+
function toSuspendableOptionsURI(rawOptions: string|URL) {
|
|
61
|
+
if (rawOptions instanceof URL) {
|
|
62
|
+
return rawOptions;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
return useMemo(() => {
|
|
66
|
+
try {
|
|
67
|
+
const res = new URL(rawOptions);
|
|
68
|
+
if (res.protocol === "select:") {
|
|
69
|
+
if (res.username && res.hostname) {
|
|
70
|
+
return res;
|
|
71
|
+
}
|
|
72
|
+
} else if (res.protocol === "setting:" || res.protocol === "settings:") {
|
|
73
|
+
if (res.protocol === "setting:") {
|
|
74
|
+
console.warn(`Encountered a Suspendable Option parameter using deprecated protocol:`, res.toString(), "\nThe \"setting\" protocol has been renamed to \"settings\"");
|
|
75
|
+
res.protocol = "settings:";
|
|
76
|
+
}
|
|
77
|
+
if (res.hostname) {
|
|
78
|
+
return res;
|
|
79
|
+
}
|
|
80
|
+
} else {
|
|
81
|
+
return res;
|
|
82
|
+
}
|
|
83
|
+
} catch {
|
|
84
|
+
// We're not throwing on an invalid URI here because we want a chance to run the deprecated-syntax handling logic
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
const selectorInfo = rawOptions.split(":") as [string, ...string[]];
|
|
88
|
+
let correctedRawOptions: string;
|
|
89
|
+
if (selectorInfo[0] === 'select') {
|
|
90
|
+
if (selectorInfo.length < 3 || !selectorInfo[1] || !selectorInfo[2]) {
|
|
91
|
+
throw new Error(`The "select" protocol for Suspendable Options must have at least 3 colon-delimited parts. Got: ${rawOptions}`);
|
|
92
|
+
}
|
|
93
|
+
// Deprecated: select:plaudit/simple-gutenberg-apis:plaudit-base.conditional-display.show-when-options:attributes
|
|
94
|
+
// Corrected: select://plaudit-base.conditional-display.show-when-options@plaudit/simple-gutenberg-apis?attributes
|
|
95
|
+
correctedRawOptions = `select://${selectorInfo[2]}@${selectorInfo[1]}`;
|
|
96
|
+
if (selectorInfo[3]) {
|
|
97
|
+
correctedRawOptions += "?" + selectorInfo[3];
|
|
98
|
+
}
|
|
99
|
+
} else if (selectorInfo[0] === 'setting' || selectorInfo[0] === 'settings') {
|
|
100
|
+
if (!selectorInfo[1]) {
|
|
101
|
+
throw new Error(`The "settings" protocol for Suspendable Options must have at least 2 colon-delimited parts. Got: ${rawOptions}`);
|
|
102
|
+
}
|
|
103
|
+
// Deprecated: setting:plaudit.markerDisplay:with-inherit
|
|
104
|
+
// Corrected: settings://plaudit.markerDisplay?with-inherit
|
|
105
|
+
correctedRawOptions = `settings://${selectorInfo[1]}`;
|
|
106
|
+
if (selectorInfo.length > 2) {
|
|
107
|
+
const query = selectorInfo.slice(2).join("&");
|
|
108
|
+
if (query.replaceAll("&", "").length > 0) {
|
|
109
|
+
correctedRawOptions += "?" + query;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
} else {
|
|
113
|
+
throw new Error(`Encountered an invalid suspendable options value: ${rawOptions}. Suspendable option values MUST be URIs.`);
|
|
114
|
+
}
|
|
115
|
+
console.warn(`Encountered a Suspendable Option parameter using deprecated syntax:`, rawOptions, "\nIt should be replaced with:", correctedRawOptions);
|
|
116
|
+
return new URL(correctedRawOptions);
|
|
117
|
+
}, [rawOptions]);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
import initSelectProtocol from "./built-in-suspendable-option-protocols/select";
|
|
121
|
+
import initSettingsProtocol from "./built-in-suspendable-option-protocols/settings";
|
|
122
|
+
initSelectProtocol();
|
|
123
|
+
initSettingsProtocol();
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export * from "./layered-styles-api";
|
|
2
|
+
export * from "./simple-block";
|
|
3
|
+
export * from "./shared-exportable-types";
|
|
4
|
+
export * from "./simple-native-property-api";
|
|
5
|
+
export * from "./snp-data-store";
|
|
6
|
+
export * from "./utilities";
|
|
7
|
+
|
|
8
|
+
export type {SuspendableOptionsHandler} from "./hooks/useSuspendableOptions";
|
|
9
|
+
|
|
10
|
+
export {type DbSource, installCustomBlockBindingsSupport, registerCustomBlockBindingsSource} from "./basic-custom-block-bindings-support";
|
|
11
|
+
export type {BlockName} from "../lib/useful-types"; // This is for backwards compatibility
|
|
12
|
+
|
|
13
|
+
import {installGutenbergExtensions} from "../index";
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* @deprecated use installGutenbergExtensions() instead
|
|
17
|
+
*/
|
|
18
|
+
export function installGutenbergBlockExtensions() {
|
|
19
|
+
installGutenbergExtensions();
|
|
20
|
+
}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
ColorPaletteCSNPConfig,
|
|
3
|
+
CommonPropertyConfig,
|
|
4
|
+
RadioPropertyCSNPConfig,
|
|
5
|
+
SelectPropertyCSNPConfig,
|
|
6
|
+
ToggleGroupPropertyCSNPConfig,
|
|
7
|
+
TogglePropertyCSNPConfig
|
|
8
|
+
} from "./csnp-api";
|
|
9
|
+
import type {PickableOptions} from "../controls";
|
|
10
|
+
import {installGutenbergExtensions} from "../index";
|
|
11
|
+
import type {BlockName} from "../lib/useful-types";
|
|
12
|
+
import {registerSimpleNativeProperties, SimpleNativeProperty} from "./simple-native-property-api";
|
|
13
|
+
|
|
14
|
+
type BaseLayeredBlockStyleLayer = {
|
|
15
|
+
name: string;
|
|
16
|
+
title: string;
|
|
17
|
+
default?: string|undefined;
|
|
18
|
+
condition?: SimpleNativeProperty['condition']
|
|
19
|
+
alwaysStore?: boolean|undefined;
|
|
20
|
+
styleProperty?: string;
|
|
21
|
+
}&Pick<CommonPropertyConfig<any, any, any, any>, 'help'>
|
|
22
|
+
|
|
23
|
+
type LayeredBlockStyleColorLayer = BaseLayeredBlockStyleLayer&{
|
|
24
|
+
picker: 'color'|'colorPalette';
|
|
25
|
+
clearable?: boolean|undefined;
|
|
26
|
+
options: PickableOptions<string, {color?: string}>|ColorPaletteCSNPConfig['options'];
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
type LayeredBlockStyleToggleLayer = BaseLayeredBlockStyleLayer&{picker: 'toggle'}&Pick<TogglePropertyCSNPConfig, 'switch'>
|
|
30
|
+
|
|
31
|
+
type LayeredBlockStyleToggleGroupLayer = BaseLayeredBlockStyleLayer&{
|
|
32
|
+
picker?: 'toggle-control'|'toggleGroup';
|
|
33
|
+
clearable?: boolean|undefined;
|
|
34
|
+
options: ToggleGroupPropertyCSNPConfig['options'];
|
|
35
|
+
}
|
|
36
|
+
type LayeredBlockStyleSelectOrRadioLayer = BaseLayeredBlockStyleLayer&{options: PickableOptions<string>}&({picker: 'select', clearable?: boolean|undefined}|{picker: 'radio'})
|
|
37
|
+
|
|
38
|
+
export type LayeredBlockStyleLayer = LayeredBlockStyleColorLayer|LayeredBlockStyleToggleLayer|LayeredBlockStyleToggleGroupLayer|LayeredBlockStyleSelectOrRadioLayer;
|
|
39
|
+
|
|
40
|
+
export interface LayeredBlockStylesConfig {
|
|
41
|
+
block: BlockName[]|BlockName;
|
|
42
|
+
layers: LayeredBlockStyleLayer[];
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export function registerLayeredBlockStyles(config: LayeredBlockStylesConfig) {
|
|
46
|
+
registerSimpleNativeProperties({
|
|
47
|
+
block: config.block,
|
|
48
|
+
properties: {
|
|
49
|
+
group: 'layered-styles',
|
|
50
|
+
title: "Layered Styles",
|
|
51
|
+
properties: config.layers.map(layer => {
|
|
52
|
+
const sharedProps = {
|
|
53
|
+
name: layer.name,
|
|
54
|
+
label: layer.title,
|
|
55
|
+
condition: layer.condition,
|
|
56
|
+
alwaysStore: layer.alwaysStore ?? ((layer.default ?? '') !== ''),
|
|
57
|
+
styleProperty: layer.styleProperty
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
const clearable = "clearable" in layer && (layer.clearable ?? false);
|
|
61
|
+
let defaultValue: string|undefined;
|
|
62
|
+
if (clearable) {
|
|
63
|
+
if (layer.default) {
|
|
64
|
+
console.error(`Layered Style, "${layer.title}" on ${Array.isArray(config.block) ? config.block.join(', ') : config.block}`,
|
|
65
|
+
"is improperly configured with both clearable and a non-empty default.");
|
|
66
|
+
defaultValue = "";
|
|
67
|
+
} else {
|
|
68
|
+
defaultValue = layer.default;
|
|
69
|
+
}
|
|
70
|
+
} else {
|
|
71
|
+
defaultValue = layer.default;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
switch (layer.picker) {
|
|
75
|
+
case undefined:
|
|
76
|
+
case 'toggle-control':
|
|
77
|
+
case 'toggleGroup':
|
|
78
|
+
return {
|
|
79
|
+
...sharedProps,
|
|
80
|
+
clearable,
|
|
81
|
+
control: 'toggleGroup',
|
|
82
|
+
default: defaultValue,
|
|
83
|
+
options: layer.options,
|
|
84
|
+
help: layer.help
|
|
85
|
+
} as ToggleGroupPropertyCSNPConfig;
|
|
86
|
+
case 'color':
|
|
87
|
+
case 'colorPalette':
|
|
88
|
+
return {
|
|
89
|
+
...sharedProps,
|
|
90
|
+
allowCustom: false,
|
|
91
|
+
clearable,
|
|
92
|
+
control: 'colorPalette',
|
|
93
|
+
default: defaultValue,
|
|
94
|
+
options: layer.options,
|
|
95
|
+
help: layer.help
|
|
96
|
+
} as ColorPaletteCSNPConfig;
|
|
97
|
+
case 'radio':
|
|
98
|
+
return {
|
|
99
|
+
...sharedProps,
|
|
100
|
+
control: 'radio',
|
|
101
|
+
options: layer.options,
|
|
102
|
+
default: layer.default,
|
|
103
|
+
allowCustom: false,
|
|
104
|
+
help: layer.help
|
|
105
|
+
} as RadioPropertyCSNPConfig;
|
|
106
|
+
case 'select':
|
|
107
|
+
return {
|
|
108
|
+
...sharedProps,
|
|
109
|
+
clearable,
|
|
110
|
+
control: 'select',
|
|
111
|
+
default: defaultValue,
|
|
112
|
+
options: layer.options,
|
|
113
|
+
help: layer.help
|
|
114
|
+
} as SelectPropertyCSNPConfig;
|
|
115
|
+
case 'toggle':
|
|
116
|
+
return {
|
|
117
|
+
...sharedProps,
|
|
118
|
+
control: 'toggle',
|
|
119
|
+
default: defaultValue,
|
|
120
|
+
switch: layer.switch ?? {small: true},
|
|
121
|
+
help: layer.help,
|
|
122
|
+
transformer: {
|
|
123
|
+
to(input: unknown) {
|
|
124
|
+
return input !== undefined && input !== null ? (typeof input === 'boolean' ? input : input?.toString().toLowerCase() === 'true') : undefined;
|
|
125
|
+
},
|
|
126
|
+
from(value: boolean|undefined) {
|
|
127
|
+
return value?.toString();
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
} as TogglePropertyCSNPConfig
|
|
131
|
+
}
|
|
132
|
+
})
|
|
133
|
+
}
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* @deprecated use installGutenbergExtensions() instead.
|
|
139
|
+
*/
|
|
140
|
+
export function installLayeredBlockStylesSupport() {
|
|
141
|
+
installGutenbergExtensions();
|
|
142
|
+
}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import {select} from "@wordpress/data";
|
|
2
|
+
|
|
3
|
+
import type {ActualBlockEditProps} from "../lib/useful-types";
|
|
4
|
+
import type {PDSimpleNativeProperty} from "./simple-native-property-api";
|
|
5
|
+
import {makeHasPropClassName} from "./simple-native-property-impl";
|
|
6
|
+
import {SNPDataStore} from "./snp-data-store";
|
|
7
|
+
|
|
8
|
+
export class LayeredStylesDataStore extends SNPDataStore {
|
|
9
|
+
getAttribute(name: string): any {
|
|
10
|
+
if (name.startsWith("__plaudit/")) {
|
|
11
|
+
return this.blockEditProps.attributes[name];
|
|
12
|
+
}
|
|
13
|
+
const layer = select('plaudit/gutenberg-api-extensions').blockStylesLayer(this.blockEditProps.name, name);
|
|
14
|
+
if (layer === undefined) {
|
|
15
|
+
return undefined;
|
|
16
|
+
}
|
|
17
|
+
return extractStyleLayerValueFromAttributes(this.blockEditProps.attributes, layer.name) ?? layer.default;
|
|
18
|
+
}
|
|
19
|
+
setAttribute(name: string, rawValue: any) {
|
|
20
|
+
if (name.startsWith("__plaudit/")) {
|
|
21
|
+
this.blockEditProps.setAttributes({[name]: rawValue});
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
const layers = select('plaudit/gutenberg-api-extensions').blockStylesLayers(this.blockEditProps.name);
|
|
25
|
+
if (layers === undefined) {
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
const layer = layers[name];
|
|
29
|
+
if (layer === undefined) {
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const className = this.blockEditProps.attributes['className'];
|
|
34
|
+
|
|
35
|
+
const value = rawValue?.toString() || (layer.default ?? '');
|
|
36
|
+
const currentLayerClassPrefix = `style-${name}-`;
|
|
37
|
+
if (typeof className !== 'string' || !className) {
|
|
38
|
+
if (value.length) {
|
|
39
|
+
this.blockEditProps.setAttributes({
|
|
40
|
+
className: "styleProperty" in layer && layer.styleProperty
|
|
41
|
+
? `${currentLayerClassPrefix}${value} ${makeHasPropClassName(layer.name)}`
|
|
42
|
+
: `${currentLayerClassPrefix}${value}`
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
this.blockEditProps.setAttributes({className: this.incorporateLayerValue(Object.values(layers), layer, name, value, className)});
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
private incorporateLayerValue(layers: PDSimpleNativeProperty[], currentLayer: PDSimpleNativeProperty, name: string, value: string, className: string): string {
|
|
51
|
+
const classNames = className.split(/\s+/);
|
|
52
|
+
const layeredStyleClassPrefixes = layers.map(layer => `style-${layer.name}-`);
|
|
53
|
+
const nonLayerClasses = classNames
|
|
54
|
+
.filter(cn => !layeredStyleClassPrefixes.some(lc => cn.startsWith(lc)));
|
|
55
|
+
|
|
56
|
+
const layerPrefixPairs = layers
|
|
57
|
+
.filter(layer => layer.name !== name)
|
|
58
|
+
.map<[PDSimpleNativeProperty, string]>(layer => [layer, `style-${layer.name}-`]);
|
|
59
|
+
const layerClasses: string[] = [];
|
|
60
|
+
for (const [layer, prefix] of layerPrefixPairs) {
|
|
61
|
+
if (this.hasCachedValue(layer.name)) {
|
|
62
|
+
const layerValue = this.getCachedValue(layer.name);
|
|
63
|
+
if (layerValue) {
|
|
64
|
+
layerClasses.push(`${prefix}${layerValue}`);
|
|
65
|
+
}
|
|
66
|
+
} else {
|
|
67
|
+
const layerValueClass = classNames.find(cn => cn.startsWith(prefix));
|
|
68
|
+
if (layerValueClass) {
|
|
69
|
+
layerClasses.push(layerValueClass);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
if (value) {
|
|
74
|
+
layerClasses.push(`style-${name}-${value}`);
|
|
75
|
+
if ('styleProperty' in currentLayer && currentLayer.styleProperty) {
|
|
76
|
+
const hasPropClassName = makeHasPropClassName(currentLayer.name);
|
|
77
|
+
if (!nonLayerClasses.includes(hasPropClassName)) {
|
|
78
|
+
nonLayerClasses.push(hasPropClassName);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
return [...nonLayerClasses, ...layerClasses.sort()].join(' ');
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
export function extractStyleLayerValueFromAttributes(attributes: ActualBlockEditProps['attributes'], layerName: string) {
|
|
87
|
+
const className = attributes['className'];
|
|
88
|
+
if (typeof className !== 'string') {
|
|
89
|
+
return undefined;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
const currentLayerClassPrefix = `style-${layerName}-`;
|
|
93
|
+
return attributes['className']?.split(/\s+/).find(className => className.startsWith(currentLayerClassPrefix))?.substring(currentLayerClassPrefix.length);
|
|
94
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import {createSlotFill, __experimentalToolsPanelItem as ToolsPanelItem, Spinner} from "@wordpress/components";
|
|
2
|
+
import {memo, useCallback, useMemo} from "@wordpress/element";
|
|
3
|
+
|
|
4
|
+
import {type NodeContextValue, useNodeContext} from "./NodeContext";
|
|
5
|
+
import type {HydratedSimpleNativeProperty, SNPControlSlots} from "../simple-native-property-api";
|
|
6
|
+
import {useToolsPanelContext} from "./ToolsPanelContext";
|
|
7
|
+
|
|
8
|
+
import {Suspense} from "react";
|
|
9
|
+
|
|
10
|
+
export type LaidOutPropertyProps = {property: HydratedSimpleNativeProperty, inToolsPanel?: boolean};
|
|
11
|
+
export const LaidOutProperty = memo(function({property, inToolsPanel}: LaidOutPropertyProps) {
|
|
12
|
+
const nodeContext = useNodeContext("render a node");
|
|
13
|
+
if (nodeContext.rendered) {
|
|
14
|
+
return <ActualPropertyRenderer property={property} nodeContext={nodeContext} inToolsPanel={inToolsPanel} />;
|
|
15
|
+
}
|
|
16
|
+
return null;
|
|
17
|
+
});
|
|
18
|
+
const divStyle = {flex: "1"};
|
|
19
|
+
function ActualPropertyRenderer({property, nodeContext, inToolsPanel}: {property: HydratedSimpleNativeProperty, nodeContext: NodeContextValue, inToolsPanel?: boolean}) {
|
|
20
|
+
const [
|
|
21
|
+
{Slot: Label, Fill: LabelFill},
|
|
22
|
+
{Slot: Messages, Fill: MessagesFill}
|
|
23
|
+
] = useMemo(() => [
|
|
24
|
+
createSlotFill(Symbol("laid-out-property-label")),
|
|
25
|
+
createSlotFill(Symbol("laid-out-property-messages"))
|
|
26
|
+
], []);
|
|
27
|
+
const onBlur = useCallback(() => nodeContext.validateNode(), [nodeContext]);
|
|
28
|
+
|
|
29
|
+
const classNames = ["plaudit-snp-laid-out-property"];
|
|
30
|
+
if (property.required) {
|
|
31
|
+
classNames.push("required");
|
|
32
|
+
}
|
|
33
|
+
if (nodeContext.validationError) {
|
|
34
|
+
classNames.push("has-validation-error");
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const transformedValue = useMemo(() => property.transformer ? property.transformer.to(nodeContext.value) : nodeContext.value,
|
|
38
|
+
[nodeContext.value, property.transformer]);
|
|
39
|
+
const onChangeWithTransform = useCallback((value: any) => {
|
|
40
|
+
nodeContext.setValue(property.transformer ? property.transformer.from(value) : value);
|
|
41
|
+
}, [nodeContext.setValue, property.transformer]);
|
|
42
|
+
|
|
43
|
+
const commonParts = <>
|
|
44
|
+
<LabelFill>{property.label}{property.required && <span className="requiredMarker">*</span>}</LabelFill>
|
|
45
|
+
<MessagesFill>
|
|
46
|
+
{nodeContext.validationError && <div className="validation-error-message">{nodeContext.validationError.split(/\r?\n/gi).map(line => <>{line}<br/></>)}</div>}
|
|
47
|
+
</MessagesFill>
|
|
48
|
+
</>;
|
|
49
|
+
if (inToolsPanel) {
|
|
50
|
+
const toolsPanelContext = useToolsPanelContext("render a tools-panel property");
|
|
51
|
+
return <ToolsPanelItem
|
|
52
|
+
label={property.label ?? property.name}
|
|
53
|
+
hasValue={useCallback(() => transformedValue !== undefined, [transformedValue])}
|
|
54
|
+
onSelect={useCallback(() => nodeContext.setValue(toolsPanelContext.getDefaultValue(property.name)), [nodeContext.setValue, toolsPanelContext, property.name])}
|
|
55
|
+
onDeselect={useCallback(() => nodeContext.setValue(undefined), [nodeContext.setValue])}
|
|
56
|
+
resetAllFilter={useCallback((a: any) => a ? Object.fromEntries(Object.entries(a).filter(([name]) => name !== property.name)) : a, [property.name])}
|
|
57
|
+
>
|
|
58
|
+
{commonParts}{renderPropInner(property, onBlur, classNames, transformedValue, onChangeWithTransform, {Label, Messages})}
|
|
59
|
+
</ToolsPanelItem>;
|
|
60
|
+
} else {
|
|
61
|
+
return <>{commonParts}{renderPropInner(property, onBlur, classNames, transformedValue, onChangeWithTransform, {Label, Messages})}</>;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
function renderPropInner(
|
|
65
|
+
property: HydratedSimpleNativeProperty, onBlur: () => void, classNames: string[], transformedValue: any, onChangeWithTransform: (value: any) => void, slots: SNPControlSlots
|
|
66
|
+
) {
|
|
67
|
+
return <div style={divStyle} className={classNames.join(" ")} onBlur={onBlur} data-plaudit-snp-control-type={property.controlType}>
|
|
68
|
+
<Suspense fallback={typeof property.initializing === 'function' ? property.initializing() : <><Spinner /> {property.initializing}</>}>
|
|
69
|
+
<property.control value={transformedValue} onChange={onChangeWithTransform} slots={slots} />
|
|
70
|
+
</Suspense>
|
|
71
|
+
</div>;
|
|
72
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import {LaidOutProperty} from "./LaidOutProperty";
|
|
2
|
+
import {NodeContextWrapper} from "./NodeContext";
|
|
3
|
+
import type {DataController} from "../simple-native-property-api";
|
|
4
|
+
import type {HydratedLaidOutProperties} from "../simple-native-property-internal-shared";
|
|
5
|
+
|
|
6
|
+
import React from "react";
|
|
7
|
+
|
|
8
|
+
export function LaidOutPropertyRow(
|
|
9
|
+
{property, dataController, inToolsPanel}: {property: HydratedLaidOutProperties[number], dataController?: DataController, inToolsPanel?: boolean}
|
|
10
|
+
) {
|
|
11
|
+
if (Array.isArray(property)) {
|
|
12
|
+
return <div style={{display: "flex", flexWrap: "wrap", columnGap: "8px"}}>
|
|
13
|
+
{...property.map(prop => <NodeContextWrapper key={prop.name} nodeName={prop.name} dataController={dataController}>
|
|
14
|
+
<LaidOutProperty property={prop} inToolsPanel={inToolsPanel} />
|
|
15
|
+
</NodeContextWrapper>)}
|
|
16
|
+
</div>;
|
|
17
|
+
} else {
|
|
18
|
+
return <NodeContextWrapper nodeName={property.name} dataController={dataController}>
|
|
19
|
+
<LaidOutProperty property={property} inToolsPanel={inToolsPanel} />
|
|
20
|
+
</NodeContextWrapper>;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import {createContext, useContext, useMemo} from "@wordpress/element";
|
|
2
|
+
|
|
3
|
+
import type {DataController, NodePath} from "../simple-native-property-api";
|
|
4
|
+
|
|
5
|
+
import type {ReactNode} from "react";
|
|
6
|
+
|
|
7
|
+
type NodeContextValueActions = {
|
|
8
|
+
setValue(value: any): void,
|
|
9
|
+
addNode(name: string|number, value?: any): void,
|
|
10
|
+
removeNode(name: string|number): void,
|
|
11
|
+
moveNode(indices: {from: number, to: number}|{from: string, to: string}): void,
|
|
12
|
+
validateNode(): void
|
|
13
|
+
};
|
|
14
|
+
export type NodeContextValue = {path: NodePath, dataController: DataController, rendered: boolean, validationError?: string, value: any}&NodeContextValueActions;
|
|
15
|
+
|
|
16
|
+
export const NodeContext = createContext<NodeContextValue|undefined>(undefined);
|
|
17
|
+
|
|
18
|
+
function makeNodeContextValue(path: NodePath, dataController: DataController): NodeContextValue {
|
|
19
|
+
const value = dataController.getValue(path);
|
|
20
|
+
const node = dataController.getNode(path);
|
|
21
|
+
// We memoize actions separately to reduce later re-render calls
|
|
22
|
+
const actions = useMemo<NodeContextValueActions>(() => ({
|
|
23
|
+
setValue: value => dataController.setValue(path, value),
|
|
24
|
+
addNode: (name, value) => dataController.addNode([...path, name], value),
|
|
25
|
+
removeNode: name => dataController.removeNode([...path, name]),
|
|
26
|
+
moveNode: indices => dataController.moveNode(path, indices),
|
|
27
|
+
validateNode: () => dataController.dispatch({type: "validateNode", path})
|
|
28
|
+
}), [path, dataController]);
|
|
29
|
+
// We can skip testing path and dataController because we're checking actions
|
|
30
|
+
return useMemo(() => ({path, dataController, rendered: node.rendered ?? true, validationError: node.validationError, value, ...actions}), [actions, node, value]);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export function useNodeContext(action: string): NodeContextValue {
|
|
34
|
+
const currentContext = useContext(NodeContext);
|
|
35
|
+
if (currentContext === undefined) {
|
|
36
|
+
throw new Error(`Cannot ${action} outside of an existing NodeContext`);
|
|
37
|
+
}
|
|
38
|
+
return currentContext;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export function DescendantNodeContext({nodeName, children}: {nodeName: string|number, children: ReactNode}) {
|
|
42
|
+
const currentContext = useNodeContext("create a descendant NodeContext");
|
|
43
|
+
const descendantPath = useMemo(
|
|
44
|
+
() => currentContext.path.toSpliced(currentContext.path.length, 0, nodeName) as NodePath, [nodeName, currentContext.path]);
|
|
45
|
+
return <NodeContext.Provider value={makeNodeContextValue(descendantPath, currentContext.dataController)} children={children} />;
|
|
46
|
+
}
|
|
47
|
+
export function RootNodeContext({nodeName, dataController, children}: {nodeName: string, dataController: DataController, children: ReactNode}) {
|
|
48
|
+
const path = useMemo<NodePath>(() => [nodeName], [nodeName]);
|
|
49
|
+
return <NodeContext.Provider value={makeNodeContextValue(path, dataController)} children={children} />;
|
|
50
|
+
}
|
|
51
|
+
type NodeContextWrapperProps = {nodeName: string|number, children: ReactNode, dataController?: undefined}|{nodeName: string, dataController: DataController, children: ReactNode};
|
|
52
|
+
export function NodeContextWrapper(props: NodeContextWrapperProps) {
|
|
53
|
+
return props.dataController !== undefined ? RootNodeContext(props) : DescendantNodeContext(props);
|
|
54
|
+
}
|