@wix/patterns-fields 1.95.0 → 1.96.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/cjs/components/address/input/address-input.js +127 -36
- package/dist/cjs/components/address/input/address-input.js.map +1 -1
- package/dist/cjs/components/address/input/address-input.st.css.js +3 -3
- package/dist/cjs/components/address/input/address-input.st.css.js.map +1 -1
- package/dist/cjs/components/audio/actions/actions-menu/actions-menu.st.css.js +3 -3
- package/dist/cjs/components/audio/actions/actions-menu/actions-menu.st.css.js.map +1 -1
- package/dist/cjs/components/audio/audio-field/controlled-audio.uni.driver.js +3 -2
- package/dist/cjs/components/audio/audio-field/controlled-audio.uni.driver.js.map +1 -1
- package/dist/cjs/components/audio/audio-field/form-audio-field.js +55 -48
- package/dist/cjs/components/audio/audio-field/form-audio-field.js.map +1 -1
- package/dist/cjs/components/audio/audio-field/form-audio-field.st.css.js +4 -4
- package/dist/cjs/components/audio/audio-field/form-audio-field.st.css.js.map +1 -1
- package/dist/cjs/components/audio/audio-player/audio-player.st.css.js +2 -2
- package/dist/cjs/components/audio/audio-player/audio-player.st.css.js.map +1 -1
- package/dist/cjs/components/color-view/cell-color-view.st.css.js +3 -3
- package/dist/cjs/components/color-view/cell-color-view.st.css.js.map +1 -1
- package/dist/cjs/components/color-view/color-view.st.css.js +4 -4
- package/dist/cjs/components/color-view/color-view.st.css.js.map +1 -1
- package/dist/cjs/components/delete-dialog/delete-dialog.st.css.js +3 -3
- package/dist/cjs/components/delete-dialog/delete-dialog.st.css.js.map +1 -1
- package/dist/cjs/components/document/form-document-field.st.css.js +7 -7
- package/dist/cjs/components/document/form-document-field.st.css.js.map +1 -1
- package/dist/cjs/components/exclamation/exclamation.st.css.js +5 -5
- package/dist/cjs/components/exclamation/exclamation.st.css.js.map +1 -1
- package/dist/cjs/components/field-validation-settings/field-validation-settings-input.js +85 -49
- package/dist/cjs/components/field-validation-settings/field-validation-settings-input.js.map +1 -1
- package/dist/cjs/components/field-validation-settings/field-validation-settings.uni.driver.js +2 -1
- package/dist/cjs/components/field-validation-settings/field-validation-settings.uni.driver.js.map +1 -1
- package/dist/cjs/components/highlighted-text/highlighted-text.st.css.js +5 -5
- package/dist/cjs/components/highlighted-text/highlighted-text.st.css.js.map +1 -1
- package/dist/cjs/components/image/thumbnail-replace-overlay.st.css.js +3 -3
- package/dist/cjs/components/image/thumbnail-replace-overlay.st.css.js.map +1 -1
- package/dist/cjs/components/media-control/cell-media-edit-shell.st.css.js +2 -2
- package/dist/cjs/components/media-control/cell-media-edit-shell.st.css.js.map +1 -1
- package/dist/cjs/components/media-control/paste-url-button.st.css.js +4 -4
- package/dist/cjs/components/media-control/paste-url-button.st.css.js.map +1 -1
- package/dist/cjs/components/media-gallery/form-media-gallery-field.st.css.js +10 -10
- package/dist/cjs/components/media-gallery/form-media-gallery-field.st.css.js.map +1 -1
- package/dist/cjs/components/media-image/media-image.st.css.js +4 -4
- package/dist/cjs/components/media-image/media-image.st.css.js.map +1 -1
- package/dist/cjs/components/media-image/overlays/overlay.st.css.js +3 -3
- package/dist/cjs/components/media-image/overlays/overlay.st.css.js.map +1 -1
- package/dist/cjs/components/media-tag/web-media-tag/media-tag.st.css.js +2 -2
- package/dist/cjs/components/media-tag/web-media-tag/media-tag.st.css.js.map +1 -1
- package/dist/cjs/components/multi-document/cell-multi-document-edit.st.css.js +3 -3
- package/dist/cjs/components/multi-document/cell-multi-document-edit.st.css.js.map +1 -1
- package/dist/cjs/components/multi-document/multi-document-input/form-multi-document.st.css.js +5 -5
- package/dist/cjs/components/multi-document/multi-document-input/form-multi-document.st.css.js.map +1 -1
- package/dist/cjs/components/reference/cell-multi-reference-input.st.css.js +2 -2
- package/dist/cjs/components/reference/cell-multi-reference-input.st.css.js.map +1 -1
- package/dist/cjs/components/reference/cell-reference-input.st.css.js +3 -3
- package/dist/cjs/components/reference/cell-reference-input.st.css.js.map +1 -1
- package/dist/cjs/components/rich-content/rich-content-input/default-value-input/rich-content-default-value-input.st.css.js +4 -4
- package/dist/cjs/components/rich-content/rich-content-input/default-value-input/rich-content-default-value-input.st.css.js.map +1 -1
- package/dist/cjs/components/rich-content/rich-content-input/form-input/rich-content-form-input.st.css.js +3 -3
- package/dist/cjs/components/rich-content/rich-content-input/form-input/rich-content-form-input.st.css.js.map +1 -1
- package/dist/cjs/components/rich-content/rich-content-input/form-read-only-input/rich-content-form-read-only-input.st.css.js +2 -2
- package/dist/cjs/components/rich-content/rich-content-input/form-read-only-input/rich-content-form-read-only-input.st.css.js.map +1 -1
- package/dist/cjs/components/rich-content/rich-content-input/rich-content-common/fullscreen-modal/fullscreen-modal.st.css.js +3 -3
- package/dist/cjs/components/rich-content/rich-content-input/rich-content-common/fullscreen-modal/fullscreen-modal.st.css.js.map +1 -1
- package/dist/cjs/components/rich-content/rich-content-input/rich-content-common/publish-loader/publish-loader.st.css.js +3 -3
- package/dist/cjs/components/rich-content/rich-content-input/rich-content-common/publish-loader/publish-loader.st.css.js.map +1 -1
- package/dist/cjs/components/rich-content/rich-content-input/rich-content-common/toggle-fullscreen-button/toggle-fullscreen-button.st.css.js +2 -2
- package/dist/cjs/components/rich-content/rich-content-input/rich-content-common/toggle-fullscreen-button/toggle-fullscreen-button.st.css.js.map +1 -1
- package/dist/cjs/components/rich-content/rich-content-input/rich-content-editor/rich-content-editor.st.css.js +7 -7
- package/dist/cjs/components/rich-content/rich-content-input/rich-content-editor/rich-content-editor.st.css.js.map +1 -1
- package/dist/cjs/components/rich-content/rich-content-input/rich-content-editor/rich-content-toolbar.st.css.js +5 -5
- package/dist/cjs/components/rich-content/rich-content-input/rich-content-editor/rich-content-toolbar.st.css.js.map +1 -1
- package/dist/cjs/components/rich-content/rich-content-input/rich-content-viewer/rich-content-viewer.st.css.js +4 -4
- package/dist/cjs/components/rich-content/rich-content-input/rich-content-viewer/rich-content-viewer.st.css.js.map +1 -1
- package/dist/cjs/components/rich-text/rich-text-input/rich-text-editor/rich-editor.st.css.js +18 -18
- package/dist/cjs/components/rich-text/rich-text-input/rich-text-editor/rich-editor.st.css.js.map +1 -1
- package/dist/cjs/components/rich-text/rich-text-input/rich-text-editor/rich-text-editor.st.css.js +4 -4
- package/dist/cjs/components/rich-text/rich-text-input/rich-text-editor/rich-text-editor.st.css.js.map +1 -1
- package/dist/cjs/components/rich-text/rich-text-input/rich-text-editor/toolbar/toolbar.st.css.js +18 -18
- package/dist/cjs/components/rich-text/rich-text-input/rich-text-editor/toolbar/toolbar.st.css.js.map +1 -1
- package/dist/cjs/components/text/text-view.st.css.js +3 -3
- package/dist/cjs/components/text/text-view.st.css.js.map +1 -1
- package/dist/cjs/components/url/form-url.js +22 -9
- package/dist/cjs/components/url/form-url.js.map +1 -1
- package/dist/cjs/components/video/form-video-field.js +35 -28
- package/dist/cjs/components/video/form-video-field.js.map +1 -1
- package/dist/cjs/services/atlas/types.js.map +1 -1
- package/dist/cjs/services/atlas/wix-atlas-service.js +16 -1
- package/dist/cjs/services/atlas/wix-atlas-service.js.map +1 -1
- package/dist/cjs/styles.global.css +1 -1
- package/dist/cjs/types/validation.js.map +1 -1
- package/dist/esm/components/address/input/address-input.js +139 -38
- package/dist/esm/components/address/input/address-input.js.map +1 -1
- package/dist/esm/components/address/input/address-input.st.css.js +2 -2
- package/dist/esm/components/address/input/address-input.st.css.js.map +1 -1
- package/dist/esm/components/audio/actions/actions-menu/actions-menu.st.css.js +2 -2
- package/dist/esm/components/audio/audio-field/controlled-audio.uni.driver.js +3 -2
- package/dist/esm/components/audio/audio-field/controlled-audio.uni.driver.js.map +1 -1
- package/dist/esm/components/audio/audio-field/form-audio-field.js +9 -13
- package/dist/esm/components/audio/audio-field/form-audio-field.js.map +1 -1
- package/dist/esm/components/audio/audio-field/form-audio-field.st.css.js +2 -2
- package/dist/esm/components/audio/audio-field/form-audio-field.st.css.js.map +1 -1
- package/dist/esm/components/audio/audio-player/audio-player.st.css.js +2 -2
- package/dist/esm/components/color-view/cell-color-view.st.css.js +2 -2
- package/dist/esm/components/color-view/cell-color-view.st.css.js.map +1 -1
- package/dist/esm/components/color-view/color-view.st.css.js +2 -2
- package/dist/esm/components/color-view/color-view.st.css.js.map +1 -1
- package/dist/esm/components/delete-dialog/delete-dialog.st.css.js +2 -2
- package/dist/esm/components/document/form-document-field.st.css.js +2 -2
- package/dist/esm/components/exclamation/exclamation.st.css.js +2 -2
- package/dist/esm/components/field-validation-settings/field-validation-settings-input.js +45 -10
- package/dist/esm/components/field-validation-settings/field-validation-settings-input.js.map +1 -1
- package/dist/esm/components/field-validation-settings/field-validation-settings.uni.driver.js +2 -1
- package/dist/esm/components/field-validation-settings/field-validation-settings.uni.driver.js.map +1 -1
- package/dist/esm/components/highlighted-text/highlighted-text.st.css.js +3 -3
- package/dist/esm/components/image/thumbnail-replace-overlay.st.css.js +2 -2
- package/dist/esm/components/media-control/cell-media-edit-shell.st.css.js +2 -2
- package/dist/esm/components/media-control/paste-url-button.st.css.js +2 -2
- package/dist/esm/components/media-gallery/form-media-gallery-field.st.css.js +2 -2
- package/dist/esm/components/media-image/media-image.st.css.js +3 -3
- package/dist/esm/components/media-image/overlays/overlay.st.css.js +2 -2
- package/dist/esm/components/media-tag/web-media-tag/media-tag.st.css.js +2 -2
- package/dist/esm/components/multi-document/cell-multi-document-edit.st.css.js +2 -2
- package/dist/esm/components/multi-document/multi-document-input/form-multi-document.st.css.js +2 -2
- package/dist/esm/components/multi-document/multi-document-input/form-multi-document.st.css.js.map +1 -1
- package/dist/esm/components/reference/cell-multi-reference-input.st.css.js +2 -2
- package/dist/esm/components/reference/cell-multi-reference-input.st.css.js.map +1 -1
- package/dist/esm/components/reference/cell-reference-input.st.css.js +2 -2
- package/dist/esm/components/rich-content/rich-content-input/default-value-input/rich-content-default-value-input.st.css.js +2 -2
- package/dist/esm/components/rich-content/rich-content-input/form-input/rich-content-form-input.st.css.js +2 -2
- package/dist/esm/components/rich-content/rich-content-input/form-input/rich-content-form-input.st.css.js.map +1 -1
- package/dist/esm/components/rich-content/rich-content-input/form-read-only-input/rich-content-form-read-only-input.st.css.js +2 -2
- package/dist/esm/components/rich-content/rich-content-input/form-read-only-input/rich-content-form-read-only-input.st.css.js.map +1 -1
- package/dist/esm/components/rich-content/rich-content-input/rich-content-common/fullscreen-modal/fullscreen-modal.st.css.js +2 -2
- package/dist/esm/components/rich-content/rich-content-input/rich-content-common/fullscreen-modal/fullscreen-modal.st.css.js.map +1 -1
- package/dist/esm/components/rich-content/rich-content-input/rich-content-common/publish-loader/publish-loader.st.css.js +2 -2
- package/dist/esm/components/rich-content/rich-content-input/rich-content-common/publish-loader/publish-loader.st.css.js.map +1 -1
- package/dist/esm/components/rich-content/rich-content-input/rich-content-common/toggle-fullscreen-button/toggle-fullscreen-button.st.css.js +2 -2
- package/dist/esm/components/rich-content/rich-content-input/rich-content-editor/rich-content-editor.st.css.js +2 -2
- package/dist/esm/components/rich-content/rich-content-input/rich-content-editor/rich-content-toolbar.st.css.js +2 -2
- package/dist/esm/components/rich-content/rich-content-input/rich-content-viewer/rich-content-viewer.st.css.js +2 -2
- package/dist/esm/components/rich-text/rich-text-input/rich-text-editor/rich-editor.st.css.js +2 -2
- package/dist/esm/components/rich-text/rich-text-input/rich-text-editor/rich-text-editor.st.css.js +2 -2
- package/dist/esm/components/rich-text/rich-text-input/rich-text-editor/rich-text-editor.st.css.js.map +1 -1
- package/dist/esm/components/rich-text/rich-text-input/rich-text-editor/toolbar/toolbar.st.css.js +2 -2
- package/dist/esm/components/rich-text/rich-text-input/rich-text-editor/toolbar/toolbar.st.css.js.map +1 -1
- package/dist/esm/components/text/text-view.st.css.js +2 -2
- package/dist/esm/components/url/form-url.js +14 -1
- package/dist/esm/components/url/form-url.js.map +1 -1
- package/dist/esm/components/video/form-video-field.js +8 -1
- package/dist/esm/components/video/form-video-field.js.map +1 -1
- package/dist/esm/services/atlas/wix-atlas-service.js +22 -2
- package/dist/esm/services/atlas/wix-atlas-service.js.map +1 -1
- package/dist/esm/styles.global.css +1 -1
- package/dist/types/components/address/input/address-input.d.ts.map +1 -1
- package/dist/types/components/address/input/address-input.st.css.d.ts.map +1 -1
- package/dist/types/components/audio/audio-field/controlled-audio.uni.driver.d.ts +1 -0
- package/dist/types/components/audio/audio-field/controlled-audio.uni.driver.d.ts.map +1 -1
- package/dist/types/components/audio/audio-field/form-audio-field.d.ts.map +1 -1
- package/dist/types/components/audio/audio-field/form-audio-field.st.css.d.ts.map +1 -1
- package/dist/types/components/color-view/cell-color-view.st.css.d.ts.map +1 -1
- package/dist/types/components/color-view/color-view.st.css.d.ts.map +1 -1
- package/dist/types/components/controlled-input.uni.driver.d.ts +1 -0
- package/dist/types/components/controlled-input.uni.driver.d.ts.map +1 -1
- package/dist/types/components/field-validation-settings/field-validation-settings-input.d.ts +4 -1
- package/dist/types/components/field-validation-settings/field-validation-settings-input.d.ts.map +1 -1
- package/dist/types/components/field-validation-settings/field-validation-settings.uni.driver.d.ts +7 -0
- package/dist/types/components/field-validation-settings/field-validation-settings.uni.driver.d.ts.map +1 -1
- package/dist/types/components/multi-document/multi-document-input/form-multi-document.st.css.d.ts.map +1 -1
- package/dist/types/components/reference/cell-multi-reference-input.st.css.d.ts.map +1 -1
- package/dist/types/components/rich-content/rich-content-input/form-input/rich-content-form-input.st.css.d.ts.map +1 -1
- package/dist/types/components/rich-content/rich-content-input/form-read-only-input/rich-content-form-read-only-input.st.css.d.ts.map +1 -1
- package/dist/types/components/rich-content/rich-content-input/rich-content-common/fullscreen-modal/fullscreen-modal.st.css.d.ts.map +1 -1
- package/dist/types/components/rich-content/rich-content-input/rich-content-common/publish-loader/publish-loader.st.css.d.ts.map +1 -1
- package/dist/types/components/rich-text/rich-text-input/rich-text-editor/rich-text-editor.st.css.d.ts.map +1 -1
- package/dist/types/components/rich-text/rich-text-input/rich-text-editor/toolbar/toolbar.st.css.d.ts.map +1 -1
- package/dist/types/components/url/form-url.d.ts.map +1 -1
- package/dist/types/components/video/form-video-field.d.ts.map +1 -1
- package/dist/types/services/atlas/types.d.ts +5 -1
- package/dist/types/services/atlas/types.d.ts.map +1 -1
- package/dist/types/services/atlas/wix-atlas-service.d.ts +6 -1
- package/dist/types/services/atlas/wix-atlas-service.d.ts.map +1 -1
- package/dist/types/types/validation.d.ts +6 -1
- package/dist/types/types/validation.d.ts.map +1 -1
- package/package.json +4 -4
- package/src/__tests__/components/address/address-input.driver.tsx +17 -1
- package/src/__tests__/components/address/address-input.spec.tsx +207 -1
- package/src/__tests__/components/field-validation-settings/field-validation-settings-input.spec.tsx +87 -0
- package/src/__tests__/components/url/form-url.spec.tsx +63 -0
- package/src/__tests__/components/video/form-video.spec.tsx +17 -0
- package/src/__tests__/exports/controlled-inputs.spec.tsx +46 -0
- package/src/components/address/input/address-input.st.css.ts +2 -2
- package/src/components/address/input/address-input.tsx +163 -50
- package/src/components/audio/actions/actions-menu/actions-menu.st.css.ts +2 -2
- package/src/components/audio/audio-field/controlled-audio.uni.driver.ts +3 -2
- package/src/components/audio/audio-field/form-audio-field.st.css.ts +2 -2
- package/src/components/audio/audio-field/form-audio-field.tsx +59 -53
- package/src/components/audio/audio-player/audio-player.st.css.ts +2 -2
- package/src/components/color-view/cell-color-view.st.css.ts +2 -2
- package/src/components/color-view/color-view.st.css.ts +2 -2
- package/src/components/delete-dialog/delete-dialog.st.css.ts +2 -2
- package/src/components/document/form-document-field.st.css.ts +2 -2
- package/src/components/exclamation/exclamation.st.css.ts +2 -2
- package/src/components/field-validation-settings/field-validation-settings-input.tsx +75 -11
- package/src/components/field-validation-settings/field-validation-settings.uni.driver.ts +3 -1
- package/src/components/highlighted-text/highlighted-text.st.css.ts +3 -3
- package/src/components/image/thumbnail-replace-overlay.st.css.ts +2 -2
- package/src/components/media-control/cell-media-edit-shell.st.css.ts +2 -2
- package/src/components/media-control/paste-url-button.st.css.ts +2 -2
- package/src/components/media-gallery/form-media-gallery-field.st.css.ts +2 -2
- package/src/components/media-image/media-image.st.css.ts +3 -3
- package/src/components/media-image/overlays/overlay.st.css.ts +2 -2
- package/src/components/media-tag/web-media-tag/media-tag.st.css.ts +2 -2
- package/src/components/multi-document/cell-multi-document-edit.st.css.ts +2 -2
- package/src/components/multi-document/multi-document-input/form-multi-document.st.css.ts +2 -2
- package/src/components/reference/cell-multi-reference-input.st.css.ts +2 -2
- package/src/components/reference/cell-reference-input.st.css.ts +2 -2
- package/src/components/rich-content/rich-content-input/default-value-input/rich-content-default-value-input.st.css.ts +2 -2
- package/src/components/rich-content/rich-content-input/form-input/rich-content-form-input.st.css.ts +2 -2
- package/src/components/rich-content/rich-content-input/form-read-only-input/rich-content-form-read-only-input.st.css.ts +2 -2
- package/src/components/rich-content/rich-content-input/rich-content-common/fullscreen-modal/fullscreen-modal.st.css.ts +2 -2
- package/src/components/rich-content/rich-content-input/rich-content-common/publish-loader/publish-loader.st.css.ts +2 -2
- package/src/components/rich-content/rich-content-input/rich-content-common/toggle-fullscreen-button/toggle-fullscreen-button.st.css.ts +2 -2
- package/src/components/rich-content/rich-content-input/rich-content-editor/rich-content-editor.st.css.ts +2 -2
- package/src/components/rich-content/rich-content-input/rich-content-editor/rich-content-toolbar.st.css.ts +2 -2
- package/src/components/rich-content/rich-content-input/rich-content-viewer/rich-content-viewer.st.css.ts +2 -2
- package/src/components/rich-text/rich-text-input/rich-text-editor/rich-editor.st.css.ts +2 -2
- package/src/components/rich-text/rich-text-input/rich-text-editor/rich-text-editor.st.css.ts +2 -2
- package/src/components/rich-text/rich-text-input/rich-text-editor/toolbar/toolbar.st.css.ts +2 -2
- package/src/components/text/text-view.st.css.ts +2 -2
- package/src/components/url/form-url.tsx +16 -1
- package/src/components/video/form-video-field.tsx +6 -0
- package/src/services/atlas/types.ts +6 -1
- package/src/services/atlas/wix-atlas-service.ts +27 -3
- package/src/styles.global.css +1 -1
- package/src/types/validation.ts +6 -1
- package/dist/cjs/components/media-loader/index.js +0 -10
- package/dist/cjs/components/media-loader/index.js.map +0 -1
- package/dist/cjs/components/media-loader/media-loader.js +0 -37
- package/dist/cjs/components/media-loader/media-loader.js.map +0 -1
- package/dist/cjs/components/media-loader/media-loader.st.css +0 -20
- package/dist/cjs/components/media-loader/media-loader.st.css.js +0 -29
- package/dist/cjs/components/media-loader/media-loader.st.css.js.map +0 -1
- package/dist/esm/components/media-loader/index.js +0 -2
- package/dist/esm/components/media-loader/index.js.map +0 -1
- package/dist/esm/components/media-loader/media-loader.js +0 -8
- package/dist/esm/components/media-loader/media-loader.js.map +0 -1
- package/dist/esm/components/media-loader/media-loader.st.css +0 -20
- package/dist/esm/components/media-loader/media-loader.st.css.js +0 -15
- package/dist/esm/components/media-loader/media-loader.st.css.js.map +0 -1
- package/dist/types/components/media-loader/index.d.ts +0 -2
- package/dist/types/components/media-loader/index.d.ts.map +0 -1
- package/dist/types/components/media-loader/media-loader.d.ts +0 -7
- package/dist/types/components/media-loader/media-loader.d.ts.map +0 -1
- package/dist/types/components/media-loader/media-loader.st.css.d.ts +0 -20
- package/dist/types/components/media-loader/media-loader.st.css.d.ts.map +0 -1
- package/src/components/media-loader/index.ts +0 -1
- package/src/components/media-loader/media-loader.st.css +0 -20
- package/src/components/media-loader/media-loader.st.css.ts +0 -25
- package/src/components/media-loader/media-loader.tsx +0 -30
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { location } from '@wix/atlas';
|
|
1
|
+
import type { autocomplete, location } from '@wix/atlas';
|
|
2
2
|
/**
|
|
3
3
|
* The @wix/atlas SDK types are auto-generated from public API schemas and are incomplete.
|
|
4
4
|
*/
|
|
@@ -6,8 +6,12 @@ type SdkAddress = NonNullable<location.SearchResult['address']>;
|
|
|
6
6
|
export interface AtlasAddress extends SdkAddress {
|
|
7
7
|
formatted?: string;
|
|
8
8
|
}
|
|
9
|
+
export type AtlasPrediction = autocomplete.Prediction;
|
|
9
10
|
export interface AtlasService {
|
|
10
11
|
searchAddress: (query: string) => Promise<AtlasAddress[]>;
|
|
12
|
+
/** Supply both methods to show predictions and resolve the selected place. */
|
|
13
|
+
predictAddress?: (query: string) => Promise<AtlasPrediction[]>;
|
|
14
|
+
getAddress?: (searchId: string) => Promise<AtlasAddress | undefined>;
|
|
11
15
|
}
|
|
12
16
|
export {};
|
|
13
17
|
//# sourceMappingURL=types.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/services/atlas/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/services/atlas/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAEzD;;GAEG;AACH,KAAK,UAAU,GAAG,WAAW,CAAC,QAAQ,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC,CAAC;AAEhE,MAAM,WAAW,YAAa,SAAQ,UAAU;IAC9C,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,MAAM,eAAe,GAAG,YAAY,CAAC,UAAU,CAAC;AAEtD,MAAM,WAAW,YAAY;IAC3B,aAAa,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC;IAC1D,8EAA8E;IAC9E,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,eAAe,EAAE,CAAC,CAAC;IAC/D,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,YAAY,GAAG,SAAS,CAAC,CAAC;CACtE"}
|
|
@@ -1,9 +1,14 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { WixPatternsContainer } from '@wix/bex-core';
|
|
2
|
+
import type { AtlasService, AtlasAddress, AtlasPrediction } from './types';
|
|
2
3
|
/**
|
|
3
4
|
* Wix Atlas service implementation for address search/autocomplete
|
|
4
5
|
* Uses the public @wix/atlas SDK which handles authentication automatically
|
|
5
6
|
*/
|
|
6
7
|
export declare class WixAtlasService implements AtlasService {
|
|
8
|
+
private readonly errorHandler?;
|
|
9
|
+
constructor(errorHandler?: WixPatternsContainer["errorHandler"] | undefined);
|
|
10
|
+
predictAddress(query: string): Promise<AtlasPrediction[]>;
|
|
11
|
+
getAddress(searchId: string): Promise<AtlasAddress | undefined>;
|
|
7
12
|
searchAddress(query: string): Promise<AtlasAddress[]>;
|
|
8
13
|
}
|
|
9
14
|
//# sourceMappingURL=wix-atlas-service.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wix-atlas-service.d.ts","sourceRoot":"","sources":["../../../../src/services/atlas/wix-atlas-service.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"wix-atlas-service.d.ts","sourceRoot":"","sources":["../../../../src/services/atlas/wix-atlas-service.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAE1D,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAG3E;;;GAGG;AACH,qBAAa,eAAgB,YAAW,YAAY;IAEhD,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAC;gBAAb,YAAY,CAAC,EAAE,oBAAoB,CAAC,cAAc,CAAC,YAAA;IAGhE,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC;IAQzD,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,SAAS,CAAC;IAQ/D,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;CAiB5D"}
|
|
@@ -28,6 +28,8 @@ export interface CharactersLimitFieldValidationRuleConfig {
|
|
|
28
28
|
separator: string;
|
|
29
29
|
outOfBoundsError(min: number, max: number): string;
|
|
30
30
|
maxBelowMinError: string;
|
|
31
|
+
/** Shown under this rule while another rule blocks it. */
|
|
32
|
+
exclusiveRulesExplanation?: string;
|
|
31
33
|
}
|
|
32
34
|
export interface SpecificValuesFieldValidationRuleConfig {
|
|
33
35
|
type: 'specificValues';
|
|
@@ -37,7 +39,8 @@ export interface SpecificValuesFieldValidationRuleConfig {
|
|
|
37
39
|
duplicateError: string;
|
|
38
40
|
addButton: string;
|
|
39
41
|
removeButton: string;
|
|
40
|
-
|
|
42
|
+
/** Shown under this rule while another rule blocks it. */
|
|
43
|
+
exclusiveRulesExplanation?: string;
|
|
41
44
|
}
|
|
42
45
|
export interface PatternFieldValidationRuleConfig {
|
|
43
46
|
type: 'pattern';
|
|
@@ -48,6 +51,8 @@ export interface PatternFieldValidationRuleConfig {
|
|
|
48
51
|
/** Shown for a pattern that compiles but is refused because matching it
|
|
49
52
|
* could hang the page. Falls back to `invalidError`. */
|
|
50
53
|
unsafeError?: string;
|
|
54
|
+
/** Shown under this rule while another rule blocks it. */
|
|
55
|
+
exclusiveRulesExplanation?: string;
|
|
51
56
|
}
|
|
52
57
|
export type FieldValidationRuleConfig = RequiredFieldValidationRuleConfig | CharactersLimitFieldValidationRuleConfig | SpecificValuesFieldValidationRuleConfig | PatternFieldValidationRuleConfig;
|
|
53
58
|
export type FieldValidationRule = FieldValidationRuleConfig['type'];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../../src/types/validation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAEnD,MAAM,MAAM,sBAAsB,GAAG;IACnC,QAAQ,EAAE,OAAO,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,6BAA6B,GAAG;IAC1C,eAAe,EAAE;QAAE,GAAG,CAAC,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CACjD,CAAC;AAEF,MAAM,MAAM,4BAA4B,GAAG;IACzC,cAAc,EAAE,aAAa,EAAE,CAAC;CACjC,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG;IAClC,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,MAAM,WAAW,iCAAiC;IAChD,IAAI,EAAE,UAAU,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,wCAAwC;IACvD,IAAI,EAAE,iBAAiB,CAAC;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAAC;IACnD,gBAAgB,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../../src/types/validation.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wix/patterns-fields",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.96.0",
|
|
4
4
|
"license": "UNLICENSED",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Kobi",
|
|
@@ -124,7 +124,7 @@
|
|
|
124
124
|
"@wix/atlas": "^1.0.35",
|
|
125
125
|
"@wix/data": "^1.0.323",
|
|
126
126
|
"@wix/media": "^1.0.231",
|
|
127
|
-
"@wix/patterns-fields-utils": "1.
|
|
127
|
+
"@wix/patterns-fields-utils": "1.77.0",
|
|
128
128
|
"@wix/rich-content": "1.0.37",
|
|
129
129
|
"@wix/sdk": "^1.17.2",
|
|
130
130
|
"@wix/wix-ui-icons-common": "^3.189.0",
|
|
@@ -152,7 +152,7 @@
|
|
|
152
152
|
"@types/lodash": "^4.17.20",
|
|
153
153
|
"@types/react": "^16.14.68",
|
|
154
154
|
"@wix/babel-cli": "^1.11.0",
|
|
155
|
-
"@wix/bex-core": "2.
|
|
155
|
+
"@wix/bex-core": "2.374.0",
|
|
156
156
|
"@wix/design-system": "^1.319.0",
|
|
157
157
|
"@wix/eslint-config-yoshi": "^6.74.0",
|
|
158
158
|
"@wix/jest-yoshi-preset": "^6.74.0",
|
|
@@ -212,5 +212,5 @@
|
|
|
212
212
|
"optional": true
|
|
213
213
|
}
|
|
214
214
|
},
|
|
215
|
-
"falconPackageHash": "
|
|
215
|
+
"falconPackageHash": "5cd0bb88af543328ef37718c741e23a8661d02f7f12673a9410dde77"
|
|
216
216
|
}
|
|
@@ -8,6 +8,7 @@ import { AddressInputUniDriver } from '../../../components/address/input/address
|
|
|
8
8
|
import { uniTestkitFactoryCreator } from '@wix/wix-ui-test-utils/testing-library';
|
|
9
9
|
import { flush } from '@wix/bex-core/testkit';
|
|
10
10
|
import { PatternsFieldsTestProvider } from '../../../testkit/patterns-fields-test-provider';
|
|
11
|
+
import { InputUniDriver } from '@wix/design-system/dist/testkit/unidriver';
|
|
11
12
|
|
|
12
13
|
const SEARCH_DEBOUNCE_MS = 250;
|
|
13
14
|
|
|
@@ -36,10 +37,19 @@ export class AddressInputDriver {
|
|
|
36
37
|
|
|
37
38
|
waitForDebounce() {
|
|
38
39
|
return act(async () => {
|
|
40
|
+
// Legacy timers do not advance the clock lodash's debounce reads.
|
|
41
|
+
jest.spyOn(Date, 'now').mockReturnValue(Date.now() + SEARCH_DEBOUNCE_MS);
|
|
39
42
|
jest.advanceTimersByTime(SEARCH_DEBOUNCE_MS);
|
|
40
43
|
});
|
|
41
44
|
}
|
|
42
45
|
|
|
46
|
+
pressEscape() {
|
|
47
|
+
return uniTestkitFactoryCreator(InputUniDriver)({
|
|
48
|
+
wrapper: this.renderResult.container,
|
|
49
|
+
dataHook: 'address-input',
|
|
50
|
+
}).keyDown({ key: 'Escape' });
|
|
51
|
+
}
|
|
52
|
+
|
|
43
53
|
render(props: AddressInputProps) {
|
|
44
54
|
this._renderResult = render(
|
|
45
55
|
<AddressInput {...props} atlasService={this._mockService} />,
|
|
@@ -47,7 +57,13 @@ export class AddressInputDriver {
|
|
|
47
57
|
);
|
|
48
58
|
}
|
|
49
59
|
|
|
60
|
+
unmount() {
|
|
61
|
+
this.renderResult.unmount();
|
|
62
|
+
}
|
|
63
|
+
|
|
50
64
|
async flush(iterations?: number) {
|
|
51
|
-
|
|
65
|
+
await act(async () => {
|
|
66
|
+
await flush(iterations);
|
|
67
|
+
});
|
|
52
68
|
}
|
|
53
69
|
}
|
|
@@ -6,7 +6,22 @@ import {
|
|
|
6
6
|
createAtlasServiceMock,
|
|
7
7
|
} from '../../../services/atlas/atlas-service-mock';
|
|
8
8
|
|
|
9
|
+
const mockPredict = jest.fn();
|
|
10
|
+
const mockGetPlace = jest.fn();
|
|
11
|
+
|
|
12
|
+
jest.mock('@wix/atlas', () => ({
|
|
13
|
+
autocomplete: { predict: (...args: unknown[]) => mockPredict(...args) },
|
|
14
|
+
places: { getPlace: (...args: unknown[]) => mockGetPlace(...args) },
|
|
15
|
+
location: { search: jest.fn() },
|
|
16
|
+
}));
|
|
17
|
+
|
|
9
18
|
describe('AddressInput', () => {
|
|
19
|
+
beforeEach(() => {
|
|
20
|
+
jest.useFakeTimers('legacy');
|
|
21
|
+
jest.clearAllMocks();
|
|
22
|
+
});
|
|
23
|
+
afterEach(() => jest.restoreAllMocks());
|
|
24
|
+
|
|
10
25
|
const mockAddress: Address = {
|
|
11
26
|
formatted: 'Halimon 25, Tel Mond, IL',
|
|
12
27
|
city: 'Tel Mond',
|
|
@@ -16,12 +31,16 @@ describe('AddressInput', () => {
|
|
|
16
31
|
const setup = async ({
|
|
17
32
|
mockAtlasService,
|
|
18
33
|
initialValue,
|
|
34
|
+
onChange,
|
|
35
|
+
onSelectAddress,
|
|
19
36
|
}: {
|
|
20
37
|
mockAtlasService?: AtlasService;
|
|
21
38
|
initialValue?: Address;
|
|
39
|
+
onChange?: (value?: Address) => void;
|
|
40
|
+
onSelectAddress?: () => void;
|
|
22
41
|
} = {}) => {
|
|
23
42
|
const driver = new AddressInputDriver({ service: mockAtlasService });
|
|
24
|
-
driver.render({ value: initialValue });
|
|
43
|
+
driver.render({ value: initialValue, onChange, onSelectAddress });
|
|
25
44
|
|
|
26
45
|
await driver.flush();
|
|
27
46
|
return { driver };
|
|
@@ -72,4 +91,191 @@ describe('AddressInput', () => {
|
|
|
72
91
|
expect(await driver.addressInput.getInputValue()).toBe('Test address');
|
|
73
92
|
expect(await driver.addressInput.getAmountOfItems()).toBe(0);
|
|
74
93
|
});
|
|
94
|
+
|
|
95
|
+
it('resolves the selected prediction before returning the complete address', async () => {
|
|
96
|
+
const onChange = jest.fn();
|
|
97
|
+
const onSelectAddress = jest.fn();
|
|
98
|
+
const service: AtlasService = {
|
|
99
|
+
searchAddress: jest.fn(),
|
|
100
|
+
predictAddress: jest.fn().mockResolvedValue([
|
|
101
|
+
{
|
|
102
|
+
searchId: 'place-1',
|
|
103
|
+
description: mockAddress.formatted,
|
|
104
|
+
textStructure: {
|
|
105
|
+
mainText: 'Halimon 25',
|
|
106
|
+
secondaryText: 'Tel Mond, IL',
|
|
107
|
+
},
|
|
108
|
+
},
|
|
109
|
+
]),
|
|
110
|
+
getAddress: jest.fn().mockResolvedValue(mockAddress),
|
|
111
|
+
};
|
|
112
|
+
const { driver } = await setup({
|
|
113
|
+
mockAtlasService: service,
|
|
114
|
+
onChange,
|
|
115
|
+
onSelectAddress,
|
|
116
|
+
});
|
|
117
|
+
await driver.addressInput.clickInput();
|
|
118
|
+
await driver.addressInput.enterText('Halimon');
|
|
119
|
+
await driver.waitForDebounce();
|
|
120
|
+
|
|
121
|
+
expect(await driver.addressInput.getItemMainLabelAt(0)).toBe('Halimon 25');
|
|
122
|
+
expect(await driver.addressInput.getItemSecondaryLabelAt(0)).toBe(
|
|
123
|
+
'Tel Mond, IL',
|
|
124
|
+
);
|
|
125
|
+
expect(onChange).not.toHaveBeenCalled();
|
|
126
|
+
|
|
127
|
+
await driver.addressInput.clickAtOption(0);
|
|
128
|
+
await driver.flush();
|
|
129
|
+
|
|
130
|
+
expect(service.getAddress).toHaveBeenCalledWith('place-1');
|
|
131
|
+
expect(service.searchAddress).not.toHaveBeenCalled();
|
|
132
|
+
expect(onChange).toHaveBeenCalledWith(mockAddress);
|
|
133
|
+
expect(onSelectAddress).toHaveBeenCalledTimes(1);
|
|
134
|
+
expect(await driver.addressInput.getInputValue()).toBe(
|
|
135
|
+
mockAddress.formatted,
|
|
136
|
+
);
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
it('notifies the owner when the input is emptied', async () => {
|
|
140
|
+
const onChange = jest.fn();
|
|
141
|
+
const { driver } = await setup({ initialValue: mockAddress, onChange });
|
|
142
|
+
|
|
143
|
+
await driver.addressInput.enterText('');
|
|
144
|
+
await driver.flush();
|
|
145
|
+
|
|
146
|
+
expect(onChange).toHaveBeenCalledWith(undefined);
|
|
147
|
+
expect(await driver.addressInput.getInputValue()).toBe('');
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
it('uses Atlas predictions and place details by default', async () => {
|
|
151
|
+
mockPredict.mockResolvedValue({
|
|
152
|
+
predictions: [
|
|
153
|
+
{
|
|
154
|
+
searchId: 'atlas-place',
|
|
155
|
+
description: mockAddress.formatted,
|
|
156
|
+
textStructure: {
|
|
157
|
+
mainText: 'Halimon 25',
|
|
158
|
+
secondaryText: 'Tel Mond, IL',
|
|
159
|
+
},
|
|
160
|
+
},
|
|
161
|
+
],
|
|
162
|
+
});
|
|
163
|
+
mockGetPlace.mockResolvedValue({ place: { address: mockAddress } });
|
|
164
|
+
const onChange = jest.fn();
|
|
165
|
+
const { driver } = await setup({ onChange });
|
|
166
|
+
await driver.addressInput.clickInput();
|
|
167
|
+
await driver.addressInput.enterText('Halimon');
|
|
168
|
+
await driver.waitForDebounce();
|
|
169
|
+
await driver.addressInput.clickAtOption(0);
|
|
170
|
+
await driver.flush();
|
|
171
|
+
|
|
172
|
+
expect(mockPredict).toHaveBeenCalledWith('Halimon');
|
|
173
|
+
expect(mockGetPlace).toHaveBeenCalledWith('atlas-place');
|
|
174
|
+
expect(onChange).toHaveBeenCalledWith(mockAddress);
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
it('keeps suggestions for the latest query when an older search finishes later', async () => {
|
|
178
|
+
let resolveFirst: (addresses: Address[]) => void = () => {};
|
|
179
|
+
const first = new Promise<Address[]>((resolve) => {
|
|
180
|
+
resolveFirst = resolve;
|
|
181
|
+
});
|
|
182
|
+
const newerAddress = { formatted: 'New York, NY, USA' };
|
|
183
|
+
const service: AtlasService = {
|
|
184
|
+
searchAddress: jest
|
|
185
|
+
.fn()
|
|
186
|
+
.mockReturnValueOnce(first)
|
|
187
|
+
.mockResolvedValueOnce([newerAddress]),
|
|
188
|
+
};
|
|
189
|
+
const { driver } = await setup({ mockAtlasService: service });
|
|
190
|
+
await driver.addressInput.clickInput();
|
|
191
|
+
await driver.addressInput.enterText('New');
|
|
192
|
+
await driver.waitForDebounce();
|
|
193
|
+
await driver.addressInput.enterText('New York');
|
|
194
|
+
await driver.waitForDebounce();
|
|
195
|
+
resolveFirst([mockAddress]);
|
|
196
|
+
await driver.flush();
|
|
197
|
+
|
|
198
|
+
expect(await driver.addressInput.getItemMainLabelAt(0)).toBe('New York');
|
|
199
|
+
expect(await driver.addressInput.getAmountOfItems()).toBe(1);
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
it('does not restore suggestions when a search completes after clearing', async () => {
|
|
203
|
+
let resolveSearch: (addresses: Address[]) => void = () => {};
|
|
204
|
+
const result = new Promise<Address[]>((resolve) => {
|
|
205
|
+
resolveSearch = resolve;
|
|
206
|
+
});
|
|
207
|
+
const { driver } = await setup({
|
|
208
|
+
mockAtlasService: { searchAddress: () => result },
|
|
209
|
+
});
|
|
210
|
+
await driver.addressInput.clickInput();
|
|
211
|
+
await driver.addressInput.enterText('Halimon');
|
|
212
|
+
await driver.waitForDebounce();
|
|
213
|
+
await driver.addressInput.enterText('');
|
|
214
|
+
resolveSearch([mockAddress]);
|
|
215
|
+
await driver.flush();
|
|
216
|
+
|
|
217
|
+
expect(await driver.addressInput.getAmountOfItems()).toBe(0);
|
|
218
|
+
expect(await driver.addressInput.getInputValue()).toBe('');
|
|
219
|
+
});
|
|
220
|
+
|
|
221
|
+
it('does not commit a place lookup that finishes after the input unmounts', async () => {
|
|
222
|
+
let resolveAddress: (address: Address) => void = () => {};
|
|
223
|
+
const result = new Promise<Address>((resolve) => {
|
|
224
|
+
resolveAddress = resolve;
|
|
225
|
+
});
|
|
226
|
+
const onChange = jest.fn();
|
|
227
|
+
const onSelectAddress = jest.fn();
|
|
228
|
+
const service: AtlasService = {
|
|
229
|
+
searchAddress: jest.fn(),
|
|
230
|
+
predictAddress: async () => [
|
|
231
|
+
{ searchId: 'place-1', description: mockAddress.formatted },
|
|
232
|
+
],
|
|
233
|
+
getAddress: () => result,
|
|
234
|
+
};
|
|
235
|
+
const { driver } = await setup({
|
|
236
|
+
mockAtlasService: service,
|
|
237
|
+
onChange,
|
|
238
|
+
onSelectAddress,
|
|
239
|
+
});
|
|
240
|
+
await driver.addressInput.clickInput();
|
|
241
|
+
await driver.addressInput.enterText('Halimon');
|
|
242
|
+
await driver.waitForDebounce();
|
|
243
|
+
await driver.addressInput.clickAtOption(0);
|
|
244
|
+
driver.unmount();
|
|
245
|
+
resolveAddress(mockAddress);
|
|
246
|
+
await driver.flush();
|
|
247
|
+
|
|
248
|
+
expect(onChange).not.toHaveBeenCalled();
|
|
249
|
+
expect(onSelectAddress).not.toHaveBeenCalled();
|
|
250
|
+
});
|
|
251
|
+
|
|
252
|
+
it('does not replace the address when a place lookup finishes after Escape', async () => {
|
|
253
|
+
let resolveAddress: (address: Address) => void = () => {};
|
|
254
|
+
const result = new Promise<Address>((resolve) => {
|
|
255
|
+
resolveAddress = resolve;
|
|
256
|
+
});
|
|
257
|
+
const onChange = jest.fn();
|
|
258
|
+
const service: AtlasService = {
|
|
259
|
+
searchAddress: jest.fn(),
|
|
260
|
+
predictAddress: async () => [
|
|
261
|
+
{ searchId: 'new-place', description: 'New York, NY, USA' },
|
|
262
|
+
],
|
|
263
|
+
getAddress: () => result,
|
|
264
|
+
};
|
|
265
|
+
const { driver } = await setup({
|
|
266
|
+
mockAtlasService: service,
|
|
267
|
+
initialValue: mockAddress,
|
|
268
|
+
onChange,
|
|
269
|
+
});
|
|
270
|
+
await driver.addressInput.clickInput();
|
|
271
|
+
await driver.addressInput.enterText('New York');
|
|
272
|
+
await driver.waitForDebounce();
|
|
273
|
+
await driver.addressInput.clickAtOption(0);
|
|
274
|
+
await driver.pressEscape();
|
|
275
|
+
|
|
276
|
+
resolveAddress({ formatted: 'New York, NY, USA' });
|
|
277
|
+
await driver.flush();
|
|
278
|
+
|
|
279
|
+
expect(onChange).not.toHaveBeenCalled();
|
|
280
|
+
});
|
|
75
281
|
});
|
package/src/__tests__/components/field-validation-settings/field-validation-settings-input.spec.tsx
CHANGED
|
@@ -30,6 +30,8 @@ const charactersLimitRule: FieldValidationRuleConfig = {
|
|
|
30
30
|
separator: 'and',
|
|
31
31
|
outOfBoundsError: (min, max) => `Enter a value from ${min} to ${max}.`,
|
|
32
32
|
maxBelowMinError: 'Maximum must not be below minimum.',
|
|
33
|
+
exclusiveRulesExplanation:
|
|
34
|
+
"You can't limit character count for specific values.",
|
|
33
35
|
};
|
|
34
36
|
|
|
35
37
|
const specificValuesRule: FieldValidationRuleConfig = {
|
|
@@ -49,6 +51,8 @@ const patternRule: FieldValidationRuleConfig = {
|
|
|
49
51
|
tooltip: 'Pattern tooltip',
|
|
50
52
|
inputLabel: 'Regular expression',
|
|
51
53
|
invalidError: 'Enter a valid regular expression.',
|
|
54
|
+
exclusiveRulesExplanation:
|
|
55
|
+
"You can't add pattern validation for specific values.",
|
|
52
56
|
};
|
|
53
57
|
|
|
54
58
|
const allRules = [
|
|
@@ -68,6 +72,7 @@ interface RenderInputOptions {
|
|
|
68
72
|
readOnly?: boolean;
|
|
69
73
|
invalid?: boolean;
|
|
70
74
|
disabledRules?: readonly FieldValidationRuleConfig['type'][];
|
|
75
|
+
exclusiveSpecificValues?: boolean;
|
|
71
76
|
}
|
|
72
77
|
|
|
73
78
|
const renderInput = (
|
|
@@ -77,6 +82,7 @@ const renderInput = (
|
|
|
77
82
|
readOnly,
|
|
78
83
|
invalid,
|
|
79
84
|
disabledRules,
|
|
85
|
+
exclusiveSpecificValues,
|
|
80
86
|
}: RenderInputOptions = {},
|
|
81
87
|
) => {
|
|
82
88
|
const onChange = jest.fn<void, [FieldValidationSettingsValue]>();
|
|
@@ -91,6 +97,7 @@ const renderInput = (
|
|
|
91
97
|
readOnly={readOnly}
|
|
92
98
|
invalid={invalid}
|
|
93
99
|
disabledRules={disabledRules}
|
|
100
|
+
exclusiveSpecificValues={exclusiveSpecificValues}
|
|
94
101
|
onChange={(nextData) => {
|
|
95
102
|
onChange(nextData);
|
|
96
103
|
setData(nextData);
|
|
@@ -337,6 +344,86 @@ describe('FieldValidationSettingsInput', () => {
|
|
|
337
344
|
expect(await driver.getPatternToggle().isDisabled()).toBe(true);
|
|
338
345
|
});
|
|
339
346
|
|
|
347
|
+
it('explains exclusivity under each rule that specific values block', async () => {
|
|
348
|
+
const { driver } = renderInput({ specificValues: [] });
|
|
349
|
+
|
|
350
|
+
expect(
|
|
351
|
+
await driver.getExclusiveRulesExplanation('characters-limit').text(),
|
|
352
|
+
).toBe("You can't limit character count for specific values.");
|
|
353
|
+
expect(await driver.getExclusiveRulesExplanation('pattern').text()).toBe(
|
|
354
|
+
"You can't add pattern validation for specific values.",
|
|
355
|
+
);
|
|
356
|
+
expect(
|
|
357
|
+
await driver.getExclusiveRulesExplanation('specific-values').exists(),
|
|
358
|
+
).toBe(false);
|
|
359
|
+
});
|
|
360
|
+
|
|
361
|
+
it('explains exclusivity under specific values when a character limit blocks it', async () => {
|
|
362
|
+
const { driver } = renderInput({ charactersLimit: {} });
|
|
363
|
+
|
|
364
|
+
expect(
|
|
365
|
+
await driver.getExclusiveRulesExplanation('specific-values').text(),
|
|
366
|
+
).toBe('Disable the active rule first.');
|
|
367
|
+
expect(
|
|
368
|
+
await driver.getExclusiveRulesExplanation('characters-limit').exists(),
|
|
369
|
+
).toBe(false);
|
|
370
|
+
});
|
|
371
|
+
|
|
372
|
+
it('falls back to the specific-values explanation exactly once for legacy configs', async () => {
|
|
373
|
+
const { driver, container } = renderInput(
|
|
374
|
+
{ specificValues: [] },
|
|
375
|
+
{
|
|
376
|
+
rules: [
|
|
377
|
+
{ ...charactersLimitRule, exclusiveRulesExplanation: undefined },
|
|
378
|
+
specificValuesRule,
|
|
379
|
+
{ ...patternRule, exclusiveRulesExplanation: undefined },
|
|
380
|
+
],
|
|
381
|
+
},
|
|
382
|
+
);
|
|
383
|
+
|
|
384
|
+
expect(await driver.hasExclusiveRulesExplanation()).toBe(true);
|
|
385
|
+
expect(
|
|
386
|
+
Array.from(
|
|
387
|
+
container.querySelectorAll('[data-hook$="exclusive-help"]'),
|
|
388
|
+
).map((node) => node.textContent),
|
|
389
|
+
).toEqual(['Disable the active rule first.']);
|
|
390
|
+
});
|
|
391
|
+
|
|
392
|
+
it('omits an exclusivity explanation when no rule config supplies one', async () => {
|
|
393
|
+
const { driver } = renderInput(
|
|
394
|
+
{ specificValues: [] },
|
|
395
|
+
{
|
|
396
|
+
rules: [
|
|
397
|
+
{ ...charactersLimitRule, exclusiveRulesExplanation: undefined },
|
|
398
|
+
{ ...specificValuesRule, exclusiveRulesExplanation: undefined },
|
|
399
|
+
],
|
|
400
|
+
},
|
|
401
|
+
);
|
|
402
|
+
|
|
403
|
+
expect(await driver.getCharactersLimitToggle().isDisabled()).toBe(true);
|
|
404
|
+
expect(await driver.hasExclusiveRulesExplanation()).toBe(false);
|
|
405
|
+
});
|
|
406
|
+
|
|
407
|
+
it('keeps every rule toggle enabled when specific values are not exclusive', async () => {
|
|
408
|
+
const { driver } = renderInput(
|
|
409
|
+
{ specificValues: [] },
|
|
410
|
+
{ exclusiveSpecificValues: false },
|
|
411
|
+
);
|
|
412
|
+
|
|
413
|
+
expect(await driver.getSpecificValuesToggle().isDisabled()).toBe(false);
|
|
414
|
+
expect(await driver.getCharactersLimitToggle().isDisabled()).toBe(false);
|
|
415
|
+
expect(await driver.getPatternToggle().isDisabled()).toBe(false);
|
|
416
|
+
});
|
|
417
|
+
|
|
418
|
+
it('does not explain exclusivity when specific values are not exclusive', async () => {
|
|
419
|
+
const { driver } = renderInput(
|
|
420
|
+
{ charactersLimit: {} },
|
|
421
|
+
{ exclusiveSpecificValues: false },
|
|
422
|
+
);
|
|
423
|
+
|
|
424
|
+
expect(await driver.hasExclusiveRulesExplanation()).toBe(false);
|
|
425
|
+
});
|
|
426
|
+
|
|
340
427
|
it('keeps active conflicting rules enabled so loaded data can be repaired', async () => {
|
|
341
428
|
const { driver, onChange } = renderInput({
|
|
342
429
|
charactersLimit: {},
|
|
@@ -109,6 +109,69 @@ describe('FormUrl field', () => {
|
|
|
109
109
|
expect(await driver.tk.hasError()).toBe(false);
|
|
110
110
|
});
|
|
111
111
|
|
|
112
|
+
it('shows a min-length error when the URL is shorter than minLength', async () => {
|
|
113
|
+
const driver = setup({
|
|
114
|
+
field: makeField({
|
|
115
|
+
type: 'URL',
|
|
116
|
+
validation: { required: false, stringLengthRange: { minLength: 25 } },
|
|
117
|
+
}),
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
await driver.tk.enterText('https://wix.com');
|
|
121
|
+
|
|
122
|
+
expect(await driver.tk.hasError()).toBe(true);
|
|
123
|
+
expect(await driver.tk.getErrorMessage()).toBe(
|
|
124
|
+
'cairo.fieldValidation.minCharacter{charMin=25}',
|
|
125
|
+
);
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
it('shows a max-length error when the URL is longer than maxLength', async () => {
|
|
129
|
+
const driver = setup({
|
|
130
|
+
field: makeField({
|
|
131
|
+
type: 'URL',
|
|
132
|
+
validation: { required: false, stringLengthRange: { maxLength: 20 } },
|
|
133
|
+
}),
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
await driver.tk.enterText('https://example.com/a/very/long/path');
|
|
137
|
+
|
|
138
|
+
expect(await driver.tk.hasError()).toBe(true);
|
|
139
|
+
expect(await driver.tk.getErrorMessage()).toBe(
|
|
140
|
+
'cairo.fieldValidation.maxCharacter{charMax=20}',
|
|
141
|
+
);
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
it('accepts a URL inside the allowed length range', async () => {
|
|
145
|
+
const driver = setup({
|
|
146
|
+
field: makeField({
|
|
147
|
+
type: 'URL',
|
|
148
|
+
validation: {
|
|
149
|
+
required: false,
|
|
150
|
+
stringLengthRange: { minLength: 10, maxLength: 40 },
|
|
151
|
+
},
|
|
152
|
+
}),
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
await driver.tk.enterText('https://example.com');
|
|
156
|
+
|
|
157
|
+
expect(await driver.tk.hasError()).toBe(false);
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
it('reports the malformed-URL error before the length error', async () => {
|
|
161
|
+
const driver = setup({
|
|
162
|
+
field: makeField({
|
|
163
|
+
type: 'URL',
|
|
164
|
+
validation: { required: false, stringLengthRange: { minLength: 25 } },
|
|
165
|
+
}),
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
await driver.tk.enterText('not a url');
|
|
169
|
+
|
|
170
|
+
expect(await driver.tk.getErrorMessage()).toBe(
|
|
171
|
+
'cairo.customFields.url-input.error',
|
|
172
|
+
);
|
|
173
|
+
});
|
|
174
|
+
|
|
112
175
|
it('reports the malformed-URL error before the pattern error', async () => {
|
|
113
176
|
const driver = setup({
|
|
114
177
|
field: makeField({
|
|
@@ -2,6 +2,7 @@ import '../../../testkit/test-polyfills';
|
|
|
2
2
|
|
|
3
3
|
import type { Field } from '@wix/bex-core';
|
|
4
4
|
|
|
5
|
+
import { Z_INDEX_MODAL_POPOVER } from '../../../components/common';
|
|
5
6
|
import { FormVideo } from '../../../components/video/form-video';
|
|
6
7
|
import { FormVideoDriver } from '../../../components/video/form-video.driver';
|
|
7
8
|
import { FormFieldDriver, makeField } from '../../form-field.driver';
|
|
@@ -82,6 +83,22 @@ describe('FormVideo field', () => {
|
|
|
82
83
|
);
|
|
83
84
|
});
|
|
84
85
|
|
|
86
|
+
it('raises the more-actions menu above modal content', async () => {
|
|
87
|
+
const field = makeField({ type: 'VIDEO' });
|
|
88
|
+
const driver = setup({ field, initialValue: VALID_VIDEO_URI });
|
|
89
|
+
|
|
90
|
+
await driver.tk.clickMore();
|
|
91
|
+
|
|
92
|
+
const deleteAction = document.querySelector(
|
|
93
|
+
`[data-hook="video-delete-${field.id}"]`,
|
|
94
|
+
);
|
|
95
|
+
expect(deleteAction).toBeTruthy();
|
|
96
|
+
expect(deleteAction!.closest('[data-zindex]')).toHaveAttribute(
|
|
97
|
+
'data-zindex',
|
|
98
|
+
String(Z_INDEX_MODAL_POPOVER),
|
|
99
|
+
);
|
|
100
|
+
});
|
|
101
|
+
|
|
85
102
|
// The empty state is the only one that can fail `required`, so its add
|
|
86
103
|
// button is what react-hook-form should land on.
|
|
87
104
|
it('focuses the add button when a required value blocks submit', async () => {
|
|
@@ -488,6 +488,52 @@ describe('controlled inputs', () => {
|
|
|
488
488
|
expect(onChange).toHaveBeenCalledWith(undefined);
|
|
489
489
|
});
|
|
490
490
|
|
|
491
|
+
// The testkit factory resolves a dataHook once, when the driver is built, so
|
|
492
|
+
// a driver made before the click keeps answering about the old render. Each
|
|
493
|
+
// assertion below uses a driver created after the render it describes.
|
|
494
|
+
it('shows the audio loader inside the add button while the picker is open', async () => {
|
|
495
|
+
let resolvePick: (value: unknown) => void = () => {};
|
|
496
|
+
const openMediaManager = jest.fn().mockImplementation(
|
|
497
|
+
() =>
|
|
498
|
+
new Promise((resolve) => {
|
|
499
|
+
resolvePick = resolve;
|
|
500
|
+
}),
|
|
501
|
+
);
|
|
502
|
+
const { container } = render(
|
|
503
|
+
<ControlledAudioInput
|
|
504
|
+
data={undefined}
|
|
505
|
+
onChange={jest.fn()}
|
|
506
|
+
dataHook="audio-loading"
|
|
507
|
+
/>,
|
|
508
|
+
{ wrapper: withMediaManager(openMediaManager) },
|
|
509
|
+
);
|
|
510
|
+
|
|
511
|
+
await getInput(container, 'audio-loading').audio.clickAddButton();
|
|
512
|
+
await act(async () => {});
|
|
513
|
+
|
|
514
|
+
expect(openMediaManager).toHaveBeenCalledTimes(1);
|
|
515
|
+
|
|
516
|
+
const fieldBox = container.querySelector<HTMLElement>(
|
|
517
|
+
'[data-hook="audio-loading"]',
|
|
518
|
+
);
|
|
519
|
+
expect(fieldBox).not.toBeNull();
|
|
520
|
+
expect(
|
|
521
|
+
fieldBox!.querySelector('[data-hook="fromAudioInput.loader"]'),
|
|
522
|
+
).not.toBeNull();
|
|
523
|
+
|
|
524
|
+
const loading = getInput(container, 'audio-loading').audio;
|
|
525
|
+
expect(await loading.isLoading()).toBe(true);
|
|
526
|
+
expect(await loading.getAddButtonText()).toBe('');
|
|
527
|
+
|
|
528
|
+
await act(async () => {
|
|
529
|
+
resolvePick({ items: [] });
|
|
530
|
+
});
|
|
531
|
+
|
|
532
|
+
const settled = getInput(container, 'audio-loading').audio;
|
|
533
|
+
expect(await settled.isLoading()).toBe(false);
|
|
534
|
+
expect(await settled.getAddButtonText()).toBe('CMS.audio.button.add');
|
|
535
|
+
});
|
|
536
|
+
|
|
491
537
|
it('disables the audio replace and delete actions when readOnly', async () => {
|
|
492
538
|
const { container } = render(
|
|
493
539
|
<ControlledAudioInput
|