@atlaskit/focus-ring 0.2.4 → 1.0.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/CHANGELOG.md +31 -0
- package/dist/cjs/focus-ring.js +27 -12
- package/dist/cjs/index.js +9 -1
- package/dist/cjs/use-focus-ring.js +65 -0
- package/dist/cjs/version.json +1 -1
- package/dist/es2019/focus-ring.js +36 -18
- package/dist/es2019/index.js +2 -1
- package/dist/es2019/use-focus-ring.js +43 -0
- package/dist/es2019/version.json +1 -1
- package/dist/esm/focus-ring.js +28 -12
- package/dist/esm/index.js +2 -1
- package/dist/esm/use-focus-ring.js +54 -0
- package/dist/esm/version.json +1 -1
- package/dist/types/focus-ring.d.ts +11 -0
- package/dist/types/index.d.ts +2 -0
- package/dist/types/types.d.ts +14 -3
- package/dist/types/use-focus-ring.d.ts +34 -0
- package/package.json +13 -8
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,36 @@
|
|
|
1
1
|
# @atlaskit/focus-ring
|
|
2
2
|
|
|
3
|
+
## 1.0.0
|
|
4
|
+
|
|
5
|
+
### Major Changes
|
|
6
|
+
|
|
7
|
+
- [`3e1a93c6b67`](https://bitbucket.org/atlassian/atlassian-frontend/commits/3e1a93c6b67) - Releases FocusRing to v1.
|
|
8
|
+
|
|
9
|
+
### Minor Changes
|
|
10
|
+
|
|
11
|
+
- [`63b8679585b`](https://bitbucket.org/atlassian/atlassian-frontend/commits/63b8679585b) - Adds an additional prop `focus` to the `FocusRing` to allow the component to also be controlled. This prop is designed to be used in conjunction with a complementary hook; `useFocusRing`.
|
|
12
|
+
|
|
13
|
+
## 0.2.7
|
|
14
|
+
|
|
15
|
+
### Patch Changes
|
|
16
|
+
|
|
17
|
+
- [`19d72473dfb`](https://bitbucket.org/atlassian/atlassian-frontend/commits/19d72473dfb) - Updates usage of deprecated token names so they're aligned with the latest naming conventions. No UI or visual changes
|
|
18
|
+
- [`19d72473dfb`](https://bitbucket.org/atlassian/atlassian-frontend/commits/19d72473dfb) - [ux] The component has reworked its internal so that it can now better deal with issues where the background-color was obscured by the focus-ring box shadow.
|
|
19
|
+
- Updated dependencies
|
|
20
|
+
|
|
21
|
+
## 0.2.6
|
|
22
|
+
|
|
23
|
+
### Patch Changes
|
|
24
|
+
|
|
25
|
+
- Updated dependencies
|
|
26
|
+
|
|
27
|
+
## 0.2.5
|
|
28
|
+
|
|
29
|
+
### Patch Changes
|
|
30
|
+
|
|
31
|
+
- [`f460cc7c411`](https://bitbucket.org/atlassian/atlassian-frontend/commits/f460cc7c411) - Builds for this package now pass through a tokens babel plugin, removing runtime invocations of the tokens() function and improving bundle size.
|
|
32
|
+
- Updated dependencies
|
|
33
|
+
|
|
3
34
|
## 0.2.4
|
|
4
35
|
|
|
5
36
|
### Patch Changes
|
package/dist/cjs/focus-ring.js
CHANGED
|
@@ -11,21 +11,20 @@ var _core = require("@emotion/core");
|
|
|
11
11
|
|
|
12
12
|
var _colors = require("@atlaskit/theme/colors");
|
|
13
13
|
|
|
14
|
-
var _tokens = require("@atlaskit/tokens");
|
|
15
|
-
|
|
16
14
|
/** @jsx jsx */
|
|
17
|
-
var
|
|
18
|
-
|
|
19
|
-
outline:
|
|
15
|
+
var BORDER_WIDTH = 2;
|
|
16
|
+
var baseFocusOutsideStyles = (0, _core.css)({
|
|
17
|
+
outline: "".concat(BORDER_WIDTH, "px solid ").concat("var(--ds-border-focused, ".concat(_colors.B100, ")")),
|
|
18
|
+
outlineOffset: BORDER_WIDTH
|
|
20
19
|
});
|
|
21
20
|
var baseInsetStyles = (0, _core.css)({
|
|
22
|
-
boxShadow: "inset 0px 0px 0px
|
|
21
|
+
boxShadow: "inset 0px 0px 0px ".concat(BORDER_WIDTH, "px ").concat("var(--ds-border-focused, ".concat(_colors.B100, ")")),
|
|
23
22
|
outline: 'none'
|
|
24
23
|
});
|
|
25
24
|
var focusRingStyles = (0, _core.css)({
|
|
26
|
-
'&:focus-visible':
|
|
25
|
+
'&:focus-visible': baseFocusOutsideStyles,
|
|
27
26
|
'@supports not selector(*:focus-visible)': {
|
|
28
|
-
'&:focus':
|
|
27
|
+
'&:focus': baseFocusOutsideStyles
|
|
29
28
|
},
|
|
30
29
|
'@media screen and (forced-colors: active), screen and (-ms-high-contrast: active)': {
|
|
31
30
|
'&:focus-visible': {
|
|
@@ -51,20 +50,36 @@ var insetFocusRingStyles = (0, _core.css)({
|
|
|
51
50
|
* A focus ring is used indicate the currently focused item.
|
|
52
51
|
*
|
|
53
52
|
* - [Code](https://atlaskit.atlassian.com/packages/design-system/focus-ring)
|
|
53
|
+
*
|
|
54
|
+
* @example
|
|
55
|
+
* ```jsx
|
|
56
|
+
* import FocusRing from '@atlaskit/focus-ring';
|
|
57
|
+
*
|
|
58
|
+
* const InteractiveComponent = () => (
|
|
59
|
+
* <FocusRing>
|
|
60
|
+
* <button type="button">Hello</button>
|
|
61
|
+
* </FocusRing>
|
|
62
|
+
* )
|
|
63
|
+
* ```
|
|
54
64
|
*/
|
|
55
65
|
|
|
56
66
|
var FocusRing = function FocusRing(_ref) {
|
|
57
67
|
var children = _ref.children,
|
|
58
|
-
isInset = _ref.isInset
|
|
68
|
+
isInset = _ref.isInset,
|
|
69
|
+
focus = _ref.focus;
|
|
70
|
+
var controlledStyles = isInset ? baseInsetStyles : baseFocusOutsideStyles;
|
|
71
|
+
var uncontrolledStyles = isInset ? insetFocusRingStyles : focusRingStyles;
|
|
72
|
+
var focusCls = typeof focus === 'undefined' ? uncontrolledStyles : focus === 'on' && controlledStyles;
|
|
59
73
|
return (0, _core.jsx)(_core.ClassNames, null, function (_ref2) {
|
|
60
74
|
var css = _ref2.css,
|
|
61
75
|
cx = _ref2.cx;
|
|
62
|
-
return _react.Children.only(
|
|
76
|
+
return _react.Children.only( // This may look unwieldy but means we skip applying styles / cloning if no className is applicable
|
|
77
|
+
focusCls ?
|
|
63
78
|
/*#__PURE__*/
|
|
64
79
|
// eslint-disable-next-line @repo/internal/react/no-clone-element
|
|
65
80
|
(0, _react.cloneElement)(children, {
|
|
66
|
-
className: cx([css(
|
|
67
|
-
}));
|
|
81
|
+
className: cx([css(focusCls), children.props.className])
|
|
82
|
+
}) : children);
|
|
68
83
|
});
|
|
69
84
|
};
|
|
70
85
|
|
package/dist/cjs/index.js
CHANGED
|
@@ -11,5 +11,13 @@ Object.defineProperty(exports, "default", {
|
|
|
11
11
|
return _focusRing.default;
|
|
12
12
|
}
|
|
13
13
|
});
|
|
14
|
+
Object.defineProperty(exports, "useFocusRing", {
|
|
15
|
+
enumerable: true,
|
|
16
|
+
get: function get() {
|
|
17
|
+
return _useFocusRing.default;
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
var _focusRing = _interopRequireDefault(require("./focus-ring"));
|
|
14
22
|
|
|
15
|
-
var
|
|
23
|
+
var _useFocusRing = _interopRequireDefault(require("./use-focus-ring"));
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
|
|
5
|
+
Object.defineProperty(exports, "__esModule", {
|
|
6
|
+
value: true
|
|
7
|
+
});
|
|
8
|
+
exports.default = void 0;
|
|
9
|
+
|
|
10
|
+
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
|
|
11
|
+
|
|
12
|
+
var _react = require("react");
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* __Use focus ring__
|
|
16
|
+
*
|
|
17
|
+
* The `useFocusRing` hook is designed to manage focus for the `FocusRing` in cases where the `FocusRing`'s visual application
|
|
18
|
+
* and the element that takes focus, differ. See the `focus` prop of `FocusRing` for more information.
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* ```jsx
|
|
22
|
+
* import VisuallyHidden from '@atlaskit/visuall-hidden';
|
|
23
|
+
* import FocusRing, { useFocusRing } from '@atlaskit/focus-ring';
|
|
24
|
+
*
|
|
25
|
+
* const InteractiveComponent = () => {
|
|
26
|
+
* const { focusState, focusProps } = useFocusRing();
|
|
27
|
+
*
|
|
28
|
+
* return (
|
|
29
|
+
* <div>
|
|
30
|
+
* <VisuallHidden>
|
|
31
|
+
* <input {...focusProps} />
|
|
32
|
+
* </VisuallyHidden>
|
|
33
|
+
* <FocusRing focus={focusState}>
|
|
34
|
+
* <div role="button">Hello</div>
|
|
35
|
+
* </FocusRing>
|
|
36
|
+
* </div>
|
|
37
|
+
* );
|
|
38
|
+
*
|
|
39
|
+
* }
|
|
40
|
+
* ```
|
|
41
|
+
*/
|
|
42
|
+
var useFocusRing = function useFocusRing() {
|
|
43
|
+
var initialState = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'off';
|
|
44
|
+
|
|
45
|
+
var _useState = (0, _react.useState)(initialState),
|
|
46
|
+
_useState2 = (0, _slicedToArray2.default)(_useState, 2),
|
|
47
|
+
focusState = _useState2[0],
|
|
48
|
+
setFocusState = _useState2[1];
|
|
49
|
+
|
|
50
|
+
var focusProps = (0, _react.useRef)({
|
|
51
|
+
onFocus: function onFocus() {
|
|
52
|
+
return setFocusState('on');
|
|
53
|
+
},
|
|
54
|
+
onBlur: function onBlur() {
|
|
55
|
+
return setFocusState('off');
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
return {
|
|
59
|
+
focusState: focusState,
|
|
60
|
+
focusProps: focusProps.current
|
|
61
|
+
};
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
var _default = useFocusRing;
|
|
65
|
+
exports.default = _default;
|
package/dist/cjs/version.json
CHANGED
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
/** @jsx jsx */
|
|
2
2
|
import { Children, cloneElement } from 'react';
|
|
3
3
|
import { ClassNames, css, jsx } from '@emotion/core';
|
|
4
|
-
import { B100
|
|
5
|
-
|
|
6
|
-
const
|
|
7
|
-
|
|
8
|
-
|
|
4
|
+
import { B100 } from '@atlaskit/theme/colors';
|
|
5
|
+
const BORDER_WIDTH = 2;
|
|
6
|
+
const baseFocusOutsideStyles = css({
|
|
7
|
+
outline: `${BORDER_WIDTH}px solid ${`var(--ds-border-focused, ${B100})`}`,
|
|
8
|
+
outlineOffset: BORDER_WIDTH
|
|
9
9
|
});
|
|
10
10
|
const baseInsetStyles = css({
|
|
11
|
-
boxShadow: `inset 0px 0px 0px
|
|
11
|
+
boxShadow: `inset 0px 0px 0px ${BORDER_WIDTH}px ${`var(--ds-border-focused, ${B100})`}`,
|
|
12
12
|
outline: 'none'
|
|
13
13
|
});
|
|
14
14
|
const focusRingStyles = css({
|
|
15
|
-
'&:focus-visible':
|
|
15
|
+
'&:focus-visible': baseFocusOutsideStyles,
|
|
16
16
|
'@supports not selector(*:focus-visible)': {
|
|
17
|
-
'&:focus':
|
|
17
|
+
'&:focus': baseFocusOutsideStyles
|
|
18
18
|
},
|
|
19
19
|
'@media screen and (forced-colors: active), screen and (-ms-high-contrast: active)': {
|
|
20
20
|
'&:focus-visible': {
|
|
@@ -40,19 +40,37 @@ const insetFocusRingStyles = css({
|
|
|
40
40
|
* A focus ring is used indicate the currently focused item.
|
|
41
41
|
*
|
|
42
42
|
* - [Code](https://atlaskit.atlassian.com/packages/design-system/focus-ring)
|
|
43
|
+
*
|
|
44
|
+
* @example
|
|
45
|
+
* ```jsx
|
|
46
|
+
* import FocusRing from '@atlaskit/focus-ring';
|
|
47
|
+
*
|
|
48
|
+
* const InteractiveComponent = () => (
|
|
49
|
+
* <FocusRing>
|
|
50
|
+
* <button type="button">Hello</button>
|
|
51
|
+
* </FocusRing>
|
|
52
|
+
* )
|
|
53
|
+
* ```
|
|
43
54
|
*/
|
|
44
55
|
|
|
45
56
|
const FocusRing = ({
|
|
46
57
|
children,
|
|
47
|
-
isInset
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
})
|
|
58
|
+
isInset,
|
|
59
|
+
focus
|
|
60
|
+
}) => {
|
|
61
|
+
const controlledStyles = isInset ? baseInsetStyles : baseFocusOutsideStyles;
|
|
62
|
+
const uncontrolledStyles = isInset ? insetFocusRingStyles : focusRingStyles;
|
|
63
|
+
const focusCls = typeof focus === 'undefined' ? uncontrolledStyles : focus === 'on' && controlledStyles;
|
|
64
|
+
return jsx(ClassNames, null, ({
|
|
65
|
+
css,
|
|
66
|
+
cx
|
|
67
|
+
}) => Children.only( // This may look unwieldy but means we skip applying styles / cloning if no className is applicable
|
|
68
|
+
focusCls ?
|
|
69
|
+
/*#__PURE__*/
|
|
70
|
+
// eslint-disable-next-line @repo/internal/react/no-clone-element
|
|
71
|
+
cloneElement(children, {
|
|
72
|
+
className: cx([css(focusCls), children.props.className])
|
|
73
|
+
}) : children));
|
|
74
|
+
};
|
|
57
75
|
|
|
58
76
|
export default FocusRing;
|
package/dist/es2019/index.js
CHANGED
|
@@ -1 +1,2 @@
|
|
|
1
|
-
export { default } from './focus-ring';
|
|
1
|
+
export { default } from './focus-ring';
|
|
2
|
+
export { default as useFocusRing } from './use-focus-ring';
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { useRef, useState } from 'react';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* __Use focus ring__
|
|
5
|
+
*
|
|
6
|
+
* The `useFocusRing` hook is designed to manage focus for the `FocusRing` in cases where the `FocusRing`'s visual application
|
|
7
|
+
* and the element that takes focus, differ. See the `focus` prop of `FocusRing` for more information.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```jsx
|
|
11
|
+
* import VisuallyHidden from '@atlaskit/visuall-hidden';
|
|
12
|
+
* import FocusRing, { useFocusRing } from '@atlaskit/focus-ring';
|
|
13
|
+
*
|
|
14
|
+
* const InteractiveComponent = () => {
|
|
15
|
+
* const { focusState, focusProps } = useFocusRing();
|
|
16
|
+
*
|
|
17
|
+
* return (
|
|
18
|
+
* <div>
|
|
19
|
+
* <VisuallHidden>
|
|
20
|
+
* <input {...focusProps} />
|
|
21
|
+
* </VisuallyHidden>
|
|
22
|
+
* <FocusRing focus={focusState}>
|
|
23
|
+
* <div role="button">Hello</div>
|
|
24
|
+
* </FocusRing>
|
|
25
|
+
* </div>
|
|
26
|
+
* );
|
|
27
|
+
*
|
|
28
|
+
* }
|
|
29
|
+
* ```
|
|
30
|
+
*/
|
|
31
|
+
const useFocusRing = (initialState = 'off') => {
|
|
32
|
+
const [focusState, setFocusState] = useState(initialState);
|
|
33
|
+
const focusProps = useRef({
|
|
34
|
+
onFocus: () => setFocusState('on'),
|
|
35
|
+
onBlur: () => setFocusState('off')
|
|
36
|
+
});
|
|
37
|
+
return {
|
|
38
|
+
focusState,
|
|
39
|
+
focusProps: focusProps.current
|
|
40
|
+
};
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
export default useFocusRing;
|
package/dist/es2019/version.json
CHANGED
package/dist/esm/focus-ring.js
CHANGED
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
/** @jsx jsx */
|
|
2
2
|
import { Children, cloneElement } from 'react';
|
|
3
3
|
import { ClassNames, css, jsx } from '@emotion/core';
|
|
4
|
-
import { B100
|
|
5
|
-
|
|
6
|
-
var
|
|
7
|
-
|
|
8
|
-
|
|
4
|
+
import { B100 } from '@atlaskit/theme/colors';
|
|
5
|
+
var BORDER_WIDTH = 2;
|
|
6
|
+
var baseFocusOutsideStyles = css({
|
|
7
|
+
outline: "".concat(BORDER_WIDTH, "px solid ").concat("var(--ds-border-focused, ".concat(B100, ")")),
|
|
8
|
+
outlineOffset: BORDER_WIDTH
|
|
9
9
|
});
|
|
10
10
|
var baseInsetStyles = css({
|
|
11
|
-
boxShadow: "inset 0px 0px 0px
|
|
11
|
+
boxShadow: "inset 0px 0px 0px ".concat(BORDER_WIDTH, "px ").concat("var(--ds-border-focused, ".concat(B100, ")")),
|
|
12
12
|
outline: 'none'
|
|
13
13
|
});
|
|
14
14
|
var focusRingStyles = css({
|
|
15
|
-
'&:focus-visible':
|
|
15
|
+
'&:focus-visible': baseFocusOutsideStyles,
|
|
16
16
|
'@supports not selector(*:focus-visible)': {
|
|
17
|
-
'&:focus':
|
|
17
|
+
'&:focus': baseFocusOutsideStyles
|
|
18
18
|
},
|
|
19
19
|
'@media screen and (forced-colors: active), screen and (-ms-high-contrast: active)': {
|
|
20
20
|
'&:focus-visible': {
|
|
@@ -40,20 +40,36 @@ var insetFocusRingStyles = css({
|
|
|
40
40
|
* A focus ring is used indicate the currently focused item.
|
|
41
41
|
*
|
|
42
42
|
* - [Code](https://atlaskit.atlassian.com/packages/design-system/focus-ring)
|
|
43
|
+
*
|
|
44
|
+
* @example
|
|
45
|
+
* ```jsx
|
|
46
|
+
* import FocusRing from '@atlaskit/focus-ring';
|
|
47
|
+
*
|
|
48
|
+
* const InteractiveComponent = () => (
|
|
49
|
+
* <FocusRing>
|
|
50
|
+
* <button type="button">Hello</button>
|
|
51
|
+
* </FocusRing>
|
|
52
|
+
* )
|
|
53
|
+
* ```
|
|
43
54
|
*/
|
|
44
55
|
|
|
45
56
|
var FocusRing = function FocusRing(_ref) {
|
|
46
57
|
var children = _ref.children,
|
|
47
|
-
isInset = _ref.isInset
|
|
58
|
+
isInset = _ref.isInset,
|
|
59
|
+
focus = _ref.focus;
|
|
60
|
+
var controlledStyles = isInset ? baseInsetStyles : baseFocusOutsideStyles;
|
|
61
|
+
var uncontrolledStyles = isInset ? insetFocusRingStyles : focusRingStyles;
|
|
62
|
+
var focusCls = typeof focus === 'undefined' ? uncontrolledStyles : focus === 'on' && controlledStyles;
|
|
48
63
|
return jsx(ClassNames, null, function (_ref2) {
|
|
49
64
|
var css = _ref2.css,
|
|
50
65
|
cx = _ref2.cx;
|
|
51
|
-
return Children.only(
|
|
66
|
+
return Children.only( // This may look unwieldy but means we skip applying styles / cloning if no className is applicable
|
|
67
|
+
focusCls ?
|
|
52
68
|
/*#__PURE__*/
|
|
53
69
|
// eslint-disable-next-line @repo/internal/react/no-clone-element
|
|
54
70
|
cloneElement(children, {
|
|
55
|
-
className: cx([css(
|
|
56
|
-
}));
|
|
71
|
+
className: cx([css(focusCls), children.props.className])
|
|
72
|
+
}) : children);
|
|
57
73
|
});
|
|
58
74
|
};
|
|
59
75
|
|
package/dist/esm/index.js
CHANGED
|
@@ -1 +1,2 @@
|
|
|
1
|
-
export { default } from './focus-ring';
|
|
1
|
+
export { default } from './focus-ring';
|
|
2
|
+
export { default as useFocusRing } from './use-focus-ring';
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
|
|
2
|
+
import { useRef, useState } from 'react';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* __Use focus ring__
|
|
6
|
+
*
|
|
7
|
+
* The `useFocusRing` hook is designed to manage focus for the `FocusRing` in cases where the `FocusRing`'s visual application
|
|
8
|
+
* and the element that takes focus, differ. See the `focus` prop of `FocusRing` for more information.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```jsx
|
|
12
|
+
* import VisuallyHidden from '@atlaskit/visuall-hidden';
|
|
13
|
+
* import FocusRing, { useFocusRing } from '@atlaskit/focus-ring';
|
|
14
|
+
*
|
|
15
|
+
* const InteractiveComponent = () => {
|
|
16
|
+
* const { focusState, focusProps } = useFocusRing();
|
|
17
|
+
*
|
|
18
|
+
* return (
|
|
19
|
+
* <div>
|
|
20
|
+
* <VisuallHidden>
|
|
21
|
+
* <input {...focusProps} />
|
|
22
|
+
* </VisuallyHidden>
|
|
23
|
+
* <FocusRing focus={focusState}>
|
|
24
|
+
* <div role="button">Hello</div>
|
|
25
|
+
* </FocusRing>
|
|
26
|
+
* </div>
|
|
27
|
+
* );
|
|
28
|
+
*
|
|
29
|
+
* }
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
32
|
+
var useFocusRing = function useFocusRing() {
|
|
33
|
+
var initialState = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'off';
|
|
34
|
+
|
|
35
|
+
var _useState = useState(initialState),
|
|
36
|
+
_useState2 = _slicedToArray(_useState, 2),
|
|
37
|
+
focusState = _useState2[0],
|
|
38
|
+
setFocusState = _useState2[1];
|
|
39
|
+
|
|
40
|
+
var focusProps = useRef({
|
|
41
|
+
onFocus: function onFocus() {
|
|
42
|
+
return setFocusState('on');
|
|
43
|
+
},
|
|
44
|
+
onBlur: function onBlur() {
|
|
45
|
+
return setFocusState('off');
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
return {
|
|
49
|
+
focusState: focusState,
|
|
50
|
+
focusProps: focusProps.current
|
|
51
|
+
};
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
export default useFocusRing;
|
package/dist/esm/version.json
CHANGED
|
@@ -7,6 +7,17 @@ import type { FocusRingProps } from './types';
|
|
|
7
7
|
* A focus ring is used indicate the currently focused item.
|
|
8
8
|
*
|
|
9
9
|
* - [Code](https://atlaskit.atlassian.com/packages/design-system/focus-ring)
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```jsx
|
|
13
|
+
* import FocusRing from '@atlaskit/focus-ring';
|
|
14
|
+
*
|
|
15
|
+
* const InteractiveComponent = () => (
|
|
16
|
+
* <FocusRing>
|
|
17
|
+
* <button type="button">Hello</button>
|
|
18
|
+
* </FocusRing>
|
|
19
|
+
* )
|
|
20
|
+
* ```
|
|
10
21
|
*/
|
|
11
22
|
declare const FocusRing: FC<FocusRingProps>;
|
|
12
23
|
export default FocusRing;
|
package/dist/types/index.d.ts
CHANGED
package/dist/types/types.d.ts
CHANGED
|
@@ -1,5 +1,16 @@
|
|
|
1
|
-
import type { ReactElement } from 'react';
|
|
2
|
-
export
|
|
1
|
+
import type { FocusEventHandler, ReactElement } from 'react';
|
|
2
|
+
export interface FocusEventHandlers {
|
|
3
|
+
onFocus: FocusEventHandler;
|
|
4
|
+
onBlur: FocusEventHandler;
|
|
5
|
+
}
|
|
6
|
+
export declare type FocusState = 'on' | 'off';
|
|
7
|
+
export interface FocusRingProps {
|
|
8
|
+
/**
|
|
9
|
+
* Makes the `FocusRing` a controlled component (opting out of native focus behavior). The focus ring
|
|
10
|
+
* will apply the visual focus indicator when the `focus` prop is set to `on`. This prop should be used
|
|
11
|
+
* in conjunction with `useFocusRing`.
|
|
12
|
+
*/
|
|
13
|
+
focus?: FocusState;
|
|
3
14
|
/**
|
|
4
15
|
* Controls whether the focus ring should be applied around or within the composed element.
|
|
5
16
|
*/
|
|
@@ -8,4 +19,4 @@ export declare type FocusRingProps = {
|
|
|
8
19
|
* The focusable element to be rendered within the `FocusRing`.
|
|
9
20
|
*/
|
|
10
21
|
children: ReactElement;
|
|
11
|
-
}
|
|
22
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { FocusEventHandlers, FocusState } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* __Use focus ring__
|
|
4
|
+
*
|
|
5
|
+
* The `useFocusRing` hook is designed to manage focus for the `FocusRing` in cases where the `FocusRing`'s visual application
|
|
6
|
+
* and the element that takes focus, differ. See the `focus` prop of `FocusRing` for more information.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```jsx
|
|
10
|
+
* import VisuallyHidden from '@atlaskit/visuall-hidden';
|
|
11
|
+
* import FocusRing, { useFocusRing } from '@atlaskit/focus-ring';
|
|
12
|
+
*
|
|
13
|
+
* const InteractiveComponent = () => {
|
|
14
|
+
* const { focusState, focusProps } = useFocusRing();
|
|
15
|
+
*
|
|
16
|
+
* return (
|
|
17
|
+
* <div>
|
|
18
|
+
* <VisuallHidden>
|
|
19
|
+
* <input {...focusProps} />
|
|
20
|
+
* </VisuallyHidden>
|
|
21
|
+
* <FocusRing focus={focusState}>
|
|
22
|
+
* <div role="button">Hello</div>
|
|
23
|
+
* </FocusRing>
|
|
24
|
+
* </div>
|
|
25
|
+
* );
|
|
26
|
+
*
|
|
27
|
+
* }
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
30
|
+
declare const useFocusRing: (initialState?: FocusState) => {
|
|
31
|
+
readonly focusState: FocusState;
|
|
32
|
+
readonly focusProps: FocusEventHandlers;
|
|
33
|
+
};
|
|
34
|
+
export default useFocusRing;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atlaskit/focus-ring",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "1.0.0",
|
|
4
4
|
"description": "A focus ring is used to indicate the currently focused item.",
|
|
5
5
|
"author": "Atlassian Pty Ltd",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -9,10 +9,9 @@
|
|
|
9
9
|
},
|
|
10
10
|
"atlassian": {
|
|
11
11
|
"team": "Design System Team",
|
|
12
|
-
"
|
|
13
|
-
"releaseModel": "continuous",
|
|
12
|
+
"releaseModel": "scheduled",
|
|
14
13
|
"website": {
|
|
15
|
-
"name": "
|
|
14
|
+
"name": "Focus ring"
|
|
16
15
|
}
|
|
17
16
|
},
|
|
18
17
|
"repository": "https://bitbucket.org/atlassian/atlassian-frontend",
|
|
@@ -26,8 +25,8 @@
|
|
|
26
25
|
".": "./src/index.tsx"
|
|
27
26
|
},
|
|
28
27
|
"dependencies": {
|
|
29
|
-
"@atlaskit/theme": "^12.
|
|
30
|
-
"@atlaskit/tokens": "^0.
|
|
28
|
+
"@atlaskit/theme": "^12.1.0",
|
|
29
|
+
"@atlaskit/tokens": "^0.6.0",
|
|
31
30
|
"@babel/runtime": "^7.0.0",
|
|
32
31
|
"@emotion/core": "^10.0.9"
|
|
33
32
|
},
|
|
@@ -35,10 +34,13 @@
|
|
|
35
34
|
"react": "^16.8.0"
|
|
36
35
|
},
|
|
37
36
|
"devDependencies": {
|
|
38
|
-
"@atlaskit/
|
|
37
|
+
"@atlaskit/button": "^16.1.2",
|
|
39
38
|
"@atlaskit/docs": "*",
|
|
39
|
+
"@atlaskit/progress-indicator": "^9.2.0",
|
|
40
40
|
"@atlaskit/ssr": "*",
|
|
41
|
+
"@atlaskit/textfield": "^5.1.2",
|
|
41
42
|
"@atlaskit/visual-regression": "*",
|
|
43
|
+
"@atlaskit/visually-hidden": "^1.0.0",
|
|
42
44
|
"@atlaskit/webdriver-runner": "*",
|
|
43
45
|
"@atlassian/atlassian-frontend-prettier-config-1.0.0": "npm:@atlassian/atlassian-frontend-prettier-config@1.0.0",
|
|
44
46
|
"@testing-library/react": "^8.0.1",
|
|
@@ -53,7 +55,10 @@
|
|
|
53
55
|
},
|
|
54
56
|
"@repo/internal": {
|
|
55
57
|
"design-system": "v1",
|
|
56
|
-
"styling":
|
|
58
|
+
"styling": [
|
|
59
|
+
"static",
|
|
60
|
+
"emotion"
|
|
61
|
+
],
|
|
57
62
|
"ui-components": "lite-mode",
|
|
58
63
|
"analytics": "analytics-next",
|
|
59
64
|
"theming": "tokens",
|