vira
Version:
A simple and highly versatile design system using element-vir.
65 lines (62 loc) • 2.44 kB
JavaScript
import { check } from '@augment-vir/assert';
import { css, unsafeCSS } from 'element-vir';
import { viraFormCssVars } from './form-styles.js';
function cssValueOrRaw(value) {
if (check.isString(value)) {
return unsafeCSS(value);
}
else {
return value.value;
}
}
/**
* Create styles that look like an outline for the given selector.
*
* It is recommended to use the pseudo selector chain ":focus:focus-visible:not(:active)" to
* preventing clicking an element from creating focus styles in Chrome.
*
* @category Styles
*/
export function createFocusStyles({ elementBorderSize = '1px', outlineGap = '2px', outlineWidth = '2px', noNesting, outlineColor = viraFormCssVars['vira-form-focus-outline-color'], borderRadius = viraFormCssVars['vira-form-focus-outline-border-radius'], renderInside, } = {}) {
const insetSpacing = css `calc(${cssValueOrRaw(outlineGap)})`;
const outsetSpacing = css `calc(${cssValueOrRaw(outlineWidth)} + ${cssValueOrRaw(outlineGap)} + ${cssValueOrRaw(elementBorderSize)})`;
const styles = renderInside
? css `
content: '';
top: ${insetSpacing};
left: ${insetSpacing};
position: absolute;
width: calc(100% - calc(${insetSpacing} * 2));
height: calc(100% - calc(${insetSpacing} * 2));
box-sizing: border-box;
pointer-events: none;
border: ${cssValueOrRaw(outlineWidth)} solid ${cssValueOrRaw(outlineColor)};
border-radius: ${cssValueOrRaw(borderRadius)};
z-index: 100;
`
: css `
content: '';
top: calc(${outsetSpacing} * -1);
left: calc(${outsetSpacing} * -1);
position: absolute;
width: calc(100% + calc(${outsetSpacing} * 2));
height: calc(100% + calc(${outsetSpacing} * 2));
box-sizing: border-box;
pointer-events: none;
border: ${cssValueOrRaw(outlineWidth)} solid ${cssValueOrRaw(outlineColor)};
border-radius: ${cssValueOrRaw(borderRadius)};
z-index: 100;
`;
if (noNesting) {
return styles;
}
return css `
outline: none;
&:focus {
outline: none;
}
&:focus:focus-visible:not(:active):not([disabled])::after {
${styles}
}
`;
}