@atlaskit/spotlight 0.6.0 → 0.6.2

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,18 @@
1
1
  # @atlaskit/spotlight
2
2
 
3
+ ## 0.6.2
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies
8
+
9
+ ## 0.6.1
10
+
11
+ ### Patch Changes
12
+
13
+ - [`598872f9c6e06`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/598872f9c6e06) -
14
+ Spotlight now dismisses on user click-outside.
15
+
3
16
  ## 0.6.0
4
17
 
5
18
  ### Minor Changes
@@ -19,6 +19,10 @@ function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r
19
19
  // eslint-disable-next-line @repo/internal/react/require-jsdoc
20
20
  var SpotlightContext = exports.SpotlightContext = /*#__PURE__*/(0, _react.createContext)({
21
21
  card: {
22
+ ref: null,
23
+ setRef: function setRef() {
24
+ return undefined;
25
+ },
22
26
  placement: 'bottom-end',
23
27
  setPlacement: function setPlacement() {
24
28
  return undefined;
@@ -90,17 +94,23 @@ var SpotlightContextProvider = exports.SpotlightContextProvider = function Spotl
90
94
  setUpdate = _useState6[1];
91
95
  var _useState7 = (0, _react.useState)(),
92
96
  _useState8 = (0, _slicedToArray2.default)(_useState7, 2),
93
- ref = _useState8[0],
94
- setRef = _useState8[1];
95
- var _useState9 = (0, _react.useState)(function () {
97
+ popoverRef = _useState8[0],
98
+ setPopoverRef = _useState8[1];
99
+ var _useState9 = (0, _react.useState)(null),
100
+ _useState0 = (0, _slicedToArray2.default)(_useState9, 2),
101
+ cardRef = _useState0[0],
102
+ setCardRef = _useState0[1];
103
+ var _useState1 = (0, _react.useState)(function () {
96
104
  return undefined;
97
105
  }),
98
- _useState0 = (0, _slicedToArray2.default)(_useState9, 2),
99
- dismiss = _useState0[0],
100
- setDismiss = _useState0[1];
106
+ _useState10 = (0, _slicedToArray2.default)(_useState1, 2),
107
+ dismiss = _useState10[0],
108
+ setDismiss = _useState10[1];
101
109
  return /*#__PURE__*/React.createElement(SpotlightContext.Provider, {
102
110
  value: {
103
111
  card: {
112
+ ref: cardRef,
113
+ setRef: setCardRef,
104
114
  placement: placement,
105
115
  setPlacement: setPlacement
106
116
  },
@@ -109,8 +119,8 @@ var SpotlightContextProvider = exports.SpotlightContextProvider = function Spotl
109
119
  setId: setHeadingId
110
120
  },
111
121
  popoverContent: {
112
- ref: ref,
113
- setRef: setRef,
122
+ ref: popoverRef,
123
+ setRef: setPopoverRef,
114
124
  update: update,
115
125
  setUpdate: setUpdate,
116
126
  dismiss: dismiss,
@@ -42,11 +42,16 @@ var SpotlightCard = exports.SpotlightCard = /*#__PURE__*/(0, _react.forwardRef)(
42
42
  testId = _ref.testId;
43
43
  var _useContext = (0, _react.useContext)(_context.SpotlightContext),
44
44
  card = _useContext.card;
45
+ var cardRef = (0, _react.useRef)(null);
46
+ (0, _react.useEffect)(function () {
47
+ card.setRef(cardRef);
48
+ }, [card]);
45
49
  return /*#__PURE__*/React.createElement("div", {
46
50
  "data-testid": testId,
47
51
  ref: ref,
48
52
  className: (0, _runtime.ax)([styles.root])
49
53
  }, /*#__PURE__*/React.createElement(_caret.Caret, null), /*#__PURE__*/React.createElement(_compiled.Box, {
54
+ ref: cardRef,
50
55
  backgroundColor: "color.background.neutral.bold",
51
56
  xcss: (0, _css.cx)(styles.card, placementStyles[card.placement])
52
57
  }, children));
@@ -29,7 +29,7 @@ var SpotlightDismissControl = exports.SpotlightDismissControl = /*#__PURE__*/(0,
29
29
  onClick = _ref.onClick,
30
30
  testId = _ref.testId;
31
31
  return /*#__PURE__*/React.createElement(_compiled.Pressable
32
- // eslint-disable-next-line jsx-a11y/no-autofocus -- VERIFIED: autoFocus moving to first focusable element on non-modal modal dialog.
32
+ // eslint-disable-next-line @atlassian/a11y/no-autofocus -- VERIFIED: autoFocus moving to first focusable element on non-modal modal dialog.
33
33
  , {
34
34
  autoFocus: autoFocus,
35
35
  onClick: onClick,
@@ -15,6 +15,7 @@ var _mergeRefs = _interopRequireDefault(require("@atlaskit/ds-lib/merge-refs"));
15
15
  var _popper = require("@atlaskit/popper");
16
16
  var _context = require("../../controllers/context");
17
17
  var _useFocusWithin = require("../../utils/use-focus-within");
18
+ var _useOnClickOutside = require("../../utils/use-on-click-outside");
18
19
  var _useOnEscape = require("../../utils/use-on-escape");
19
20
  function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != _typeof(e) && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); return f; })(e, t); }
20
21
  var styles = {
@@ -91,6 +92,9 @@ var PopoverContent = exports.PopoverContent = function PopoverContent(_ref) {
91
92
  }
92
93
  dismiss(event);
93
94
  });
95
+ (0, _useOnClickOutside.useOnClickOutside)(function (event) {
96
+ dismiss(event);
97
+ });
94
98
  return /*#__PURE__*/React.createElement(_popper.Popper, {
95
99
  offset: offset,
96
100
  placement: popperPlacementMap[placement]
@@ -0,0 +1,37 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.useOnClickOutside = void 0;
7
+ var _react = require("react");
8
+ var _bindEventListener = require("bind-event-listener");
9
+ var _browserApis = require("@atlaskit/browser-apis");
10
+ var _context = require("../../controllers/context");
11
+ var useOnClickOutside = exports.useOnClickOutside = function useOnClickOutside(onClickOutside) {
12
+ var _useContext = (0, _react.useContext)(_context.SpotlightContext),
13
+ card = _useContext.card;
14
+ var ref = card.ref;
15
+ (0, _react.useEffect)(function () {
16
+ var doc = (0, _browserApis.getDocument)();
17
+ if (!doc) {
18
+ return;
19
+ }
20
+ var unbindMouseDown = (0, _bindEventListener.bind)(doc, {
21
+ type: 'mousedown',
22
+ listener: function listener(event) {
23
+ if (!ref || !ref.current) {
24
+ return;
25
+ }
26
+ var target = event.target instanceof Node ? event.target : null;
27
+ if (ref.current.contains(target)) {
28
+ return;
29
+ }
30
+ onClickOutside(event);
31
+ }
32
+ });
33
+ return function () {
34
+ unbindMouseDown();
35
+ };
36
+ }, [onClickOutside, ref]);
37
+ };
@@ -8,6 +8,8 @@ import { createContext, useId, useState } from 'react';
8
8
  // eslint-disable-next-line @repo/internal/react/require-jsdoc
9
9
  export const SpotlightContext = /*#__PURE__*/createContext({
10
10
  card: {
11
+ ref: null,
12
+ setRef: () => undefined,
11
13
  placement: 'bottom-end',
12
14
  setPlacement: () => undefined
13
15
  },
@@ -33,11 +35,14 @@ export const SpotlightContextProvider = ({
33
35
  const [placement, setPlacement] = useState('bottom-end');
34
36
  const [headingId, setHeadingId] = useState(`${id}-heading`);
35
37
  const [update, setUpdate] = useState(() => async () => undefined);
36
- const [ref, setRef] = useState();
38
+ const [popoverRef, setPopoverRef] = useState();
39
+ const [cardRef, setCardRef] = useState(null);
37
40
  const [dismiss, setDismiss] = useState(() => undefined);
38
41
  return /*#__PURE__*/React.createElement(SpotlightContext.Provider, {
39
42
  value: {
40
43
  card: {
44
+ ref: cardRef,
45
+ setRef: setCardRef,
41
46
  placement,
42
47
  setPlacement
43
48
  },
@@ -46,8 +51,8 @@ export const SpotlightContextProvider = ({
46
51
  setId: setHeadingId
47
52
  },
48
53
  popoverContent: {
49
- ref,
50
- setRef,
54
+ ref: popoverRef,
55
+ setRef: setPopoverRef,
51
56
  update,
52
57
  setUpdate,
53
58
  dismiss,
@@ -2,7 +2,7 @@
2
2
  import "./index.compiled.css";
3
3
  import * as React from 'react';
4
4
  import { ax, ix } from "@compiled/react/runtime";
5
- import { forwardRef, useContext } from 'react';
5
+ import { forwardRef, useContext, useEffect, useRef } from 'react';
6
6
  import { cx } from '@atlaskit/css';
7
7
  import { Box } from '@atlaskit/primitives/compiled';
8
8
  import { SpotlightContext } from '../../controllers/context';
@@ -36,11 +36,16 @@ export const SpotlightCard = /*#__PURE__*/forwardRef(({
36
36
  const {
37
37
  card
38
38
  } = useContext(SpotlightContext);
39
+ const cardRef = useRef(null);
40
+ useEffect(() => {
41
+ card.setRef(cardRef);
42
+ }, [card]);
39
43
  return /*#__PURE__*/React.createElement("div", {
40
44
  "data-testid": testId,
41
45
  ref: ref,
42
46
  className: ax([styles.root])
43
47
  }, /*#__PURE__*/React.createElement(Caret, null), /*#__PURE__*/React.createElement(Box, {
48
+ ref: cardRef,
44
49
  backgroundColor: "color.background.neutral.bold",
45
50
  xcss: cx(styles.card, placementStyles[card.placement])
46
51
  }, children));
@@ -20,7 +20,7 @@ export const SpotlightDismissControl = /*#__PURE__*/forwardRef(({
20
20
  testId
21
21
  }, ref) => {
22
22
  return /*#__PURE__*/React.createElement(Pressable
23
- // eslint-disable-next-line jsx-a11y/no-autofocus -- VERIFIED: autoFocus moving to first focusable element on non-modal modal dialog.
23
+ // eslint-disable-next-line @atlassian/a11y/no-autofocus -- VERIFIED: autoFocus moving to first focusable element on non-modal modal dialog.
24
24
  , {
25
25
  autoFocus: autoFocus,
26
26
  onClick: onClick,
@@ -7,6 +7,7 @@ import mergeRefs from '@atlaskit/ds-lib/merge-refs';
7
7
  import { Popper } from '@atlaskit/popper';
8
8
  import { SpotlightContext } from '../../controllers/context';
9
9
  import { useFocusWithin } from '../../utils/use-focus-within';
10
+ import { useOnClickOutside } from '../../utils/use-on-click-outside';
10
11
  import { useOnEscape } from '../../utils/use-on-escape';
11
12
  const styles = {
12
13
  root: "_1pby1fw0"
@@ -77,6 +78,9 @@ export const PopoverContent = ({
77
78
  }
78
79
  dismiss(event);
79
80
  });
81
+ useOnClickOutside(event => {
82
+ dismiss(event);
83
+ });
80
84
  return /*#__PURE__*/React.createElement(Popper, {
81
85
  offset: offset,
82
86
  placement: popperPlacementMap[placement]
@@ -0,0 +1,32 @@
1
+ import { useContext, useEffect } from 'react';
2
+ import { bind } from 'bind-event-listener';
3
+ import { getDocument } from '@atlaskit/browser-apis';
4
+ import { SpotlightContext } from '../../controllers/context';
5
+ export const useOnClickOutside = onClickOutside => {
6
+ const {
7
+ card
8
+ } = useContext(SpotlightContext);
9
+ const ref = card.ref;
10
+ useEffect(() => {
11
+ const doc = getDocument();
12
+ if (!doc) {
13
+ return;
14
+ }
15
+ const unbindMouseDown = bind(doc, {
16
+ type: 'mousedown',
17
+ listener: event => {
18
+ if (!ref || !ref.current) {
19
+ return;
20
+ }
21
+ const target = event.target instanceof Node ? event.target : null;
22
+ if (ref.current.contains(target)) {
23
+ return;
24
+ }
25
+ onClickOutside(event);
26
+ }
27
+ });
28
+ return () => {
29
+ unbindMouseDown();
30
+ };
31
+ }, [onClickOutside, ref]);
32
+ };
@@ -11,6 +11,10 @@ import { createContext, useId, useState } from 'react';
11
11
  // eslint-disable-next-line @repo/internal/react/require-jsdoc
12
12
  export var SpotlightContext = /*#__PURE__*/createContext({
13
13
  card: {
14
+ ref: null,
15
+ setRef: function setRef() {
16
+ return undefined;
17
+ },
14
18
  placement: 'bottom-end',
15
19
  setPlacement: function setPlacement() {
16
20
  return undefined;
@@ -82,17 +86,23 @@ export var SpotlightContextProvider = function SpotlightContextProvider(_ref) {
82
86
  setUpdate = _useState6[1];
83
87
  var _useState7 = useState(),
84
88
  _useState8 = _slicedToArray(_useState7, 2),
85
- ref = _useState8[0],
86
- setRef = _useState8[1];
87
- var _useState9 = useState(function () {
89
+ popoverRef = _useState8[0],
90
+ setPopoverRef = _useState8[1];
91
+ var _useState9 = useState(null),
92
+ _useState0 = _slicedToArray(_useState9, 2),
93
+ cardRef = _useState0[0],
94
+ setCardRef = _useState0[1];
95
+ var _useState1 = useState(function () {
88
96
  return undefined;
89
97
  }),
90
- _useState0 = _slicedToArray(_useState9, 2),
91
- dismiss = _useState0[0],
92
- setDismiss = _useState0[1];
98
+ _useState10 = _slicedToArray(_useState1, 2),
99
+ dismiss = _useState10[0],
100
+ setDismiss = _useState10[1];
93
101
  return /*#__PURE__*/React.createElement(SpotlightContext.Provider, {
94
102
  value: {
95
103
  card: {
104
+ ref: cardRef,
105
+ setRef: setCardRef,
96
106
  placement: placement,
97
107
  setPlacement: setPlacement
98
108
  },
@@ -101,8 +111,8 @@ export var SpotlightContextProvider = function SpotlightContextProvider(_ref) {
101
111
  setId: setHeadingId
102
112
  },
103
113
  popoverContent: {
104
- ref: ref,
105
- setRef: setRef,
114
+ ref: popoverRef,
115
+ setRef: setPopoverRef,
106
116
  update: update,
107
117
  setUpdate: setUpdate,
108
118
  dismiss: dismiss,
@@ -2,7 +2,7 @@
2
2
  import "./index.compiled.css";
3
3
  import * as React from 'react';
4
4
  import { ax, ix } from "@compiled/react/runtime";
5
- import { forwardRef, useContext } from 'react';
5
+ import { forwardRef, useContext, useEffect, useRef } from 'react';
6
6
  import { cx } from '@atlaskit/css';
7
7
  import { Box } from '@atlaskit/primitives/compiled';
8
8
  import { SpotlightContext } from '../../controllers/context';
@@ -34,11 +34,16 @@ export var SpotlightCard = /*#__PURE__*/forwardRef(function (_ref, ref) {
34
34
  testId = _ref.testId;
35
35
  var _useContext = useContext(SpotlightContext),
36
36
  card = _useContext.card;
37
+ var cardRef = useRef(null);
38
+ useEffect(function () {
39
+ card.setRef(cardRef);
40
+ }, [card]);
37
41
  return /*#__PURE__*/React.createElement("div", {
38
42
  "data-testid": testId,
39
43
  ref: ref,
40
44
  className: ax([styles.root])
41
45
  }, /*#__PURE__*/React.createElement(Caret, null), /*#__PURE__*/React.createElement(Box, {
46
+ ref: cardRef,
42
47
  backgroundColor: "color.background.neutral.bold",
43
48
  xcss: cx(styles.card, placementStyles[card.placement])
44
49
  }, children));
@@ -20,7 +20,7 @@ export var SpotlightDismissControl = /*#__PURE__*/forwardRef(function (_ref, ref
20
20
  onClick = _ref.onClick,
21
21
  testId = _ref.testId;
22
22
  return /*#__PURE__*/React.createElement(Pressable
23
- // eslint-disable-next-line jsx-a11y/no-autofocus -- VERIFIED: autoFocus moving to first focusable element on non-modal modal dialog.
23
+ // eslint-disable-next-line @atlassian/a11y/no-autofocus -- VERIFIED: autoFocus moving to first focusable element on non-modal modal dialog.
24
24
  , {
25
25
  autoFocus: autoFocus,
26
26
  onClick: onClick,
@@ -7,6 +7,7 @@ import mergeRefs from '@atlaskit/ds-lib/merge-refs';
7
7
  import { Popper } from '@atlaskit/popper';
8
8
  import { SpotlightContext } from '../../controllers/context';
9
9
  import { useFocusWithin } from '../../utils/use-focus-within';
10
+ import { useOnClickOutside } from '../../utils/use-on-click-outside';
10
11
  import { useOnEscape } from '../../utils/use-on-escape';
11
12
  var styles = {
12
13
  root: "_1pby1fw0"
@@ -82,6 +83,9 @@ export var PopoverContent = function PopoverContent(_ref) {
82
83
  }
83
84
  dismiss(event);
84
85
  });
86
+ useOnClickOutside(function (event) {
87
+ dismiss(event);
88
+ });
85
89
  return /*#__PURE__*/React.createElement(Popper, {
86
90
  offset: offset,
87
91
  placement: popperPlacementMap[placement]
@@ -0,0 +1,31 @@
1
+ import { useContext, useEffect } from 'react';
2
+ import { bind } from 'bind-event-listener';
3
+ import { getDocument } from '@atlaskit/browser-apis';
4
+ import { SpotlightContext } from '../../controllers/context';
5
+ export var useOnClickOutside = function useOnClickOutside(onClickOutside) {
6
+ var _useContext = useContext(SpotlightContext),
7
+ card = _useContext.card;
8
+ var ref = card.ref;
9
+ useEffect(function () {
10
+ var doc = getDocument();
11
+ if (!doc) {
12
+ return;
13
+ }
14
+ var unbindMouseDown = bind(doc, {
15
+ type: 'mousedown',
16
+ listener: function listener(event) {
17
+ if (!ref || !ref.current) {
18
+ return;
19
+ }
20
+ var target = event.target instanceof Node ? event.target : null;
21
+ if (ref.current.contains(target)) {
22
+ return;
23
+ }
24
+ onClickOutside(event);
25
+ }
26
+ });
27
+ return function () {
28
+ unbindMouseDown();
29
+ };
30
+ }, [onClickOutside, ref]);
31
+ };
@@ -6,6 +6,8 @@ import { type Dispatch, type MutableRefObject, type ReactNode, type SetStateActi
6
6
  import type { Placement } from '../types';
7
7
  export interface SpotlightContextType {
8
8
  card: {
9
+ ref: MutableRefObject<HTMLDivElement | null> | null;
10
+ setRef: Dispatch<SetStateAction<MutableRefObject<HTMLDivElement | null> | null>>;
9
11
  placement: Placement;
10
12
  setPlacement: Dispatch<SetStateAction<Placement>>;
11
13
  };
@@ -13,7 +13,7 @@ export interface PopoverContentProps {
13
13
  testId?: string;
14
14
  placement: Placement;
15
15
  isVisible?: boolean;
16
- dismiss: (event: KeyboardEvent) => void;
16
+ dismiss: (event: KeyboardEvent | MouseEvent) => void;
17
17
  children: ReactNode;
18
18
  }
19
19
  /**
@@ -0,0 +1 @@
1
+ export declare const useOnClickOutside: (onClickOutside: (event: MouseEvent) => void) => void;
@@ -6,6 +6,8 @@ import { type Dispatch, type MutableRefObject, type ReactNode, type SetStateActi
6
6
  import type { Placement } from '../types';
7
7
  export interface SpotlightContextType {
8
8
  card: {
9
+ ref: MutableRefObject<HTMLDivElement | null> | null;
10
+ setRef: Dispatch<SetStateAction<MutableRefObject<HTMLDivElement | null> | null>>;
9
11
  placement: Placement;
10
12
  setPlacement: Dispatch<SetStateAction<Placement>>;
11
13
  };
@@ -13,7 +13,7 @@ export interface PopoverContentProps {
13
13
  testId?: string;
14
14
  placement: Placement;
15
15
  isVisible?: boolean;
16
- dismiss: (event: KeyboardEvent) => void;
16
+ dismiss: (event: KeyboardEvent | MouseEvent) => void;
17
17
  children: ReactNode;
18
18
  }
19
19
  /**
@@ -0,0 +1 @@
1
+ export declare const useOnClickOutside: (onClickOutside: (event: MouseEvent) => void) => void;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/spotlight",
3
- "version": "0.6.0",
3
+ "version": "0.6.2",
4
4
  "description": "A spotlight introduces users to various points of interest across Atlassian through focused messages or multi-step tours.",
5
5
  "author": "Atlassian Pty Ltd",
6
6
  "license": "Apache-2.0",
@@ -28,14 +28,14 @@
28
28
  "dependencies": {
29
29
  "@atlaskit/browser-apis": "^0.0.1",
30
30
  "@atlaskit/button": "^23.5.0",
31
- "@atlaskit/css": "^0.14.0",
31
+ "@atlaskit/css": "^0.15.0",
32
32
  "@atlaskit/ds-lib": "^5.1.0",
33
33
  "@atlaskit/heading": "^5.2.0",
34
34
  "@atlaskit/icon": "^28.5.0",
35
35
  "@atlaskit/image": "^3.0.0",
36
36
  "@atlaskit/popper": "^7.1.0",
37
- "@atlaskit/primitives": "^14.15.0",
38
- "@atlaskit/tokens": "^6.4.0",
37
+ "@atlaskit/primitives": "^15.0.0",
38
+ "@atlaskit/tokens": "^6.5.0",
39
39
  "@atlaskit/visually-hidden": "^3.0.0",
40
40
  "@babel/runtime": "^7.0.0",
41
41
  "@compiled/react": "^0.18.3",