@instructure/ui-view 10.16.4-snapshot-3 → 10.16.4-snapshot-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
@@ -3,7 +3,7 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
- ## [10.16.4-snapshot-3](https://github.com/instructure/instructure-ui/compare/v10.16.3...v10.16.4-snapshot-3) (2025-05-08)
6
+ ## [10.16.4-snapshot-5](https://github.com/instructure/instructure-ui/compare/v10.16.3...v10.16.4-snapshot-5) (2025-05-08)
7
7
 
8
8
  **Note:** Version bump only for package @instructure/ui-view
9
9
 
@@ -1,4 +1,4 @@
1
- var _View, _View2, _h, _h2, _h3, _h4, _h5, _View3, _View4, _View5, _View6, _View7, _View8, _View9, _View10;
1
+ var _View, _View2, _h, _h2, _h3, _h4, _h5, _View3, _View4, _View5, _View6, _View7, _View8;
2
2
  /*
3
3
  * The MIT License (MIT)
4
4
  *
@@ -210,32 +210,8 @@ describe('<View />', () => {
210
210
  const newStyles = getComputedStyle(view);
211
211
  expect(newStyles.maxWidth).toEqual('200px');
212
212
  });
213
- describe('withFocusOutline', () => {
214
- it('should warn when withFocusOutline is true without position=relative', () => {
215
- render(_View8 || (_View8 = _jsx(View, {
216
- withFocusOutline: true,
217
- children: _jsx("h1", {
218
- children: "View Content"
219
- })
220
- })));
221
- const expectedErrorMessage = 'Warning: [View] the focus outline will only show if the `position` prop is `relative`.';
222
- expect(consoleErrorMock).toHaveBeenCalledWith(expect.stringContaining(expectedErrorMessage), expect.any(String));
223
- });
224
- it('should warn when withFocusOutline is `true`, display is set to `inline`, and focusPosition is set to `offset`', () => {
225
- render(_View9 || (_View9 = _jsx(View, {
226
- withFocusOutline: true,
227
- display: "inline",
228
- focusPosition: "offset",
229
- children: _jsx("h1", {
230
- children: "View Content"
231
- })
232
- })));
233
- const expectedErrorMessage = 'Warning: [View] when display is set to `inline` the focus outline will only show if `focusPosition` is set to `inset`.';
234
- expect(consoleErrorMock).toHaveBeenCalledWith(expect.stringContaining(expectedErrorMessage), expect.any(String));
235
- });
236
- });
237
213
  it('should meet a11y standards', async () => {
238
- const _render11 = render(_View10 || (_View10 = _jsx(View, {
214
+ const _render11 = render(_View8 || (_View8 = _jsx(View, {
239
215
  children: "View Content"
240
216
  }))),
241
217
  container = _render11.container;
package/es/View/props.js CHANGED
@@ -61,11 +61,12 @@ const propTypes = {
61
61
  withVisualDebug: PropTypes.bool,
62
62
  dir: PropTypes.oneOf(Object.values(textDirectionContextConsumer.DIRECTION)),
63
63
  overscrollBehavior: PropTypes.oneOf(['auto', 'contain', 'none']),
64
- focusRingBorderRadius: PropTypes.string
64
+ focusRingBorderRadius: PropTypes.string,
65
+ focusWithin: PropTypes.bool
65
66
  };
66
67
 
67
68
  // This variable will be attached as static property on the `View` component
68
69
  // so we don't rely on the `PropTypes` validators for our internal logic.
69
70
  // This means on prod builds the consuming applications can safely delete propTypes.
70
- const allowedProps = ['as', 'background', 'borderColor', 'borderRadius', 'borderWidth', 'children', 'cursor', 'dir', 'display', 'elementRef', 'focusColor', 'focusPosition', 'height', 'insetBlockEnd', 'insetBlockStart', 'insetInlineEnd', 'insetInlineStart', 'margin', 'maxHeight', 'maxWidth', 'minHeight', 'minWidth', 'overflowX', 'overflowY', 'overscrollBehavior', 'padding', 'position', 'shadow', 'shouldAnimateFocus', 'stacking', 'textAlign', 'width', 'withFocusOutline', 'withVisualDebug', 'focusRingBorderRadius'];
71
+ const allowedProps = ['as', 'background', 'borderColor', 'borderRadius', 'borderWidth', 'children', 'cursor', 'dir', 'display', 'elementRef', 'focusColor', 'focusPosition', 'height', 'insetBlockEnd', 'insetBlockStart', 'insetInlineEnd', 'insetInlineStart', 'margin', 'maxHeight', 'maxWidth', 'minHeight', 'minWidth', 'overflowX', 'overflowY', 'overscrollBehavior', 'padding', 'position', 'shadow', 'shouldAnimateFocus', 'stacking', 'textAlign', 'width', 'withFocusOutline', 'withVisualDebug', 'focusRingBorderRadius', 'focusWithin'];
71
72
  export { propTypes, allowedProps };
package/es/View/styles.js CHANGED
@@ -25,7 +25,7 @@
25
25
  import { DIRECTION } from '@instructure/ui-i18n';
26
26
  import { getShorthandPropValue, mirrorShorthandEdges, mirrorShorthandCorners } from '@instructure/emotion';
27
27
  import { pickProps } from '@instructure/ui-react-utils';
28
- import { logError as error } from '@instructure/console';
28
+ import { alpha } from '@instructure/ui-color-utils';
29
29
  const getBorderStyle = ({
30
30
  borderRadius,
31
31
  borderWidth,
@@ -115,20 +115,6 @@ const getFocusRingRadius = (borderRadius, props) => {
115
115
  }
116
116
  return `${baseRadiusStyle}None`;
117
117
  };
118
- const getFocusOutline = props => {
119
- const position = props.position,
120
- display = props.display,
121
- focusPosition = props.focusPosition,
122
- shouldDisplayFocusOutline = props.withFocusOutline;
123
- if (typeof shouldDisplayFocusOutline === 'undefined') {
124
- return shouldDisplayFocusOutline;
125
- }
126
- if (shouldDisplayFocusOutline) {
127
- error(display === 'inline' || position === 'relative', '[View] the focus outline will only show if the `position` prop is `relative`.');
128
- error(display !== 'inline' || focusPosition === 'inset', '[View] when display is set to `inline` the focus outline will only show if `focusPosition` is set to `inset`.');
129
- }
130
- return shouldDisplayFocusOutline;
131
- };
132
118
  const withBorder = props => {
133
119
  const borderWidth = props.borderWidth;
134
120
  return borderWidth && borderWidth !== '0' && borderWidth !== 'none';
@@ -136,24 +122,18 @@ const withBorder = props => {
136
122
  const getFocusStyles = (props, componentTheme) => {
137
123
  const focusColor = props.focusColor,
138
124
  focusPosition = props.focusPosition,
139
- position = props.position,
140
125
  shouldAnimateFocus = props.shouldAnimateFocus,
141
126
  borderRadius = props.borderRadius,
142
- focusRingBorderRadius = props.focusRingBorderRadius;
143
- const focusOutline = getFocusOutline(props);
144
- const shouldUseBrowserFocus = typeof focusOutline === 'undefined';
127
+ focusRingBorderRadius = props.focusRingBorderRadius,
128
+ withFocusOutline = props.withFocusOutline,
129
+ focusWithin = props.focusWithin;
130
+ const focusPos = focusPosition == 'offset' || focusPosition == 'inset' ? focusPosition : 'offset';
145
131
  const focusPositionVariants = {
146
132
  offset: {
147
- top: `calc(${componentTheme.focusOutlineOffset} * -1)`,
148
- left: `calc(${componentTheme.focusOutlineOffset} * -1)`,
149
- right: `calc(${componentTheme.focusOutlineOffset} * -1)`,
150
- bottom: `calc(${componentTheme.focusOutlineOffset}* -1)`
133
+ outlineOffset: `calc(${componentTheme.focusOutlineOffset} - ${componentTheme.focusOutlineWidth})`
151
134
  },
152
135
  inset: {
153
- top: `calc(${componentTheme.focusOutlineInset} * -1)`,
154
- left: `calc(${componentTheme.focusOutlineInset} * -1)`,
155
- right: `calc(${componentTheme.focusOutlineInset} * -1)`,
156
- bottom: `calc(${componentTheme.focusOutlineInset} * -1)`
136
+ outlineOffset: `calc(${componentTheme.focusOutlineInset} - ${componentTheme.focusOutlineWidth})`
157
137
  }
158
138
  };
159
139
  const focusColorVariants = {
@@ -162,88 +142,68 @@ const getFocusStyles = (props, componentTheme) => {
162
142
  success: componentTheme.focusColorSuccess,
163
143
  danger: componentTheme.focusColorDanger
164
144
  };
165
- if (position === 'relative') {
166
- const focusRingRadius = getFocusRingRadius(borderRadius, props);
167
- const focusRingVariants = {
168
- 'focusRing--radiusInherit': 'inherit',
169
- 'focusRing--radiusNone': 0
170
- };
171
- const borderRadiusByOffset = {
172
- offset: {
173
- 'focusRing--radiusSmall': {
174
- borderRadius: `calc(${componentTheme.borderRadiusSmall} + (${componentTheme.focusOutlineOffset} - ${componentTheme.focusOutlineWidth}))`
175
- },
176
- 'focusRing--radiusMedium': {
177
- borderRadius: `calc(${componentTheme.borderRadiusMedium} + (${componentTheme.focusOutlineOffset} - ${componentTheme.focusOutlineWidth}))`
178
- },
179
- 'focusRing--radiusLarge': {
180
- borderRadius: `calc(${componentTheme.borderRadiusLarge} + (${componentTheme.focusOutlineOffset} - ${componentTheme.focusOutlineWidth}))`
181
- },
182
- 'focusRing--radiusCustom': {
183
- borderRadius: `calc(${focusRingBorderRadius} + (${componentTheme.focusOutlineOffset} - ${componentTheme.focusOutlineWidth}))`
184
- }
145
+ const focusRingRadius = getFocusRingRadius(borderRadius, props);
146
+ const focusRingVariants = {
147
+ 'focusRing--radiusInherit': 'inherit',
148
+ 'focusRing--radiusNone': 0
149
+ };
150
+ const borderRadiusByOffset = {
151
+ offset: {
152
+ 'focusRing--radiusSmall': {
153
+ borderRadius: `calc(${componentTheme.borderRadiusSmall} + (${componentTheme.focusOutlineOffset} - ${componentTheme.focusOutlineWidth}))`
154
+ },
155
+ 'focusRing--radiusMedium': {
156
+ borderRadius: `calc(${componentTheme.borderRadiusMedium} + (${componentTheme.focusOutlineOffset} - ${componentTheme.focusOutlineWidth}))`
185
157
  },
186
- inset: {
187
- 'focusRing--radiusSmall': {
188
- borderRadius: `calc(${componentTheme.borderRadiusSmall} - (${componentTheme.focusOutlineInset} + ${componentTheme.focusOutlineWidth}))`
189
- },
190
- 'focusRing--radiusMedium': {
191
- borderRadius: `calc(${componentTheme.borderRadiusMedium} - (${componentTheme.focusOutlineInset} + ${componentTheme.focusOutlineWidth}))`
192
- },
193
- 'focusRing--radiusLarge': {
194
- borderRadius: `calc(${componentTheme.borderRadiusLarge} - (${componentTheme.focusOutlineInset} + ${componentTheme.focusOutlineWidth}))`
195
- },
196
- 'focusRing--radiusCustom': {
197
- borderRadius: `calc(${focusRingBorderRadius} - (${componentTheme.focusOutlineOffset} + ${componentTheme.focusOutlineWidth}))`
198
- }
158
+ 'focusRing--radiusLarge': {
159
+ borderRadius: `calc(${componentTheme.borderRadiusLarge} + (${componentTheme.focusOutlineOffset} - ${componentTheme.focusOutlineWidth}))`
160
+ },
161
+ 'focusRing--radiusCustom': {
162
+ borderRadius: `calc(${focusRingBorderRadius} + (${componentTheme.focusOutlineOffset} - ${componentTheme.focusOutlineWidth}))`
199
163
  }
200
- };
201
- return {
202
- '&::before': {
203
- pointerEvents: 'none',
204
- content: '""',
205
- position: 'absolute',
206
- borderStyle: componentTheme.focusOutlineStyle,
207
- borderWidth: componentTheme.focusOutlineWidth,
208
- borderColor: focusColorVariants[focusColor],
209
- opacity: 0,
210
- borderRadius: focusRingVariants[focusRingRadius],
211
- ...borderRadiusByOffset[focusPosition][focusRingRadius],
212
- ...focusPositionVariants[focusPosition],
213
- ...(shouldAnimateFocus ? {
214
- transition: 'all 0.2s',
215
- transform: 'scale(0.95)'
216
- } : {}),
217
- ...(focusOutline ? {
218
- opacity: 1,
219
- transform: 'scale(1)'
220
- } : {})
164
+ },
165
+ inset: {
166
+ 'focusRing--radiusSmall': {
167
+ borderRadius: `calc(${componentTheme.borderRadiusSmall} - (${componentTheme.focusOutlineInset} + ${componentTheme.focusOutlineWidth}))`
168
+ },
169
+ 'focusRing--radiusMedium': {
170
+ borderRadius: `calc(${componentTheme.borderRadiusMedium} - (${componentTheme.focusOutlineInset} + ${componentTheme.focusOutlineWidth}))`
171
+ },
172
+ 'focusRing--radiusLarge': {
173
+ borderRadius: `calc(${componentTheme.borderRadiusLarge} - (${componentTheme.focusOutlineInset} + ${componentTheme.focusOutlineWidth}))`
221
174
  },
222
- '&:focus': {
223
- outline: 'none',
224
- '&::before': {
225
- ...(shouldUseBrowserFocus ? {
226
- opacity: 1,
227
- transform: 'scale(1)'
228
- } : {})
229
- }
175
+ 'focusRing--radiusCustom': {
176
+ borderRadius: `calc(${focusRingBorderRadius} - (${componentTheme.focusOutlineOffset} + ${componentTheme.focusOutlineWidth}))`
230
177
  }
231
- };
232
- }
178
+ }
179
+ };
233
180
  return {
234
- '&::before': {
235
- borderStyle: 'none'
236
- },
237
- outlineStyle: 'none',
238
- outlineColor: focusColorVariants[focusColor],
239
- ...(focusOutline ? {
240
- outlineWidth: componentTheme.focusOutlineWidth,
241
- outlineStyle: componentTheme.focusOutlineStyle
181
+ outlineOffset: '-0.8rem',
182
+ // value when not in focus, its invisible
183
+ outlineColor: alpha(focusColorVariants[focusColor], 0),
184
+ outlineStyle: componentTheme.focusOutlineStyle,
185
+ outlineWidth: componentTheme.focusOutlineWidth,
186
+ borderRadius: focusRingVariants[focusRingRadius],
187
+ // inherit or none
188
+ ...borderRadiusByOffset[focusPos][focusRingRadius],
189
+ // border radius value
190
+ ...(shouldAnimateFocus ? {
191
+ transition: 'outline-color 0.2s, outline-offset 0.25s'
192
+ } : {}),
193
+ ...(withFocusOutline ? {
194
+ ...focusPositionVariants[focusPos],
195
+ outlineColor: focusColorVariants[focusColor]
242
196
  } : {}),
243
197
  '&:focus': {
244
- ...(shouldUseBrowserFocus ? {
245
- outlineWidth: componentTheme.focusOutlineWidth,
246
- outlineStyle: componentTheme.focusOutlineStyle
198
+ ...(typeof withFocusOutline === 'undefined' ? {
199
+ ...focusPositionVariants[focusPos],
200
+ outlineColor: focusColorVariants[focusColor]
201
+ } : {})
202
+ },
203
+ '&:focus-within': {
204
+ ...(focusWithin ? {
205
+ ...focusPositionVariants[focusPos],
206
+ outlineColor: focusColorVariants[focusColor]
247
207
  } : {})
248
208
  }
249
209
  };
@@ -256,7 +216,6 @@ const getFocusStyles = (props, componentTheme) => {
256
216
  * Generates the style object from the theme and provided additional information
257
217
  * @param {Object} componentTheme The theme variable object.
258
218
  * @param {Object} props the props of the component, the style is applied to
259
- * @param {Object} extraArgs
260
219
  * @return {Object} The final style object, which will be used in the component
261
220
  */
262
221
  const generateStyle = (componentTheme, props) => {
@@ -266,7 +225,6 @@ const generateStyle = (componentTheme, props) => {
266
225
  padding = props.padding,
267
226
  position = props.position,
268
227
  display = props.display,
269
- focusPosition = props.focusPosition,
270
228
  textAlign = props.textAlign,
271
229
  borderColor = props.borderColor,
272
230
  background = props.background,
@@ -306,7 +264,6 @@ const generateStyle = (componentTheme, props) => {
306
264
  insetInlineEnd,
307
265
  insetInlineStart
308
266
  });
309
- const shouldUseFocusStyles = position === 'relative' || display === 'inline' && focusPosition === 'inset';
310
267
  const displayVariants = {
311
268
  inline: {
312
269
  label: 'view--inline',
@@ -459,7 +416,8 @@ const generateStyle = (componentTheme, props) => {
459
416
  position: position !== 'static' ? position : '',
460
417
  overscrollBehavior: overscrollBehavior ? overscrollBehavior : 'auto',
461
418
  ...(withVisualDebug ? {
462
- outline: `0.0625rem dashed ${componentTheme.debugOutlineColor}`
419
+ //outline: `0.0625rem dashed ${componentTheme.debugOutlineColor}`
420
+ boxShadow: `0 0 0 1px ${componentTheme.debugOutlineColor}`
463
421
  } : {}),
464
422
  ...(withBorder(props) ? {
465
423
  borderStyle: componentTheme.borderStyle,
@@ -467,7 +425,7 @@ const generateStyle = (componentTheme, props) => {
467
425
  borderColor: borderColor
468
426
  })
469
427
  } : {}),
470
- ...(shouldUseFocusStyles ? focusStyles : {})
428
+ ...focusStyles
471
429
  },
472
430
  inlineStyles: {
473
431
  //every '&' symbol will add another class to the rule, so it will be stronger
@@ -6,7 +6,7 @@ require("@testing-library/jest-dom");
6
6
  var _index = require("../../index");
7
7
  var _runAxeCheck = require("@instructure/ui-axe-check/lib/runAxeCheck.js");
8
8
  var _jsxRuntime = require("@emotion/react/jsx-runtime");
9
- var _View, _View2, _h, _h2, _h3, _h4, _h5, _View3, _View4, _View5, _View6, _View7, _View8, _View9, _View10;
9
+ var _View, _View2, _h, _h2, _h3, _h4, _h5, _View3, _View4, _View5, _View6, _View7, _View8;
10
10
  /*
11
11
  * The MIT License (MIT)
12
12
  *
@@ -211,32 +211,8 @@ describe('<View />', () => {
211
211
  const newStyles = getComputedStyle(view);
212
212
  expect(newStyles.maxWidth).toEqual('200px');
213
213
  });
214
- describe('withFocusOutline', () => {
215
- it('should warn when withFocusOutline is true without position=relative', () => {
216
- (0, _react.render)(_View8 || (_View8 = (0, _jsxRuntime.jsx)(_index.View, {
217
- withFocusOutline: true,
218
- children: (0, _jsxRuntime.jsx)("h1", {
219
- children: "View Content"
220
- })
221
- })));
222
- const expectedErrorMessage = 'Warning: [View] the focus outline will only show if the `position` prop is `relative`.';
223
- expect(consoleErrorMock).toHaveBeenCalledWith(expect.stringContaining(expectedErrorMessage), expect.any(String));
224
- });
225
- it('should warn when withFocusOutline is `true`, display is set to `inline`, and focusPosition is set to `offset`', () => {
226
- (0, _react.render)(_View9 || (_View9 = (0, _jsxRuntime.jsx)(_index.View, {
227
- withFocusOutline: true,
228
- display: "inline",
229
- focusPosition: "offset",
230
- children: (0, _jsxRuntime.jsx)("h1", {
231
- children: "View Content"
232
- })
233
- })));
234
- const expectedErrorMessage = 'Warning: [View] when display is set to `inline` the focus outline will only show if `focusPosition` is set to `inset`.';
235
- expect(consoleErrorMock).toHaveBeenCalledWith(expect.stringContaining(expectedErrorMessage), expect.any(String));
236
- });
237
- });
238
214
  it('should meet a11y standards', async () => {
239
- const _render11 = (0, _react.render)(_View10 || (_View10 = (0, _jsxRuntime.jsx)(_index.View, {
215
+ const _render11 = (0, _react.render)(_View8 || (_View8 = (0, _jsxRuntime.jsx)(_index.View, {
240
216
  children: "View Content"
241
217
  }))),
242
218
  container = _render11.container;
package/lib/View/props.js CHANGED
@@ -68,10 +68,11 @@ const propTypes = exports.propTypes = {
68
68
  withVisualDebug: _propTypes.default.bool,
69
69
  dir: _propTypes.default.oneOf(Object.values(_textDirectionContextConsumer.textDirectionContextConsumer.DIRECTION)),
70
70
  overscrollBehavior: _propTypes.default.oneOf(['auto', 'contain', 'none']),
71
- focusRingBorderRadius: _propTypes.default.string
71
+ focusRingBorderRadius: _propTypes.default.string,
72
+ focusWithin: _propTypes.default.bool
72
73
  };
73
74
 
74
75
  // This variable will be attached as static property on the `View` component
75
76
  // so we don't rely on the `PropTypes` validators for our internal logic.
76
77
  // This means on prod builds the consuming applications can safely delete propTypes.
77
- const allowedProps = exports.allowedProps = ['as', 'background', 'borderColor', 'borderRadius', 'borderWidth', 'children', 'cursor', 'dir', 'display', 'elementRef', 'focusColor', 'focusPosition', 'height', 'insetBlockEnd', 'insetBlockStart', 'insetInlineEnd', 'insetInlineStart', 'margin', 'maxHeight', 'maxWidth', 'minHeight', 'minWidth', 'overflowX', 'overflowY', 'overscrollBehavior', 'padding', 'position', 'shadow', 'shouldAnimateFocus', 'stacking', 'textAlign', 'width', 'withFocusOutline', 'withVisualDebug', 'focusRingBorderRadius'];
78
+ const allowedProps = exports.allowedProps = ['as', 'background', 'borderColor', 'borderRadius', 'borderWidth', 'children', 'cursor', 'dir', 'display', 'elementRef', 'focusColor', 'focusPosition', 'height', 'insetBlockEnd', 'insetBlockStart', 'insetInlineEnd', 'insetInlineStart', 'margin', 'maxHeight', 'maxWidth', 'minHeight', 'minWidth', 'overflowX', 'overflowY', 'overscrollBehavior', 'padding', 'position', 'shadow', 'shouldAnimateFocus', 'stacking', 'textAlign', 'width', 'withFocusOutline', 'withVisualDebug', 'focusRingBorderRadius', 'focusWithin'];
@@ -7,7 +7,7 @@ exports.default = void 0;
7
7
  var _uiI18n = require("@instructure/ui-i18n");
8
8
  var _emotion = require("@instructure/emotion");
9
9
  var _pickProps = require("@instructure/ui-react-utils/lib/pickProps.js");
10
- var _console = require("@instructure/console");
10
+ var _alpha = require("@instructure/ui-color-utils/lib/alpha.js");
11
11
  /*
12
12
  * The MIT License (MIT)
13
13
  *
@@ -121,20 +121,6 @@ const getFocusRingRadius = (borderRadius, props) => {
121
121
  }
122
122
  return `${baseRadiusStyle}None`;
123
123
  };
124
- const getFocusOutline = props => {
125
- const position = props.position,
126
- display = props.display,
127
- focusPosition = props.focusPosition,
128
- shouldDisplayFocusOutline = props.withFocusOutline;
129
- if (typeof shouldDisplayFocusOutline === 'undefined') {
130
- return shouldDisplayFocusOutline;
131
- }
132
- if (shouldDisplayFocusOutline) {
133
- (0, _console.logError)(display === 'inline' || position === 'relative', '[View] the focus outline will only show if the `position` prop is `relative`.');
134
- (0, _console.logError)(display !== 'inline' || focusPosition === 'inset', '[View] when display is set to `inline` the focus outline will only show if `focusPosition` is set to `inset`.');
135
- }
136
- return shouldDisplayFocusOutline;
137
- };
138
124
  const withBorder = props => {
139
125
  const borderWidth = props.borderWidth;
140
126
  return borderWidth && borderWidth !== '0' && borderWidth !== 'none';
@@ -142,24 +128,18 @@ const withBorder = props => {
142
128
  const getFocusStyles = (props, componentTheme) => {
143
129
  const focusColor = props.focusColor,
144
130
  focusPosition = props.focusPosition,
145
- position = props.position,
146
131
  shouldAnimateFocus = props.shouldAnimateFocus,
147
132
  borderRadius = props.borderRadius,
148
- focusRingBorderRadius = props.focusRingBorderRadius;
149
- const focusOutline = getFocusOutline(props);
150
- const shouldUseBrowserFocus = typeof focusOutline === 'undefined';
133
+ focusRingBorderRadius = props.focusRingBorderRadius,
134
+ withFocusOutline = props.withFocusOutline,
135
+ focusWithin = props.focusWithin;
136
+ const focusPos = focusPosition == 'offset' || focusPosition == 'inset' ? focusPosition : 'offset';
151
137
  const focusPositionVariants = {
152
138
  offset: {
153
- top: `calc(${componentTheme.focusOutlineOffset} * -1)`,
154
- left: `calc(${componentTheme.focusOutlineOffset} * -1)`,
155
- right: `calc(${componentTheme.focusOutlineOffset} * -1)`,
156
- bottom: `calc(${componentTheme.focusOutlineOffset}* -1)`
139
+ outlineOffset: `calc(${componentTheme.focusOutlineOffset} - ${componentTheme.focusOutlineWidth})`
157
140
  },
158
141
  inset: {
159
- top: `calc(${componentTheme.focusOutlineInset} * -1)`,
160
- left: `calc(${componentTheme.focusOutlineInset} * -1)`,
161
- right: `calc(${componentTheme.focusOutlineInset} * -1)`,
162
- bottom: `calc(${componentTheme.focusOutlineInset} * -1)`
142
+ outlineOffset: `calc(${componentTheme.focusOutlineInset} - ${componentTheme.focusOutlineWidth})`
163
143
  }
164
144
  };
165
145
  const focusColorVariants = {
@@ -168,88 +148,68 @@ const getFocusStyles = (props, componentTheme) => {
168
148
  success: componentTheme.focusColorSuccess,
169
149
  danger: componentTheme.focusColorDanger
170
150
  };
171
- if (position === 'relative') {
172
- const focusRingRadius = getFocusRingRadius(borderRadius, props);
173
- const focusRingVariants = {
174
- 'focusRing--radiusInherit': 'inherit',
175
- 'focusRing--radiusNone': 0
176
- };
177
- const borderRadiusByOffset = {
178
- offset: {
179
- 'focusRing--radiusSmall': {
180
- borderRadius: `calc(${componentTheme.borderRadiusSmall} + (${componentTheme.focusOutlineOffset} - ${componentTheme.focusOutlineWidth}))`
181
- },
182
- 'focusRing--radiusMedium': {
183
- borderRadius: `calc(${componentTheme.borderRadiusMedium} + (${componentTheme.focusOutlineOffset} - ${componentTheme.focusOutlineWidth}))`
184
- },
185
- 'focusRing--radiusLarge': {
186
- borderRadius: `calc(${componentTheme.borderRadiusLarge} + (${componentTheme.focusOutlineOffset} - ${componentTheme.focusOutlineWidth}))`
187
- },
188
- 'focusRing--radiusCustom': {
189
- borderRadius: `calc(${focusRingBorderRadius} + (${componentTheme.focusOutlineOffset} - ${componentTheme.focusOutlineWidth}))`
190
- }
151
+ const focusRingRadius = getFocusRingRadius(borderRadius, props);
152
+ const focusRingVariants = {
153
+ 'focusRing--radiusInherit': 'inherit',
154
+ 'focusRing--radiusNone': 0
155
+ };
156
+ const borderRadiusByOffset = {
157
+ offset: {
158
+ 'focusRing--radiusSmall': {
159
+ borderRadius: `calc(${componentTheme.borderRadiusSmall} + (${componentTheme.focusOutlineOffset} - ${componentTheme.focusOutlineWidth}))`
160
+ },
161
+ 'focusRing--radiusMedium': {
162
+ borderRadius: `calc(${componentTheme.borderRadiusMedium} + (${componentTheme.focusOutlineOffset} - ${componentTheme.focusOutlineWidth}))`
191
163
  },
192
- inset: {
193
- 'focusRing--radiusSmall': {
194
- borderRadius: `calc(${componentTheme.borderRadiusSmall} - (${componentTheme.focusOutlineInset} + ${componentTheme.focusOutlineWidth}))`
195
- },
196
- 'focusRing--radiusMedium': {
197
- borderRadius: `calc(${componentTheme.borderRadiusMedium} - (${componentTheme.focusOutlineInset} + ${componentTheme.focusOutlineWidth}))`
198
- },
199
- 'focusRing--radiusLarge': {
200
- borderRadius: `calc(${componentTheme.borderRadiusLarge} - (${componentTheme.focusOutlineInset} + ${componentTheme.focusOutlineWidth}))`
201
- },
202
- 'focusRing--radiusCustom': {
203
- borderRadius: `calc(${focusRingBorderRadius} - (${componentTheme.focusOutlineOffset} + ${componentTheme.focusOutlineWidth}))`
204
- }
164
+ 'focusRing--radiusLarge': {
165
+ borderRadius: `calc(${componentTheme.borderRadiusLarge} + (${componentTheme.focusOutlineOffset} - ${componentTheme.focusOutlineWidth}))`
166
+ },
167
+ 'focusRing--radiusCustom': {
168
+ borderRadius: `calc(${focusRingBorderRadius} + (${componentTheme.focusOutlineOffset} - ${componentTheme.focusOutlineWidth}))`
205
169
  }
206
- };
207
- return {
208
- '&::before': {
209
- pointerEvents: 'none',
210
- content: '""',
211
- position: 'absolute',
212
- borderStyle: componentTheme.focusOutlineStyle,
213
- borderWidth: componentTheme.focusOutlineWidth,
214
- borderColor: focusColorVariants[focusColor],
215
- opacity: 0,
216
- borderRadius: focusRingVariants[focusRingRadius],
217
- ...borderRadiusByOffset[focusPosition][focusRingRadius],
218
- ...focusPositionVariants[focusPosition],
219
- ...(shouldAnimateFocus ? {
220
- transition: 'all 0.2s',
221
- transform: 'scale(0.95)'
222
- } : {}),
223
- ...(focusOutline ? {
224
- opacity: 1,
225
- transform: 'scale(1)'
226
- } : {})
170
+ },
171
+ inset: {
172
+ 'focusRing--radiusSmall': {
173
+ borderRadius: `calc(${componentTheme.borderRadiusSmall} - (${componentTheme.focusOutlineInset} + ${componentTheme.focusOutlineWidth}))`
174
+ },
175
+ 'focusRing--radiusMedium': {
176
+ borderRadius: `calc(${componentTheme.borderRadiusMedium} - (${componentTheme.focusOutlineInset} + ${componentTheme.focusOutlineWidth}))`
177
+ },
178
+ 'focusRing--radiusLarge': {
179
+ borderRadius: `calc(${componentTheme.borderRadiusLarge} - (${componentTheme.focusOutlineInset} + ${componentTheme.focusOutlineWidth}))`
227
180
  },
228
- '&:focus': {
229
- outline: 'none',
230
- '&::before': {
231
- ...(shouldUseBrowserFocus ? {
232
- opacity: 1,
233
- transform: 'scale(1)'
234
- } : {})
235
- }
181
+ 'focusRing--radiusCustom': {
182
+ borderRadius: `calc(${focusRingBorderRadius} - (${componentTheme.focusOutlineOffset} + ${componentTheme.focusOutlineWidth}))`
236
183
  }
237
- };
238
- }
184
+ }
185
+ };
239
186
  return {
240
- '&::before': {
241
- borderStyle: 'none'
242
- },
243
- outlineStyle: 'none',
244
- outlineColor: focusColorVariants[focusColor],
245
- ...(focusOutline ? {
246
- outlineWidth: componentTheme.focusOutlineWidth,
247
- outlineStyle: componentTheme.focusOutlineStyle
187
+ outlineOffset: '-0.8rem',
188
+ // value when not in focus, its invisible
189
+ outlineColor: (0, _alpha.alpha)(focusColorVariants[focusColor], 0),
190
+ outlineStyle: componentTheme.focusOutlineStyle,
191
+ outlineWidth: componentTheme.focusOutlineWidth,
192
+ borderRadius: focusRingVariants[focusRingRadius],
193
+ // inherit or none
194
+ ...borderRadiusByOffset[focusPos][focusRingRadius],
195
+ // border radius value
196
+ ...(shouldAnimateFocus ? {
197
+ transition: 'outline-color 0.2s, outline-offset 0.25s'
198
+ } : {}),
199
+ ...(withFocusOutline ? {
200
+ ...focusPositionVariants[focusPos],
201
+ outlineColor: focusColorVariants[focusColor]
248
202
  } : {}),
249
203
  '&:focus': {
250
- ...(shouldUseBrowserFocus ? {
251
- outlineWidth: componentTheme.focusOutlineWidth,
252
- outlineStyle: componentTheme.focusOutlineStyle
204
+ ...(typeof withFocusOutline === 'undefined' ? {
205
+ ...focusPositionVariants[focusPos],
206
+ outlineColor: focusColorVariants[focusColor]
207
+ } : {})
208
+ },
209
+ '&:focus-within': {
210
+ ...(focusWithin ? {
211
+ ...focusPositionVariants[focusPos],
212
+ outlineColor: focusColorVariants[focusColor]
253
213
  } : {})
254
214
  }
255
215
  };
@@ -262,7 +222,6 @@ const getFocusStyles = (props, componentTheme) => {
262
222
  * Generates the style object from the theme and provided additional information
263
223
  * @param {Object} componentTheme The theme variable object.
264
224
  * @param {Object} props the props of the component, the style is applied to
265
- * @param {Object} extraArgs
266
225
  * @return {Object} The final style object, which will be used in the component
267
226
  */
268
227
  const generateStyle = (componentTheme, props) => {
@@ -272,7 +231,6 @@ const generateStyle = (componentTheme, props) => {
272
231
  padding = props.padding,
273
232
  position = props.position,
274
233
  display = props.display,
275
- focusPosition = props.focusPosition,
276
234
  textAlign = props.textAlign,
277
235
  borderColor = props.borderColor,
278
236
  background = props.background,
@@ -312,7 +270,6 @@ const generateStyle = (componentTheme, props) => {
312
270
  insetInlineEnd,
313
271
  insetInlineStart
314
272
  });
315
- const shouldUseFocusStyles = position === 'relative' || display === 'inline' && focusPosition === 'inset';
316
273
  const displayVariants = {
317
274
  inline: {
318
275
  label: 'view--inline',
@@ -465,7 +422,8 @@ const generateStyle = (componentTheme, props) => {
465
422
  position: position !== 'static' ? position : '',
466
423
  overscrollBehavior: overscrollBehavior ? overscrollBehavior : 'auto',
467
424
  ...(withVisualDebug ? {
468
- outline: `0.0625rem dashed ${componentTheme.debugOutlineColor}`
425
+ //outline: `0.0625rem dashed ${componentTheme.debugOutlineColor}`
426
+ boxShadow: `0 0 0 1px ${componentTheme.debugOutlineColor}`
469
427
  } : {}),
470
428
  ...(withBorder(props) ? {
471
429
  borderStyle: componentTheme.borderStyle,
@@ -473,7 +431,7 @@ const generateStyle = (componentTheme, props) => {
473
431
  borderColor: borderColor
474
432
  })
475
433
  } : {}),
476
- ...(shouldUseFocusStyles ? focusStyles : {})
434
+ ...focusStyles
477
435
  },
478
436
  inlineStyles: {
479
437
  //every '&' symbol will add another class to the rule, so it will be stronger