Skip to content
This repository was archived by the owner on Jan 13, 2025. It is now read-only.

Commit 587d8f8

Browse files
joyzhongcopybara-github
authored andcommitted
feat(focus): Add focus ring component.
PiperOrigin-RevId: 481651148
1 parent 3de982c commit 587d8f8

File tree

5 files changed

+138
-0
lines changed

5 files changed

+138
-0
lines changed

Diff for: packages/material-components-web/package.json

+1
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
"@material/fab": "^14.0.0",
3636
"@material/feature-targeting": "^14.0.0",
3737
"@material/floating-label": "^14.0.0",
38+
"@material/focus": "^14.0.0",
3839
"@material/focus-ring": "^14.0.0",
3940
"@material/form-field": "^14.0.0",
4041
"@material/icon-button": "^14.0.0",

Diff for: packages/mdc-focus/README.md

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# Focus
2+
3+
This package contains focus-related utilities.
4+
5+
## Focus rings
6+
7+
To add a focus ring to an element, ensure the following requirements:
8+
- The focus ring should be a child of the element which it is offset from.
9+
- The element which the focus ring is offset from should have a
10+
non-static `position` CSS value. This is because the focus ring has
11+
`position: absolute` and is then positioned relative to its container
12+
element.
13+
- The focus ring can be shown in Sass via `focus-ring-theme.show-focus-ring()`.
14+
15+
16+
See the following example:
17+
18+
```html
19+
<button class="mdc-button">
20+
<span>Click me!</span>
21+
<div class="mdc-focus-ring"></div>
22+
</button>
23+
```
24+
25+
```scss
26+
.mdc-button {
27+
position: relative;
28+
}
29+
30+
.mdc-focus-ring {
31+
@include focus-ring-theme.static-styles();
32+
@include focus-ring-theme.theme-styles(focus-ring-theme.$light-theme);
33+
}
34+
35+
.mdc-button:focus-visible .mdc-focus-ring {
36+
@include focus-ring-theme.show-focus-ring();
37+
}
38+
```

Diff for: packages/mdc-focus/_focus-ring-theme.scss

+70
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
@use 'sass:map';
2+
@use '@material/theme/keys';
3+
@use '@material/theme/theme';
4+
5+
$_custom-property-prefix: 'focus-ring';
6+
7+
$light-theme: (
8+
offset-horizontal: 2px,
9+
offset-vertical: 2px,
10+
ring-color: 'secondary',
11+
ring-border-start-start-radius: 'inherit',
12+
ring-border-start-end-radius: 'inherit',
13+
ring-border-end-end-radius: 'inherit',
14+
ring-border-end-start-radius: 'inherit',
15+
track-width: 3px,
16+
);
17+
18+
@mixin theme($theme) {
19+
@include theme.validate-theme($light-theme, $theme);
20+
@include keys.declare-custom-properties($theme, $_custom-property-prefix);
21+
}
22+
23+
@mixin theme-styles($theme) {
24+
@include theme.validate-theme-styles($light-theme, $theme);
25+
$theme: keys.create-theme-properties($theme, $_custom-property-prefix);
26+
27+
$_border-width: map.get($theme, 'track-width');
28+
$_border-color: map.get($theme, 'ring-color');
29+
$_border-start-start-radius: map.get(
30+
$theme,
31+
'ring-border-start-start-radius'
32+
);
33+
$_border-start-end-radius: map.get($theme, 'ring-border-start-end-radius');
34+
$_border-end-end-radius: map.get($theme, 'ring-border-end-end-radius');
35+
$_border-end-start-radius: map.get($theme, 'ring-border-end-start-radius');
36+
$_offset-vertical: map.get($theme, 'offset-vertical');
37+
$_offset-horizontal: map.get($theme, 'offset-horizontal');
38+
39+
@include theme.property(
40+
border,
41+
'border-width solid border-color',
42+
$replace: (border-width: $_border-width, border-color: $_border-color)
43+
);
44+
@include theme.property(
45+
border-start-start-radius,
46+
$_border-start-start-radius
47+
);
48+
@include theme.property(border-start-end-radius, $_border-start-end-radius);
49+
@include theme.property(border-end-end-radius, $_border-end-end-radius);
50+
@include theme.property(border-end-start-radius, $_border-end-start-radius);
51+
@include theme.property(
52+
inset-block,
53+
'calc(-1 * (offset-vertical + border-width))',
54+
$replace: (offset-vertical: $_offset-vertical, border-width: $_border-width)
55+
);
56+
@include theme.property(
57+
inset-inline,
58+
'calc(-1 * (offset-horizontal + border-width))',
59+
$replace: (
60+
offset-horizontal: $_offset-horizontal,
61+
border-width: $_border-width
62+
)
63+
);
64+
}
65+
66+
/// This should be applied to the focus ring element when the focus ring
67+
/// should be shown (e.g. based on `:focus-visible` pseudoclass).
68+
@mixin show-focus-ring() {
69+
display: block;
70+
}

Diff for: packages/mdc-focus/_focus-ring.scss

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
@mixin static-styles() {
2+
display: none;
3+
pointer-events: none;
4+
position: absolute;
5+
}

Diff for: packages/mdc-focus/package.json

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
{
2+
"name": "@material/focus",
3+
"description": "The Material Components Web focus ring utilities",
4+
"version": "14.0.0",
5+
"license": "MIT",
6+
"keywords": [
7+
"material components",
8+
"material design",
9+
"focus",
10+
"focusring"
11+
],
12+
"sideEffects": false,
13+
"repository": {
14+
"type": "git",
15+
"url": "git+https://github.com/material-components/material-components-web.git",
16+
"directory": "packages/mdc-focus"
17+
},
18+
"publishConfig": {
19+
"access": "public"
20+
},
21+
"dependencies": {
22+
"@material/theme": "^14.0.0"
23+
}
24+
}

0 commit comments

Comments
 (0)