Skip to content

Commit 7fe1ac1

Browse files
authored
Merge pull request #98 from hashicorp/focus-ring-mixin-refactoring
Refactor "focus-ring" tokens and mixins to support both "active" and "critical" colors
2 parents 541469c + 411cd9b commit 7fe1ac1

File tree

12 files changed

+152
-50
lines changed

12 files changed

+152
-50
lines changed

.changeset/serious-peas-explain.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@hashicorp/design-system-tokens": minor
3+
---
4+
5+
refactored “focus-ring” tokens and CSS helpers to support both “action” and “critical“ colors

.changeset/thirty-fireants-cheat.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@hashicorp/design-system-components": patch
3+
---
4+
5+
refactored the “focus-ring” mixins to support both “action” (default) and “critical“ colors

packages/components/app/styles/mixins/_focus-ring.scss

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,22 @@
22
// - https://github.com/hashicorp/design-system-components/issues/161
33
// - https://www.tpgi.com/focus-visible-and-backwards-compatibility/
44

5-
@mixin hds-focus-ring-basic() {
5+
@mixin hds-focus-ring-basic($color: action) {
66
outline-style: solid; // used to avoid double outline+focus-ring in Safari (see https://github.com/hashicorp/design-system-components/issues/161#issuecomment-1031548656)
77
outline-color: transparent;
88

99
// default focus for browsers that still rely on ":focus"
1010
&:focus,
1111
&.is-focus {
12-
box-shadow: var(--token-focus-ring-box-shadow);
12+
box-shadow: var(--token-focus-ring-#{$color}-box-shadow);
1313
}
1414
// undo the previous declaration for browsers that support ":focus-visible" but wouldn't normally show default focus styles
1515
&:focus:not(:focus-visible) {
1616
box-shadow: none;
1717
}
1818
// set focus for browsers that support ":focus-visible"
1919
&:focus-visible {
20-
box-shadow: var(--token-focus-ring-box-shadow);
20+
box-shadow: var(--token-focus-ring-#{$color}-box-shadow);
2121
}
2222
// remove the focus ring on "active + focused" state (by design)
2323
&:focus:active,
@@ -26,7 +26,7 @@
2626
}
2727
}
2828

29-
@mixin hds-focus-ring-with-pseudo-element($top: 0, $right: 0, $bottom: 0, $left: 0, $radius: 5px) {
29+
@mixin hds-focus-ring-with-pseudo-element($top: 0, $right: 0, $bottom: 0, $left: 0, $radius: 5px, $color: action) {
3030
isolation: isolate; // used to create a new stacking context (needed to have the pseudo element below text/icon but not the parent container)
3131
outline-style: solid; // used to avoid double outline+focus-ring in Safari (see https://github.com/hashicorp/design-system-components/issues/161#issuecomment-1031548656)
3232
outline-color: transparent;
@@ -48,7 +48,7 @@
4848
&:focus,
4949
&.is-focus {
5050
&::before {
51-
box-shadow: var(--token-focus-ring-box-shadow);
51+
box-shadow: var(--token-focus-ring-#{$color}-box-shadow);
5252
}
5353
}
5454
// undo the previous declaration for browsers that support ":focus-visible" but wouldn't normally show default focus styles
@@ -60,7 +60,7 @@
6060
// set focus for browsers that support ":focus-visible"
6161
&:focus-visible {
6262
&::before {
63-
box-shadow: var(--token-focus-ring-box-shadow);
63+
box-shadow: var(--token-focus-ring-#{$color}-box-shadow);
6464
}
6565
}
6666
// remove the focus ring on "active + focused" state (by design)

packages/components/tests/dummy/app/templates/foundations/focus-ring.hbs

Lines changed: 61 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,18 +63,77 @@
6363
value).</li>
6464
</ul>
6565

66+
<h4 class="dummy-h4">Sass mixins</h4>
67+
<p class="dummy-paragraph">We have also created two
68+
<strong>Sass mixins</strong>
69+
<code class="dummy-code">hds-focus-ring-basic</code>
70+
and
71+
<code class="dummy-code">hds-focus-ring-with-pseudo-element</code>
72+
but they're mainly used for internal use (to the design system codebase). These mixins do more than just apply the
73+
focus style: they also take care of all the different way to declare the
74+
<code class="dummy-code">:focus/:focus-visible</code>
75+
for different browsers.
76+
</p>
77+
<p class="dummy-paragraph">To use these mixins you have to import the Sass file
78+
<code class="dummy-code">packages/components/app/styles/mixins/_focus-ring.scss</code>
79+
contained in the
80+
<code class="dummy-code">@hashicorp/design-system</code>
81+
monorepo or the same file
82+
<code class="dummy-code">app/styles/mixins/_focus-ring.scss</code>
83+
distributed in the
84+
<code class="dummy-code">@hashicorp/design-system-components</code>
85+
package.</p>
86+
<p class="dummy-paragraph">Then the mixins can be invoked in this way:</p>
87+
{{! prettier-ignore-start }}
88+
<CodeBlock
89+
@language="css"
90+
@code="
91+
/* include the mixin file via @use (path will depend on your context) */
92+
@use '../mixins/focus-ring' as *;
93+
94+
/* apply the focus-ring as box-shadow ('action' will be the default color ) */
95+
.your-selector {
96+
[...your CSS declarations]
97+
@include hds-focus-ring-basic();
98+
}
99+
100+
/* apply the focus-ring as pseudo-element (with 'critical' color ) */
101+
.your-selector {
102+
[...your CSS declarations]
103+
@include hds-focus-ring-with-pseudo-element($top: 0, $right: 0, $bottom: 0, $left: 0, $radius: 5px, $color: critical);
104+
}
105+
"
106+
/>
107+
{{! prettier-ignore-end }}
108+
66109
</section>
67110

68111
<section data-test-percy>
69112
<h3 class="dummy-h3">Showcase</h3>
70113
<h4 class="dummy-h4">Focus ring:</h4>
71114
<p class="dummy-paragraph">Standalone "focus ring" effect</p>
72115
<div class="dummy-focus-ring-samples">
73-
<div class="dummy-focus-ring-sample hds-focus-ring-box-shadow">
116+
<div class="dummy-focus-ring-sample hds-focus-ring-action-box-shadow">
74117
<DummyPlaceholder @text="no radius" @width="100" @height="100" @background="transparent" />
75118
</div>
76-
<div class="dummy-focus-ring-sample dummy-focus-ring-sample--border-radius hds-focus-ring-box-shadow">
119+
<div class="dummy-focus-ring-sample dummy-focus-ring-sample--border-radius hds-focus-ring-action-box-shadow">
77120
<DummyPlaceholder @text="with border radius" @width="100" @height="100" @background="transparent" />
78121
</div>
79122
</div>
123+
<div class="dummy-focus-ring-samples">
124+
<div class="dummy-focus-ring-sample">
125+
<span class="dummy-text-small">action</span>
126+
<br />
127+
<div class="hds-focus-ring-action-box-shadow">
128+
<DummyPlaceholder @text="with border radius" @width="100" @height="100" @background="transparent" />
129+
</div>
130+
</div>
131+
<div class="dummy-focus-ring-sample">
132+
<span class="dummy-text-small">critical</span>
133+
<br />
134+
<div class="hds-focus-ring-critical-box-shadow">
135+
<DummyPlaceholder @text="with border radius" @width="100" @height="100" @background="transparent" />
136+
</div>
137+
</div>
138+
</div>
80139
</section>
Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
/**
22
* Do not edit directly
3-
* Generated on Tue, 22 Feb 2022 21:05:19 GMT
3+
* Generated on Fri, 18 Mar 2022 20:06:01 GMT
44
*/
55

6-
.hds-focus-ring-box-shadow { box-shadow: var(--token-focus-ring-box-shadow); }
6+
.hds-focus-ring-action-box-shadow { box-shadow: var(--token-focus-ring-action-box-shadow); }
7+
.hds-focus-ring-critical-box-shadow { box-shadow: var(--token-focus-ring-critical-box-shadow); }

packages/tokens/dist/devdot/css/tokens.css

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/**
22
* Do not edit directly
3-
* Generated on Thu, 17 Mar 2022 08:19:13 GMT
3+
* Generated on Fri, 18 Mar 2022 20:06:01 GMT
44
*/
55

66
:root {
@@ -238,7 +238,8 @@
238238
--token-surface-high-box-shadow: 0 0 0 1px #656a7640, 0px 2px 3px 0px #656a7626, 0px 16px 16px -10px #656a7633;
239239
--token-surface-higher-box-shadow: 0 0 0 1px #656a7633, 0px 2px 3px 0px #656a761a, 0px 12px 28px 0px #656a7640;
240240
--token-surface-overlay-box-shadow: 0 0 0 1px #3b3d4566, 0px 2px 3px 0px #3b3d4580, 0px 12px 24px 0px #3b3d4599;
241-
--token-focus-ring-box-shadow: inset 0 0 0 1px #0c56e9, 0 0 0 3px #5990ff;
241+
--token-focus-ring-action-box-shadow: inset 0 0 0 1px #0c56e9, 0 0 0 3px #5990ff;
242+
--token-focus-ring-critical-box-shadow: inset 0 0 0 1px #c00005, 0 0 0 3px #dd7578;
242243
--token-typography-font-stack-display: -apple-system, BlinkMacSystemFont, SF Pro Display, Segoe UI Display, Ubuntu, sans-serif;
243244
--token-typography-font-stack-text: -apple-system, BlinkMacSystemFont, SF Pro Text, Segoe UI Text, Ubuntu, sans-serif;
244245
--token-typography-font-stack-code: SF Mono, Consolas, Ubuntu Mono, monospace;

packages/tokens/dist/docs/devdot/tokens.json

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5288,15 +5288,34 @@
52885288
{
52895289
"value": "inset 0 0 0 1px #0c56e9, 0 0 0 3px #5990ff",
52905290
"original": {
5291-
"value": "{focus-ring.internal.box-shadow.value}, {focus-ring.external.box-shadow.value}"
5291+
"value": "{focus-ring.action.internal-box-shadow.value}, {focus-ring.action.external-box-shadow.value}"
52925292
},
5293-
"name": "token-focus-ring-box-shadow",
5293+
"name": "token-focus-ring-action-box-shadow",
52945294
"attributes": {
52955295
"category": "focus-ring",
5296-
"type": "box-shadow"
5296+
"type": "action",
5297+
"item": "box-shadow"
52975298
},
52985299
"path": [
52995300
"focus-ring",
5301+
"action",
5302+
"box-shadow"
5303+
]
5304+
},
5305+
{
5306+
"value": "inset 0 0 0 1px #c00005, 0 0 0 3px #dd7578",
5307+
"original": {
5308+
"value": "{focus-ring.critical.internal-box-shadow.value}, {focus-ring.critical.external-box-shadow.value}"
5309+
},
5310+
"name": "token-focus-ring-critical-box-shadow",
5311+
"attributes": {
5312+
"category": "focus-ring",
5313+
"type": "critical",
5314+
"item": "box-shadow"
5315+
},
5316+
"path": [
5317+
"focus-ring",
5318+
"critical",
53005319
"box-shadow"
53015320
]
53025321
},

packages/tokens/dist/docs/products/tokens.json

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5242,15 +5242,34 @@
52425242
{
52435243
"value": "inset 0 0 0 1px #0c56e9, 0 0 0 3px #5990ff",
52445244
"original": {
5245-
"value": "{focus-ring.internal.box-shadow.value}, {focus-ring.external.box-shadow.value}"
5245+
"value": "{focus-ring.action.internal-box-shadow.value}, {focus-ring.action.external-box-shadow.value}"
52465246
},
5247-
"name": "token-focus-ring-box-shadow",
5247+
"name": "token-focus-ring-action-box-shadow",
52485248
"attributes": {
52495249
"category": "focus-ring",
5250-
"type": "box-shadow"
5250+
"type": "action",
5251+
"item": "box-shadow"
52515252
},
52525253
"path": [
52535254
"focus-ring",
5255+
"action",
5256+
"box-shadow"
5257+
]
5258+
},
5259+
{
5260+
"value": "inset 0 0 0 1px #c00005, 0 0 0 3px #dd7578",
5261+
"original": {
5262+
"value": "{focus-ring.critical.internal-box-shadow.value}, {focus-ring.critical.external-box-shadow.value}"
5263+
},
5264+
"name": "token-focus-ring-critical-box-shadow",
5265+
"attributes": {
5266+
"category": "focus-ring",
5267+
"type": "critical",
5268+
"item": "box-shadow"
5269+
},
5270+
"path": [
5271+
"focus-ring",
5272+
"critical",
52545273
"box-shadow"
52555274
]
52565275
},
Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
/**
22
* Do not edit directly
3-
* Generated on Tue, 22 Feb 2022 21:05:19 GMT
3+
* Generated on Fri, 18 Mar 2022 20:06:01 GMT
44
*/
55

6-
.hds-focus-ring-box-shadow { box-shadow: var(--token-focus-ring-box-shadow); }
6+
.hds-focus-ring-action-box-shadow { box-shadow: var(--token-focus-ring-action-box-shadow); }
7+
.hds-focus-ring-critical-box-shadow { box-shadow: var(--token-focus-ring-critical-box-shadow); }

packages/tokens/dist/products/css/tokens.css

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/**
22
* Do not edit directly
3-
* Generated on Mon, 07 Mar 2022 11:14:41 GMT
3+
* Generated on Fri, 18 Mar 2022 20:06:01 GMT
44
*/
55

66
:root {
@@ -236,7 +236,8 @@
236236
--token-surface-high-box-shadow: 0 0 0 1px #656a7640, 0px 2px 3px 0px #656a7626, 0px 16px 16px -10px #656a7633;
237237
--token-surface-higher-box-shadow: 0 0 0 1px #656a7633, 0px 2px 3px 0px #656a761a, 0px 12px 28px 0px #656a7640;
238238
--token-surface-overlay-box-shadow: 0 0 0 1px #3b3d4566, 0px 2px 3px 0px #3b3d4580, 0px 12px 24px 0px #3b3d4599;
239-
--token-focus-ring-box-shadow: inset 0 0 0 1px #0c56e9, 0 0 0 3px #5990ff;
239+
--token-focus-ring-action-box-shadow: inset 0 0 0 1px #0c56e9, 0 0 0 3px #5990ff;
240+
--token-focus-ring-critical-box-shadow: inset 0 0 0 1px #c00005, 0 0 0 3px #dd7578;
240241
--token-typography-font-stack-display: -apple-system, BlinkMacSystemFont, SF Pro Display, Segoe UI Display, Ubuntu, sans-serif;
241242
--token-typography-font-stack-text: -apple-system, BlinkMacSystemFont, SF Pro Text, Segoe UI Text, Ubuntu, sans-serif;
242243
--token-typography-font-stack-code: SF Mono, Consolas, Ubuntu Mono, monospace;

0 commit comments

Comments
 (0)