Skip to content

Instantly share code, notes, and snippets.

@CuddleBunny
Created July 1, 2024 14:35
Show Gist options
  • Save CuddleBunny/1cce486be2dc940e8cd299d45d9efbab to your computer and use it in GitHub Desktop.
Save CuddleBunny/1cce486be2dc940e8cd299d45d9efbab to your computer and use it in GitHub Desktop.
FAST text-field Material style label
import { css, ElementStyles } from '@microsoft/fast-element';
import { disabledCursor, display, focusVisible, FoundationElementTemplate, TextFieldOptions } from '@microsoft/fast-foundation';
import { accentFillActive, accentFillHover, neutralFillHover, neutralFillRest, neutralForegroundRest, neutralInputFillHover, neutralInputFillRest, neutralStrokeFocus, neutralStrokeRest, designTokens } from '../../design-tokens';
import { heightNumber, paddingNumber } from '../../styles/size';
export const textFieldStyles: FoundationElementTemplate<ElementStyles, TextFieldOptions> = (
context,
definition
) => css`
${display("inline-block")} :host {
font-family: ${designTokens['typography-font-family'].token};
outline: none;
user-select: none;
}
.root {
display: flex;
flex-direction: row;
position: relative;
box-sizing: border-box;
border: calc(${designTokens['space-stroke-width'].token} * 1px) solid ${neutralStrokeRest};
border-radius: calc(${designTokens['space-input-corner-radius'].token} * 1px);
height: calc(${heightNumber} * 1px);
color: ${neutralForegroundRest};
background: ${neutralInputFillRest};
box-shadow: 0 0 30px 0 rgba(0, 0, 0, 0.1);
}
:host(.label__visible) .root {
padding-top: ${designTokens['typography-type-ramp-minus-2-line-height'].token};
height: calc(${heightNumber} * 1px + ${designTokens['typography-type-ramp-minus-2-font-size'].token});
}
.control {
position: relative;
flex-grow: 1;
-webkit-appearance: none;
background: transparent;
border: 0;
height: 100%;
border: none;
padding: 0 calc(${paddingNumber} * 1px);
font-size: ${designTokens['typography-type-ramp-base-font-size'].token};
line-height: ${designTokens['typography-type-ramp-base-line-height'].token};
color: ${neutralForegroundRest};
}
.control:hover,
.control:${focusVisible},
.control:disabled,
.control:active {
outline: none;
}
.label {
position: absolute;
top: calc(50% - ${designTokens['typography-type-ramp-base-line-height'].token} / 2);
display: block;
padding-left: calc(${paddingNumber} * 1px);
color: ${neutralForegroundRest};
font-size: ${designTokens['typography-type-ramp-base-font-size'].token};
line-height: ${designTokens['typography-type-ramp-base-line-height'].token};
user-select: none;
cursor: text;
transition: 200ms ease;
}
.label__hidden {
display: none;
visibility: hidden;
}
.control:focus + .label,
.control:not(:placeholder-shown) + .label,
:host([placeholder]) .control + .label
{
top: calc(${designTokens['space-design-unit'].token} * 1px);
font-size: ${designTokens['typography-type-ramp-minus-2-font-size'].token};
line-height: ${designTokens['typography-type-ramp-minus-2-line-height'].token};
}
.before-content,
.after-content {
${
/* Glyph size and margin-left is temporary -
replace when adaptive typography is figured out */ ""
} width: 16px;
height: 16px;
margin: auto;
fill: ${neutralForegroundRest};
}
.before-content {
margin-inline-start: 11px;
}
.after-content {
margin-inline-end: 11px;
}
.password-toggle {
width: 1em;
height: 100%;
color: blue;
margin-right: calc(${paddingNumber} * 2px);
}
:host(:hover:not(.disabled)) .root {
background: ${neutralInputFillHover};
border-color: ${accentFillHover};
}
:host(:active:not(.disabled)) .root {
background: ${neutralInputFillHover};
border-color: ${accentFillActive};
}
:host(:focus-within:not(.disabled)) .root {
border-color: ${neutralStrokeFocus};
}
/* TODO: Use appearance behavior for filled and stealth text fields */
:host(.filled) .root {
background: ${neutralFillRest};
}
:host(.filled:hover:not(.disabled)) .root {
background: ${neutralFillHover};
}
:host(.stealth) .control {
padding: 0;
}
:host(.stealth) .root,
:host(.stealth:hover:not(.disabled)) .root,
:host(.stealth:focus-within:not(.disabled)) .root {
background: transparent;
border-color: transparent;
box-shadow: none;
}
:host(.disabled) .label,
:host(.readonly) .label,
:host(.readonly) .control,
:host(.disabled) .control {
cursor: ${disabledCursor};
}
:host(.disabled) {
opacity: ${designTokens['color-disabled-opacity'].token};
}
:host([disabled]) .control {
border-color: ${neutralStrokeRest};
}
:host(.error) .root {
border-color: ${designTokens['color-error'].token};
}
input::-webkit-outer-spin-button,
input::-webkit-inner-spin-button {
-webkit-appearance: none;
margin: 0;
}
/* Firefox */
input[type=number] {
-moz-appearance: textfield;
}
`;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment