From 62d8aaa93842818bb51626606f8e93a8358924d4 Mon Sep 17 00:00:00 2001 From: John Kreitlow <863023+radium-v@users.noreply.github.com> Date: Mon, 28 Oct 2024 14:38:30 -0700 Subject: [PATCH] chore(web-components): replace state partials with state function (#33037) --- ...-04faf08a-3fc9-47e1-bade-1f263207c6e5.json | 7 + .../src/avatar/avatar.styles.ts | 95 ++- .../src/checkbox/checkbox.styles.ts | 8 +- .../src/counter-badge/counter-badge.styles.ts | 8 +- .../web-components/src/field/field.styles.ts | 95 +-- .../web-components/src/image/image.styles.ts | 26 +- .../web-components/src/label/label.styles.ts | 9 +- .../web-components/src/link/link.styles.ts | 6 +- .../src/menu-item/menu-item.styles.ts | 8 +- .../web-components/src/styles/states/index.ts | 602 +++++++++++++++--- .../web-components/src/text/text.styles.ts | 87 +-- .../src/utils/element-internals.ts | 28 + 12 files changed, 692 insertions(+), 287 deletions(-) create mode 100644 change/@fluentui-web-components-04faf08a-3fc9-47e1-bade-1f263207c6e5.json diff --git a/change/@fluentui-web-components-04faf08a-3fc9-47e1-bade-1f263207c6e5.json b/change/@fluentui-web-components-04faf08a-3fc9-47e1-bade-1f263207c6e5.json new file mode 100644 index 00000000000000..674578e94e1165 --- /dev/null +++ b/change/@fluentui-web-components-04faf08a-3fc9-47e1-bade-1f263207c6e5.json @@ -0,0 +1,7 @@ +{ + "type": "prerelease", + "comment": "replace state partials with stateSelector function", + "packageName": "@fluentui/web-components", + "email": "863023+radium-v@users.noreply.github.com", + "dependentChangeType": "patch" +} diff --git a/packages/web-components/src/avatar/avatar.styles.ts b/packages/web-components/src/avatar/avatar.styles.ts index aa8c1c9fdafab9..5b7b4493a54e6c 100644 --- a/packages/web-components/src/avatar/avatar.styles.ts +++ b/packages/web-components/src/avatar/avatar.styles.ts @@ -1,5 +1,38 @@ import { css } from '@microsoft/fast-element'; import { display } from '../utils/index.js'; +import { + anchorState, + beigeState, + blueState, + brandState, + brassState, + brownState, + cornflowerState, + cranberryState, + darkGreenState, + darkRedState, + forestState, + goldState, + grapeState, + lavenderState, + lightTealState, + lilacState, + magentaState, + marigoldState, + minkState, + navyState, + peachState, + pinkState, + platinumState, + plumState, + pumpkinState, + purpleState, + redState, + royalBlueState, + seafoamState, + steelState, + tealState, +} from '../styles/states/index.js'; import { borderRadiusCircular, borderRadiusLarge, @@ -322,157 +355,157 @@ export const styles = css` border-radius: ${borderRadiusXLarge}; } - :host(:is([state--brand], :state(brand))) { + :host(${brandState}) { color: ${colorNeutralForegroundStaticInverted}; background-color: ${colorBrandBackgroundStatic}; } - :host(:is([state--dark-red], :state(dark-red))) { + :host(${darkRedState}) { color: ${colorPaletteDarkRedForeground2}; background-color: ${colorPaletteDarkRedBackground2}; } - :host(:is([state--cranberry], :state(cranberry))) { + :host(${cranberryState}) { color: ${colorPaletteCranberryForeground2}; background-color: ${colorPaletteCranberryBackground2}; } - :host(:is([state--red], :state(red))) { + :host(${redState}) { color: ${colorPaletteRedForeground2}; background-color: ${colorPaletteRedBackground2}; } - :host(:is([state--pumpkin], :state(pumpkin))) { + :host(${pumpkinState}) { color: ${colorPalettePumpkinForeground2}; background-color: ${colorPalettePumpkinBackground2}; } - :host(:is([state--peach], :state(peach))) { + :host(${peachState}) { color: ${colorPalettePeachForeground2}; background-color: ${colorPalettePeachBackground2}; } - :host(:is([state--marigold], :state(marigold))) { + :host(${marigoldState}) { color: ${colorPaletteMarigoldForeground2}; background-color: ${colorPaletteMarigoldBackground2}; } - :host(:is([state--gold], :state(gold))) { + :host(${goldState}) { color: ${colorPaletteGoldForeground2}; background-color: ${colorPaletteGoldBackground2}; } - :host(:is([state--brass], :state(brass))) { + :host(${brassState}) { color: ${colorPaletteBrassForeground2}; background-color: ${colorPaletteBrassBackground2}; } - :host(:is([state--brown], :state(brown))) { + :host(${brownState}) { color: ${colorPaletteBrownForeground2}; background-color: ${colorPaletteBrownBackground2}; } - :host(:is([state--forest], :state(forest))) { + :host(${forestState}) { color: ${colorPaletteForestForeground2}; background-color: ${colorPaletteForestBackground2}; } - :host(:is([state--seafoam], :state(seafoam))) { + :host(${seafoamState}) { color: ${colorPaletteSeafoamForeground2}; background-color: ${colorPaletteSeafoamBackground2}; } - :host(:is([state--dark-green], :state(dark-green))) { + :host(${darkGreenState}) { color: ${colorPaletteDarkGreenForeground2}; background-color: ${colorPaletteDarkGreenBackground2}; } - :host(:is([state--light-teal], :state(light-teal))) { + :host(${lightTealState}) { color: ${colorPaletteLightTealForeground2}; background-color: ${colorPaletteLightTealBackground2}; } - :host(:is([state--teal], :state(teal))) { + :host(${tealState}) { color: ${colorPaletteTealForeground2}; background-color: ${colorPaletteTealBackground2}; } - :host(:is([state--steel], :state(steel))) { + :host(${steelState}) { color: ${colorPaletteSteelForeground2}; background-color: ${colorPaletteSteelBackground2}; } - :host(:is([state--blue], :state(blue))) { + :host(${blueState}) { color: ${colorPaletteBlueForeground2}; background-color: ${colorPaletteBlueBackground2}; } - :host(:is([state--royal-blue], :state(royal-blue))) { + :host(${royalBlueState}) { color: ${colorPaletteRoyalBlueForeground2}; background-color: ${colorPaletteRoyalBlueBackground2}; } - :host(:is([state--cornflower], :state(cornflower))) { + :host(${cornflowerState}) { color: ${colorPaletteCornflowerForeground2}; background-color: ${colorPaletteCornflowerBackground2}; } - :host(:is([state--navy], :state(navy))) { + :host(${navyState}) { color: ${colorPaletteNavyForeground2}; background-color: ${colorPaletteNavyBackground2}; } - :host(:is([state--lavender], :state(lavender))) { + :host(${lavenderState}) { color: ${colorPaletteLavenderForeground2}; background-color: ${colorPaletteLavenderBackground2}; } - :host(:is([state--purple], :state(purple))) { + :host(${purpleState}) { color: ${colorPalettePurpleForeground2}; background-color: ${colorPalettePurpleBackground2}; } - :host(:is([state--grape], :state(grape))) { + :host(${grapeState}) { color: ${colorPaletteGrapeForeground2}; background-color: ${colorPaletteGrapeBackground2}; } - :host(:is([state--lilac], :state(lilac))) { + :host(${lilacState}) { color: ${colorPaletteLilacForeground2}; background-color: ${colorPaletteLilacBackground2}; } - :host(:is([state--pink], :state(pink))) { + :host(${pinkState}) { color: ${colorPalettePinkForeground2}; background-color: ${colorPalettePinkBackground2}; } - :host(:is([state--magenta], :state(magenta))) { + :host(${magentaState}) { color: ${colorPaletteMagentaForeground2}; background-color: ${colorPaletteMagentaBackground2}; } - :host(:is([state--plum], :state(plum))) { + :host(${plumState}) { color: ${colorPalettePlumForeground2}; background-color: ${colorPalettePlumBackground2}; } - :host(:is([state--beige], :state(beige))) { + :host(${beigeState}) { color: ${colorPaletteBeigeForeground2}; background-color: ${colorPaletteBeigeBackground2}; } - :host(:is([state--mink], :state(mink))) { + :host(${minkState}) { color: ${colorPaletteMinkForeground2}; background-color: ${colorPaletteMinkBackground2}; } - :host(:is([state--platinum], :state(platinum))) { + :host(${platinumState}) { color: ${colorPalettePlatinumForeground2}; background-color: ${colorPalettePlatinumBackground2}; } - :host(:is([state--anchor], :state(anchor))) { + :host(${anchorState}) { color: ${colorPaletteAnchorForeground2}; background-color: ${colorPaletteAnchorBackground2}; } diff --git a/packages/web-components/src/checkbox/checkbox.styles.ts b/packages/web-components/src/checkbox/checkbox.styles.ts index e68c2d860f0a5b..235cdbbd547439 100644 --- a/packages/web-components/src/checkbox/checkbox.styles.ts +++ b/packages/web-components/src/checkbox/checkbox.styles.ts @@ -1,5 +1,5 @@ import { css } from '@microsoft/fast-element'; -import { checkedState, circularState, largeState } from '../styles/states/index.js'; +import { checkedState, circularState, indeterminateState, largeState } from '../styles/states/index.js'; import { borderRadiusCircular, borderRadiusMedium, @@ -25,12 +25,6 @@ import { import { forcedColorsStylesheetBehavior } from '../utils/behaviors/match-media-stylesheet-behavior.js'; import { display } from '../utils/display.js'; -/** - * Selector for the `indeterminate` state. - * @public - */ -const indeterminateState = css.partial`:is([state--indeterminate], :state(indeterminate))`; - /** Checkbox styles * * @public diff --git a/packages/web-components/src/counter-badge/counter-badge.styles.ts b/packages/web-components/src/counter-badge/counter-badge.styles.ts index 1baf7fa840c15e..1b0b9eca70015c 100644 --- a/packages/web-components/src/counter-badge/counter-badge.styles.ts +++ b/packages/web-components/src/counter-badge/counter-badge.styles.ts @@ -1,13 +1,7 @@ import { css } from '@microsoft/fast-element'; import { badgeBaseStyles, badgeFilledStyles, badgeGhostStyles, badgeSizeStyles } from '../styles/index.js'; import { borderRadiusMedium, borderRadiusSmall } from '../theme/design-tokens.js'; -import { extraSmallState, roundedState, smallState, tinyState } from '../styles/states/index.js'; - -/** - * Selector for the `dot` state. - * @public - */ -const dotState = css.partial`:is([state--dot], :state(dot))`; +import { dotState, extraSmallState, roundedState, smallState, tinyState } from '../styles/states/index.js'; /** Badge styles * @public diff --git a/packages/web-components/src/field/field.styles.ts b/packages/web-components/src/field/field.styles.ts index 00c466120ef53f..52f7446984d59a 100644 --- a/packages/web-components/src/field/field.styles.ts +++ b/packages/web-components/src/field/field.styles.ts @@ -1,5 +1,20 @@ import { css } from '@microsoft/fast-element'; -import { disabledState } from '../styles/states/index.js'; +import { + badInputState, + customErrorState, + disabledState, + focusVisibleState, + hasMessageState, + patternMismatchState, + rangeOverflowState, + rangeUnderflowState, + stepMismatchState, + tooLongState, + tooShortState, + typeMismatchState, + validState, + valueMissingState, +} from '../styles/states/index.js'; import { borderRadiusMedium, colorNeutralForeground1, @@ -23,84 +38,6 @@ import { import { display } from '../utils/display.js'; import { ValidationFlags } from './field.options.js'; -/** - * Selector for the `focus-visible` state. - * @public - */ -const focusVisibleState = css.partial`:is([state--focus-visible], :state(focus-visible))`; - -/** - * Selector for the `bad-input` state. - * @public - */ -const badInputState = css.partial`:is([state--${ValidationFlags.badInput}], :state(${ValidationFlags.badInput}))`; - -/** - * Selector for the `custom-error` state. - * @public - */ -const customErrorState = css.partial`:is([state--${ValidationFlags.customError}], :state(${ValidationFlags.customError}))`; - -/** - * Selector for the `pattern-mismatch` state. - * @public - */ -const patternMismatchState = css.partial`:is([state--${ValidationFlags.patternMismatch}], :state(${ValidationFlags.patternMismatch}))`; - -/** - * Selector for the `range-overflow` state. - * @public - */ -const rangeOverflowState = css.partial`:is([state--${ValidationFlags.rangeOverflow}], :state(${ValidationFlags.rangeOverflow}))`; - -/** - * Selector for the `range-underflow` state. - * @public - */ -const rangeUnderflowState = css.partial`:is([state--${ValidationFlags.rangeUnderflow}], :state(${ValidationFlags.rangeUnderflow}))`; - -/** - * Selector for the `step-mismatch` state. - * @public - */ -const stepMismatchState = css.partial`:is([state--${ValidationFlags.stepMismatch}], :state(${ValidationFlags.stepMismatch}))`; - -/** - * Selector for the `too-long` state. - * @public - */ -const tooLongState = css.partial`:is([state--${ValidationFlags.tooLong}], :state(${ValidationFlags.tooLong}))`; - -/** - * Selector for the `too-short` state. - * @public - */ -const tooShortState = css.partial`:is([state--${ValidationFlags.tooShort}], :state(${ValidationFlags.tooShort}))`; - -/** - * Selector for the `type-mismatch` state. - * @public - */ -const typeMismatchState = css.partial`:is([state--${ValidationFlags.typeMismatch}], :state(${ValidationFlags.typeMismatch}))`; - -/** - * Selector for the `valid` state. - * @public - */ -const validState = css.partial`:is([state-${ValidationFlags.valid}], :state(${ValidationFlags.valid}))`; - -/** - * Selector for the `value-missing` state. - * @public - */ -const valueMissingState = css.partial`:is([state--${ValidationFlags.valueMissing}], :state(${ValidationFlags.valueMissing}))`; - -/** - * Selector for the `has-message` state. - * @public - */ -const hasMessageState = css.partial`:is([state--has-message], :state(has-message))`; - /** * The styles for the {@link Field} component. * diff --git a/packages/web-components/src/image/image.styles.ts b/packages/web-components/src/image/image.styles.ts index c1908dd051e11b..fbb57abb310ad2 100644 --- a/packages/web-components/src/image/image.styles.ts +++ b/packages/web-components/src/image/image.styles.ts @@ -6,7 +6,17 @@ import { shadow4, strokeWidthThin, } from '../theme/design-tokens.js'; -import { circularState, roundedState } from '../styles/states/index.js'; +import { + blockState, + borderedState, + circularState, + fitCenterState, + fitContainState, + fitCoverState, + fitNoneState, + roundedState, + shadowState, +} from '../styles/states/index.js'; /** Image styles * @@ -23,38 +33,38 @@ export const styles = css` min-width: 8px; display: inline-block; } - :host(:is([state--block], :state(block))) ::slotted(img) { + :host(${blockState}) ::slotted(img) { width: 100%; height: auto; } - :host(:is([state--bordered], :state(bordered))) ::slotted(img) { + :host(${borderedState}) ::slotted(img) { border: ${strokeWidthThin} solid ${colorNeutralStroke2}; } - :host(:is([state--fit-none], :state(fit-none))) ::slotted(img) { + :host(${fitNoneState}) ::slotted(img) { object-fit: none; object-position: top left; height: 100%; width: 100%; } - :host(:is([state--fit-center], :state(fit-center))) ::slotted(img) { + :host(${fitCenterState}) ::slotted(img) { object-fit: none; object-position: center; height: 100%; width: 100%; } - :host(:is([state--fit-contain], :state(fit-contain))) ::slotted(img) { + :host(${fitContainState}) ::slotted(img) { object-fit: contain; object-position: center; height: 100%; width: 100%; } - :host(:is([state--fit-cover], :state(fit-cover))) ::slotted(img) { + :host(${fitCoverState}) ::slotted(img) { object-fit: cover; object-position: center; height: 100%; width: 100%; } - :host(:is([state--shadowed], :state(shadowed))) ::slotted(img) { + :host(${shadowState}) ::slotted(img) { box-shadow: ${shadow4}; } :host(${circularState}) ::slotted(img) { diff --git a/packages/web-components/src/label/label.styles.ts b/packages/web-components/src/label/label.styles.ts index efa284e405cda0..688d374e3e592d 100644 --- a/packages/web-components/src/label/label.styles.ts +++ b/packages/web-components/src/label/label.styles.ts @@ -15,7 +15,7 @@ import { lineHeightBase400, spacingHorizontalXS, } from '../theme/design-tokens.js'; -import { largeState, smallState } from '../styles/states/index.js'; +import { disabledState, largeState, semiboldState, smallState } from '../styles/states/index.js'; /** Label styles * @public @@ -48,13 +48,12 @@ export const styles = css` line-height: ${lineHeightBase400}; } - :host(${largeState}), - :host(:is([state--semibold], :state(semibold))) { + :host(:is(${largeState}, ${semiboldState})) { font-weight: ${fontWeightSemibold}; } - :host(:is([state--disabled], :state(disabled))), - :host(:is([state--disabled], :state(disabled))) .asterisk { + :host(${disabledState}), + :host(${disabledState}) .asterisk { color: ${colorNeutralForegroundDisabled}; } `; diff --git a/packages/web-components/src/link/link.styles.ts b/packages/web-components/src/link/link.styles.ts index d66996dbb478cf..edc08729f13c60 100644 --- a/packages/web-components/src/link/link.styles.ts +++ b/packages/web-components/src/link/link.styles.ts @@ -12,7 +12,7 @@ import { fontWeightRegular, strokeWidthThin, } from '../theme/design-tokens.js'; -import { subtleState } from '../styles/states/index.js'; +import { inlineState, subtleState } from '../styles/states/index.js'; export const styles = css` ${display('inline')} @@ -29,7 +29,7 @@ export const styles = css` overflow: inherit; text-align: start; text-decoration: none; - text-decoration-thinkness: ${strokeWidthThin}; + text-decoration-thickness: ${strokeWidthThin}; text-overflow: inherit; user-select: text; } @@ -62,7 +62,7 @@ export const styles = css` } :host-context(:is(h1, h2, h3, h4, h5, h6, p, fluent-text)), - :host(:is([state--inline], :state(inline))) { + :host(${inlineState}) { font: inherit; text-decoration: underline; } diff --git a/packages/web-components/src/menu-item/menu-item.styles.ts b/packages/web-components/src/menu-item/menu-item.styles.ts index c088546188c377..b800785338e885 100644 --- a/packages/web-components/src/menu-item/menu-item.styles.ts +++ b/packages/web-components/src/menu-item/menu-item.styles.ts @@ -20,13 +20,7 @@ import { lineHeightBase200, lineHeightBase300, } from '../theme/design-tokens.js'; -import { checkedState, disabledState } from '../styles/states/index.js'; - -/** - * Selector for the `submenu` state. - * @public - */ -export const submenuState = css.partial`:is([state--submenu], :state(submenu))`; +import { checkedState, disabledState, submenuState } from '../styles/states/index.js'; /** MenuItem styles * @public diff --git a/packages/web-components/src/styles/states/index.ts b/packages/web-components/src/styles/states/index.ts index 72df500552b569..2490cd67fda9ff 100644 --- a/packages/web-components/src/styles/states/index.ts +++ b/packages/web-components/src/styles/states/index.ts @@ -1,313 +1,721 @@ -import { css } from '@microsoft/fast-element'; +import { stateSelector } from '../../utils/element-internals.js'; /** - * Selector for the `checked` state. + * Selector for the `align-end` state. * @public */ -export const checkedState = css.partial`:is([state--checked], :state(checked))`; +export const alignEndState = stateSelector('align-end'); /** - * Selector for the `disabled` state. + * Selector for the `align-start` state. * @public */ -export const disabledState = css.partial`:is([state--disabled], :state(disabled))`; +export const alignStartState = stateSelector('align-start'); /** - * Selector for the `filled-lighter` state. + * Selector for the `anchor` state. * @public */ -export const filledLighterState = css.partial`:is([state--filled-lighter], :state(filled-lighter))`; +export const anchorState = stateSelector('anchor'); /** - * Selector for the `filled-darker` state. + * Selector for the `auto-resize` state. * @public */ -export const filledDarkerState = css.partial`:is([state--filled-darker], :state(filled-darker))`; +export const autoResizeState = stateSelector('auto-resize'); /** - * Selector for the `ghost` state. + * Selector for the `bad-input` state. * @public */ -export const ghostState = css.partial`:is([state--ghost], :state(ghost))`; +export const badInputState = stateSelector('bad-input'); /** - * Selector for the `inverted` state. + * Selector for the `beige` state. * @public */ -export const invertedState = css.partial`:is([state--inverted], :state(inverted))`; +export const beigeState = stateSelector('beige'); /** - * Selector for the `primary` state. + * Selector for the `block` state. * @public */ -export const primaryState = css.partial`:is([state--primary], :state(primary))`; +export const blockState = stateSelector('block'); /** - * Selector for the `outline` state. + * Selector for the `blue` state. * @public */ -export const outlineState = css.partial`:is([state--outline], :state(outline))`; +export const blueState = stateSelector('blue'); /** - * Selector for the `strong` state. + * Selector for the `bold` state. * @public */ -export const strongState = css.partial`:is([state--strong], :state(strong))`; +export const boldState = stateSelector('bold'); /** - * Selector for the `subtle` state. + * Selector for the `bordered` state. * @public */ -export const subtleState = css.partial`:is([state--subtle], :state(subtle))`; +export const borderedState = stateSelector('bordered'); /** - * Selector for the `tint` state. + * Selector for the `brand` state. * @public */ -export const tintState = css.partial`:is([state--tint], :state(tint))`; +export const brandState = stateSelector('brand'); /** - * Selector for the `underline` state. + * Selector for the `brass` state. * @public */ -export const underlineState = css.partial`:is([state--underline], :state(underline))`; +export const brassState = stateSelector('brass'); /** - * Selector for the `transparent` state. + * Selector for the `brown` state. + * @public + */ +export const brownState = stateSelector('brown'); + +/** + * Selector for the `center` state. + * @public + */ +export const centerState = stateSelector('center'); + +/** + * Selector for the `checked` state. * @public */ -export const transparentState = css.partial`:is([state--transparent], :state(transparent))`; +export const checkedState = stateSelector('checked'); /** * Selector for the `circular` state. * @public */ -export const circularState = css.partial`:is([state--circular], :state(circular))`; +export const circularState = stateSelector('circular'); /** - * Selector for the `rounded` state. + * Selector for the `cornflower` state. * @public */ -export const roundedState = css.partial`:is([state--rounded], :state(rounded))`; +export const cornflowerState = stateSelector('cornflower'); /** - * Selector for the `square` state. + * Selector for the `cranberry` state. * @public */ -export const squareState = css.partial`:is([state--square], :state(square))`; +export const cranberryState = stateSelector('cranberry'); /** - * Selector for the `tiny` state. + * Selector for the `custom-error` state. * @public */ -export const tinyState = css.partial`:is([state--tiny], :state(tiny))`; +export const customErrorState = stateSelector('custom-error'); /** - * Selector for the `extra-small` state. + * Selector for the `danger` state. * @public */ -export const extraSmallState = css.partial`:is([state--extra-small], :state(extra-small))`; +export const dangerState = stateSelector('danger'); /** - * Selector for the `small` state. + * Selector for the `dark-green` state. * @public */ -export const smallState = css.partial`:is([state--small], :state(small))`; +export const darkGreenState = stateSelector('dark-green'); /** - * Selector for the `medium` state. + * Selector for the `dark-red` state. * @public */ -export const mediumState = css.partial`:is([state--medium], :state(medium))`; +export const darkRedState = stateSelector('dark-red'); /** - * Selector for the `large` state. + * Selector for the `disabled` state. + * @public + */ +export const disabledState = stateSelector('disabled'); + +/** + * Selector for the `display-shadow` state. * @public */ -export const largeState = css.partial`:is([state--large], :state(large))`; +export const displayShadowState = stateSelector('display-shadow'); + +/** + * Selector for the `dot` state. + * @public + */ +export const dotState = stateSelector('dot'); + +/** + * Selector for the `end` state. + * @public + */ +export const endState = stateSelector('end'); + +/** + * Selector for the `error` state. + * @public + */ +export const errorState = stateSelector('error'); + +/** + * Selector for the `expanded` state. + * @public + */ +export const expandedState = stateSelector('expanded'); /** * Selector for the `extra-large` state. * @public */ -export const extraLargeState = css.partial`:is([state--extra-large], :state(extra-large))`; +export const extraLargeState = stateSelector('extra-large'); /** - * Selector for the `huge` state. + * Selector for the `extra-small` state. * @public */ -export const hugeState = css.partial`:is([state--huge], :state(huge))`; +export const extraSmallState = stateSelector('extra-small'); /** - * Selector for the `alignment` start state. + * Selector for the `filled-darker` state. * @public */ -export const alignStartState = css.partial`:is([state--align-start], :state(align-start))`; +export const filledDarkerState = stateSelector('filled-darker'); /** - * Selector for the `alignment` end state. + * Selector for the `filled-lighter` state. * @public */ -export const alignEndState = css.partial`:is([state--align-end], :state(align-end))`; +export const filledLighterState = stateSelector('filled-lighter'); /** - * Selector for the `inset` state. + * Selector for the `fit-center` state. * @public */ -export const insetState = css.partial`:is([state--inset], :state(inset))`; +export const fitCenterState = stateSelector('fit-center'); /** - * Selector for the `iconOnly` state. + * Selector for the `fit-contain` state. * @public */ -export const iconOnlyState = css.partial`:is([state--icon], :state(icon))`; +export const fitContainState = stateSelector('fit-contain'); /** - * Selector for the `pressed` state. + * Selector for the `fit-cover` state. * @public */ -export const pressedState = css.partial`:is([state--pressed], :state(pressed))`; +export const fitCoverState = stateSelector('fit-cover'); /** - * Selector for the `brand` state. + * Selector for the `fit-none` state. * @public */ -export const brandState = css.partial`:is([state--brand], :state(brand))`; +export const fitNoneState = stateSelector('fit-none'); /** - * Selector for the `error` state. + * Selector for the `focus-visible` state. * @public */ -export const errorState = css.partial`:is([state--error], :state(error))`; +export const focusVisibleState = stateSelector('focus-visible'); /** - * Selector for the `danger` state. + * Selector for the `forest` state. * @public */ -export const dangerState = css.partial`:is([state--danger], :state(danger))`; +export const forestState = stateSelector('forest'); + +/** + * Selector for the `ghost` state. + * @public + */ +export const ghostState = stateSelector('ghost'); + +/** + * Selector for the `gold` state. + * @public + */ +export const goldState = stateSelector('gold'); + +/** + * Selector for the `grape` state. + * @public + */ +export const grapeState = stateSelector('grape'); + +/** + * Selector for the `has-message` state. + * @public + */ +export const hasMessageState = stateSelector('has-message'); + +/** + * Selector for the `huge` state. + * @public + */ +export const hugeState = stateSelector('huge'); + +/** + * Selector for the `icon` state. + * @public + */ +export const iconOnlyState = stateSelector('icon'); /** * Selector for the `important` state. * @public */ -export const importantState = css.partial`:is([state--important], :state(important))`; +export const importantState = stateSelector('important'); + +/** + * Selector for the `indeterminate` state. + * @public + */ +export const indeterminateState = stateSelector('indeterminate'); /** * Selector for the `informative` state. * @public */ -export const informativeState = css.partial`:is([state--informative], :state(informative))`; +export const informativeState = stateSelector('informative'); + +/** + * Selector for the `inline` state. + * @public + */ +export const inlineState = stateSelector('inline'); + +/** + * Selector for the `inset` state. + * @public + */ +export const insetState = stateSelector('inset'); + +/** + * Selector for the `inverted` state. + * @public + */ +export const invertedState = stateSelector('inverted'); + +/** + * Selector for the `italic` state. + * @public + */ +export const italicState = stateSelector('italic'); + +/** + * Selector for the `justify` state. + * @public + */ +export const justifyState = stateSelector('justify'); + +/** + * Selector for the `large` state. + * @public + */ +export const largeState = stateSelector('large'); + +/** + * Selector for the `lavender` state. + * @public + */ +export const lavenderState = stateSelector('lavender'); + +/** + * Selector for the `light-teal` state. + * @public + */ +export const lightTealState = stateSelector('light-teal'); + +/** + * Selector for the `lilac` state. + * @public + */ +export const lilacState = stateSelector('lilac'); + +/** + * Selector for the `magenta` state. + * @public + */ +export const magentaState = stateSelector('magenta'); /** * Selector for the `marigold` state. * @public */ -export const marigoldState = css.partial`:is([state--marigold], :state(marigold))`; +export const marigoldState = stateSelector('marigold'); + +/** + * Selector for the `medium` state. + * @public + */ +export const mediumState = stateSelector('medium'); + +/** + * Selector for the `mink` state. + * @public + */ +export const minkState = stateSelector('mink'); + +/** + * Selector for the `monospace` state. + * @public + */ +export const monospaceState = stateSelector('monospace'); + +/** + * Selector for the `multiline` state. + * @public + */ +export const multiLineState = stateSelector('multiline'); + +/** + * Selector for the `navy` state. + * @public + */ +export const navyState = stateSelector('navy'); /** * Selector for the `neutral` state. * @public */ -export const neutralState = css.partial`:is([state--neutral], :state(neutral))`; +export const neutralState = stateSelector('neutral'); /** - * Selector for the `severe` state. + * Selector for the `nowrap` state. * @public */ -export const severeState = css.partial`:is([state--severe], :state(severe))`; +export const nowrapState = stateSelector('nowrap'); /** - * Selector for the `success` state. + * Selector for the `numeric` state. * @public */ -export const successState = css.partial`:is([state--success], :state(success))`; +export const numericState = stateSelector('numeric'); /** - * Selector for the `warning` state. + * Selector for the `outline` state. * @public */ -export const warningState = css.partial`:is([state--warning], :state(warning))`; +export const outlineState = stateSelector('outline'); /** - * Selector for the `vertical` state. + * Selector for the `pattern-mismatch` state. * @public */ -export const verticalState = css.partial`:is([state--vertical], :state(vertical))`; +export const patternMismatchState = stateSelector('pattern-mismatch'); /** - * Selector for the `horizontal` state. + * Selector for the `peach` state. * @public */ -export const horizontalState = css.partial`:is([state--horizontal], :state(horizontal))`; +export const peachState = stateSelector('peach'); /** - * Selector for the `singleline` state. + * Selector for the `pink` state. * @public */ -export const singleLineState = css.partial`:is([state--singleline], :state(singleline))`; +export const pinkState = stateSelector('pink'); /** - * Selector for the `multiline` state. + * Selector for the `platinum` state. * @public */ -export const multiLineState = css.partial`:is([state--multiline], :state(multiline))`; +export const platinumState = stateSelector('platinum'); /** - * Selector for the `expanded` state. + * Selector for the `plum` state. * @public */ -export const expandedState = css.partial`:is([state--expanded], :state(expanded))`; +export const plumState = stateSelector('plum'); /** - * Selector for the `block` state. + * Selector for the `pressed` state. * @public */ -export const blockState = css.partial`:is([state--block], :state(block))`; +export const pressedState = stateSelector('pressed'); /** - * Selector for the `resize` state. This indicates the element is resizable. + * Selector for the `primary` state. * @public */ -export const resizeState = css.partial`:is([state--resize], :state(resize))`; +export const primaryState = stateSelector('primary'); + +/** + * Selector for the `pumpkin` state. + * @public + */ +export const pumpkinState = stateSelector('pumpkin'); + +/** + * Selector for the `purple` state. + * @public + */ +export const purpleState = stateSelector('purple'); + +/** + * Selector for the `range-overflow` state. + * @public + */ +export const rangeOverflowState = stateSelector('range-overflow'); + +/** + * Selector for the `range-underflow` state. + * @public + */ +export const rangeUnderflowState = stateSelector('range-underflow'); + +/** + * Selector for the `red` state. + * @public + */ +export const redState = stateSelector('red'); + +/** + * Selector for the `resize-both` state. + * @public + */ +export const resizeBothState = stateSelector('resize-both'); /** * Selector for the `resize-horizontal` state. * @public */ -export const resizeHorizontalState = css.partial`:is([state--resize-horizontal], :state(resize-horizontal))`; +export const resizeHorizontalState = stateSelector('resize-horizontal'); /** * Selector for the `resize-vertical` state. * @public */ -export const resizeVerticalState = css.partial`:is([state--resize-vertical], :state(resize-vertical))`; +export const resizeVerticalState = stateSelector('resize-vertical'); /** - * Selector for the `resize-both` state. + * Selector for the `rounded` state. * @public */ -export const resizeBothState = css.partial`:is([state--resize-both], :state(resize-both))`; +export const roundedState = stateSelector('rounded'); /** - * Selector for the `auto-resize` state. + * Selector for the `royal-blue` state. * @public */ -export const autoResizeState = css.partial`:is([state--auto-resize], :state(auto-resize))`; +export const royalBlueState = stateSelector('royal-blue'); /** - * Selector for the `display-shadow` state. + * Selector for the `seafoam` state. + * @public + */ +export const seafoamState = stateSelector('seafoam'); + +/** + * Selector for the `semibold` state. + * @public + */ +export const semiboldState = stateSelector('semibold'); + +/** + * Selector for the `severe` state. + * @public + */ +export const severeState = stateSelector('severe'); + +/** + * Selector for the `shadow` state. + * @public + */ +export const shadowState = stateSelector('shadow'); + +/** + * Selector for the `size1000` state. + * @public + */ +export const size1000State = stateSelector('size-1000'); + +/** + * Selector for the `size100` state. + * @public + */ +export const size100State = stateSelector('size-100'); + +/** + * Selector for the `size200` state. + * @public + */ +export const size200State = stateSelector('size-200'); + +/** + * Selector for the `size400` state. + * @public + */ +export const size400State = stateSelector('size-400'); + +/** + * Selector for the `size500` state. + * @public + */ +export const size500State = stateSelector('size-500'); + +/** + * Selector for the `size600` state. + * @public + */ +export const size600State = stateSelector('size-600'); + +/** + * Selector for the `size700` state. + * @public + */ +export const size700State = stateSelector('size-700'); + +/** + * Selector for the `size800` state. + * @public + */ +export const size800State = stateSelector('size-800'); + +/** + * Selector for the `size900` state. + * @public + */ +export const size900State = stateSelector('size-900'); + +/** + * Selector for the `small` state. + * @public + */ +export const smallState = stateSelector('small'); + +/** + * Selector for the `square` state. * @public */ -export const displayShadowState = css.partial`:is([state--display-shadow], :state(display-shadow))`; +export const squareState = stateSelector('square'); -/* +/** + * Selector for the `steel` state. + * @public + */ +export const steelState = stateSelector('steel'); + +/** + * Selector for the `step-mismatch` state. + * @public + */ +export const stepMismatchState = stateSelector('step-mismatch'); + +/** + * Selector for the `strikethrough` state. + * @public + */ +export const strikethroughState = stateSelector('strikethrough'); + +/** + * Selector for the `strong` state. + * @public + */ +export const strongState = stateSelector('strong'); + +/** + * Selector for the `submenu` state. + * @public + */ +export const submenuState = stateSelector('submenu'); + +/** + * Selector for the `subtle` state. + * @public + */ +export const subtleState = stateSelector('subtle'); + +/** + * Selector for the `success` state. + * @public + */ +export const successState = stateSelector('success'); + +/** + * Selector for the `teal` state. + * @public + */ +export const tealState = stateSelector('teal'); + +/** + * Selector for the `tint` state. + * @public + */ +export const tintState = stateSelector('tint'); + +/** + * Selector for the `tiny` state. + * @public + */ +export const tinyState = stateSelector('tiny'); + +/** + * Selector for the `too-long` state. + * @public + */ +export const tooLongState = stateSelector('too-long'); + +/** + * Selector for the `too-short` state. + * @public + */ +export const tooShortState = stateSelector('too-short'); + +/** + * Selector for the `transparent` state. + * @public + */ +export const transparentState = stateSelector('transparent'); + +/** + * Selector for the `truncate` state. + * @public + */ +export const truncateState = stateSelector('truncate'); + +/** + * Selector for the `type-mismatch` state. + * @public + */ +export const typeMismatchState = stateSelector('type-mismatch'); + +/** + * Selector for the `underline` state. + * @public + */ +export const underlineState = stateSelector('underline'); + +/** * Selector for the `user-invalid` state. * @public */ -export const userInvalidState = css.partial`:is([state--user-invalid], :state(user-invalid))`; +export const userInvalidState = stateSelector('user-invalid'); + +/** + * Selector for the `valid` state. + * @public + */ +export const validState = stateSelector('valid'); /** - * Selector for the `user-valid` state. + * Selector for the `value-missing` state. + * @public + */ +export const valueMissingState = stateSelector('value-missing'); + +/** + * Selector for the `vertical` state. + * @public + */ +export const verticalState = stateSelector('vertical'); + +/** + * Selector for the `warning` state. * @public */ -export const userValidState = css.partial`:is([state--user-valid], :state(user-valid))`; +export const warningState = stateSelector('warning'); diff --git a/packages/web-components/src/text/text.styles.ts b/packages/web-components/src/text/text.styles.ts index b7041e04a1c9cc..cf8e2191654a3f 100644 --- a/packages/web-components/src/text/text.styles.ts +++ b/packages/web-components/src/text/text.styles.ts @@ -29,30 +29,31 @@ import { lineHeightHero800, lineHeightHero900, } from '../theme/design-tokens.js'; - -/** - * Selector for the `nowrap` state. - * @public - */ -const nowrapState = css.partial`:is([state--nowrap], :state(nowrap))`; - -/** - * Selector for the `truncate` state. - * @public - */ -const truncateState = css.partial`:is([state--truncate], :state(truncate))`; - -/** - * Selector for the `underline` state. - * @public - */ -const underlineState = css.partial`:is([state--underline], :state(underline))`; - -/** - * Selector for the `strikethrough` state. - * @public - */ -const strikethroughState = css.partial`:is([state--strikethrough], :state(strikethrough))`; +import { + blockState, + boldState, + centerState, + endState, + italicState, + justifyState, + mediumState, + monospaceState, + nowrapState, + numericState, + semiboldState, + size1000State, + size100State, + size200State, + size400State, + size500State, + size600State, + size700State, + size800State, + size900State, + strikethroughState, + truncateState, + underlineState, +} from '../styles/states/index.js'; /** Text styles * @public @@ -78,10 +79,10 @@ export const styles = css` :host(${truncateState}) ::slotted(*) { text-overflow: ellipsis; } - :host(:is([state--block], :state(block))) { + :host(${blockState}) { display: block; } - :host(:is([state--italic], :state(italic))) { + :host(${italicState}) { font-style: italic; } :host(${underlineState}) { @@ -93,64 +94,64 @@ export const styles = css` :host(${underlineState}${strikethroughState}) { text-decoration-line: line-through underline; } - :host(:is([state--size-100], :state(size-100))) { + :host(${size100State}) { font-size: ${fontSizeBase100}; line-height: ${lineHeightBase100}; } - :host(:is([state--size-200], :state(size-200))) { + :host(${size200State}) { font-size: ${fontSizeBase200}; line-height: ${lineHeightBase200}; } - :host(:is([state--size-400], :state(size-400))) { + :host(${size400State}) { font-size: ${fontSizeBase400}; line-height: ${lineHeightBase400}; } - :host(:is([state--size-500], :state(size-500))) { + :host(${size500State}) { font-size: ${fontSizeBase500}; line-height: ${lineHeightBase500}; } - :host(:is([state--size-600], :state(size-600))) { + :host(${size600State}) { font-size: ${fontSizeBase600}; line-height: ${lineHeightBase600}; } - :host(:is([state--size-700], :state(size-700))) { + :host(${size700State}) { font-size: ${fontSizeHero700}; line-height: ${lineHeightHero700}; } - :host(:is([state--size-800], :state(size-800))) { + :host(${size800State}) { font-size: ${fontSizeHero800}; line-height: ${lineHeightHero800}; } - :host(:is([state--size-900], :state(size-900))) { + :host(${size900State}) { font-size: ${fontSizeHero900}; line-height: ${lineHeightHero900}; } - :host(:is([state--size-1000], :state(size-1000))) { + :host(${size1000State}) { font-size: ${fontSizeHero1000}; line-height: ${lineHeightHero1000}; } - :host(:is([state--monospace], :state(monospace))) { + :host(${monospaceState}) { font-family: ${fontFamilyMonospace}; } - :host(:is([state--numeric], :state(numeric))) { + :host(${numericState}) { font-family: ${fontFamilyNumeric}; } - :host(:is([state--medium], :state(medium))) { + :host(${mediumState}) { font-weight: ${fontWeightMedium}; } - :host(:is([state--semibold], :state(semibold))) { + :host(${semiboldState}) { font-weight: ${fontWeightSemibold}; } - :host(:is([state--bold], :state(bold))) { + :host(${boldState}) { font-weight: ${fontWeightBold}; } - :host(:is([state--center], :state(center))) { + :host(${centerState}) { text-align: center; } - :host(:is([state--end], :state(end))) { + :host(${endState}) { text-align: end; } - :host(:is([state--justify], :state(justify))) { + :host(${justifyState}) { text-align: justify; } diff --git a/packages/web-components/src/utils/element-internals.ts b/packages/web-components/src/utils/element-internals.ts index 937cc4775f012c..26cb6517697d38 100644 --- a/packages/web-components/src/utils/element-internals.ts +++ b/packages/web-components/src/utils/element-internals.ts @@ -1,9 +1,37 @@ +/** + * Inference type for a CSS custom state selector. + * @public + */ +export type StateSelector = S extends string ? `:state(${S})` | `[state--${S}]` : never; + /** * Check if the browser supports Custom States. * @public */ export const CustomStatesSetSupported = CSS.supports('selector(:state(g))'); +/** + * Map to store the state values. + * @internal + */ +const statesMap = new Map>(); + +/** + * Returns a string that represents a CSS custom state selector. + * + * @param state - the state value. + * @returns a string that represents a CSS state selector, or a custom attribute selector if the browser does not + * support Custom States. + * + * @public + */ +export function stateSelector(state: S): StateSelector { + return (statesMap.get(state) ?? + statesMap + .set(state, CustomStatesSetSupported ? `:state(${state})` : `[state--${state}]`) + .get(state)) as StateSelector; +} + /** * This function is used to toggle a state on the control. If the browser supports Custom States, the state is toggled * on the `ElementInternals.states` set. If the browser does not support Custom States, the state is toggled on the host