@atlaskit/spotlight 0.9.3 → 0.9.5

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/CHANGELOG.md CHANGED
@@ -1,5 +1,33 @@
1
1
  # @atlaskit/spotlight
2
2
 
3
+ ## 0.9.5
4
+
5
+ ### Patch Changes
6
+
7
+ - [`e0d5103c4e6cd`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/e0d5103c4e6cd) -
8
+ Expose `strategy` prop on `PopoverContent` which is passed through to the underlying
9
+ `react-popper`.
10
+
11
+ ## 0.9.4
12
+
13
+ ### Patch Changes
14
+
15
+ - [`063f646d9daec`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/063f646d9daec) -
16
+ Added `usePreloadMedia` hook to preload video and image assets before they are rendered in the
17
+ DOM.
18
+
19
+ This hook is useful in the context of `@atlaskit/spotlight` where by default media will only load
20
+ when `PopoverContent.isVisible` is set to true. `usePreloadMedia` preloads the assets for better
21
+ performance and user experience. The hook accepts a source URL and a MIME type, creates a
22
+ temporary media element to trigger browser caching, and the cached asset will be used when the
23
+ actual media element is rendered.
24
+
25
+ Supported MIME types:
26
+ - Videos: `video/mp4`, `video/webm`, `video/ogg`, `video/mpeg`, `video/x-matroska`
27
+ - Images: `image/jpeg`, `image/png`, `image/gif`, `image/webp`, `image/svg+xml`
28
+
29
+ Example usage: usePreloadMedia(videoSrc, { mimetype: 'video/mp4' });
30
+
3
31
  ## 0.9.3
4
32
 
5
33
  ### Patch Changes
@@ -19,6 +19,8 @@ Spotlights are most effective for onboarding new users, driving feature discover
19
19
  important changes. Use them sparingly. If your UI needs frequent spotlights, consider simplifying
20
20
  the core experience instead.
21
21
 
22
+ [Track and reduce message fatigue with Post Office (Atlassians only)](https://go.atlassian.com/use-post-office)
23
+
22
24
  ### Single-step spotlight
23
25
 
24
26
  The ideal spotlight experience is lightweight and a single-step. Always try to limit your experience
package/dist/cjs/index.js CHANGED
@@ -105,6 +105,12 @@ Object.defineProperty(exports, "UNSAFE_UpdateOnChange", {
105
105
  return _UNSAFE_updateOnChange.UNSAFE_UpdateOnChange;
106
106
  }
107
107
  });
108
+ Object.defineProperty(exports, "usePreloadMedia", {
109
+ enumerable: true,
110
+ get: function get() {
111
+ return _usePreloadMedia.usePreloadMedia;
112
+ }
113
+ });
108
114
  var _card = require("./ui/card");
109
115
  var _body = require("./ui/body");
110
116
  var _header = require("./ui/header");
@@ -121,4 +127,5 @@ var _media = require("./ui/media");
121
127
  var _popoverProvider = require("./ui/popover-provider");
122
128
  var _popoverContent = require("./ui/popover-content");
123
129
  var _popoverTarget = require("./ui/popover-target");
124
- var _UNSAFE_updateOnChange = require("./ui/UNSAFE_update-on-change");
130
+ var _UNSAFE_updateOnChange = require("./ui/UNSAFE_update-on-change");
131
+ var _usePreloadMedia = require("./utils/use-preload-media");
@@ -70,7 +70,8 @@ var PopoverContent = exports.PopoverContent = function PopoverContent(props) {
70
70
  back = props.back,
71
71
  testId = props.testId,
72
72
  _props$offset = props.offset,
73
- offset = _props$offset === void 0 ? defaultOffset : _props$offset;
73
+ offset = _props$offset === void 0 ? defaultOffset : _props$offset,
74
+ strategy = props.strategy;
74
75
 
75
76
  /**
76
77
  * A user should only be able to pass a `done` or a `next`. Not both.
@@ -140,6 +141,7 @@ var PopoverContent = exports.PopoverContent = function PopoverContent(props) {
140
141
  });
141
142
  return /*#__PURE__*/React.createElement(_popper.Popper, {
142
143
  offset: offset,
144
+ strategy: strategy,
143
145
  placement: popperPlacementMap[placement]
144
146
  }, function (_ref) {
145
147
  var localRef = _ref.ref,
@@ -0,0 +1,62 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.usePreloadMedia = void 0;
8
+ var _react = require("react");
9
+ var _browserApis = require("@atlaskit/browser-apis");
10
+ var _noop = _interopRequireDefault(require("@atlaskit/ds-lib/noop"));
11
+ // eslint-disable-next-line @repo/internal/react/consistent-types-definitions
12
+
13
+ /**
14
+ * Preloads media (video/image) files to be cached by the browser.
15
+ * Once loaded, the browser cache will be used when rendering the actual media element.
16
+ *
17
+ * @param src - The media source URL to preload
18
+ * @param options - Configuration options including the MIME type
19
+ */
20
+ var usePreloadMedia = exports.usePreloadMedia = function usePreloadMedia(src, options) {
21
+ (0, _react.useEffect)(function () {
22
+ var handler = mimeTypeHandlers[options.mimetype];
23
+ return handler(src);
24
+ }, [src, options.mimetype]);
25
+ };
26
+ var preloadVideo = function preloadVideo(src) {
27
+ var doc = (0, _browserApis.getDocument)();
28
+ if (!doc) {
29
+ return _noop.default;
30
+ }
31
+ var video = doc.createElement('video');
32
+ video.src = src;
33
+ video.preload = 'auto';
34
+ video.load();
35
+ return function () {
36
+ video.src = '';
37
+ video.load();
38
+ };
39
+ };
40
+ var preloadImage = function preloadImage(src) {
41
+ var doc = (0, _browserApis.getDocument)();
42
+ if (!doc) {
43
+ return _noop.default;
44
+ }
45
+ var img = new Image();
46
+ img.src = src;
47
+ return function () {
48
+ img.src = '';
49
+ };
50
+ };
51
+ var mimeTypeHandlers = {
52
+ 'video/mp4': preloadVideo,
53
+ 'video/webm': preloadVideo,
54
+ 'video/ogg': preloadVideo,
55
+ 'video/mpeg': preloadVideo,
56
+ 'video/x-matroska': preloadVideo,
57
+ 'image/jpeg': preloadImage,
58
+ 'image/png': preloadImage,
59
+ 'image/gif': preloadImage,
60
+ 'image/webp': preloadImage,
61
+ 'image/svg+xml': preloadImage
62
+ };
@@ -14,4 +14,5 @@ export { SpotlightMedia } from './ui/media';
14
14
  export { PopoverProvider } from './ui/popover-provider';
15
15
  export { PopoverContent } from './ui/popover-content';
16
16
  export { PopoverTarget } from './ui/popover-target';
17
- export { UNSAFE_UpdateOnChange } from './ui/UNSAFE_update-on-change';
17
+ export { UNSAFE_UpdateOnChange } from './ui/UNSAFE_update-on-change';
18
+ export { usePreloadMedia } from './utils/use-preload-media';
@@ -59,7 +59,8 @@ export const PopoverContent = props => {
59
59
  dismiss,
60
60
  back,
61
61
  testId,
62
- offset = defaultOffset
62
+ offset = defaultOffset,
63
+ strategy
63
64
  } = props;
64
65
 
65
66
  /**
@@ -125,6 +126,7 @@ export const PopoverContent = props => {
125
126
  });
126
127
  return /*#__PURE__*/React.createElement(Popper, {
127
128
  offset: offset,
129
+ strategy: strategy,
128
130
  placement: popperPlacementMap[placement]
129
131
  }, ({
130
132
  ref: localRef,
@@ -0,0 +1,56 @@
1
+ import { useEffect } from 'react';
2
+ import { getDocument } from '@atlaskit/browser-apis';
3
+ import __noop from '@atlaskit/ds-lib/noop';
4
+
5
+ // eslint-disable-next-line @repo/internal/react/consistent-types-definitions
6
+
7
+ /**
8
+ * Preloads media (video/image) files to be cached by the browser.
9
+ * Once loaded, the browser cache will be used when rendering the actual media element.
10
+ *
11
+ * @param src - The media source URL to preload
12
+ * @param options - Configuration options including the MIME type
13
+ */
14
+ export const usePreloadMedia = (src, options) => {
15
+ useEffect(() => {
16
+ const handler = mimeTypeHandlers[options.mimetype];
17
+ return handler(src);
18
+ }, [src, options.mimetype]);
19
+ };
20
+ const preloadVideo = src => {
21
+ const doc = getDocument();
22
+ if (!doc) {
23
+ return __noop;
24
+ }
25
+ const video = doc.createElement('video');
26
+ video.src = src;
27
+ video.preload = 'auto';
28
+ video.load();
29
+ return () => {
30
+ video.src = '';
31
+ video.load();
32
+ };
33
+ };
34
+ const preloadImage = src => {
35
+ const doc = getDocument();
36
+ if (!doc) {
37
+ return __noop;
38
+ }
39
+ const img = new Image();
40
+ img.src = src;
41
+ return () => {
42
+ img.src = '';
43
+ };
44
+ };
45
+ const mimeTypeHandlers = {
46
+ 'video/mp4': preloadVideo,
47
+ 'video/webm': preloadVideo,
48
+ 'video/ogg': preloadVideo,
49
+ 'video/mpeg': preloadVideo,
50
+ 'video/x-matroska': preloadVideo,
51
+ 'image/jpeg': preloadImage,
52
+ 'image/png': preloadImage,
53
+ 'image/gif': preloadImage,
54
+ 'image/webp': preloadImage,
55
+ 'image/svg+xml': preloadImage
56
+ };
package/dist/esm/index.js CHANGED
@@ -14,4 +14,5 @@ export { SpotlightMedia } from './ui/media';
14
14
  export { PopoverProvider } from './ui/popover-provider';
15
15
  export { PopoverContent } from './ui/popover-content';
16
16
  export { PopoverTarget } from './ui/popover-target';
17
- export { UNSAFE_UpdateOnChange } from './ui/UNSAFE_update-on-change';
17
+ export { UNSAFE_UpdateOnChange } from './ui/UNSAFE_update-on-change';
18
+ export { usePreloadMedia } from './utils/use-preload-media';
@@ -61,7 +61,8 @@ export var PopoverContent = function PopoverContent(props) {
61
61
  back = props.back,
62
62
  testId = props.testId,
63
63
  _props$offset = props.offset,
64
- offset = _props$offset === void 0 ? defaultOffset : _props$offset;
64
+ offset = _props$offset === void 0 ? defaultOffset : _props$offset,
65
+ strategy = props.strategy;
65
66
 
66
67
  /**
67
68
  * A user should only be able to pass a `done` or a `next`. Not both.
@@ -131,6 +132,7 @@ export var PopoverContent = function PopoverContent(props) {
131
132
  });
132
133
  return /*#__PURE__*/React.createElement(Popper, {
133
134
  offset: offset,
135
+ strategy: strategy,
134
136
  placement: popperPlacementMap[placement]
135
137
  }, function (_ref) {
136
138
  var localRef = _ref.ref,
@@ -0,0 +1,56 @@
1
+ import { useEffect } from 'react';
2
+ import { getDocument } from '@atlaskit/browser-apis';
3
+ import __noop from '@atlaskit/ds-lib/noop';
4
+
5
+ // eslint-disable-next-line @repo/internal/react/consistent-types-definitions
6
+
7
+ /**
8
+ * Preloads media (video/image) files to be cached by the browser.
9
+ * Once loaded, the browser cache will be used when rendering the actual media element.
10
+ *
11
+ * @param src - The media source URL to preload
12
+ * @param options - Configuration options including the MIME type
13
+ */
14
+ export var usePreloadMedia = function usePreloadMedia(src, options) {
15
+ useEffect(function () {
16
+ var handler = mimeTypeHandlers[options.mimetype];
17
+ return handler(src);
18
+ }, [src, options.mimetype]);
19
+ };
20
+ var preloadVideo = function preloadVideo(src) {
21
+ var doc = getDocument();
22
+ if (!doc) {
23
+ return __noop;
24
+ }
25
+ var video = doc.createElement('video');
26
+ video.src = src;
27
+ video.preload = 'auto';
28
+ video.load();
29
+ return function () {
30
+ video.src = '';
31
+ video.load();
32
+ };
33
+ };
34
+ var preloadImage = function preloadImage(src) {
35
+ var doc = getDocument();
36
+ if (!doc) {
37
+ return __noop;
38
+ }
39
+ var img = new Image();
40
+ img.src = src;
41
+ return function () {
42
+ img.src = '';
43
+ };
44
+ };
45
+ var mimeTypeHandlers = {
46
+ 'video/mp4': preloadVideo,
47
+ 'video/webm': preloadVideo,
48
+ 'video/ogg': preloadVideo,
49
+ 'video/mpeg': preloadVideo,
50
+ 'video/x-matroska': preloadVideo,
51
+ 'image/jpeg': preloadImage,
52
+ 'image/png': preloadImage,
53
+ 'image/gif': preloadImage,
54
+ 'image/webp': preloadImage,
55
+ 'image/svg+xml': preloadImage
56
+ };
@@ -16,3 +16,4 @@ export { PopoverContent, type PopoverContentProps } from './ui/popover-content';
16
16
  export { PopoverTarget } from './ui/popover-target';
17
17
  export { type Placement, type DismissEvent } from './types';
18
18
  export { UNSAFE_UpdateOnChange } from './ui/UNSAFE_update-on-change';
19
+ export { usePreloadMedia } from './utils/use-preload-media';
@@ -8,6 +8,7 @@ import type { BackEvent, DismissEvent, DoneEvent, NextEvent, Placement } from '.
8
8
  * Taken from `@atlaskit/popper`
9
9
  */
10
10
  type Offset = [number | null | undefined, number | null | undefined];
11
+ type Strategy = 'absolute' | 'fixed';
11
12
  interface BasePopoverContentProps {
12
13
  /**
13
14
  * A `testId` prop is provided for specified elements, which is a unique
@@ -48,6 +49,13 @@ interface BasePopoverContentProps {
48
49
  * by the `placement` prop.
49
50
  */
50
51
  offset?: Offset;
52
+ /**
53
+ * Describes the positioning strategy to use. By default, it is `absolute`, which in the simplest cases does not require
54
+ * repositioning of the popper. If your reference element is in a fixed container, use the `fixed` strategy
55
+ *
56
+ * For more details see: https://popper.js.org/docs/v2/constructors/#strategy
57
+ */
58
+ strategy?: Strategy;
51
59
  /**
52
60
  * The content to be rendered in `PopoverContent`. This is intended to be a `SpotlightCard`.
53
61
  */
@@ -0,0 +1,13 @@
1
+ type MimeType = 'video/mp4' | 'video/webm' | 'video/ogg' | 'video/mpeg' | 'video/x-matroska' | 'image/jpeg' | 'image/png' | 'image/gif' | 'image/webp' | 'image/svg+xml';
2
+ interface PreloadMediaOptions {
3
+ mimetype: MimeType;
4
+ }
5
+ /**
6
+ * Preloads media (video/image) files to be cached by the browser.
7
+ * Once loaded, the browser cache will be used when rendering the actual media element.
8
+ *
9
+ * @param src - The media source URL to preload
10
+ * @param options - Configuration options including the MIME type
11
+ */
12
+ export declare const usePreloadMedia: (src: string, options: PreloadMediaOptions) => void;
13
+ export {};
@@ -16,3 +16,4 @@ export { PopoverContent, type PopoverContentProps } from './ui/popover-content';
16
16
  export { PopoverTarget } from './ui/popover-target';
17
17
  export { type Placement, type DismissEvent } from './types';
18
18
  export { UNSAFE_UpdateOnChange } from './ui/UNSAFE_update-on-change';
19
+ export { usePreloadMedia } from './utils/use-preload-media';
@@ -11,6 +11,7 @@ type Offset = [
11
11
  number | null | undefined,
12
12
  number | null | undefined
13
13
  ];
14
+ type Strategy = 'absolute' | 'fixed';
14
15
  interface BasePopoverContentProps {
15
16
  /**
16
17
  * A `testId` prop is provided for specified elements, which is a unique
@@ -51,6 +52,13 @@ interface BasePopoverContentProps {
51
52
  * by the `placement` prop.
52
53
  */
53
54
  offset?: Offset;
55
+ /**
56
+ * Describes the positioning strategy to use. By default, it is `absolute`, which in the simplest cases does not require
57
+ * repositioning of the popper. If your reference element is in a fixed container, use the `fixed` strategy
58
+ *
59
+ * For more details see: https://popper.js.org/docs/v2/constructors/#strategy
60
+ */
61
+ strategy?: Strategy;
54
62
  /**
55
63
  * The content to be rendered in `PopoverContent`. This is intended to be a `SpotlightCard`.
56
64
  */
@@ -0,0 +1,13 @@
1
+ type MimeType = 'video/mp4' | 'video/webm' | 'video/ogg' | 'video/mpeg' | 'video/x-matroska' | 'image/jpeg' | 'image/png' | 'image/gif' | 'image/webp' | 'image/svg+xml';
2
+ interface PreloadMediaOptions {
3
+ mimetype: MimeType;
4
+ }
5
+ /**
6
+ * Preloads media (video/image) files to be cached by the browser.
7
+ * Once loaded, the browser cache will be used when rendering the actual media element.
8
+ *
9
+ * @param src - The media source URL to preload
10
+ * @param options - Configuration options including the MIME type
11
+ */
12
+ export declare const usePreloadMedia: (src: string, options: PreloadMediaOptions) => void;
13
+ export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/spotlight",
3
- "version": "0.9.3",
3
+ "version": "0.9.5",
4
4
  "description": "A spotlight introduces users to points of interest, from focused messages to multi-step tours.",
5
5
  "author": "Atlassian Pty Ltd",
6
6
  "license": "Apache-2.0",