Skip to content

Commit f717698

Browse files
committed
refactor(many): experiment how to refactor focus rings. Trying to use View for it, but it needs a new focus-within CSS selector
1 parent 6b7d4b7 commit f717698

File tree

6 files changed

+92
-158
lines changed

6 files changed

+92
-158
lines changed

packages/ui-checkbox/src/Checkbox/CheckboxFacade/styles.ts

Lines changed: 14 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424

2525
import type { CheckboxFacadeTheme } from '@instructure/shared-types'
2626
import type { CheckboxFacadeProps, CheckboxFacadeStyle } from './props'
27+
import { alpha } from '@instructure/ui-color-utils'
2728

2829
/**
2930
* ---
@@ -86,34 +87,24 @@ const generateStyle = (
8687
justifyContent: 'center',
8788
boxSizing: 'border-box',
8889
flexShrink: 0,
89-
transition: 'all 0.2s',
90-
border: `${componentTheme.borderWidth} solid ${invalid ? componentTheme.errorBorderColor : componentTheme.borderColor}`,
90+
border: `${componentTheme.borderWidth} solid ${
91+
invalid ? componentTheme.errorBorderColor : componentTheme.borderColor
92+
}`,
9193
borderRadius: componentTheme.borderRadius,
9294
marginInlineEnd: componentTheme.marginRight,
9395
marginInlineStart: '0',
9496
padding: componentTheme.padding,
9597
...sizeVariants[size!].facade,
96-
97-
'&::before': {
98-
content: '""',
99-
position: 'absolute',
100-
top: '-0.3125rem',
101-
bottom: '-0.3125rem',
102-
left: '-0.3125rem',
103-
right: '-0.3125rem',
104-
boxSizing: 'border-box',
105-
borderRadius: `calc(${componentTheme.borderRadius} * 1.5)`,
106-
border: `${componentTheme.focusBorderWidth} ${componentTheme.focusBorderStyle} ${componentTheme.focusBorderColor}`,
107-
transition: 'all 0.2s',
108-
transform: 'scale(0.75)',
109-
opacity: 0,
110-
pointerEvents: 'none',
111-
...(focused && {
112-
transform: 'scale(1)',
113-
opacity: 1
114-
})
115-
},
116-
98+
// animate the focus ring
99+
outline: `${componentTheme.focusBorderWidth} ${
100+
componentTheme.focusBorderStyle
101+
} ${alpha(componentTheme.focusBorderColor, 0)}`,
102+
outlineOffset: '-0.2rem',
103+
transition: 'outline 0.2s, outline-offset 0.25s',
104+
...(focused && {
105+
outline: `${componentTheme.focusBorderWidth} ${componentTheme.focusBorderStyle} ${componentTheme.focusBorderColor}`,
106+
outlineOffset: '0.15rem'
107+
}),
117108
...(isChecked && {
118109
background: componentTheme.checkedBackground,
119110
borderColor: componentTheme.checkedBorderColor

packages/ui-checkbox/src/Checkbox/ToggleFacade/styles.ts

Lines changed: 16 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424

2525
import type { ToggleFacadeTheme } from '@instructure/shared-types'
2626
import type { ToggleFacadeProps, ToggleFacadeStyle } from './props'
27+
import { alpha } from '@instructure/ui-color-utils'
2728

2829
/**
2930
* ---
@@ -91,7 +92,11 @@ const generateStyle = (
9192
position: 'relative',
9293
borderRadius: '3rem',
9394
verticalAlign: 'middle',
94-
boxShadow: `inset 0 0 0 ${componentTheme.borderWidth} ${(invalid && !checked) ? componentTheme.errorBorderColor : componentTheme.borderColor}`,
95+
boxShadow: `inset 0 0 0 ${componentTheme.borderWidth} ${
96+
invalid && !checked
97+
? componentTheme.errorBorderColor
98+
: componentTheme.borderColor
99+
}`,
95100
height: componentTheme.toggleSize,
96101
width: `calc(${componentTheme.toggleSize} * 1.5)`,
97102
...labelPlacementVariants[labelPlacement!].facade,
@@ -100,27 +105,16 @@ const generateStyle = (
100105
background: componentTheme.checkedBackground,
101106
boxShadow: 'none'
102107
}),
103-
104-
'&::before': {
105-
content: '""',
106-
position: 'absolute',
107-
top: '-0.25rem',
108-
left: '-0.25rem',
109-
width: 'calc(100% + 0.5rem)',
110-
height: 'calc(100% + 0.5rem)',
111-
boxSizing: 'border-box',
112-
borderRadius: componentTheme.borderRadius,
113-
border: `${componentTheme.focusBorderWidth} ${componentTheme.focusBorderStyle} ${componentTheme.focusOutlineColor}`,
114-
transition: 'all 0.2s',
115-
transform: 'scale(0.75)',
116-
opacity: 0,
117-
pointerEvents: 'none',
118-
119-
...(focused && {
120-
transform: 'scale(1)',
121-
opacity: 1
122-
})
123-
}
108+
// animate the focus ring
109+
outline: `${componentTheme.focusBorderWidth} ${
110+
componentTheme.focusBorderStyle
111+
} ${alpha(componentTheme.focusOutlineColor, 0)}`,
112+
outlineOffset: '-0.2rem',
113+
transition: 'outline 0.2s, outline-offset 0.25s',
114+
...(focused && {
115+
outline: `${componentTheme.focusBorderWidth} ${componentTheme.focusBorderStyle} ${componentTheme.focusOutlineColor}`,
116+
outlineOffset: '0.15rem'
117+
})
124118
},
125119

126120
icon: {

packages/ui-number-input/src/NumberInput/index.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ import type {
5252
NumberInputStyleProps
5353
} from './props'
5454
import { Renderable } from '@instructure/shared-types'
55+
import { View } from '@instructure/ui-view'
5556

5657
/**
5758
---
@@ -280,7 +281,7 @@ class NumberInput extends Component<NumberInputProps, NumberInputState> {
280281
elementRef={this.handleRef}
281282
margin={margin}
282283
>
283-
<span
284+
<View // TODO this will only show focus ring if we add the :focus-within CSS selector and its prop
284285
css={this.props.styles?.inputWidth}
285286
style={width ? { width } : undefined}
286287
>
@@ -308,7 +309,7 @@ class NumberInput extends Component<NumberInputProps, NumberInputState> {
308309
/>
309310
{showArrows ? this.renderArrows(renderIcons) : null}
310311
</span>
311-
</span>
312+
</View>
312313
</FormField>
313314
)
314315
}

packages/ui-number-input/src/NumberInput/styles.ts

Lines changed: 17 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import type {
2828
NumberInputStyleProps,
2929
NumberInputStyle
3030
} from './props'
31+
import { alpha } from '@instructure/ui-color-utils'
3132

3233
/**
3334
* ---
@@ -56,19 +57,6 @@ const generateStyle = (
5657
}
5758
: {}
5859

59-
const focusStyles = hasFocus
60-
? {
61-
opacity: 1,
62-
transform: 'scale(1)'
63-
}
64-
: {}
65-
66-
const invalidStyles = invalid
67-
? {
68-
borderColor: componentTheme.errorOutlineColor
69-
}
70-
: {}
71-
7260
const invalidContainerStyles = invalid
7361
? {
7462
borderColor: componentTheme.errorBorderColor
@@ -97,6 +85,16 @@ const generateStyle = (
9785
'&::placeholder': { color: componentTheme.placeholderColor }
9886
}
9987

88+
let outlineColor
89+
if (invalid) {
90+
outlineColor = hasFocus
91+
? componentTheme.errorOutlineColor
92+
: alpha(componentTheme.errorOutlineColor, 0)
93+
} else {
94+
outlineColor = hasFocus
95+
? componentTheme.focusOutlineColor
96+
: alpha(componentTheme.focusOutlineColor, 0)
97+
}
10098
return {
10199
requiredInvalid: {
102100
color: componentTheme.requiredInvalidColor
@@ -134,24 +132,12 @@ const generateStyle = (
134132
label: 'numberInput_inputWidth',
135133
display: 'block',
136134
position: 'relative',
137-
'&::before': {
138-
content: '""',
139-
pointerEvents: 'none',
140-
boxSizing: 'border-box',
141-
display: 'block',
142-
position: 'absolute',
143-
top: '-0.25rem',
144-
bottom: '-0.25rem',
145-
left: '-0.25rem',
146-
right: '-0.25rem',
147-
border: `${componentTheme.focusOutlineWidth} ${componentTheme.focusOutlineStyle} ${componentTheme.focusOutlineColor}`,
148-
borderRadius: `calc(${componentTheme.borderRadius} * 1.5)`,
149-
transition: 'all 0.2s',
150-
opacity: 0,
151-
transform: 'scale(0.95)',
152-
...focusStyles,
153-
...invalidStyles
154-
}
135+
borderRadius: componentTheme.borderRadius
136+
// animate the focus ring TODO move this to View?
137+
//transition: 'outline-color 0.2s, outline-offset 0.25s',
138+
//outline: `${componentTheme.focusOutlineWidth} ${componentTheme.focusOutlineStyle} ${outlineColor}`,
139+
//outlineOffset: '-0.8rem',
140+
//...(hasFocus && { outlineOffset: '0.15rem'}),
155141
},
156142
inputContainer: {
157143
label: 'numberInput_inputContainer',

packages/ui-text-input/src/TextInput/styles.ts

Lines changed: 17 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import type {
2828
TextInputStyleProps,
2929
TextInputStyle
3030
} from './props'
31+
import { alpha } from '@instructure/ui-color-utils'
3132

3233
/**
3334
* ---
@@ -78,29 +79,12 @@ const generateStyle = (
7879
}
7980
: {}
8081

81-
const focusedStyle = focused
82-
? {
83-
opacity: 1,
84-
outlineOffset: '0.15rem'
85-
}
86-
: {
87-
opacity: 0,
88-
outlineOffset: '-0.9rem'
89-
}
90-
9182
const invalidStyle = invalid
9283
? {
9384
borderColor: componentTheme.errorBorderColor
9485
}
9586
: {}
9687

97-
const invalidAndFocusedStyle =
98-
invalid && focused
99-
? {
100-
borderColor: componentTheme.errorBorderColor
101-
}
102-
: {}
103-
10488
const inputStyle = {
10589
all: 'initial',
10690
'&::-ms-clear': {
@@ -150,6 +134,16 @@ const generateStyle = (
150134
flexDirection: 'row'
151135
}
152136

137+
let outlineColor
138+
if (invalid) {
139+
outlineColor = focused
140+
? componentTheme.errorOutlineColor
141+
: alpha(componentTheme.errorOutlineColor, 0)
142+
} else {
143+
outlineColor = focused
144+
? componentTheme.focusOutlineColor
145+
: alpha(componentTheme.focusOutlineColor, 0)
146+
}
153147
return {
154148
requiredInvalid: {
155149
color: componentTheme.requiredInvalidColor
@@ -166,27 +160,14 @@ const generateStyle = (
166160
display: 'block',
167161
boxSizing: 'border-box',
168162
border: `${componentTheme.borderWidth} ${componentTheme.borderStyle} ${componentTheme.borderColor}`,
169-
borderRadius: componentTheme.borderRadius,
170163
background: componentTheme.background,
171164
color: componentTheme.color,
172-
173-
'&::before': {
174-
content: '""',
175-
pointerEvents: 'none',
176-
position: 'absolute',
177-
display: 'block',
178-
boxSizing: 'border-box',
179-
top: '0',
180-
bottom: '0',
181-
left: '0',
182-
right: '0',
183-
outline: `${componentTheme.focusOutlineWidth} ${componentTheme.focusOutlineStyle} ${componentTheme.focusOutlineColor}`,
184-
borderRadius: componentTheme.borderRadius,
185-
transition: 'opacity 0.2s, outline-offset 0.2s ease-out',
186-
187-
...focusedStyle, // properties to transition on :focus
188-
...invalidAndFocusedStyle
189-
},
165+
borderRadius: componentTheme.borderRadius,
166+
// animate the focus ring
167+
outline: `${componentTheme.focusOutlineWidth} ${componentTheme.focusOutlineStyle} ${outlineColor}`,
168+
outlineOffset: '-0.8rem',
169+
transition: 'outline 0.2s, outline-offset 0.25s',
170+
...(focused && { outlineOffset: '0.15rem' }),
190171
...disabledStyle,
191172
...invalidStyle
192173
},

0 commit comments

Comments
 (0)