diff --git a/.agents/skills/port-gitlab-ui-component/SKILL.md b/.agents/skills/port-gitlab-ui-component/SKILL.md index d24824b..35d784b 100644 --- a/.agents/skills/port-gitlab-ui-component/SKILL.md +++ b/.agents/skills/port-gitlab-ui-component/SKILL.md @@ -69,6 +69,8 @@ Keep stylesheet provenance boundaries strict. A component's colocated CSS may co When authoring component CSS, prefer `@apply` with supported upstream `gl-*` utilities wherever it preserves the intended declaration and cascade. When upstream already uses `@apply`, keep its utility choices, variant prefixes, grouping, and source order as closely as the local Tailwind build and React structure allow. Keep native CSS for component-specific tokens, Sass-only constructs, compatibility adaptations, missing utilities, or cases where `@apply` would change specificity or source-order behavior. See [references/react-porting.md](references/react-porting.md) for the detailed boundary. +Match the upstream stylesheet's selector organization as closely as the local React and Base UI structure allows. When upstream uses Sass-style nesting, preserve the equivalent nesting for states, modifiers, descendants, combinators, and conditional at-rules; when upstream leaves a rule flat, keep its local counterpart flat instead of introducing nesting merely because the build supports it. Nest only when the existing `postcss-nested` pipeline expands to the same selector set, specificity, at-rule context, and source order. Do not introduce Sass variables, mixins, loops, or interpolation. + If upstream behavior cannot be supported without a missing local primitive, either add the smallest reusable prerequisite within scope or preserve a clear typed API boundary and document the deliberate deferral. Never silently drop a supported state. ### 4. Verify in increasing cost order diff --git a/.agents/skills/port-gitlab-ui-component/references/react-porting.md b/.agents/skills/port-gitlab-ui-component/references/react-porting.md index eaed836..0193347 100644 --- a/.agents/skills/port-gitlab-ui-component/references/react-porting.md +++ b/.agents/skills/port-gitlab-ui-component/references/react-porting.md @@ -29,10 +29,13 @@ Use this reference after the upstream compatibility checklist is known. It captu - Model closed variants with `cva` and exported literal unions. Keep structural classes separate from consumer `className` merging. - Treat upstream stylesheet boundaries as part of the port. Colocated component CSS may contain only rules whose semantic source is the corresponding upstream component stylesheet, including declarations generated by mixins, utilities, or required build-compatibility transforms invoked there. Rules supplied transitively by Bootstrap, vendor/global styles, or imported stylesheets belong in the matching shared styles layer, scoped to a component marker where needed and imported before component-private CSS. - Translate Sass into colocated CSS and prefer `@apply` with supported `gl-*` utilities whenever they express the same semantics. +- Treat the upstream nesting structure as part of the stylesheet organization. Mirror equivalent Sass-style nesting for pseudo-classes, pseudo-elements, modifiers, suffixes, descendants, combinators, and nested `@media`, `@supports`, or `@container` rules when the local selectors correspond directly. If upstream keeps a rule flat, keep the local counterpart flat; nesting support alone is not a reason to reorganize it. +- Before nesting selector lists or sharing a parent rule, confirm that expansion produces exactly the intended selector set. The compiled result must preserve selector specificity, declarations, at-rule context, relative source order, and cascade. If React or Base UI adaptation breaks the one-to-one structure, prefer the clearest semantically equivalent local organization and record meaningful deviations. +- Use only Sass-style nesting syntax supported by the existing `postcss-nested` pipeline. Keep Sass variables, mixins, loops, and interpolation expanded into supported CSS rather than introducing a new preprocessing capability. - When upstream already uses `@apply`, preserve the same utility candidates, variant prefixes, grouping, and source order wherever practical instead of rewriting them into merely equivalent utilities. Deviate only when required by unsupported local utilities or configuration, React or Base UI structure, or cascade and specificity constraints; record meaningful deviations. - Use the same `@apply` approach for exact utility equivalents introduced by React or Base UI adaptations. - Keep native CSS declarations for component-specific tokens, Sass variables/calculations/mixins after expansion, literal values without a meaningful utility, and cases where `@apply` would change cascade, specificity, or source-order behavior. Keep transitive global-style compensation in the appropriate shared layer rather than a component's colocated stylesheet. Do not invent arbitrary utilities merely to eliminate native declarations. -- Component source may contain `@apply`, but the published styles output must contain only compiled CSS. Verify that the styles package build expands every directive and regenerate `packages/styles/dist` rather than editing it directly. +- Component source may contain `@apply` and supported nesting, but the published styles output must contain only fully expanded CSS. Verify that the styles package build expands every directive and nested rule, and regenerate `packages/styles/dist` rather than editing it directly. - Inspect mixin definitions and transitive global styles before replacing them; do not approximate a hidden behavior by appearance alone. - Cover hover, active, focus-visible, disabled, dark theme, forced colors, reduced motion, and responsive behavior only where upstream or shared foundations support them. - Import component CSS from `packages/styles/src/components.css`. Regenerate `packages/styles/dist` with the styles package build; never hand-edit generated output. diff --git a/packages/styles/dist/gitlab-ui.css b/packages/styles/dist/gitlab-ui.css index eec152b..418043b 100644 --- a/packages/styles/dist/gitlab-ui.css +++ b/packages/styles/dist/gitlab-ui.css @@ -2773,31 +2773,31 @@ h1, h2, h3, h4, h5, h6, .h1, .h2, .h3, .h4, .h5, .h6 { a { color: var(--gl-text-color-link); text-decoration-line: none; - &:hover { - @media (hover: hover) { - color: var(--gl-text-color-link); - } +} +@media (hover: hover) { +a:hover { + color: var(--gl-text-color-link) } - &:hover { - @media (hover: hover) { - text-decoration-line: underline; } +@media (hover: hover) { +a:hover { + text-decoration-line: underline } -} + } a:not([href]):not([class]) { color: inherit; text-decoration-line: none; - &:hover { - @media (hover: hover) { - color: inherit; - } +} +@media (hover: hover) { +a:not([href]):not([class]):hover { + color: inherit } - &:hover { - @media (hover: hover) { - text-decoration-line: none; } +@media (hover: hover) { +a:not([href]):not([class]):hover { + text-decoration-line: none } -} + } caption { color: var(--gl-text-color-subtle); } @@ -4032,21 +4032,23 @@ table.gl-table:is( .b-table-stacked, .b-table-stacked-sm, .b-table-stacked-md, . border-radius: var(--gl-alert-border-radius); padding-inline: calc(3rem + var(--gl-alert-padding-x, 0px)); position: relative; - @media (forced-colors: active) { +} +@media (forced-colors: active) { + .gl-alert { border: 1px solid transparent; } - &::before { - content: ""; - display: block; - width: 100%; - height: 2px; - position: absolute; - top: -1px; - left: 0; - } - .gl-link:not(.gl-label-link) { - text-decoration-line: underline; - } +} +.gl-alert::before { + content: ""; + display: block; + width: 100%; + height: 2px; + position: absolute; + top: -1px; + left: 0; +} +.gl-alert .gl-link:not(.gl-label-link) { + text-decoration-line: underline; } .gl-alert-not-dismissible { padding-right: calc(1rem + var(--gl-alert-padding-x, 0px)); @@ -4072,9 +4074,9 @@ table.gl-table:is( .b-table-stacked, .b-table-stacked-sm, .b-table-stacked-md, . display: flex; align-items: center; height: 1.25rem; - .gl-alert-has-title & { - top: calc(0.75rem + 2px); - } +} +.gl-alert-has-title .gl-alert-icon-container { + top: calc(0.75rem + 2px); } .gl-alert-body { --tw-leading: var(--gl-line-height-20); @@ -4117,83 +4119,83 @@ table.gl-table:is( .b-table-stacked, .b-table-stacked-sm, .b-table-stacked-md, . position: absolute; top: calc(0.75rem + 2px); right: calc(0.75rem + var(--gl-alert-padding-x, 0px)); - .gl-alert-has-title & { - top: 0.75rem; - } +} +.gl-alert-has-title .gl-dismiss-btn { + top: 0.75rem; } .gl-alert-danger { background-color: var(--gl-alert-danger-background-color); border-bottom: 1px solid var(--gl-alert-danger-border-bottom-color); - &::before { - background: linear-gradient( to right, transparent 0%, var(--gl-alert-danger-border-top-color) 50%, transparent 100% ); - } - .gl-alert-title { - color: var(--gl-alert-danger-title-color); - } - @media (forced-colors: none) { - .gl-alert-icon { - color: var(--gl-feedback-danger-icon-color); - } +} +.gl-alert-danger::before { + background: linear-gradient( to right, transparent 0%, var(--gl-alert-danger-border-top-color) 50%, transparent 100% ); +} +.gl-alert-danger .gl-alert-title { + color: var(--gl-alert-danger-title-color); +} +@media (forced-colors: none) { + .gl-alert-danger .gl-alert-icon { + color: var(--gl-feedback-danger-icon-color); } } .gl-alert-warning { background-color: var(--gl-alert-warning-background-color); border-bottom: 1px solid var(--gl-alert-warning-border-bottom-color); - &::before { - background: linear-gradient( to right, transparent 0%, var(--gl-alert-warning-border-top-color) 50%, transparent 100% ); - } - .gl-alert-title { - color: var(--gl-alert-warning-title-color); - } - @media (forced-colors: none) { - .gl-alert-icon { - color: var(--gl-feedback-warning-icon-color); - } +} +.gl-alert-warning::before { + background: linear-gradient( to right, transparent 0%, var(--gl-alert-warning-border-top-color) 50%, transparent 100% ); +} +.gl-alert-warning .gl-alert-title { + color: var(--gl-alert-warning-title-color); +} +@media (forced-colors: none) { + .gl-alert-warning .gl-alert-icon { + color: var(--gl-feedback-warning-icon-color); } } .gl-alert-tip { background-color: var(--gl-alert-neutral-background-color); border-bottom: 1px solid var(--gl-alert-neutral-border-bottom-color); - &::before { - background: linear-gradient( to right, transparent 0%, var(--gl-alert-neutral-border-top-color) 50%, transparent 100% ); - } - .gl-alert-title { - color: var(--gl-alert-neutral-title-color); - } - @media (forced-colors: none) { - .gl-alert-icon { - color: var(--gl-feedback-neutral-icon-color); - } +} +.gl-alert-tip::before { + background: linear-gradient( to right, transparent 0%, var(--gl-alert-neutral-border-top-color) 50%, transparent 100% ); +} +.gl-alert-tip .gl-alert-title { + color: var(--gl-alert-neutral-title-color); +} +@media (forced-colors: none) { + .gl-alert-tip .gl-alert-icon { + color: var(--gl-feedback-neutral-icon-color); } } .gl-alert-info { background-color: var(--gl-alert-info-background-color); border-bottom: 1px solid var(--gl-alert-info-border-bottom-color); - &::before { - background: linear-gradient( to right, transparent 0%, var(--gl-alert-info-border-top-color) 50%, transparent 100% ); - } - .gl-alert-title { - color: var(--gl-alert-info-title-color); - } - @media (forced-colors: none) { - .gl-alert-icon { - color: var(--gl-feedback-info-icon-color); - } +} +.gl-alert-info::before { + background: linear-gradient( to right, transparent 0%, var(--gl-alert-info-border-top-color) 50%, transparent 100% ); +} +.gl-alert-info .gl-alert-title { + color: var(--gl-alert-info-title-color); +} +@media (forced-colors: none) { + .gl-alert-info .gl-alert-icon { + color: var(--gl-feedback-info-icon-color); } } .gl-alert-success { background-color: var(--gl-alert-success-background-color); border-bottom: 1px solid var(--gl-alert-success-border-bottom-color); - &::before { - background: linear-gradient( to right, transparent 0%, var(--gl-alert-success-border-top-color) 50%, transparent 100% ); - } - .gl-alert-title { - color: var(--gl-alert-success-title-color); - } - @media (forced-colors: none) { - .gl-alert-icon { - color: var(--gl-feedback-success-icon-color); - } +} +.gl-alert-success::before { + background: linear-gradient( to right, transparent 0%, var(--gl-alert-success-border-top-color) 50%, transparent 100% ); +} +.gl-alert-success .gl-alert-title { + color: var(--gl-alert-success-title-color); +} +@media (forced-colors: none) { + .gl-alert-success .gl-alert-icon { + color: var(--gl-feedback-success-icon-color); } } .gl-attribute-list-container { @@ -4902,104 +4904,104 @@ a.gl-badge.badge-tier:not(.disabled):active, a.gl-badge.badge-tier:not(.disabled padding-left: calc(1rem + var(--gl-broadcast-message-padding-x, 0px)); padding-right: calc(0.75rem + var(--gl-broadcast-message-padding-x, 0px)); padding-block: var(--gl-spacing-scale-5); - &.indigo { - --gl-broadcast-message-bg-color: var(--gl-broadcast-banner-background-color-indigo); - --gl-broadcast-message-border-color: var(--gl-broadcast-banner-border-color-indigo); - --gl-broadcast-message-text-color: var(--gl-broadcast-banner-text-color-indigo); - --gl-broadcast-message-icon-color: var(--gl-broadcast-banner-icon-color-indigo); - } - &.light-indigo { - --gl-broadcast-message-bg-color: var(--gl-broadcast-banner-background-color-lightindigo); - --gl-broadcast-message-border-color: var(--gl-broadcast-banner-border-color-lightindigo); - --gl-broadcast-message-text-color: var(--gl-broadcast-banner-text-color-lightindigo); - --gl-broadcast-message-icon-color: var(--gl-broadcast-banner-icon-color-lightindigo); - } - &.blue { - --gl-broadcast-message-bg-color: var(--gl-broadcast-banner-background-color-blue); - --gl-broadcast-message-border-color: var(--gl-broadcast-banner-border-color-blue); - --gl-broadcast-message-text-color: var(--gl-broadcast-banner-text-color-blue); - --gl-broadcast-message-icon-color: var(--gl-broadcast-banner-icon-color-blue); - } - &.light-blue { - --gl-broadcast-message-bg-color: var(--gl-broadcast-banner-background-color-lightblue); - --gl-broadcast-message-border-color: var(--gl-broadcast-banner-border-color-lightblue); - --gl-broadcast-message-text-color: var(--gl-broadcast-banner-text-color-lightblue); - --gl-broadcast-message-icon-color: var(--gl-broadcast-banner-icon-color-lightblue); - } - &.green { - --gl-broadcast-message-bg-color: var(--gl-broadcast-banner-background-color-green); - --gl-broadcast-message-border-color: var(--gl-broadcast-banner-border-color-green); - --gl-broadcast-message-text-color: var(--gl-broadcast-banner-text-color-green); - --gl-broadcast-message-icon-color: var(--gl-broadcast-banner-icon-color-green); - } - &.light-green { - --gl-broadcast-message-bg-color: var(--gl-broadcast-banner-background-color-lightgreen); - --gl-broadcast-message-border-color: var(--gl-broadcast-banner-border-color-lightgreen); - --gl-broadcast-message-text-color: var(--gl-broadcast-banner-text-color-lightgreen); - --gl-broadcast-message-icon-color: var(--gl-broadcast-banner-icon-color-lightgreen); - } - &.red { - --gl-broadcast-message-bg-color: var(--gl-broadcast-banner-background-color-red); - --gl-broadcast-message-border-color: var(--gl-broadcast-banner-border-color-red); - --gl-broadcast-message-text-color: var(--gl-broadcast-banner-text-color-red); - --gl-broadcast-message-icon-color: var(--gl-broadcast-banner-icon-color-red); - } - &.light-red { - --gl-broadcast-message-bg-color: var(--gl-broadcast-banner-background-color-lightred); - --gl-broadcast-message-border-color: var(--gl-broadcast-banner-border-color-lightred); - --gl-broadcast-message-text-color: var(--gl-broadcast-banner-text-color-lightred); - --gl-broadcast-message-icon-color: var(--gl-broadcast-banner-icon-color-lightred); - } - &.dark { - --gl-broadcast-message-bg-color: var(--gl-broadcast-banner-background-color-dark); - --gl-broadcast-message-border-color: var(--gl-broadcast-banner-border-color-dark); - --gl-broadcast-message-text-color: var(--gl-broadcast-banner-text-color-dark); - --gl-broadcast-message-icon-color: var(--gl-broadcast-banner-icon-color-dark); - } - &.light { - --gl-broadcast-message-bg-color: var(--gl-broadcast-banner-background-color-light); - --gl-broadcast-message-border-color: var(--gl-broadcast-banner-border-color-light); - --gl-broadcast-message-text-color: var(--gl-broadcast-banner-text-color-light); - --gl-broadcast-message-icon-color: var(--gl-broadcast-banner-icon-color-light); - } - &[class~="banner"] { - background-color: var(--gl-broadcast-message-bg-color); - box-shadow: inset 0 -1px 0 0 var(--gl-broadcast-message-border-color); - color: var(--gl-broadcast-message-text-color); - .gl-broadcast-message-icon { - color: var(--gl-broadcast-message-icon-color); - } - } - &.notification { - border-style: var(--tw-border-style); - border-width: 1px; - border-style: solid; - border-color: var(--gl-border-color-default); - --tw-shadow: var(--gl-shadow-md); - box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow); - background-color: var(--gl-background-color-overlap); - color: var(--gl-text-color-default); - border-radius: var(--gl-broadcast-banner-border-radius); - max-width: 18.75rem; - } +} +.gl-broadcast-message.indigo { + --gl-broadcast-message-bg-color: var(--gl-broadcast-banner-background-color-indigo); + --gl-broadcast-message-border-color: var(--gl-broadcast-banner-border-color-indigo); + --gl-broadcast-message-text-color: var(--gl-broadcast-banner-text-color-indigo); + --gl-broadcast-message-icon-color: var(--gl-broadcast-banner-icon-color-indigo); +} +.gl-broadcast-message.light-indigo { + --gl-broadcast-message-bg-color: var(--gl-broadcast-banner-background-color-lightindigo); + --gl-broadcast-message-border-color: var(--gl-broadcast-banner-border-color-lightindigo); + --gl-broadcast-message-text-color: var(--gl-broadcast-banner-text-color-lightindigo); + --gl-broadcast-message-icon-color: var(--gl-broadcast-banner-icon-color-lightindigo); +} +.gl-broadcast-message.blue { + --gl-broadcast-message-bg-color: var(--gl-broadcast-banner-background-color-blue); + --gl-broadcast-message-border-color: var(--gl-broadcast-banner-border-color-blue); + --gl-broadcast-message-text-color: var(--gl-broadcast-banner-text-color-blue); + --gl-broadcast-message-icon-color: var(--gl-broadcast-banner-icon-color-blue); +} +.gl-broadcast-message.light-blue { + --gl-broadcast-message-bg-color: var(--gl-broadcast-banner-background-color-lightblue); + --gl-broadcast-message-border-color: var(--gl-broadcast-banner-border-color-lightblue); + --gl-broadcast-message-text-color: var(--gl-broadcast-banner-text-color-lightblue); + --gl-broadcast-message-icon-color: var(--gl-broadcast-banner-icon-color-lightblue); +} +.gl-broadcast-message.green { + --gl-broadcast-message-bg-color: var(--gl-broadcast-banner-background-color-green); + --gl-broadcast-message-border-color: var(--gl-broadcast-banner-border-color-green); + --gl-broadcast-message-text-color: var(--gl-broadcast-banner-text-color-green); + --gl-broadcast-message-icon-color: var(--gl-broadcast-banner-icon-color-green); +} +.gl-broadcast-message.light-green { + --gl-broadcast-message-bg-color: var(--gl-broadcast-banner-background-color-lightgreen); + --gl-broadcast-message-border-color: var(--gl-broadcast-banner-border-color-lightgreen); + --gl-broadcast-message-text-color: var(--gl-broadcast-banner-text-color-lightgreen); + --gl-broadcast-message-icon-color: var(--gl-broadcast-banner-icon-color-lightgreen); +} +.gl-broadcast-message.red { + --gl-broadcast-message-bg-color: var(--gl-broadcast-banner-background-color-red); + --gl-broadcast-message-border-color: var(--gl-broadcast-banner-border-color-red); + --gl-broadcast-message-text-color: var(--gl-broadcast-banner-text-color-red); + --gl-broadcast-message-icon-color: var(--gl-broadcast-banner-icon-color-red); +} +.gl-broadcast-message.light-red { + --gl-broadcast-message-bg-color: var(--gl-broadcast-banner-background-color-lightred); + --gl-broadcast-message-border-color: var(--gl-broadcast-banner-border-color-lightred); + --gl-broadcast-message-text-color: var(--gl-broadcast-banner-text-color-lightred); + --gl-broadcast-message-icon-color: var(--gl-broadcast-banner-icon-color-lightred); +} +.gl-broadcast-message.dark { + --gl-broadcast-message-bg-color: var(--gl-broadcast-banner-background-color-dark); + --gl-broadcast-message-border-color: var(--gl-broadcast-banner-border-color-dark); + --gl-broadcast-message-text-color: var(--gl-broadcast-banner-text-color-dark); + --gl-broadcast-message-icon-color: var(--gl-broadcast-banner-icon-color-dark); +} +.gl-broadcast-message.light { + --gl-broadcast-message-bg-color: var(--gl-broadcast-banner-background-color-light); + --gl-broadcast-message-border-color: var(--gl-broadcast-banner-border-color-light); + --gl-broadcast-message-text-color: var(--gl-broadcast-banner-text-color-light); + --gl-broadcast-message-icon-color: var(--gl-broadcast-banner-icon-color-light); +} +.gl-broadcast-message[class~="banner"] { + background-color: var(--gl-broadcast-message-bg-color); + box-shadow: inset 0 -1px 0 0 var(--gl-broadcast-message-border-color); + color: var(--gl-broadcast-message-text-color); +} +.gl-broadcast-message[class~="banner"] .gl-broadcast-message-icon { + color: var(--gl-broadcast-message-icon-color); +} +.gl-broadcast-message.notification { + border-style: var(--tw-border-style); + border-width: 1px; + border-style: solid; + border-color: var(--gl-border-color-default); + --tw-shadow: var(--gl-shadow-md); + box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow); + background-color: var(--gl-background-color-overlap); + color: var(--gl-text-color-default); + border-radius: var(--gl-broadcast-banner-border-radius); + max-width: 18.75rem; } .gl-broadcast-message-content { display: flex; justify-content: center; - a { - color: inherit; - text-decoration-line: underline; - } - p:last-of-type { - margin-bottom: var(--gl-spacing-scale-0); - } +} +.gl-broadcast-message-content a { + color: inherit; + text-decoration-line: underline; +} +.gl-broadcast-message-content p:last-of-type { + margin-bottom: var(--gl-spacing-scale-0); } .gl-broadcast-message-icon { margin-right: var(--gl-spacing-scale-5); line-height: 1rem; - > svg { - vertical-align: bottom; - } +} +.gl-broadcast-message-icon > svg { + vertical-align: bottom; } .gl-broadcast-message-text { margin-top: -0.125rem; @@ -5481,9 +5483,13 @@ a.gl-badge.badge-tier:not(.disabled):active, a.gl-badge.badge-tier:not(.disabled --tw-border-style: solid; border-style: solid; border-color: transparent; - @media (prefers-contrast: more) { +} +@media (prefers-contrast: more) { +.gl-card { border-color: var(--gl-border-color-strong); +} } +.gl-card{ display: flex; flex-direction: column; overflow-wrap: break-word; @@ -5502,32 +5508,42 @@ a.gl-badge.badge-tier:not(.disabled):active, a.gl-badge.badge-tier:not(.disabled margin-block: var(--gl-spacing-scale-1); border-top-left-radius: calc(var(--gl-card-border-radius) - 1px); border-top-right-radius: calc(var(--gl-card-border-radius) - 1px); - h2, h3, h4, h5, h6 { - font-size: var(--gl-font-size-base); - color: var(--gl-text-color-heading); - margin: var(--gl-spacing-scale-0); - } +} +.gl-card-header h2, .gl-card-header h3, .gl-card-header h4, .gl-card-header h5, .gl-card-header h6 { + font-size: var(--gl-font-size-base); + color: var(--gl-text-color-heading); + margin: var(--gl-spacing-scale-0); } .gl-card-body { flex-grow: 1; padding: var(--gl-spacing-scale-3); background-color: var(--gl-background-color-default); - @media (prefers-contrast: more) { +} +@media (prefers-contrast: more) { +.gl-card-body { border-style: var(--tw-border-style); border-width: 1px; +} } - @media (prefers-contrast: more) { +@media (prefers-contrast: more) { +.gl-card-body { border-style: solid; border-color: var(--gl-border-color-default); +} } - @media (forced-colors: active) { +@media (forced-colors: active) { +.gl-card-body { border-style: var(--tw-border-style); border-width: 1px; +} } - @media (forced-colors: active) { +@media (forced-colors: active) { +.gl-card-body { border-style: solid; border-color: var(--gl-border-color-default); +} } +.gl-card-body{ border-radius: calc(var(--gl-card-border-radius) - 0.25rem); } .gl-card-footer { @@ -6904,12 +6920,22 @@ table.gl-table.table-borderless tr > :is(th, td) { background-color: var(--gl-skeleton-loader-background-color); background-image: linear-gradient(to right, var(--gl-skeleton-loader-background-color) 0, var(--gl-skeleton-loader-shimmer-color) 23%, var(--gl-skeleton-loader-shimmer-color) 27%, var(--gl-skeleton-loader-background-color) 50%); background-repeat: no-repeat; - @media (prefers-reduced-motion: no-preference) { +} +@media (prefers-reduced-motion: no-preference) { +.gl-animate-skeleton-loader { animation: gl-keyframes-skeleton-loader 2.5s linear; animation-delay: inherit; - animation-iteration-count: 3; - } + animation-iteration-count: 3 } + } +@keyframes gl-keyframes-skeleton-loader { + 0% { + background-position-x: -32rem; + } + 100% { + background-position-x: 32rem; + } + } .\!gl-max-w-20 { max-width: var(--gl-spacing-scale-20) !important; } @@ -7306,11 +7332,3 @@ table.gl-table.table-borderless tr > :is(th, td) { } } } -@keyframes gl-keyframes-skeleton-loader { - 0% { - background-position-x: -32rem; - } - 100% { - background-position-x: 32rem; - } -} diff --git a/packages/styles/package.json b/packages/styles/package.json index 2f28905..ecac0af 100644 --- a/packages/styles/package.json +++ b/packages/styles/package.json @@ -23,6 +23,7 @@ "@tailwindcss/node": "4.3.3", "@tailwindcss/oxide": "4.3.3", "postcss": "^8.5.26", + "postcss-nested": "^8.0.1", "postcss-selector-parser": "7.1.0", "tailwindcss": "^4.3.3" }, diff --git a/packages/styles/postcss.config.mjs b/packages/styles/postcss.config.mjs index 79aff69..ee9aacc 100644 --- a/packages/styles/postcss.config.mjs +++ b/packages/styles/postcss.config.mjs @@ -1,5 +1,12 @@ +import postcssNested from "postcss-nested"; + import gitlabTailwind from "./scripts/postcss-gitlab-tailwind.mjs"; +/** @internal */ +export function createPostcssPlugins(tailwindOptions) { + return [gitlabTailwind(tailwindOptions), postcssNested()]; +} + export default { - plugins: [gitlabTailwind()], + plugins: createPostcssPlugins(), }; diff --git a/packages/styles/scripts/fixtures/nesting-forms.css b/packages/styles/scripts/fixtures/nesting-forms.css new file mode 100644 index 0000000..f61cbba --- /dev/null +++ b/packages/styles/scripts/fixtures/nesting-forms.css @@ -0,0 +1,40 @@ +.nesting-fixture, +.nesting-alternate { + color: black; + + &:hover, + &.selected { + color: blue; + } + + &-suffix { + @apply gl-relative; + color: green; + } + + .descendant { + display: inline; + } + + > .child, + + .adjacent, + ~ .sibling { + display: block; + } + + .ancestor & { + color: red; + } + + @media (width >= 40rem) { + color: purple; + } + + @supports (display: grid) { + display: grid; + } + + @container (width >= 20rem) { + inline-size: 100%; + } +} diff --git a/packages/styles/scripts/fixtures/nesting.css b/packages/styles/scripts/fixtures/nesting.css new file mode 100644 index 0000000..5d38431 --- /dev/null +++ b/packages/styles/scripts/fixtures/nesting.css @@ -0,0 +1,5 @@ +.imported-nesting-fixture { + &-suffix { + color: green; + } +} diff --git a/packages/styles/scripts/form-foundations.test.mjs b/packages/styles/scripts/form-foundations.test.mjs index 8ae1f15..1c403dd 100644 --- a/packages/styles/scripts/form-foundations.test.mjs +++ b/packages/styles/scripts/form-foundations.test.mjs @@ -4,7 +4,7 @@ import { fileURLToPath } from "node:url"; import postcss from "postcss"; import selectorParser from "postcss-selector-parser"; import { expect, test } from "vitest"; -import gitlabTailwind from "./postcss-gitlab-tailwind.mjs"; +import { createPostcssPlugins } from "../postcss.config.mjs"; const packageDirectory = path.resolve(path.dirname(fileURLToPath(import.meta.url)), ".."); const inputPath = path.join(packageDirectory, "src/index.css"); @@ -12,11 +12,11 @@ const fixtureDirectory = path.join(packageDirectory, "scripts/fixtures"); async function compile() { const input = await readFile(inputPath, "utf8"); - const result = await postcss([ - gitlabTailwind({ + const result = await postcss( + createPostcssPlugins({ sources: [{ base: fixtureDirectory, pattern: "*.html", negated: false }], }), - ]).process(input, { from: inputPath }); + ).process(input, { from: inputPath }); return postcss.parse(result.css); } diff --git a/packages/styles/scripts/legacy-prefix.test.mjs b/packages/styles/scripts/legacy-prefix.test.mjs index d519770..5e20aa5 100644 --- a/packages/styles/scripts/legacy-prefix.test.mjs +++ b/packages/styles/scripts/legacy-prefix.test.mjs @@ -2,9 +2,10 @@ import { readFile } from "node:fs/promises"; import path from "node:path"; import { fileURLToPath } from "node:url"; import postcss from "postcss"; +import selectorParser from "postcss-selector-parser"; import { expect, test } from "vitest"; +import { createPostcssPlugins } from "../postcss.config.mjs"; import { toTailwindCandidate } from "./legacy-prefix.mjs"; -import gitlabTailwind from "./postcss-gitlab-tailwind.mjs"; const packageDirectory = path.resolve(path.dirname(fileURLToPath(import.meta.url)), ".."); const inputPath = path.join(packageDirectory, "src/index.css"); @@ -22,11 +23,11 @@ test("converts upstream gl-* candidates without changing variant order", () => { test("compiles @apply and restores upstream gl-* selectors", async () => { const input = await readFile(inputPath, "utf8"); - const result = await postcss([ - gitlabTailwind({ + const result = await postcss( + createPostcssPlugins({ sources: [{ base: fixtureDirectory, pattern: "*.html", negated: false }], }), - ]).process(input, { from: inputPath }); + ).process(input, { from: inputPath }); expect(result.css).not.toMatch(/@apply/u); expect(result.css).toMatch(/body\s*\{[^}]*background-color:/su); @@ -40,30 +41,130 @@ test("compiles @apply and restores upstream gl-* selectors", async () => { expect(result.css).not.toMatch(/:where\(\.gl-dark \*\)/u); }, 30000); -test("hoists plugin keyframes while preserving nested media rules", async () => { +test("expands nested media rules", async () => { const input = await readFile(inputPath, "utf8"); - const result = await postcss([ - gitlabTailwind({ candidates: ["animate-skeleton-loader"] }), - ]).process(input, { from: inputPath }); + const result = await postcss( + createPostcssPlugins({ candidates: ["animate-skeleton-loader"] }), + ).process(input, { from: inputPath }); const root = postcss.parse(result.css); const skeletonRule = root.nodes.find( (node) => node.type === "rule" && node.selector === ".gl-animate-skeleton-loader", ); - const keyframes = root.nodes.find( - (node) => node.type === "atrule" - && node.name === "keyframes" - && node.params === "gl-keyframes-skeleton-loader", - ); - expect(skeletonRule).toBeDefined(); expect(skeletonRule.nodes.some( (node) => node.type === "atrule" && node.name === "media", - )).toBe(true); - expect(skeletonRule.nodes.some( - (node) => node.type === "atrule" && node.name === "keyframes", )).toBe(false); - expect(keyframes).toBeDefined(); - expect(result.css).toContain( - "\n@keyframes gl-keyframes-skeleton-loader {\n 0% {", + const reducedMotionRules = root.nodes + .filter( + (node) => node.type === "atrule" + && node.name === "media" + && node.params.includes("prefers-reduced-motion"), + ) + .flatMap((node) => node.nodes ?? []); + expect(reducedMotionRules.some( + (node) => node.type === "rule" && node.selector === ".gl-animate-skeleton-loader", + )).toBe(true); +}, 30000); + +test("expands the Sass-like nesting forms used by upstream styles", async () => { + const inputPath = path.join(fixtureDirectory, "nesting-forms.css"); + const input = await readFile(inputPath, "utf8"); + const result = await postcss(createPostcssPlugins()).process(input, { from: inputPath }); + const root = postcss.parse(result.css); + expect(result.css).not.toMatch(/@apply/u); + const selectorsForDeclaration = (property, value, container = root) => { + const selectors = []; + container.walkRules((rule) => { + if(rule.nodes.some( + (node) => node.type === "decl" && node.prop === property && node.value === value, + )) selectors.push(...rule.selectors); + }); + return selectors.sort(); + }; + const findAtRule = (name) => root.nodes.find( + (node) => node.type === "atrule" && node.name === name, + ); + + expect(selectorsForDeclaration("color", "blue")).toEqual([ + ".nesting-alternate.selected", + ".nesting-alternate:hover", + ".nesting-fixture.selected", + ".nesting-fixture:hover", + ]); + expect(selectorsForDeclaration("color", "green")).toEqual([ + ".nesting-alternate-suffix", + ".nesting-fixture-suffix", + ]); + expect(selectorsForDeclaration("display", "inline")).toEqual([ + ".nesting-alternate .descendant", + ".nesting-fixture .descendant", + ]); + expect(selectorsForDeclaration("display", "block")).toEqual([ + ".nesting-alternate + .adjacent", + ".nesting-alternate > .child", + ".nesting-alternate ~ .sibling", + ".nesting-fixture + .adjacent", + ".nesting-fixture > .child", + ".nesting-fixture ~ .sibling", + ]); + expect(selectorsForDeclaration("color", "red")).toEqual([ + ".ancestor .nesting-alternate", + ".ancestor .nesting-fixture", + ]); + + const media = findAtRule("media"); + const supports = findAtRule("supports"); + const container = findAtRule("container"); + expect(media?.params).toBe("(width >= 40rem)"); + expect(supports?.params).toBe("(display: grid)"); + expect(container?.params).toBe("(width >= 20rem)"); + expect(selectorsForDeclaration("color", "purple", media)).toEqual([ + ".nesting-alternate", + ".nesting-fixture", + ]); + expect(selectorsForDeclaration("display", "grid", supports)).toEqual([ + ".nesting-alternate", + ".nesting-fixture", + ]); + expect(selectorsForDeclaration("inline-size", "100%", container)).toEqual([ + ".nesting-alternate", + ".nesting-fixture", + ]); +}); + +test("expands suffix nesting in imported stylesheets before Tailwind parses it", async () => { + const from = path.join(packageDirectory, "scripts/nesting-entry.css"); + const result = await postcss(createPostcssPlugins()).process( + "@import \"./fixtures/nesting.css\";", + { from }, ); + + expect(result.css).toContain(".imported-nesting-fixture-suffix {"); + expect(result.css).not.toContain(":is(.imported-nesting-fixture)-suffix"); +}); + +test("published stylesheet contains only expanded rules", async () => { + const input = await readFile(inputPath, "utf8"); + const result = await postcss(createPostcssPlugins()).process(input, { from: inputPath }); + const root = postcss.parse(result.css); + const nestedRules = []; + const nestedAtRules = []; + const nestingSelectors = []; + + root.walkRules((rule) => { + if(rule.parent?.type === "rule") nestedRules.push(rule.selector); + selectorParser((selectorRoot) => { + selectorRoot.walkNesting(() => nestingSelectors.push(rule.selector)); + }).processSync(rule.selector); + }); + root.walkAtRules((atRule) => { + if(atRule.parent?.type === "rule") nestedAtRules.push(`@${atRule.name} ${atRule.params}`); + }); + + expect(result.css).not.toMatch(/@apply/u); + expect(result.css).toContain(".gl-alert-danger {"); + expect(result.css).not.toContain(":is(.gl-alert)-danger"); + expect(nestedRules).toEqual([]); + expect(nestedAtRules).toEqual([]); + expect(nestingSelectors).toEqual([]); }, 30000); diff --git a/packages/styles/scripts/postcss-gitlab-tailwind.mjs b/packages/styles/scripts/postcss-gitlab-tailwind.mjs index fd9a078..6f31b15 100644 --- a/packages/styles/scripts/postcss-gitlab-tailwind.mjs +++ b/packages/styles/scripts/postcss-gitlab-tailwind.mjs @@ -4,6 +4,7 @@ import path from "node:path"; import { loadModule } from "@tailwindcss/node"; import { Scanner } from "@tailwindcss/oxide"; +import postcssNested from "postcss-nested"; import { compile } from "tailwindcss"; import { @@ -33,31 +34,19 @@ function compilerSources(compiler, base) { return sources; } -function removeOneIndentLevel(node) { - for(const property of ["before", "after"]) { - const rawValue = node.raws[property]; - if(typeof rawValue === "string") { - node.raws[property] = rawValue.replace(/(\r?\n) {2}/gu, "$1"); - } - } - - for(const child of node.nodes ?? []) removeOneIndentLevel(child); -} - -function hoistKeyframesFromStyleRules(root) { - const keyframesToHoist = []; - - root.walkAtRules((atRule) => { - if(!atRule.name.endsWith("keyframes") || atRule.parent?.type !== "rule") return; - - atRule.remove(); - atRule.raws.before = "\n"; - atRule.raws.after = "\n"; - for(const child of atRule.nodes ?? []) removeOneIndentLevel(child); - keyframesToHoist.push(atRule); +async function prepareStylesheet(postcss, content, from) { + // Tailwind parses stylesheets before downstream PostCSS plugins run, and + // bundlers such as Vite may inline imports into the entry AST first. Expand + // source nesting here so Sass-style selectors such as `&-suffix` survive + // Tailwind's `@apply` pass; the configured postcss-nested pass still handles + // any nesting left in Tailwind's completed AST. + const rewritten = rewriteLegacyApplyDirectives(content, from); + const result = await postcss([postcssNested()]).process(rewritten, { + from, + map: false, }); - root.append(keyframesToHoist); + return result.css; } export default function gitlabTailwind({ candidates = [], sources: additionalSources = [] } = {}) { @@ -67,7 +56,7 @@ export default function gitlabTailwind({ candidates = [], sources: additionalSou const from = result.opts.from ? path.resolve(result.opts.from) : undefined; const base = from ? path.dirname(from) : process.cwd(); const dependencies = new Set(); - const input = rewriteLegacyApplyDirectives(root.toString(), from); + const input = await prepareStylesheet(postcss, root.toString(), from); const compiler = await compile(input, { base, @@ -89,7 +78,7 @@ export default function gitlabTailwind({ candidates = [], sources: additionalSou return { path: stylesheetPath, base: path.dirname(stylesheetPath), - content: rewriteLegacyApplyDirectives(content, stylesheetPath), + content: await prepareStylesheet(postcss, content, stylesheetPath), }; }, }); @@ -101,9 +90,6 @@ export default function gitlabTailwind({ candidates = [], sources: additionalSou const compiledRoot = postcss.parse(css, { from }); restoreLegacySelectors(compiledRoot, candidateMap); - // Tailwind 4 preserves plugin-authored nested keyframes, but production - // CSS minifiers expect keyframes at the stylesheet root. - hoistKeyframesFromStyleRules(compiledRoot); root.removeAll(); root.append(compiledRoot.nodes); diff --git a/packages/styles/src/dropdowns/new-dropdown.css b/packages/styles/src/dropdowns/new-dropdown.css index a6b63ff..a04d33d 100644 --- a/packages/styles/src/dropdowns/new-dropdown.css +++ b/packages/styles/src/dropdowns/new-dropdown.css @@ -15,52 +15,58 @@ @apply gl-block gl-w-full; } -.gl-new-dropdown .gl-new-dropdown-toggle.gl-button:not(.gl-new-dropdown-toggle-no-caret, .btn-icon) { - @apply gl-pr-3; -} +.gl-new-dropdown { + .gl-new-dropdown-toggle.gl-button:not(.gl-new-dropdown-toggle-no-caret, .btn-icon) { + @apply gl-pr-3; + } -.gl-new-dropdown .gl-new-dropdown-toggle.gl-button.btn-sm:not(.gl-new-dropdown-toggle-no-caret, .btn-icon) { - @apply gl-pr-2; -} + .gl-new-dropdown-toggle.gl-button.btn-sm:not(.gl-new-dropdown-toggle-no-caret, .btn-icon) { + @apply gl-pr-2; + } -.gl-new-dropdown .gl-new-dropdown-toggle .gl-button-text { - @apply gl-inline-flex gl-items-center; -} + .gl-new-dropdown-toggle { + .gl-button-text { + @apply gl-inline-flex gl-items-center; -.gl-new-dropdown .gl-new-dropdown-toggle .gl-button-text:has(.gl-sr-only) { - width: auto; -} + &:has(.gl-sr-only) { + width: auto; + } + } + } -.gl-new-dropdown .gl-new-dropdown-button-text { - @apply gl-mr-auto gl-overflow-hidden gl-text-ellipsis; -} + .gl-new-dropdown-button-text { + @apply gl-mr-auto gl-overflow-hidden gl-text-ellipsis; + } -.gl-new-dropdown .gl-button:not(.gl-new-dropdown-caret-only) .gl-button-icon.gl-new-dropdown-chevron { - @apply gl-ml-2 gl-mr-0; -} + .gl-button:not(.gl-new-dropdown-caret-only) .gl-button-icon.gl-new-dropdown-chevron { + @apply gl-ml-2 gl-mr-0; + } -.gl-new-dropdown .gl-new-dropdown-icon-only.gl-button:not(.gl-new-dropdown-toggle-no-caret) { - @apply gl-pl-3 gl-pr-2; -} + .gl-new-dropdown-icon-only { + &.gl-button:not(.gl-new-dropdown-toggle-no-caret) { + @apply gl-pl-3 gl-pr-2; + } -.gl-new-dropdown .gl-new-dropdown-icon-only.gl-button.btn-sm:not(.gl-new-dropdown-toggle-no-caret) { - @apply gl-pr-0; -} + &.gl-button.btn-sm:not(.gl-new-dropdown-toggle-no-caret) { + @apply gl-pr-0; + } -.gl-new-dropdown .gl-new-dropdown-icon-only .gl-button-icon.gl-button-icon { - @apply gl-mr-0; -} + .gl-button-icon.gl-button-icon { + @apply gl-mr-0; + } -.gl-new-dropdown .gl-new-dropdown-icon-only .gl-button-icon.gl-button-loading-indicator { - @apply gl-mr-2; -} + .gl-button-icon.gl-button-loading-indicator { + @apply gl-mr-2; + } + } -.gl-new-dropdown .gl-new-dropdown-caret-only { - @apply gl-pl-2; -} + .gl-new-dropdown-caret-only { + @apply gl-pl-2; -.gl-new-dropdown .gl-new-dropdown-caret-only.btn-sm { - @apply gl-pl-0; + &.btn-sm { + @apply gl-pl-0; + } + } } .gl-new-dropdown-container { @@ -122,89 +128,91 @@ - 0.5rem ) ); -} -.gl-new-dropdown-contents:focus-visible { - box-shadow: - 0 0 0 1px var(--gl-focus-ring-inner-color), - 0 0 0 3px var(--gl-focus-ring-outer-color); - outline: none; -} + &:focus-visible { + box-shadow: + 0 0 0 1px var(--gl-focus-ring-inner-color), + 0 0 0 3px var(--gl-focus-ring-outer-color); + outline: none; + } -.gl-new-dropdown-contents ul { - @apply gl-list-none; + ul { + @apply gl-list-none; + } } .gl-new-dropdown-contents-with-scrim-overlay { padding: 0; } -.gl-new-dropdown-contents .top-scrim-wrapper, -.gl-new-dropdown-contents .bottom-scrim-wrapper { - position: sticky; - right: 1px; - left: 1px; - z-index: 1; - display: block; - height: 0.25rem; - overflow: visible; - pointer-events: none; - opacity: 0; - transition: opacity 0.1s; -} +.gl-new-dropdown-contents { + .top-scrim-wrapper, + .bottom-scrim-wrapper { + position: sticky; + right: 1px; + left: 1px; + z-index: 1; + display: block; + height: 0.25rem; + overflow: visible; + pointer-events: none; + opacity: 0; + transition: opacity 0.1s; + } -.gl-new-dropdown-contents .top-scrim-wrapper { - top: 0; -} + .top-scrim-wrapper { + top: 0; + } -.gl-new-dropdown-contents .top-scrim { - position: absolute; - right: 0; - left: 0; -} + .top-scrim { + position: absolute; + right: 0; + left: 0; + } -.gl-new-dropdown-contents .top-scrim-light { - height: 2.25rem; - background: linear-gradient( - 180deg, - var(--gl-dropdown-background-color) 0%, - var(--gl-color-alpha-0) - ); - border-radius: 0.375rem 0.375rem 0 0; -} + .top-scrim-light { + height: 2.25rem; + background: linear-gradient( + 180deg, + var(--gl-dropdown-background-color) 0%, + var(--gl-color-alpha-0) + ); + border-radius: 0.375rem 0.375rem 0 0; + } -.gl-new-dropdown-contents .top-scrim-dark { - height: 0.25rem; - background: linear-gradient( - 180deg, - var(--gl-shadow-color-default) 0%, - var(--gl-color-alpha-0) 100% - ); -} + .top-scrim-dark { + height: 0.25rem; + background: linear-gradient( + 180deg, + var(--gl-shadow-color-default) 0%, + var(--gl-color-alpha-0) 100% + ); + } -.gl-new-dropdown-contents .bottom-scrim-wrapper { - bottom: 0; -} + .bottom-scrim-wrapper { + bottom: 0; + } -.gl-new-dropdown-contents .bottom-scrim { - position: relative; - top: -2rem; - height: 0; - background: linear-gradient( - 180deg, - var(--gl-color-alpha-0) 0%, - var(--gl-dropdown-background-color) - ); - border-radius: 0 0 0.375rem 0.375rem; -} + .bottom-scrim { + position: relative; + top: -2rem; + height: 0; + background: linear-gradient( + 180deg, + var(--gl-color-alpha-0) 0%, + var(--gl-dropdown-background-color) + ); + border-radius: 0 0 0.375rem 0.375rem; + } -.gl-new-dropdown-contents.top-scrim-visible .top-scrim-wrapper, -.gl-new-dropdown-contents.bottom-scrim-visible .bottom-scrim-wrapper { - opacity: 1; -} + &.top-scrim-visible .top-scrim-wrapper, + &.bottom-scrim-visible .bottom-scrim-wrapper { + opacity: 1; + } -.gl-new-dropdown-contents.bottom-scrim-visible .bottom-scrim { - height: 2.25rem; + &.bottom-scrim-visible .bottom-scrim { + height: 2.25rem; + } } .gl-new-dropdown-arrow { @@ -273,102 +281,96 @@ box-shadow 0.2s cubic-bezier(0.22, 0.61, 0.36, 1); } -.gl-new-dropdown-item:not([data-disabled]):hover > .gl-new-dropdown-item-content { - color: var(--gl-dropdown-option-text-color-hover); - background-color: var(--gl-dropdown-option-background-color-unselected-hover); -} - -.gl-new-dropdown-item:not([data-disabled])[data-highlighted] > .gl-new-dropdown-item-content, -.gl-new-dropdown-item:not([data-disabled]):focus-visible > .gl-new-dropdown-item-content { - color: var(--gl-dropdown-option-text-color-focus); - background-color: var(--gl-dropdown-option-background-color-unselected-focus); -} - -.gl-new-dropdown-item:not([data-disabled]):active > .gl-new-dropdown-item-content, -.gl-new-dropdown-item:not([data-disabled]):focus-visible > .gl-new-dropdown-item-content, -.gl-new-dropdown-item:not([data-disabled]):focus-visible:active > .gl-new-dropdown-item-content { - box-shadow: - inset 0 0 0 2px var(--gl-focus-ring-outer-color), - inset 0 0 0 3px var(--gl-focus-ring-inner-color), - inset 0 0 0 1px var(--gl-focus-ring-inner-color); -} - -.gl-new-dropdown-item:not([data-disabled]):focus-visible > .gl-new-dropdown-item-content { - z-index: 1; -} - -.gl-new-dropdown-item:not([data-disabled]):active > .gl-new-dropdown-item-content, -.gl-new-dropdown-item:not([data-disabled]):focus-visible:active > .gl-new-dropdown-item-content { - color: var(--gl-dropdown-option-text-color-active); - background-color: var(--gl-dropdown-option-background-color-unselected-active); -} - -.gl-new-dropdown-item[data-disabled] { - @apply gl-cursor-not-allowed gl-select-none; -} - -.gl-new-dropdown-item[data-disabled] > .gl-new-dropdown-item-content { - color: var(--gl-text-color-disabled); - pointer-events: none; -} - -.gl-new-dropdown-item[aria-selected="true"] > .gl-new-dropdown-item-content { - background-color: var(--gl-dropdown-option-background-color-selected-default); -} +.gl-new-dropdown-item { + &:not([data-disabled]):hover > .gl-new-dropdown-item-content { + color: var(--gl-dropdown-option-text-color-hover); + background-color: var(--gl-dropdown-option-background-color-unselected-hover); + } -.gl-new-dropdown-item[aria-selected="true"][data-disabled] - > .gl-new-dropdown-item-content, -.gl-new-dropdown-item[aria-selected="true"].disabled - > .gl-new-dropdown-item-content { - background-color: var(--gl-background-color-disabled); -} + &:not([data-disabled])[data-highlighted] > .gl-new-dropdown-item-content, + &:not([data-disabled]):focus-visible > .gl-new-dropdown-item-content { + color: var(--gl-dropdown-option-text-color-focus); + background-color: var(--gl-dropdown-option-background-color-unselected-focus); + } -.gl-new-dropdown-item[aria-selected="true"]:not([data-disabled], .disabled):hover - > .gl-new-dropdown-item-content { - background-color: var(--gl-dropdown-option-background-color-selected-hover); -} + &:not([data-disabled]):active > .gl-new-dropdown-item-content, + &:not([data-disabled]):focus-visible > .gl-new-dropdown-item-content, + &:not([data-disabled]):focus-visible:active > .gl-new-dropdown-item-content { + box-shadow: + inset 0 0 0 2px var(--gl-focus-ring-outer-color), + inset 0 0 0 3px var(--gl-focus-ring-inner-color), + inset 0 0 0 1px var(--gl-focus-ring-inner-color); + } -.gl-new-dropdown-item[aria-selected="true"]:not([data-disabled], .disabled):hover - .gl-new-dropdown-item-check-icon { - color: var(--gl-dropdown-option-indicator-color-selected-hover); -} + &:not([data-disabled]):focus-visible > .gl-new-dropdown-item-content { + z-index: 1; + } -.gl-new-dropdown-item[aria-selected="true"]:not([data-disabled], .disabled)[data-highlighted] - > .gl-new-dropdown-item-content, -.gl-new-dropdown-item[aria-selected="true"]:not([data-disabled], .disabled):focus-visible - > .gl-new-dropdown-item-content { - background-color: var(--gl-dropdown-option-background-color-selected-focus); -} + &:not([data-disabled]):active > .gl-new-dropdown-item-content, + &:not([data-disabled]):focus-visible:active > .gl-new-dropdown-item-content { + color: var(--gl-dropdown-option-text-color-active); + background-color: var(--gl-dropdown-option-background-color-unselected-active); + } -.gl-new-dropdown-item[aria-selected="true"]:not([data-disabled], .disabled)[data-highlighted] - .gl-new-dropdown-item-check-icon, -.gl-new-dropdown-item[aria-selected="true"]:not([data-disabled], .disabled):focus-visible - .gl-new-dropdown-item-check-icon { - color: var(--gl-dropdown-option-indicator-color-selected-focus); -} + &[data-disabled] { + @apply gl-cursor-not-allowed gl-select-none; -.gl-new-dropdown-item[aria-selected="true"]:not([data-disabled], .disabled):active - > .gl-new-dropdown-item-content, -.gl-new-dropdown-item[aria-selected="true"]:not([data-disabled], .disabled):focus-visible:active - > .gl-new-dropdown-item-content { - background-color: var(--gl-dropdown-option-background-color-selected-active); -} + > .gl-new-dropdown-item-content { + color: var(--gl-text-color-disabled); + pointer-events: none; + } + } -.gl-new-dropdown-item[aria-selected="true"]:not([data-disabled], .disabled):active - .gl-new-dropdown-item-check-icon, -.gl-new-dropdown-item[aria-selected="true"]:not([data-disabled], .disabled):focus-visible:active - .gl-new-dropdown-item-check-icon { - color: var(--gl-dropdown-option-indicator-color-selected-active); -} + &[aria-selected="true"] { + > .gl-new-dropdown-item-content { + background-color: var(--gl-dropdown-option-background-color-selected-default); + } + + &[data-disabled] > .gl-new-dropdown-item-content, + &.disabled > .gl-new-dropdown-item-content { + background-color: var(--gl-background-color-disabled); + } + + &:not([data-disabled], .disabled):hover { + > .gl-new-dropdown-item-content { + background-color: var(--gl-dropdown-option-background-color-selected-hover); + } + + .gl-new-dropdown-item-check-icon { + color: var(--gl-dropdown-option-indicator-color-selected-hover); + } + } + + &:not([data-disabled], .disabled)[data-highlighted] > .gl-new-dropdown-item-content, + &:not([data-disabled], .disabled):focus-visible > .gl-new-dropdown-item-content { + background-color: var(--gl-dropdown-option-background-color-selected-focus); + } + + &:not([data-disabled], .disabled)[data-highlighted] .gl-new-dropdown-item-check-icon, + &:not([data-disabled], .disabled):focus-visible .gl-new-dropdown-item-check-icon { + color: var(--gl-dropdown-option-indicator-color-selected-focus); + } + + &:not([data-disabled], .disabled):active > .gl-new-dropdown-item-content, + &:not([data-disabled], .disabled):focus-visible:active > .gl-new-dropdown-item-content { + background-color: var(--gl-dropdown-option-background-color-selected-active); + } + + &:not([data-disabled], .disabled):active .gl-new-dropdown-item-check-icon, + &:not([data-disabled], .disabled):focus-visible:active .gl-new-dropdown-item-check-icon { + color: var(--gl-dropdown-option-indicator-color-selected-active); + } + } -.gl-new-dropdown-item.gl-new-dropdown-item-highlighted:not([data-disabled], .disabled) - > .gl-new-dropdown-item-content { - color: var(--gl-dropdown-option-text-color-focus); - background-color: var(--gl-dropdown-option-background-color-unselected-focus); - box-shadow: - inset 0 0 0 2px var(--gl-focus-ring-outer-color), - inset 0 0 0 3px var(--gl-focus-ring-inner-color), - inset 0 0 0 1px var(--gl-focus-ring-inner-color); + &.gl-new-dropdown-item-highlighted:not([data-disabled], .disabled) + > .gl-new-dropdown-item-content { + color: var(--gl-dropdown-option-text-color-focus); + background-color: var(--gl-dropdown-option-background-color-unselected-focus); + box-shadow: + inset 0 0 0 2px var(--gl-focus-ring-outer-color), + inset 0 0 0 3px var(--gl-focus-ring-inner-color), + inset 0 0 0 1px var(--gl-focus-ring-inner-color); + } } .gl-new-dropdown-item-check-icon { @@ -376,9 +378,11 @@ color: var(--gl-dropdown-option-indicator-color-selected-default); } -.gl-new-dropdown-item[data-disabled] .gl-new-dropdown-item-check-icon, -.gl-new-dropdown-item.disabled .gl-new-dropdown-item-check-icon { - color: var(--gl-icon-color-disabled); +.gl-new-dropdown-item { + &[data-disabled] .gl-new-dropdown-item-check-icon, + &.disabled .gl-new-dropdown-item-check-icon { + color: var(--gl-icon-color-disabled); + } } .gl-new-dropdown-item-text-wrapper { @@ -387,50 +391,58 @@ .gl-new-dropdown-item-icon { @apply gl-mr-2 gl-inline-block gl-h-5 gl-w-5 gl-shrink-0; -} -.gl-new-dropdown-item-icon .gl-icon { - vertical-align: -3px; + .gl-icon { + vertical-align: -3px; + } } -.gl-new-dropdown-item-danger > .gl-new-dropdown-item-content { - color: var(--gl-action-danger-foreground-color-default); - background-color: var(--gl-action-danger-background-color-default); -} +.gl-new-dropdown-item-danger { + > .gl-new-dropdown-item-content { + color: var(--gl-action-danger-foreground-color-default); + background-color: var(--gl-action-danger-background-color-default); + } -.gl-new-dropdown-item-danger:not([data-disabled]):hover > .gl-new-dropdown-item-content { - color: var(--gl-action-danger-foreground-color-hover); - background-color: var(--gl-action-danger-background-color-hover); -} + &:not([data-disabled]):hover > .gl-new-dropdown-item-content { + color: var(--gl-action-danger-foreground-color-hover); + background-color: var(--gl-action-danger-background-color-hover); + } -.gl-new-dropdown-item-danger:not([data-disabled])[data-highlighted] > .gl-new-dropdown-item-content, -.gl-new-dropdown-item-danger:not([data-disabled]):focus-visible > .gl-new-dropdown-item-content { - color: var(--gl-action-danger-foreground-color-focus); - background-color: var(--gl-action-danger-background-color-focus); -} + &:not([data-disabled])[data-highlighted] > .gl-new-dropdown-item-content, + &:not([data-disabled]):focus-visible > .gl-new-dropdown-item-content { + color: var(--gl-action-danger-foreground-color-focus); + background-color: var(--gl-action-danger-background-color-focus); + } -.gl-new-dropdown-item-danger:not([data-disabled]):active > .gl-new-dropdown-item-content, -.gl-new-dropdown-item-danger:not([data-disabled]):focus-visible:active > .gl-new-dropdown-item-content { - color: var(--gl-action-danger-foreground-color-active); - background-color: var(--gl-action-danger-background-color-active); + &:not([data-disabled]):active > .gl-new-dropdown-item-content, + &:not([data-disabled]):focus-visible:active > .gl-new-dropdown-item-content { + color: var(--gl-action-danger-foreground-color-active); + background-color: var(--gl-action-danger-background-color-active); + } } -.btn-group .gl-new-dropdown:not(:last-child) .gl-new-dropdown-toggle { - @apply gl-rounded-br-none gl-rounded-tr-none; -} +.btn-group { + .gl-new-dropdown:not(:last-child) { + .gl-new-dropdown-toggle { + @apply gl-rounded-br-none gl-rounded-tr-none; + } + } -.btn-group .gl-new-dropdown:not(:first-child) .gl-new-dropdown-toggle { - @apply gl-rounded-bl-none gl-rounded-tl-none; -} + .gl-new-dropdown:not(:first-child) { + .gl-new-dropdown-toggle { + @apply gl-rounded-bl-none gl-rounded-tl-none; + } + } -.btn-group .gl-new-dropdown:hover .gl-new-dropdown-toggle, -.btn-group .gl-new-dropdown .gl-new-dropdown-toggle:focus-visible, -.btn-group .gl-new-dropdown .gl-new-dropdown-toggle:active { - @apply gl-z-1; + .gl-new-dropdown:hover .gl-new-dropdown-toggle, + .gl-new-dropdown .gl-new-dropdown-toggle:focus-visible, + .gl-new-dropdown .gl-new-dropdown-toggle:active { + @apply gl-z-1; + } } -@media (prefers-reduced-motion) { - .gl-new-dropdown-item-content { +.gl-new-dropdown-item-content { + @media (prefers-reduced-motion) { transition-duration: 0.01ms !important; transition-delay: 0ms !important; } @@ -439,7 +451,8 @@ @media (forced-colors: active) { .gl-new-dropdown-item:not([data-disabled]):active > .gl-new-dropdown-item-content, .gl-new-dropdown-item:not([data-disabled]):focus-visible > .gl-new-dropdown-item-content, - .gl-new-dropdown-item:not([data-disabled]):focus-visible:active > .gl-new-dropdown-item-content { + .gl-new-dropdown-item:not([data-disabled]):focus-visible:active + > .gl-new-dropdown-item-content { outline: 2px solid LinkText; box-shadow: none; } diff --git a/packages/styles/src/forms/bootstrap-custom-forms.css b/packages/styles/src/forms/bootstrap-custom-forms.css index c88f22e..d589295 100644 --- a/packages/styles/src/forms/bootstrap-custom-forms.css +++ b/packages/styles/src/forms/bootstrap-custom-forms.css @@ -63,13 +63,13 @@ width: 1rem; height: 1.25rem; opacity: 0; -} -/* The active (pressed) state. */ -.gl-form-checkbox .custom-control-input:not(:disabled):active ~ .custom-control-label::before, -.gl-form-radio .custom-control-input:not(:disabled):active ~ .custom-control-label::before { - background-color: #b3d7ff; - border-color: #b3d7ff; + /* The active (pressed) state. */ + &:not(:disabled):active ~ .custom-control-label::before { + background-color: #b3d7ff; + border-color: #b3d7ff; + } + } .gl-form-checkbox .custom-control-label, @@ -79,104 +79,96 @@ display: inline-block; margin-bottom: 0; vertical-align: top; -} -/* Background-color and border (the box) */ -.gl-form-checkbox .custom-control-label::before, -.gl-form-radio .custom-control-label::before { - position: absolute; - top: 0.25rem; - left: -1.5rem; - display: block; - width: 1rem; - height: 1rem; - pointer-events: none; - content: ""; - border-width: 1px; - border-style: solid; - /* `$custom-forms-transition` */ - transition: - background-color 0.15s ease-in-out, - border-color 0.15s ease-in-out, - box-shadow 0.15s ease-in-out; -} - -@media (prefers-reduced-motion: reduce) { - .gl-form-checkbox .custom-control-label::before, - .gl-form-radio .custom-control-label::before { - transition: none; + /* Background-color and border (the box) */ + &::before { + position: absolute; + top: 0.25rem; + left: -1.5rem; + display: block; + width: 1rem; + height: 1rem; + pointer-events: none; + content: ""; + border-width: 1px; + border-style: solid; + /* `$custom-forms-transition` */ + transition: + background-color 0.15s ease-in-out, + border-color 0.15s ease-in-out, + box-shadow 0.15s ease-in-out; + + @media (prefers-reduced-motion: reduce) { + transition: none; + } } -} -/* Foreground (the indicator icon) */ -.gl-form-checkbox .custom-control-label::after, -.gl-form-radio .custom-control-label::after { - position: absolute; - top: 0.25rem; - left: -1.5rem; - display: block; - width: 1rem; - height: 1rem; - content: ""; - background: 50% / 50% 50% no-repeat; + /* Foreground (the indicator icon) */ + &::after { + position: absolute; + top: 0.25rem; + left: -1.5rem; + display: block; + width: 1rem; + height: 1rem; + content: ""; + background: 50% / 50% 50% no-repeat; + } } /* `form-validation-state` for `.custom-control-input`; only the * component-controlled `.is-valid` / `.is-invalid` selectors. */ -.gl-form-checkbox .custom-control-input.is-valid ~ .custom-control-label, -.gl-form-radio .custom-control-input.is-valid ~ .custom-control-label { - color: #2f7549; -} - -.gl-form-checkbox .custom-control-input.is-valid ~ .custom-control-label::before, -.gl-form-radio .custom-control-input.is-valid ~ .custom-control-label::before { - border-color: #2f7549; -} - -.gl-form-checkbox .custom-control-input.is-valid:checked ~ .custom-control-label::before, -.gl-form-radio .custom-control-input.is-valid:checked ~ .custom-control-label::before { - background-color: #3e9960; - border-color: #3e9960; -} - -.gl-form-checkbox .custom-control-input.is-valid:focus-visible ~ .custom-control-label::before, -.gl-form-radio .custom-control-input.is-valid:focus-visible ~ .custom-control-label::before { - box-shadow: 0 0 0 0.2rem rgba(47, 117, 73, 0.25); -} - -.gl-form-checkbox .custom-control-input.is-valid:focus-visible:not(:checked) - ~ .custom-control-label::before, -.gl-form-radio .custom-control-input.is-valid:focus-visible:not(:checked) - ~ .custom-control-label::before { - border-color: #2f7549; -} - -.gl-form-checkbox .custom-control-input.is-invalid ~ .custom-control-label, -.gl-form-radio .custom-control-input.is-invalid ~ .custom-control-label { - color: #c02f12; -} - -.gl-form-checkbox .custom-control-input.is-invalid ~ .custom-control-label::before, -.gl-form-radio .custom-control-input.is-invalid ~ .custom-control-label::before { - border-color: #c02f12; -} - -.gl-form-checkbox .custom-control-input.is-invalid:checked ~ .custom-control-label::before, -.gl-form-radio .custom-control-input.is-invalid:checked ~ .custom-control-label::before { - background-color: #ea3e1b; - border-color: #ea3e1b; -} - -.gl-form-checkbox .custom-control-input.is-invalid:focus-visible ~ .custom-control-label::before, -.gl-form-radio .custom-control-input.is-invalid:focus-visible ~ .custom-control-label::before { - box-shadow: 0 0 0 0.2rem rgba(192, 47, 18, 0.25); -} +.gl-form-checkbox .custom-control-input, +.gl-form-radio .custom-control-input { + &.is-valid { + ~ .custom-control-label { + color: #2f7549; + + &::before { + border-color: #2f7549; + } + } + + &:checked ~ .custom-control-label::before { + background-color: #3e9960; + border-color: #3e9960; + } + + &:focus-visible { + ~ .custom-control-label::before { + box-shadow: 0 0 0 0.2rem rgba(47, 117, 73, 0.25); + } + + &:not(:checked) ~ .custom-control-label::before { + border-color: #2f7549; + } + } + } -.gl-form-checkbox .custom-control-input.is-invalid:focus-visible:not(:checked) - ~ .custom-control-label::before, -.gl-form-radio .custom-control-input.is-invalid:focus-visible:not(:checked) - ~ .custom-control-label::before { - border-color: #c02f12; + &.is-invalid { + ~ .custom-control-label { + color: #c02f12; + + &::before { + border-color: #c02f12; + } + } + + &:checked ~ .custom-control-label::before { + background-color: #ea3e1b; + border-color: #ea3e1b; + } + + &:focus-visible { + ~ .custom-control-label::before { + box-shadow: 0 0 0 0.2rem rgba(192, 47, 18, 0.25); + } + + &:not(:checked) ~ .custom-control-label::before { + border-color: #c02f12; + } + } + } } /* `.custom-select` base. Component-specific overrides are kept in the @@ -189,19 +181,17 @@ background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; -} -@media (prefers-reduced-motion: reduce) { - .gl-form-select.custom-select { + @media (prefers-reduced-motion: reduce) { transition: none; } -} -.gl-form-select.custom-select[multiple], -.gl-form-select.custom-select[size]:not([size="1"]) { - height: auto; - padding-right: 0.75rem; - background-image: none; + &[multiple], + &[size]:not([size="1"]) { + height: auto; + padding-right: 0.75rem; + background-image: none; + } } /* `.custom-range` base (thumb/track). */ @@ -211,101 +201,103 @@ padding: 0; /* Need to reset padding */ background-color: transparent; appearance: none; -} -.gl-form-input.custom-range:focus-visible { - outline: 0; -} + &:focus-visible { + outline: 0; -/* Pseudo-elements must be split across multiple rulesets to have an effect. */ -.gl-form-input.custom-range:focus-visible::-webkit-slider-thumb { - box-shadow: 0 0 0 1px #fff, 0 0 0 0.2rem rgba(0, 123, 255, 0.25); -} + /* Pseudo-elements must be split across multiple rulesets to have an effect. */ + &::-webkit-slider-thumb { + box-shadow: 0 0 0 1px #fff, 0 0 0 0.2rem rgba(0, 123, 255, 0.25); + } -.gl-form-input.custom-range:focus-visible::-moz-range-thumb { - box-shadow: 0 0 0 1px #fff, 0 0 0 0.2rem rgba(0, 123, 255, 0.25); -} - -.gl-form-input.custom-range::-moz-focus-outer { - border: 0; -} - -.gl-form-input.custom-range::-webkit-slider-thumb { - appearance: none; - width: 1rem; - height: 1rem; - margin-top: -0.25rem; /* WebKit specific */ - background-color: #007bff; - border: 0; - border-radius: 1rem; - /* `$custom-forms-transition` */ - transition: - background-color 0.15s ease-in-out, - border-color 0.15s ease-in-out, - box-shadow 0.15s ease-in-out; -} + &::-moz-range-thumb { + box-shadow: 0 0 0 1px #fff, 0 0 0 0.2rem rgba(0, 123, 255, 0.25); + } + } -.gl-form-input.custom-range::-webkit-slider-thumb:active { - background-color: #b3d7ff; -} + &::-moz-focus-outer { + border: 0; + } -.gl-form-input.custom-range::-webkit-slider-runnable-track { - width: 100%; - height: 0.5rem; - color: transparent; - cursor: pointer; - background-color: #dee2e6; - border-color: transparent; - border-radius: 1rem; -} + &::-webkit-slider-thumb { + appearance: none; + width: 1rem; + height: 1rem; + margin-top: -0.25rem; /* WebKit specific */ + background-color: #007bff; + border: 0; + border-radius: 1rem; + /* `$custom-forms-transition` */ + transition: + background-color 0.15s ease-in-out, + border-color 0.15s ease-in-out, + box-shadow 0.15s ease-in-out; + + &:active { + background-color: #b3d7ff; + } + } -.gl-form-input.custom-range::-moz-range-thumb { - appearance: none; - width: 1rem; - height: 1rem; - background-color: #007bff; - border: 0; - border-radius: 1rem; - /* `$custom-forms-transition` */ - transition: - background-color 0.15s ease-in-out, - border-color 0.15s ease-in-out, - box-shadow 0.15s ease-in-out; -} + &::-webkit-slider-runnable-track { + width: 100%; + height: 0.5rem; + color: transparent; + cursor: pointer; + background-color: #dee2e6; + border-color: transparent; + border-radius: 1rem; + } -.gl-form-input.custom-range::-moz-range-thumb:active { - background-color: #b3d7ff; -} + &::-moz-range-thumb { + appearance: none; + width: 1rem; + height: 1rem; + background-color: #007bff; + border: 0; + border-radius: 1rem; + /* `$custom-forms-transition` */ + transition: + background-color 0.15s ease-in-out, + border-color 0.15s ease-in-out, + box-shadow 0.15s ease-in-out; + + &:active { + background-color: #b3d7ff; + } + } -.gl-form-input.custom-range::-moz-range-track { - width: 100%; - height: 0.5rem; - color: transparent; - cursor: pointer; - background-color: #dee2e6; - border-color: transparent; - border-radius: 1rem; -} + &::-moz-range-track { + width: 100%; + height: 0.5rem; + color: transparent; + cursor: pointer; + background-color: #dee2e6; + border-color: transparent; + border-radius: 1rem; + } -@media (prefers-reduced-motion: reduce) { - .gl-form-input.custom-range::-webkit-slider-thumb, - .gl-form-input.custom-range::-moz-range-thumb { - transition: none; + @media (prefers-reduced-motion: reduce) { + &::-webkit-slider-thumb, + &::-moz-range-thumb { + transition: none; + } } -} -.gl-form-input.custom-range:disabled::-webkit-slider-thumb { - background-color: #adb5bd; -} + &:disabled { + &::-webkit-slider-thumb { + background-color: #adb5bd; + } -.gl-form-input.custom-range:disabled::-webkit-slider-runnable-track { - cursor: default; -} + &::-webkit-slider-runnable-track { + cursor: default; + } -.gl-form-input.custom-range:disabled::-moz-range-thumb { - background-color: #adb5bd; -} + &::-moz-range-thumb { + background-color: #adb5bd; + } -.gl-form-input.custom-range:disabled::-moz-range-track { - cursor: default; + &::-moz-range-track { + cursor: default; + } + } } diff --git a/packages/styles/src/forms/bootstrap-forms.css b/packages/styles/src/forms/bootstrap-forms.css index f4a06c0..b41586f 100644 --- a/packages/styles/src/forms/bootstrap-forms.css +++ b/packages/styles/src/forms/bootstrap-forms.css @@ -54,8 +54,8 @@ textarea.gl-form-textarea { margin-top: 0.25rem; } -@media (prefers-reduced-motion: reduce) { - .gl-form-input.form-control { +.gl-form-input.form-control { + @media (prefers-reduced-motion: reduce) { transition: none; } } diff --git a/packages/styles/src/forms/gitlab-check-controls.css b/packages/styles/src/forms/gitlab-check-controls.css index 6cc3d61..2586c97 100644 --- a/packages/styles/src/forms/gitlab-check-controls.css +++ b/packages/styles/src/forms/gitlab-check-controls.css @@ -10,10 +10,10 @@ * radios. Only genuinely component-private rules stay in the component CSS: * the indicator shapes, mask images and the checkbox indeterminate states. * - * React adaptation: selectors that upstream nests under the combined - * `.gl-form-checkbox, .gl-form-radio` block are written out per marker class. - * Cross-type combinations that cannot occur in this React markup (e.g. a - * `[type="checkbox"]` input inside `.gl-form-radio`) are omitted. + * React adaptation: the shared rules preserve upstream's combined + * `.gl-form-checkbox, .gl-form-radio` parent. Cross-type combinations that + * cannot occur in this React markup (e.g. a `[type="checkbox"]` input inside + * `.gl-form-radio`) are omitted. */ .gl-form-checkbox, @@ -30,61 +30,45 @@ @apply gl-cursor-not-allowed gl-text-disabled; } -.gl-form-checkbox.custom-control, -.gl-form-radio.custom-control { - @apply gl-pl-5; -} - -.gl-form-checkbox.custom-control .custom-control-input ~ .custom-control-label, -.gl-form-radio.custom-control .custom-control-input ~ .custom-control-label { - @apply gl-cursor-pointer gl-pl-3 gl-mb-3; -} - -.gl-form-checkbox.custom-control .custom-control-input ~ .custom-control-label::before, -.gl-form-checkbox.custom-control .custom-control-input ~ .custom-control-label::after, -.gl-form-radio.custom-control .custom-control-input ~ .custom-control-label::before, -.gl-form-radio.custom-control .custom-control-input ~ .custom-control-label::after { - top: 0; - /* -$gl-spacing-scale-5 */ - left: -1rem; -} - -.gl-form-checkbox.custom-control .custom-control-input ~ .custom-control-label::before, -.gl-form-radio.custom-control .custom-control-input ~ .custom-control-label::before { - background-color: var(--gl-control-background-color-default); - border-color: var(--gl-control-border-color-default); -} - -.gl-form-checkbox.custom-control - .custom-control-input:not(:disabled):hover - ~ .custom-control-label::before, -.gl-form-radio.custom-control - .custom-control-input:not(:disabled):hover - ~ .custom-control-label::before { - border-color: var(--gl-control-border-color-hover); -} - -.gl-form-checkbox.custom-control - .custom-control-input:not(:disabled):focus-visible - ~ .custom-control-label::before, -.gl-form-radio.custom-control - .custom-control-input:not(:disabled):focus-visible - ~ .custom-control-label::before { - @apply gl-focus; - border-color: var(--gl-control-border-color-focus); -} - -.gl-form-checkbox.custom-control .custom-control-input:checked ~ .custom-control-label::before, -.gl-form-radio.custom-control .custom-control-input:checked ~ .custom-control-label::before { - background-color: var(--gl-control-background-color-selected-default); - border-color: var(--gl-control-border-color-selected-default); -} - -@media (forced-colors: active) { - .gl-form-checkbox.custom-control .custom-control-input:checked ~ .custom-control-label::before, - .gl-form-radio.custom-control .custom-control-input:checked ~ .custom-control-label::before { - background-color: LinkText; - border-color: LinkText; +.gl-form-checkbox, +.gl-form-radio { + &.custom-control { + @apply gl-pl-5; + + .custom-control-input ~ .custom-control-label { + @apply gl-cursor-pointer gl-pl-3 gl-mb-3; + } + + .custom-control-input ~ .custom-control-label::before, + .custom-control-input ~ .custom-control-label::after { + top: 0; + /* -$gl-spacing-scale-5 */ + left: -1rem; + } + + .custom-control-input ~ .custom-control-label::before { + background-color: var(--gl-control-background-color-default); + border-color: var(--gl-control-border-color-default); + } + + .custom-control-input:not(:disabled):hover ~ .custom-control-label::before { + border-color: var(--gl-control-border-color-hover); + } + + .custom-control-input:not(:disabled):focus-visible ~ .custom-control-label::before { + @apply gl-focus; + border-color: var(--gl-control-border-color-focus); + } + + .custom-control-input:checked ~ .custom-control-label::before { + background-color: var(--gl-control-background-color-selected-default); + border-color: var(--gl-control-border-color-selected-default); + + @media (forced-colors: active) { + background-color: LinkText; + border-color: LinkText; + } + } } } @@ -121,14 +105,14 @@ border-color: var(--gl-control-border-color-selected-hover); } -.gl-form-checkbox.custom-control - .custom-control-input:not(:disabled):focus-visible:checked - ~ .custom-control-label::before, -.gl-form-radio.custom-control - .custom-control-input:not(:disabled):focus-visible:checked - ~ .custom-control-label::before { - background-color: var(--gl-control-background-color-selected-focus); - border-color: var(--gl-control-border-color-selected-focus); +.gl-form-checkbox, +.gl-form-radio { + &.custom-control { + .custom-control-input:not(:disabled):focus-visible:checked ~ .custom-control-label::before { + background-color: var(--gl-control-background-color-selected-focus); + border-color: var(--gl-control-border-color-selected-focus); + } + } } @media (forced-colors: active) { @@ -155,31 +139,26 @@ } } -.gl-form-checkbox.custom-control .custom-control-input:not(:disabled) ~ .custom-control-label, -.gl-form-radio.custom-control .custom-control-input:not(:disabled) ~ .custom-control-label { - @apply gl-text-default; -} - -.gl-form-checkbox.custom-control .custom-control-input:disabled ~ .custom-control-label, -.gl-form-radio.custom-control .custom-control-input:disabled ~ .custom-control-label { - @apply gl-cursor-not-allowed; -} - -.gl-form-checkbox.custom-control .custom-control-input:disabled ~ .custom-control-label::before, -.gl-form-radio.custom-control .custom-control-input:disabled ~ .custom-control-label::before { - @apply gl-pointer-events-auto; - background-color: var(--gl-control-background-color-disabled); - border-color: var(--gl-control-border-color-disabled); -} - -@media (forced-colors: active) { - .gl-form-checkbox.custom-control - .custom-control-input:disabled - ~ .custom-control-label::before, - .gl-form-radio.custom-control - .custom-control-input:disabled - ~ .custom-control-label::before { - opacity: 0.5; +.gl-form-checkbox, +.gl-form-radio { + &.custom-control { + .custom-control-input:not(:disabled) ~ .custom-control-label { + @apply gl-text-default; + } + + .custom-control-input:disabled ~ .custom-control-label { + @apply gl-cursor-not-allowed; + } + + .custom-control-input:disabled ~ .custom-control-label::before { + @apply gl-pointer-events-auto; + background-color: var(--gl-control-background-color-disabled); + border-color: var(--gl-control-border-color-disabled); + + @media (forced-colors: active) { + opacity: 0.5; + } + } } } @@ -228,7 +207,9 @@ } } -.gl-form-checkbox .help-text, -.gl-form-radio .help-text { - @apply gl-mt-2 gl-mb-0 gl-text-base gl-leading-normal gl-text-subtle; +.gl-form-checkbox, +.gl-form-radio { + .help-text { + @apply gl-mt-2 gl-mb-0 gl-text-base gl-leading-normal gl-text-subtle; + } } diff --git a/packages/styles/src/forms/gitlab-text-controls.css b/packages/styles/src/forms/gitlab-text-controls.css index 58f6f7c..5edf32e 100644 --- a/packages/styles/src/forms/gitlab-text-controls.css +++ b/packages/styles/src/forms/gitlab-text-controls.css @@ -22,29 +22,24 @@ background: var(--gl-control-background-color-default); /* Bootstrap's `.form-control` base provides these upstream. */ @apply gl-block gl-w-full gl-rounded-control gl-font-regular gl-text-base gl-leading-normal gl-py-3 gl-px-4 gl-h-auto gl-border-none gl-text-default; -} -/* Bootstrap's deprecated `form-control-focus` mixin output; the - * `:not(.form-control-plaintext):focus-visible` rule below overrides it. */ -.gl-form-input:focus-visible, -.gl-form-input.form-control:focus-visible { - color: #4c4b51; - background-color: #fff; - border-color: #80bdff; - outline: 0; - box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25); -} + /* Bootstrap's deprecated `form-control-focus` mixin output; the + * `:not(.form-control-plaintext):focus-visible` rule below overrides it. */ + &:focus-visible { + color: #4c4b51; + background-color: #fff; + border-color: #80bdff; + outline: 0; + box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25); + } -@media (forced-colors: active) { - .gl-form-input, - .gl-form-input.form-control { + @media (forced-colors: active) { border: 1px solid; } -} -.gl-form-input:hover, -.gl-form-input.form-control:hover { - box-shadow: inset 0 0 0 1px var(--gl-control-border-color-hover); + &:hover { + box-shadow: inset 0 0 0 1px var(--gl-control-border-color-hover); + } } .gl-form-input:not(.gl-form-input-not-readonly):not(:disabled):not(.form-control-plaintext):not( @@ -57,61 +52,53 @@ box-shadow: none; } -.gl-form-input:disabled, -.gl-form-input.form-control:disabled { - @apply gl-cursor-not-allowed; - background: var(--gl-control-background-color-disabled); - box-shadow: inset 0 0 0 1px var(--gl-control-border-color-disabled); - @apply gl-text-disabled; -} +.gl-form-input, +.gl-form-input.form-control { -/* `gl-focus($color: var(--gl-control-border-color-focus))` */ -.gl-form-input:not(.form-control-plaintext):focus-visible, -.gl-form-input.form-control:not(.form-control-plaintext):focus-visible { - background: var(--gl-control-background-color-default); - @apply gl-text-default; - box-shadow: - inset 0 0 0 1px var(--gl-control-border-color-focus), - 0 0 0 1px var(--gl-focus-ring-inner-color), - 0 0 0 3px var(--gl-focus-ring-outer-color); - outline: none; -} + &:disabled { + @apply gl-cursor-not-allowed; + background: var(--gl-control-background-color-disabled); + box-shadow: inset 0 0 0 1px var(--gl-control-border-color-disabled); + @apply gl-text-disabled; + } + + /* `gl-focus($color: var(--gl-control-border-color-focus))` */ + &:not(.form-control-plaintext):focus-visible { + background: var(--gl-control-background-color-default); + @apply gl-text-default; + box-shadow: + inset 0 0 0 1px var(--gl-control-border-color-focus), + 0 0 0 1px var(--gl-focus-ring-inner-color), + 0 0 0 3px var(--gl-focus-ring-outer-color); + outline: none; -@media (forced-colors: active) { - .gl-form-input:not(.form-control-plaintext):focus-visible, - .gl-form-input.form-control:not(.form-control-plaintext):focus-visible { - outline: 2px solid LinkText; + @media (forced-colors: active) { + outline: 2px solid LinkText; + } } -} -.gl-form-input.is-invalid, -.gl-form-input.form-control.is-invalid { - box-shadow: inset 0 0 0 1px var(--gl-control-border-color-error); -} + &.is-invalid { + box-shadow: inset 0 0 0 1px var(--gl-control-border-color-error); -/* `gl-focus($color: var(--gl-control-border-color-error))` */ -.gl-form-input.is-invalid:focus-visible, -.gl-form-input.form-control.is-invalid:focus-visible { - box-shadow: - inset 0 0 0 1px var(--gl-control-border-color-error), - 0 0 0 1px var(--gl-focus-ring-inner-color), - 0 0 0 3px var(--gl-focus-ring-outer-color); - outline: none; -} + /* `gl-focus($color: var(--gl-control-border-color-error))` */ + &:focus-visible { + box-shadow: + inset 0 0 0 1px var(--gl-control-border-color-error), + 0 0 0 1px var(--gl-focus-ring-inner-color), + 0 0 0 3px var(--gl-focus-ring-outer-color); + outline: none; -@media (forced-colors: active) { - .gl-form-input.is-invalid:focus-visible, - .gl-form-input.form-control.is-invalid:focus-visible { - outline: 2px solid LinkText; + @media (forced-colors: active) { + outline: 2px solid LinkText; + } + } } -} -.gl-form-input::placeholder, -.gl-form-input.form-control::placeholder { - color: var(--gl-control-placeholder-color); -} + &::placeholder { + color: var(--gl-control-placeholder-color); + } -.gl-form-input.form-control-plaintext, -.gl-form-input.form-control.form-control-plaintext { - @apply gl-shadow-none; + &.form-control-plaintext { + @apply gl-shadow-none; + } } diff --git a/packages/styles/src/tables/bootstrap-tables.css b/packages/styles/src/tables/bootstrap-tables.css index 9f35526..a3a4702 100644 --- a/packages/styles/src/tables/bootstrap-tables.css +++ b/packages/styles/src/tables/bootstrap-tables.css @@ -14,10 +14,10 @@ overflow-x: auto; overscroll-behavior-x: contain; -webkit-overflow-scrolling: touch; -} -.gl-table-responsive > .gl-table { - margin-bottom: 0; + > .gl-table { + margin-bottom: 0; + } } .gl-table-responsive.b-table-sticky-header { @@ -25,29 +25,35 @@ overflow-y: auto; } -table.gl-table.b-table-fixed { - table-layout: fixed; -} +table.gl-table { + &.b-table-fixed { + table-layout: fixed; + } -table.gl-table.b-table-no-border-collapse { - border-collapse: separate; - border-spacing: 0; -} + &.b-table-no-border-collapse { + border-collapse: separate; + border-spacing: 0; + } -table.gl-table > caption { - caption-side: bottom; -} + > caption { + caption-side: bottom; + } -table.gl-table.b-table-caption-top > caption { - caption-side: top !important; + &.b-table-caption-top > caption { + caption-side: top !important; + } } -table.gl-table.table-sm tr > :is(th, td) { - padding: 0.3rem; +table.gl-table.table-sm { + tr > :is(th, td) { + padding: 0.3rem; + } } -table.gl-table.table-striped tbody tr:nth-of-type(odd) { - background-color: var(--gl-background-color-subtle); +table.gl-table.table-striped { + tbody tr:nth-of-type(odd) { + background-color: var(--gl-background-color-subtle); + } } @media print { @@ -59,19 +65,21 @@ table.gl-table.table-striped tbody tr:nth-of-type(odd) { table.gl-table.table-bordered { @apply gl-border gl-border-solid gl-border-default; -} -table.gl-table.table-bordered th, -table.gl-table.table-bordered td { - @apply gl-border gl-border-solid gl-border-default; + th, + td { + @apply gl-border gl-border-solid gl-border-default; + } } -table.gl-table.table-borderless, -table.gl-table.table-borderless th, -table.gl-table.table-borderless td, -table.gl-table.table-borderless thead th, -table.gl-table.table-borderless tbody + tbody { - border: 0; +table.gl-table.table-borderless { + &, + th, + td, + thead th, + tbody + tbody { + border: 0; + } } table.gl-table.b-table-stacked { @@ -95,187 +103,195 @@ table.gl-table.b-table-stacked { --gl-table-stacked-content-align: right; } -@container (width < 576px) { - :where(html.with-gl-container-queries) table.gl-table.b-table-stacked-sm { - --gl-table-stacked-table-display: block; - --gl-table-stacked-section-display: block; - --gl-table-stacked-row-display: block; - --gl-table-stacked-cell-display: block; - --gl-table-stacked-head-foot-display: none; - --gl-table-stacked-caption-side: top; - --gl-table-stacked-label-display: block; - --gl-table-stacked-content-display: inline-block; - --gl-table-stacked-content-width: 60%; - --gl-table-stacked-content-padding-left: 0.5rem; - --gl-table-stacked-heavy-border-width: 3px; - --gl-table-stacked-row-gap-display: block; - --gl-table-stacked-cell-side-border: 1px solid var(--gl-border-color-default); - --gl-table-stacked-label-align: left; - --gl-table-stacked-labelled-first-border-width: 1px; - --gl-table-stacked-labelled-border-width: 0; - --gl-table-stacked-content-wrap: break-word; - --gl-table-stacked-content-align: right; +table.gl-table.b-table-stacked-sm { + @container (width < 576px) { + :where(html.with-gl-container-queries) & { + --gl-table-stacked-table-display: block; + --gl-table-stacked-section-display: block; + --gl-table-stacked-row-display: block; + --gl-table-stacked-cell-display: block; + --gl-table-stacked-head-foot-display: none; + --gl-table-stacked-caption-side: top; + --gl-table-stacked-label-display: block; + --gl-table-stacked-content-display: inline-block; + --gl-table-stacked-content-width: 60%; + --gl-table-stacked-content-padding-left: 0.5rem; + --gl-table-stacked-heavy-border-width: 3px; + --gl-table-stacked-row-gap-display: block; + --gl-table-stacked-cell-side-border: 1px solid var(--gl-border-color-default); + --gl-table-stacked-label-align: left; + --gl-table-stacked-labelled-first-border-width: 1px; + --gl-table-stacked-labelled-border-width: 0; + --gl-table-stacked-content-wrap: break-word; + --gl-table-stacked-content-align: right; + } } -} -@media (width < 576px) { - :where(html:not(.with-gl-container-queries)) table.gl-table.b-table-stacked-sm { - --gl-table-stacked-table-display: block; - --gl-table-stacked-section-display: block; - --gl-table-stacked-row-display: block; - --gl-table-stacked-cell-display: block; - --gl-table-stacked-head-foot-display: none; - --gl-table-stacked-caption-side: top; - --gl-table-stacked-label-display: block; - --gl-table-stacked-content-display: inline-block; - --gl-table-stacked-content-width: 60%; - --gl-table-stacked-content-padding-left: 0.5rem; - --gl-table-stacked-heavy-border-width: 3px; - --gl-table-stacked-row-gap-display: block; - --gl-table-stacked-cell-side-border: 1px solid var(--gl-border-color-default); - --gl-table-stacked-label-align: left; - --gl-table-stacked-labelled-first-border-width: 1px; - --gl-table-stacked-labelled-border-width: 0; - --gl-table-stacked-content-wrap: break-word; - --gl-table-stacked-content-align: right; + @media (width < 576px) { + :where(html:not(.with-gl-container-queries)) & { + --gl-table-stacked-table-display: block; + --gl-table-stacked-section-display: block; + --gl-table-stacked-row-display: block; + --gl-table-stacked-cell-display: block; + --gl-table-stacked-head-foot-display: none; + --gl-table-stacked-caption-side: top; + --gl-table-stacked-label-display: block; + --gl-table-stacked-content-display: inline-block; + --gl-table-stacked-content-width: 60%; + --gl-table-stacked-content-padding-left: 0.5rem; + --gl-table-stacked-heavy-border-width: 3px; + --gl-table-stacked-row-gap-display: block; + --gl-table-stacked-cell-side-border: 1px solid var(--gl-border-color-default); + --gl-table-stacked-label-align: left; + --gl-table-stacked-labelled-first-border-width: 1px; + --gl-table-stacked-labelled-border-width: 0; + --gl-table-stacked-content-wrap: break-word; + --gl-table-stacked-content-align: right; + } } } -@container (width < 768px) { - :where(html.with-gl-container-queries) table.gl-table.b-table-stacked-md { - --gl-table-stacked-table-display: block; - --gl-table-stacked-section-display: block; - --gl-table-stacked-row-display: block; - --gl-table-stacked-cell-display: block; - --gl-table-stacked-head-foot-display: none; - --gl-table-stacked-caption-side: top; - --gl-table-stacked-label-display: block; - --gl-table-stacked-content-display: inline-block; - --gl-table-stacked-content-width: 60%; - --gl-table-stacked-content-padding-left: 0.5rem; - --gl-table-stacked-heavy-border-width: 3px; - --gl-table-stacked-row-gap-display: block; - --gl-table-stacked-cell-side-border: 1px solid var(--gl-border-color-default); - --gl-table-stacked-label-align: left; - --gl-table-stacked-labelled-first-border-width: 1px; - --gl-table-stacked-labelled-border-width: 0; - --gl-table-stacked-content-wrap: break-word; - --gl-table-stacked-content-align: right; +table.gl-table.b-table-stacked-md { + @container (width < 768px) { + :where(html.with-gl-container-queries) & { + --gl-table-stacked-table-display: block; + --gl-table-stacked-section-display: block; + --gl-table-stacked-row-display: block; + --gl-table-stacked-cell-display: block; + --gl-table-stacked-head-foot-display: none; + --gl-table-stacked-caption-side: top; + --gl-table-stacked-label-display: block; + --gl-table-stacked-content-display: inline-block; + --gl-table-stacked-content-width: 60%; + --gl-table-stacked-content-padding-left: 0.5rem; + --gl-table-stacked-heavy-border-width: 3px; + --gl-table-stacked-row-gap-display: block; + --gl-table-stacked-cell-side-border: 1px solid var(--gl-border-color-default); + --gl-table-stacked-label-align: left; + --gl-table-stacked-labelled-first-border-width: 1px; + --gl-table-stacked-labelled-border-width: 0; + --gl-table-stacked-content-wrap: break-word; + --gl-table-stacked-content-align: right; + } } -} -@media (width < 768px) { - :where(html:not(.with-gl-container-queries)) table.gl-table.b-table-stacked-md { - --gl-table-stacked-table-display: block; - --gl-table-stacked-section-display: block; - --gl-table-stacked-row-display: block; - --gl-table-stacked-cell-display: block; - --gl-table-stacked-head-foot-display: none; - --gl-table-stacked-caption-side: top; - --gl-table-stacked-label-display: block; - --gl-table-stacked-content-display: inline-block; - --gl-table-stacked-content-width: 60%; - --gl-table-stacked-content-padding-left: 0.5rem; - --gl-table-stacked-heavy-border-width: 3px; - --gl-table-stacked-row-gap-display: block; - --gl-table-stacked-cell-side-border: 1px solid var(--gl-border-color-default); - --gl-table-stacked-label-align: left; - --gl-table-stacked-labelled-first-border-width: 1px; - --gl-table-stacked-labelled-border-width: 0; - --gl-table-stacked-content-wrap: break-word; - --gl-table-stacked-content-align: right; + @media (width < 768px) { + :where(html:not(.with-gl-container-queries)) & { + --gl-table-stacked-table-display: block; + --gl-table-stacked-section-display: block; + --gl-table-stacked-row-display: block; + --gl-table-stacked-cell-display: block; + --gl-table-stacked-head-foot-display: none; + --gl-table-stacked-caption-side: top; + --gl-table-stacked-label-display: block; + --gl-table-stacked-content-display: inline-block; + --gl-table-stacked-content-width: 60%; + --gl-table-stacked-content-padding-left: 0.5rem; + --gl-table-stacked-heavy-border-width: 3px; + --gl-table-stacked-row-gap-display: block; + --gl-table-stacked-cell-side-border: 1px solid var(--gl-border-color-default); + --gl-table-stacked-label-align: left; + --gl-table-stacked-labelled-first-border-width: 1px; + --gl-table-stacked-labelled-border-width: 0; + --gl-table-stacked-content-wrap: break-word; + --gl-table-stacked-content-align: right; + } } } -@container (width < 992px) { - :where(html.with-gl-container-queries) table.gl-table.b-table-stacked-lg { - --gl-table-stacked-table-display: block; - --gl-table-stacked-section-display: block; - --gl-table-stacked-row-display: block; - --gl-table-stacked-cell-display: block; - --gl-table-stacked-head-foot-display: none; - --gl-table-stacked-caption-side: top; - --gl-table-stacked-label-display: block; - --gl-table-stacked-content-display: inline-block; - --gl-table-stacked-content-width: 60%; - --gl-table-stacked-content-padding-left: 0.5rem; - --gl-table-stacked-heavy-border-width: 3px; - --gl-table-stacked-row-gap-display: block; - --gl-table-stacked-cell-side-border: 1px solid var(--gl-border-color-default); - --gl-table-stacked-label-align: left; - --gl-table-stacked-labelled-first-border-width: 1px; - --gl-table-stacked-labelled-border-width: 0; - --gl-table-stacked-content-wrap: break-word; - --gl-table-stacked-content-align: right; +table.gl-table.b-table-stacked-lg { + @container (width < 992px) { + :where(html.with-gl-container-queries) & { + --gl-table-stacked-table-display: block; + --gl-table-stacked-section-display: block; + --gl-table-stacked-row-display: block; + --gl-table-stacked-cell-display: block; + --gl-table-stacked-head-foot-display: none; + --gl-table-stacked-caption-side: top; + --gl-table-stacked-label-display: block; + --gl-table-stacked-content-display: inline-block; + --gl-table-stacked-content-width: 60%; + --gl-table-stacked-content-padding-left: 0.5rem; + --gl-table-stacked-heavy-border-width: 3px; + --gl-table-stacked-row-gap-display: block; + --gl-table-stacked-cell-side-border: 1px solid var(--gl-border-color-default); + --gl-table-stacked-label-align: left; + --gl-table-stacked-labelled-first-border-width: 1px; + --gl-table-stacked-labelled-border-width: 0; + --gl-table-stacked-content-wrap: break-word; + --gl-table-stacked-content-align: right; + } } -} -@media (width < 992px) { - :where(html:not(.with-gl-container-queries)) table.gl-table.b-table-stacked-lg { - --gl-table-stacked-table-display: block; - --gl-table-stacked-section-display: block; - --gl-table-stacked-row-display: block; - --gl-table-stacked-cell-display: block; - --gl-table-stacked-head-foot-display: none; - --gl-table-stacked-caption-side: top; - --gl-table-stacked-label-display: block; - --gl-table-stacked-content-display: inline-block; - --gl-table-stacked-content-width: 60%; - --gl-table-stacked-content-padding-left: 0.5rem; - --gl-table-stacked-heavy-border-width: 3px; - --gl-table-stacked-row-gap-display: block; - --gl-table-stacked-cell-side-border: 1px solid var(--gl-border-color-default); - --gl-table-stacked-label-align: left; - --gl-table-stacked-labelled-first-border-width: 1px; - --gl-table-stacked-labelled-border-width: 0; - --gl-table-stacked-content-wrap: break-word; - --gl-table-stacked-content-align: right; + @media (width < 992px) { + :where(html:not(.with-gl-container-queries)) & { + --gl-table-stacked-table-display: block; + --gl-table-stacked-section-display: block; + --gl-table-stacked-row-display: block; + --gl-table-stacked-cell-display: block; + --gl-table-stacked-head-foot-display: none; + --gl-table-stacked-caption-side: top; + --gl-table-stacked-label-display: block; + --gl-table-stacked-content-display: inline-block; + --gl-table-stacked-content-width: 60%; + --gl-table-stacked-content-padding-left: 0.5rem; + --gl-table-stacked-heavy-border-width: 3px; + --gl-table-stacked-row-gap-display: block; + --gl-table-stacked-cell-side-border: 1px solid var(--gl-border-color-default); + --gl-table-stacked-label-align: left; + --gl-table-stacked-labelled-first-border-width: 1px; + --gl-table-stacked-labelled-border-width: 0; + --gl-table-stacked-content-wrap: break-word; + --gl-table-stacked-content-align: right; + } } } -@container (width < 1200px) { - :where(html.with-gl-container-queries) table.gl-table.b-table-stacked-xl { - --gl-table-stacked-table-display: block; - --gl-table-stacked-section-display: block; - --gl-table-stacked-row-display: block; - --gl-table-stacked-cell-display: block; - --gl-table-stacked-head-foot-display: none; - --gl-table-stacked-caption-side: top; - --gl-table-stacked-label-display: block; - --gl-table-stacked-content-display: inline-block; - --gl-table-stacked-content-width: 60%; - --gl-table-stacked-content-padding-left: 0.5rem; - --gl-table-stacked-heavy-border-width: 3px; - --gl-table-stacked-row-gap-display: block; - --gl-table-stacked-cell-side-border: 1px solid var(--gl-border-color-default); - --gl-table-stacked-label-align: left; - --gl-table-stacked-labelled-first-border-width: 1px; - --gl-table-stacked-labelled-border-width: 0; - --gl-table-stacked-content-wrap: break-word; - --gl-table-stacked-content-align: right; +table.gl-table.b-table-stacked-xl { + @container (width < 1200px) { + :where(html.with-gl-container-queries) & { + --gl-table-stacked-table-display: block; + --gl-table-stacked-section-display: block; + --gl-table-stacked-row-display: block; + --gl-table-stacked-cell-display: block; + --gl-table-stacked-head-foot-display: none; + --gl-table-stacked-caption-side: top; + --gl-table-stacked-label-display: block; + --gl-table-stacked-content-display: inline-block; + --gl-table-stacked-content-width: 60%; + --gl-table-stacked-content-padding-left: 0.5rem; + --gl-table-stacked-heavy-border-width: 3px; + --gl-table-stacked-row-gap-display: block; + --gl-table-stacked-cell-side-border: 1px solid var(--gl-border-color-default); + --gl-table-stacked-label-align: left; + --gl-table-stacked-labelled-first-border-width: 1px; + --gl-table-stacked-labelled-border-width: 0; + --gl-table-stacked-content-wrap: break-word; + --gl-table-stacked-content-align: right; + } } -} -@media (width < 1200px) { - :where(html:not(.with-gl-container-queries)) table.gl-table.b-table-stacked-xl { - --gl-table-stacked-table-display: block; - --gl-table-stacked-section-display: block; - --gl-table-stacked-row-display: block; - --gl-table-stacked-cell-display: block; - --gl-table-stacked-head-foot-display: none; - --gl-table-stacked-caption-side: top; - --gl-table-stacked-label-display: block; - --gl-table-stacked-content-display: inline-block; - --gl-table-stacked-content-width: 60%; - --gl-table-stacked-content-padding-left: 0.5rem; - --gl-table-stacked-heavy-border-width: 3px; - --gl-table-stacked-row-gap-display: block; - --gl-table-stacked-cell-side-border: 1px solid var(--gl-border-color-default); - --gl-table-stacked-label-align: left; - --gl-table-stacked-labelled-first-border-width: 1px; - --gl-table-stacked-labelled-border-width: 0; - --gl-table-stacked-content-wrap: break-word; - --gl-table-stacked-content-align: right; + @media (width < 1200px) { + :where(html:not(.with-gl-container-queries)) & { + --gl-table-stacked-table-display: block; + --gl-table-stacked-section-display: block; + --gl-table-stacked-row-display: block; + --gl-table-stacked-cell-display: block; + --gl-table-stacked-head-foot-display: none; + --gl-table-stacked-caption-side: top; + --gl-table-stacked-label-display: block; + --gl-table-stacked-content-display: inline-block; + --gl-table-stacked-content-width: 60%; + --gl-table-stacked-content-padding-left: 0.5rem; + --gl-table-stacked-heavy-border-width: 3px; + --gl-table-stacked-row-gap-display: block; + --gl-table-stacked-cell-side-border: 1px solid var(--gl-border-color-default); + --gl-table-stacked-label-align: left; + --gl-table-stacked-labelled-first-border-width: 1px; + --gl-table-stacked-labelled-border-width: 0; + --gl-table-stacked-content-wrap: break-word; + --gl-table-stacked-content-align: right; + } } } @@ -288,143 +304,59 @@ table.gl-table:is( ) { display: var(--gl-table-stacked-table-display, table); width: 100%; -} -table.gl-table:is( - .b-table-stacked, - .b-table-stacked-sm, - .b-table-stacked-md, - .b-table-stacked-lg, - .b-table-stacked-xl -) > caption, -table.gl-table:is( - .b-table-stacked, - .b-table-stacked-sm, - .b-table-stacked-md, - .b-table-stacked-lg, - .b-table-stacked-xl -) > tbody { - display: var(--gl-table-stacked-section-display, revert); -} + > caption, + > tbody { + display: var(--gl-table-stacked-section-display, revert); + } -table.gl-table:is( - .b-table-stacked, - .b-table-stacked-sm, - .b-table-stacked-md, - .b-table-stacked-lg, - .b-table-stacked-xl -) > tbody > tr { - display: var(--gl-table-stacked-row-display, revert); -} + > tbody > tr { + display: var(--gl-table-stacked-row-display, revert); + } -table.gl-table:is( - .b-table-stacked, - .b-table-stacked-sm, - .b-table-stacked-md, - .b-table-stacked-lg, - .b-table-stacked-xl -) > tbody > tr > td, -table.gl-table:is( - .b-table-stacked, - .b-table-stacked-sm, - .b-table-stacked-md, - .b-table-stacked-lg, - .b-table-stacked-xl -) > tbody > tr > th { - display: var(--gl-table-stacked-cell-display, revert); -} + > tbody > tr > td, + > tbody > tr > th { + display: var(--gl-table-stacked-cell-display, revert); + } -table.gl-table:is( - .b-table-stacked, - .b-table-stacked-sm, - .b-table-stacked-md, - .b-table-stacked-lg, - .b-table-stacked-xl -) > thead, -table.gl-table:is( - .b-table-stacked, - .b-table-stacked-sm, - .b-table-stacked-md, - .b-table-stacked-lg, - .b-table-stacked-xl -) > tfoot { - display: var(--gl-table-stacked-head-foot-display, revert); -} + > thead, + > tfoot { + display: var(--gl-table-stacked-head-foot-display, revert); + } -table.gl-table:is( - .b-table-stacked, - .b-table-stacked-sm, - .b-table-stacked-md, - .b-table-stacked-lg, - .b-table-stacked-xl -) > caption { - caption-side: var(--gl-table-stacked-caption-side, bottom); -} + > caption { + caption-side: var(--gl-table-stacked-caption-side, bottom); + } -table.gl-table:is( - .b-table-stacked, - .b-table-stacked-sm, - .b-table-stacked-md, - .b-table-stacked-lg, - .b-table-stacked-xl -) > tbody > tr > [data-label]::before { - display: var(--gl-table-stacked-label-display, none); - float: left; - width: 40%; - padding: 0 0.5rem 0 0; - margin: 0; - overflow-wrap: break-word; - font-style: normal; - font-weight: bold; - text-align: right; - content: attr(data-label); -} + > tbody > tr > [data-label]::before { + display: var(--gl-table-stacked-label-display, none); + float: left; + width: 40%; + padding: 0 0.5rem 0 0; + margin: 0; + overflow-wrap: break-word; + font-style: normal; + font-weight: bold; + text-align: right; + content: attr(data-label); + } -table.gl-table:is( - .b-table-stacked, - .b-table-stacked-sm, - .b-table-stacked-md, - .b-table-stacked-lg, - .b-table-stacked-xl -) > tbody > tr > [data-label]::after { - display: var(--gl-table-stacked-label-display, none); - clear: both; - content: ""; -} + > tbody > tr > [data-label]::after { + display: var(--gl-table-stacked-label-display, none); + clear: both; + content: ""; + } -table.gl-table:is( - .b-table-stacked, - .b-table-stacked-sm, - .b-table-stacked-md, - .b-table-stacked-lg, - .b-table-stacked-xl -) > tbody > tr > [data-label] > .gl-table-cell-content { - display: var(--gl-table-stacked-content-display, block); - width: var(--gl-table-stacked-content-width, auto); - padding-left: var(--gl-table-stacked-content-padding-left, 0); - margin: 0; -} + > tbody > tr > [data-label] > .gl-table-cell-content { + display: var(--gl-table-stacked-content-display, block); + width: var(--gl-table-stacked-content-width, auto); + padding-left: var(--gl-table-stacked-content-padding-left, 0); + margin: 0; + } -table.gl-table:is( - .b-table-stacked, - .b-table-stacked-sm, - .b-table-stacked-md, - .b-table-stacked-lg, - .b-table-stacked-xl -) > tbody > tr > :first-child, -table.gl-table:is( - .b-table-stacked, - .b-table-stacked-sm, - .b-table-stacked-md, - .b-table-stacked-lg, - .b-table-stacked-xl -) > tbody > tr > [rowspan] + td, -table.gl-table:is( - .b-table-stacked, - .b-table-stacked-sm, - .b-table-stacked-md, - .b-table-stacked-lg, - .b-table-stacked-xl -) > tbody > tr > [rowspan] + th { - border-top-width: var(--gl-table-stacked-heavy-border-width, 1px); + > tbody > tr > :first-child, + > tbody > tr > [rowspan] + td, + > tbody > tr > [rowspan] + th { + border-top-width: var(--gl-table-stacked-heavy-border-width, 1px); + } } diff --git a/packages/styles/src/typography.css b/packages/styles/src/typography.css index 1dcd448..a0e12ca 100644 --- a/packages/styles/src/typography.css +++ b/packages/styles/src/typography.css @@ -46,17 +46,17 @@ kbd { .table { @apply gl-mb-3 gl-w-full gl-bg-transparent gl-text-default; -} -.table th, -.table td { - @apply gl-border-t gl-p-4 gl-align-top; -} + th, + td { + @apply gl-border-t gl-p-4 gl-align-top; + } -.table thead th { - @apply gl-border-b gl-border-b-2 gl-align-bottom; -} + thead th { + @apply gl-border-b gl-border-b-2 gl-align-bottom; + } -.table tbody + tbody { - @apply gl-border-t gl-border-t-2; + tbody + tbody { + @apply gl-border-t gl-border-t-2; + } } diff --git a/packages/ui/src/base/accordion/accordion.css b/packages/ui/src/base/accordion/accordion.css index d659dcf..900bd59 100644 --- a/packages/ui/src/base/accordion/accordion.css +++ b/packages/ui/src/base/accordion/accordion.css @@ -9,10 +9,10 @@ .gl-accordion-item { @apply gl-mb-5; -} -.gl-accordion-item:last-child { - @apply gl-mb-0; + &:last-child { + @apply gl-mb-0; + } } .gl-accordion-item-header { diff --git a/packages/ui/src/base/alert/alert.css b/packages/ui/src/base/alert/alert.css index 0827530..564f2e8 100644 --- a/packages/ui/src/base/alert/alert.css +++ b/packages/ui/src/base/alert/alert.css @@ -40,10 +40,10 @@ .gl-link:not(.gl-label-link) { @apply gl-underline; } -} -.gl-alert-not-dismissible { - padding-right: calc(1rem + var(--gl-alert-padding-x, 0px)); + &-not-dismissible { + padding-right: calc(1rem + var(--gl-alert-padding-x, 0px)); + } } .gl-alert-sticky { diff --git a/packages/ui/src/base/attribute-list/attribute-list.css b/packages/ui/src/base/attribute-list/attribute-list.css index 682d044..aa51739 100644 --- a/packages/ui/src/base/attribute-list/attribute-list.css +++ b/packages/ui/src/base/attribute-list/attribute-list.css @@ -14,26 +14,24 @@ @apply gl-gap-x-7; } -@container (min-width: 25rem) { - .gl-attribute-list-horizontal-items { +.gl-attribute-list-horizontal-items { + @container (min-width: 25rem) { grid-template-columns: fit-content(15rem) 1fr; - } - .gl-attribute-list-horizontal-items .gl-attribute-list-item { - @apply gl-col-span-2; + .gl-attribute-list-item { + @apply gl-col-span-2; + } } -} -@container (min-width: 54rem) { - .gl-attribute-list-horizontal-items { + @container (min-width: 54rem) { grid-template-columns: repeat(2, fit-content(15rem) 1fr); @apply gl-grid-flow-col; grid-template-rows: repeat(var(--attribute-list-row-count), auto); } } -@container (min-width: 40rem) { - .gl-attribute-list-vertical-items { +.gl-attribute-list-vertical-items { + @container (min-width: 40rem) { @apply gl-grid-cols-2; @apply gl-grid-flow-col; grid-template-rows: repeat(var(--attribute-list-row-count), auto); diff --git a/packages/ui/src/base/avatar-labeled/avatar-labeled.css b/packages/ui/src/base/avatar-labeled/avatar-labeled.css index c946d2b..a12b730 100644 --- a/packages/ui/src/base/avatar-labeled/avatar-labeled.css +++ b/packages/ui/src/base/avatar-labeled/avatar-labeled.css @@ -5,25 +5,27 @@ .gl-avatar-labeled { @apply gl-inline-flex; -} -.gl-avatar-labeled-labels { - @apply gl-ml-3 gl-flex gl-flex-col gl-justify-center gl-text-base gl-leading-normal gl-text-strong !gl-text-left; -} + &-labels { + @apply gl-ml-3 gl-flex gl-flex-col gl-justify-center gl-text-base gl-leading-normal gl-text-strong !gl-text-left; + } -.gl-avatar-labeled-labels.inline-labels { - @apply gl-flex-row gl-items-center gl-gap-2; + &-labels.inline-labels { + @apply gl-flex-row gl-items-center gl-gap-2; + } } .gl-avatar-labeled-label-row { @apply -gl-mx-1 -gl-my-1 gl-flex gl-flex-wrap gl-items-center !gl-text-left; } -.gl-avatar-labeled-label { - @apply gl-p-1 gl-font-bold gl-text-strong; -} +.gl-avatar-labeled { + &-label { + @apply gl-p-1 gl-font-bold gl-text-strong; + } -.gl-avatar-labeled-sublabel { - @apply gl-text-subtle; - overflow-wrap: anywhere; + &-sublabel { + @apply gl-text-subtle; + overflow-wrap: anywhere; + } } diff --git a/packages/ui/src/base/avatar-link/avatar-link.css b/packages/ui/src/base/avatar-link/avatar-link.css index 924067a..444ab7e 100644 --- a/packages/ui/src/base/avatar-link/avatar-link.css +++ b/packages/ui/src/base/avatar-link/avatar-link.css @@ -5,34 +5,34 @@ .gl-avatar-link { @apply gl-inline-flex; -} -.gl-avatar-link .gl-avatar { - @apply gl-transition-border-color gl-duration-slow gl-ease-ease; -} + .gl-avatar { + @apply gl-transition-border-color gl-duration-slow gl-ease-ease; + } -.gl-avatar-link:hover { - @apply gl-no-underline; -} + &:hover { + @apply gl-no-underline; -.gl-avatar-link:hover .gl-avatar { - outline: 1px solid var(--gl-avatar-border-color-hover); -} + .gl-avatar { + outline: 1px solid var(--gl-avatar-border-color-hover); + } -.gl-avatar-link:hover .gl-avatar-labeled-label, -.gl-avatar-link:hover .gl-avatar-labeled-sublabel { - @apply gl-underline; -} + .gl-avatar-labeled { + &-label, + &-sublabel { + @apply gl-underline; + } + } + } -.gl-avatar-link:active, -.gl-avatar-link:focus-visible, -.gl-avatar-link:focus-visible:active { - box-shadow: none !important; - outline: none !important; -} + &:active, + &:focus-visible, + &:focus-visible:active { + box-shadow: none !important; + outline: none !important; -.gl-avatar-link:active .gl-avatar, -.gl-avatar-link:focus-visible .gl-avatar, -.gl-avatar-link:focus-visible:active .gl-avatar { - @apply gl-focus; + .gl-avatar { + @apply gl-focus; + } + } } diff --git a/packages/ui/src/base/badge/badge.css b/packages/ui/src/base/badge/badge.css index 2687bdb..25b6e55 100644 --- a/packages/ui/src/base/badge/badge.css +++ b/packages/ui/src/base/badge/badge.css @@ -16,32 +16,28 @@ background-color 0.2s cubic-bezier(0.22, 0.61, 0.36, 1), border-color 0.2s cubic-bezier(0.22, 0.61, 0.36, 1), box-shadow 0.2s cubic-bezier(0.22, 0.61, 0.36, 1); -} -@media (prefers-reduced-motion) { - .gl-badge { + @media (prefers-reduced-motion) { transition-duration: 0.01ms !important; transition-delay: 0ms !important; } -} -.gl-badge:has(.gl-truncate, .gl-text-truncate) { - @apply gl-max-w-full; -} + &:has(.gl-truncate, .gl-text-truncate) { + @apply gl-max-w-full; + } -@media (forced-colors: active) { - .gl-badge { + @media (forced-colors: active) { border: 1px solid; } -} -.gl-badge .gl-badge-icon { - @apply gl-h-5 gl-w-5 gl-shrink-0; - top: auto; -} + .gl-badge-icon { + @apply gl-h-5 gl-w-5 gl-shrink-0; + top: auto; + } -.gl-badge .gl-badge-content { - @apply gl-flex gl-justify-center gl-min-w-3; + .gl-badge-content { + @apply gl-flex gl-justify-center gl-min-w-3; + } } a.gl-badge.disabled { @@ -53,48 +49,49 @@ a.gl-badge.disabled { .gl-badge.badge-neutral { color: var(--gl-badge-neutral-text-color-default); background-color: var(--gl-badge-neutral-background-color-default); -} -.gl-badge.badge-neutral .gl-badge-icon { - color: var(--gl-badge-neutral-icon-color-default); - transition: inherit; + .gl-badge-icon { + color: var(--gl-badge-neutral-icon-color-default); + transition: inherit; + } } -a.gl-badge.badge-neutral:not(.disabled):hover { - @apply gl-no-underline; - color: var(--gl-badge-neutral-text-color-hover); - background-color: var(--gl-badge-neutral-background-color-hover); - box-shadow: inset 0 0 0 1px var(--gl-badge-neutral-border-color-hover); -} +a.gl-badge.badge-neutral:not(.disabled) { + &:hover { + @apply gl-no-underline; + color: var(--gl-badge-neutral-text-color-hover); + background-color: var(--gl-badge-neutral-background-color-hover); + box-shadow: inset 0 0 0 1px var(--gl-badge-neutral-border-color-hover); -a.gl-badge.badge-neutral:not(.disabled):hover .gl-badge-icon { - color: var(--gl-badge-neutral-icon-color-hover); -} + .gl-badge-icon { + color: var(--gl-badge-neutral-icon-color-hover); + } + } -a.gl-badge.badge-neutral:not(.disabled):focus-visible { - color: var(--gl-badge-neutral-text-color-focus); - background-color: var(--gl-badge-neutral-background-color-focus); -} + &:focus-visible { + color: var(--gl-badge-neutral-text-color-focus); + background-color: var(--gl-badge-neutral-background-color-focus); -a.gl-badge.badge-neutral:not(.disabled):focus-visible .gl-badge-icon { - color: var(--gl-badge-neutral-icon-color-focus); -} + .gl-badge-icon { + color: var(--gl-badge-neutral-icon-color-focus); + } + } -a.gl-badge.badge-neutral:not(.disabled).active, -a.gl-badge.badge-neutral:not(.disabled):active { - color: var(--gl-badge-neutral-text-color-active); - background-color: var(--gl-badge-neutral-background-color-active); -} + &.active, + &:active { + color: var(--gl-badge-neutral-text-color-active); + background-color: var(--gl-badge-neutral-background-color-active); -a.gl-badge.badge-neutral:not(.disabled).active .gl-badge-icon, -a.gl-badge.badge-neutral:not(.disabled):active .gl-badge-icon { - color: var(--gl-badge-neutral-icon-color-active); -} + .gl-badge-icon { + color: var(--gl-badge-neutral-icon-color-active); + } + } -a.gl-badge.badge-neutral:not(.disabled):active, -a.gl-badge.badge-neutral:not(.disabled):focus-visible, -a.gl-badge.badge-neutral:not(.disabled):focus-visible:active { - @apply gl-focus; + &:active, + &:focus-visible, + &:focus-visible:active { + @apply gl-focus; + } } /* Info */ @@ -102,48 +99,49 @@ a.gl-badge.badge-neutral:not(.disabled):focus-visible:active { .gl-badge.badge-info { color: var(--gl-badge-info-text-color-default); background-color: var(--gl-badge-info-background-color-default); -} -.gl-badge.badge-info .gl-badge-icon { - color: var(--gl-badge-info-icon-color-default); - transition: inherit; + .gl-badge-icon { + color: var(--gl-badge-info-icon-color-default); + transition: inherit; + } } -a.gl-badge.badge-info:not(.disabled):hover { - @apply gl-no-underline; - color: var(--gl-badge-info-text-color-hover); - background-color: var(--gl-badge-info-background-color-hover); - box-shadow: inset 0 0 0 1px var(--gl-badge-info-border-color-hover); -} +a.gl-badge.badge-info:not(.disabled) { + &:hover { + @apply gl-no-underline; + color: var(--gl-badge-info-text-color-hover); + background-color: var(--gl-badge-info-background-color-hover); + box-shadow: inset 0 0 0 1px var(--gl-badge-info-border-color-hover); -a.gl-badge.badge-info:not(.disabled):hover .gl-badge-icon { - color: var(--gl-badge-info-icon-color-hover); -} + .gl-badge-icon { + color: var(--gl-badge-info-icon-color-hover); + } + } -a.gl-badge.badge-info:not(.disabled):focus-visible { - color: var(--gl-badge-info-text-color-focus); - background-color: var(--gl-badge-info-background-color-focus); -} + &:focus-visible { + color: var(--gl-badge-info-text-color-focus); + background-color: var(--gl-badge-info-background-color-focus); -a.gl-badge.badge-info:not(.disabled):focus-visible .gl-badge-icon { - color: var(--gl-badge-info-icon-color-focus); -} + .gl-badge-icon { + color: var(--gl-badge-info-icon-color-focus); + } + } -a.gl-badge.badge-info:not(.disabled).active, -a.gl-badge.badge-info:not(.disabled):active { - color: var(--gl-badge-info-text-color-active); - background-color: var(--gl-badge-info-background-color-active); -} + &.active, + &:active { + color: var(--gl-badge-info-text-color-active); + background-color: var(--gl-badge-info-background-color-active); -a.gl-badge.badge-info:not(.disabled).active .gl-badge-icon, -a.gl-badge.badge-info:not(.disabled):active .gl-badge-icon { - color: var(--gl-badge-info-icon-color-active); -} + .gl-badge-icon { + color: var(--gl-badge-info-icon-color-active); + } + } -a.gl-badge.badge-info:not(.disabled):active, -a.gl-badge.badge-info:not(.disabled):focus-visible, -a.gl-badge.badge-info:not(.disabled):focus-visible:active { - @apply gl-focus; + &:active, + &:focus-visible, + &:focus-visible:active { + @apply gl-focus; + } } /* Success */ @@ -151,48 +149,49 @@ a.gl-badge.badge-info:not(.disabled):focus-visible:active { .gl-badge.badge-success { color: var(--gl-badge-success-text-color-default); background-color: var(--gl-badge-success-background-color-default); -} -.gl-badge.badge-success .gl-badge-icon { - color: var(--gl-badge-success-icon-color-default); - transition: inherit; + .gl-badge-icon { + color: var(--gl-badge-success-icon-color-default); + transition: inherit; + } } -a.gl-badge.badge-success:not(.disabled):hover { - @apply gl-no-underline; - color: var(--gl-badge-success-text-color-hover); - background-color: var(--gl-badge-success-background-color-hover); - box-shadow: inset 0 0 0 1px var(--gl-badge-success-border-color-hover); -} +a.gl-badge.badge-success:not(.disabled) { + &:hover { + @apply gl-no-underline; + color: var(--gl-badge-success-text-color-hover); + background-color: var(--gl-badge-success-background-color-hover); + box-shadow: inset 0 0 0 1px var(--gl-badge-success-border-color-hover); -a.gl-badge.badge-success:not(.disabled):hover .gl-badge-icon { - color: var(--gl-badge-success-icon-color-hover); -} + .gl-badge-icon { + color: var(--gl-badge-success-icon-color-hover); + } + } -a.gl-badge.badge-success:not(.disabled):focus-visible { - color: var(--gl-badge-success-text-color-focus); - background-color: var(--gl-badge-success-background-color-focus); -} + &:focus-visible { + color: var(--gl-badge-success-text-color-focus); + background-color: var(--gl-badge-success-background-color-focus); -a.gl-badge.badge-success:not(.disabled):focus-visible .gl-badge-icon { - color: var(--gl-badge-success-icon-color-focus); -} + .gl-badge-icon { + color: var(--gl-badge-success-icon-color-focus); + } + } -a.gl-badge.badge-success:not(.disabled).active, -a.gl-badge.badge-success:not(.disabled):active { - color: var(--gl-badge-success-text-color-active); - background-color: var(--gl-badge-success-background-color-active); -} + &.active, + &:active { + color: var(--gl-badge-success-text-color-active); + background-color: var(--gl-badge-success-background-color-active); -a.gl-badge.badge-success:not(.disabled).active .gl-badge-icon, -a.gl-badge.badge-success:not(.disabled):active .gl-badge-icon { - color: var(--gl-badge-success-icon-color-active); -} + .gl-badge-icon { + color: var(--gl-badge-success-icon-color-active); + } + } -a.gl-badge.badge-success:not(.disabled):active, -a.gl-badge.badge-success:not(.disabled):focus-visible, -a.gl-badge.badge-success:not(.disabled):focus-visible:active { - @apply gl-focus; + &:active, + &:focus-visible, + &:focus-visible:active { + @apply gl-focus; + } } /* Warning */ @@ -200,48 +199,49 @@ a.gl-badge.badge-success:not(.disabled):focus-visible:active { .gl-badge.badge-warning { color: var(--gl-badge-warning-text-color-default); background-color: var(--gl-badge-warning-background-color-default); -} -.gl-badge.badge-warning .gl-badge-icon { - color: var(--gl-badge-warning-icon-color-default); - transition: inherit; + .gl-badge-icon { + color: var(--gl-badge-warning-icon-color-default); + transition: inherit; + } } -a.gl-badge.badge-warning:not(.disabled):hover { - @apply gl-no-underline; - color: var(--gl-badge-warning-text-color-hover); - background-color: var(--gl-badge-warning-background-color-hover); - box-shadow: inset 0 0 0 1px var(--gl-badge-warning-border-color-hover); -} +a.gl-badge.badge-warning:not(.disabled) { + &:hover { + @apply gl-no-underline; + color: var(--gl-badge-warning-text-color-hover); + background-color: var(--gl-badge-warning-background-color-hover); + box-shadow: inset 0 0 0 1px var(--gl-badge-warning-border-color-hover); -a.gl-badge.badge-warning:not(.disabled):hover .gl-badge-icon { - color: var(--gl-badge-warning-icon-color-hover); -} + .gl-badge-icon { + color: var(--gl-badge-warning-icon-color-hover); + } + } -a.gl-badge.badge-warning:not(.disabled):focus-visible { - color: var(--gl-badge-warning-text-color-focus); - background-color: var(--gl-badge-warning-background-color-focus); -} + &:focus-visible { + color: var(--gl-badge-warning-text-color-focus); + background-color: var(--gl-badge-warning-background-color-focus); -a.gl-badge.badge-warning:not(.disabled):focus-visible .gl-badge-icon { - color: var(--gl-badge-warning-icon-color-focus); -} + .gl-badge-icon { + color: var(--gl-badge-warning-icon-color-focus); + } + } -a.gl-badge.badge-warning:not(.disabled).active, -a.gl-badge.badge-warning:not(.disabled):active { - color: var(--gl-badge-warning-text-color-active); - background-color: var(--gl-badge-warning-background-color-active); -} + &.active, + &:active { + color: var(--gl-badge-warning-text-color-active); + background-color: var(--gl-badge-warning-background-color-active); -a.gl-badge.badge-warning:not(.disabled).active .gl-badge-icon, -a.gl-badge.badge-warning:not(.disabled):active .gl-badge-icon { - color: var(--gl-badge-warning-icon-color-active); -} + .gl-badge-icon { + color: var(--gl-badge-warning-icon-color-active); + } + } -a.gl-badge.badge-warning:not(.disabled):active, -a.gl-badge.badge-warning:not(.disabled):focus-visible, -a.gl-badge.badge-warning:not(.disabled):focus-visible:active { - @apply gl-focus; + &:active, + &:focus-visible, + &:focus-visible:active { + @apply gl-focus; + } } /* Danger */ @@ -249,48 +249,49 @@ a.gl-badge.badge-warning:not(.disabled):focus-visible:active { .gl-badge.badge-danger { color: var(--gl-badge-danger-text-color-default); background-color: var(--gl-badge-danger-background-color-default); -} -.gl-badge.badge-danger .gl-badge-icon { - color: var(--gl-badge-danger-icon-color-default); - transition: inherit; + .gl-badge-icon { + color: var(--gl-badge-danger-icon-color-default); + transition: inherit; + } } -a.gl-badge.badge-danger:not(.disabled):hover { - @apply gl-no-underline; - color: var(--gl-badge-danger-text-color-hover); - background-color: var(--gl-badge-danger-background-color-hover); - box-shadow: inset 0 0 0 1px var(--gl-badge-danger-border-color-hover); -} +a.gl-badge.badge-danger:not(.disabled) { + &:hover { + @apply gl-no-underline; + color: var(--gl-badge-danger-text-color-hover); + background-color: var(--gl-badge-danger-background-color-hover); + box-shadow: inset 0 0 0 1px var(--gl-badge-danger-border-color-hover); -a.gl-badge.badge-danger:not(.disabled):hover .gl-badge-icon { - color: var(--gl-badge-danger-icon-color-hover); -} + .gl-badge-icon { + color: var(--gl-badge-danger-icon-color-hover); + } + } -a.gl-badge.badge-danger:not(.disabled):focus-visible { - color: var(--gl-badge-danger-text-color-focus); - background-color: var(--gl-badge-danger-background-color-focus); -} + &:focus-visible { + color: var(--gl-badge-danger-text-color-focus); + background-color: var(--gl-badge-danger-background-color-focus); -a.gl-badge.badge-danger:not(.disabled):focus-visible .gl-badge-icon { - color: var(--gl-badge-danger-icon-color-focus); -} + .gl-badge-icon { + color: var(--gl-badge-danger-icon-color-focus); + } + } -a.gl-badge.badge-danger:not(.disabled).active, -a.gl-badge.badge-danger:not(.disabled):active { - color: var(--gl-badge-danger-text-color-active); - background-color: var(--gl-badge-danger-background-color-active); -} + &.active, + &:active { + color: var(--gl-badge-danger-text-color-active); + background-color: var(--gl-badge-danger-background-color-active); -a.gl-badge.badge-danger:not(.disabled).active .gl-badge-icon, -a.gl-badge.badge-danger:not(.disabled):active .gl-badge-icon { - color: var(--gl-badge-danger-icon-color-active); -} + .gl-badge-icon { + color: var(--gl-badge-danger-icon-color-active); + } + } -a.gl-badge.badge-danger:not(.disabled):active, -a.gl-badge.badge-danger:not(.disabled):focus-visible, -a.gl-badge.badge-danger:not(.disabled):focus-visible:active { - @apply gl-focus; + &:active, + &:focus-visible, + &:focus-visible:active { + @apply gl-focus; + } } /* Tier */ @@ -298,48 +299,49 @@ a.gl-badge.badge-danger:not(.disabled):focus-visible:active { .gl-badge.badge-tier { color: var(--gl-badge-tier-text-color-default); background-color: var(--gl-badge-tier-background-color-default); -} -.gl-badge.badge-tier .gl-badge-icon { - color: var(--gl-badge-tier-icon-color-default); - transition: inherit; + .gl-badge-icon { + color: var(--gl-badge-tier-icon-color-default); + transition: inherit; + } } -a.gl-badge.badge-tier:not(.disabled):hover { - @apply gl-no-underline; - color: var(--gl-badge-tier-text-color-hover); - background-color: var(--gl-badge-tier-background-color-hover); - box-shadow: inset 0 0 0 1px var(--gl-badge-tier-border-color-hover); -} +a.gl-badge.badge-tier:not(.disabled) { + &:hover { + @apply gl-no-underline; + color: var(--gl-badge-tier-text-color-hover); + background-color: var(--gl-badge-tier-background-color-hover); + box-shadow: inset 0 0 0 1px var(--gl-badge-tier-border-color-hover); -a.gl-badge.badge-tier:not(.disabled):hover .gl-badge-icon { - color: var(--gl-badge-tier-icon-color-hover); -} + .gl-badge-icon { + color: var(--gl-badge-tier-icon-color-hover); + } + } -a.gl-badge.badge-tier:not(.disabled):focus-visible { - color: var(--gl-badge-tier-text-color-focus); - background-color: var(--gl-badge-tier-background-color-focus); -} + &:focus-visible { + color: var(--gl-badge-tier-text-color-focus); + background-color: var(--gl-badge-tier-background-color-focus); -a.gl-badge.badge-tier:not(.disabled):focus-visible .gl-badge-icon { - color: var(--gl-badge-tier-icon-color-focus); -} + .gl-badge-icon { + color: var(--gl-badge-tier-icon-color-focus); + } + } -a.gl-badge.badge-tier:not(.disabled).active, -a.gl-badge.badge-tier:not(.disabled):active { - color: var(--gl-badge-tier-text-color-active); - background-color: var(--gl-badge-tier-background-color-active); -} + &.active, + &:active { + color: var(--gl-badge-tier-text-color-active); + background-color: var(--gl-badge-tier-background-color-active); -a.gl-badge.badge-tier:not(.disabled).active .gl-badge-icon, -a.gl-badge.badge-tier:not(.disabled):active .gl-badge-icon { - color: var(--gl-badge-tier-icon-color-active); -} + .gl-badge-icon { + color: var(--gl-badge-tier-icon-color-active); + } + } -a.gl-badge.badge-tier:not(.disabled):active, -a.gl-badge.badge-tier:not(.disabled):focus-visible, -a.gl-badge.badge-tier:not(.disabled):focus-visible:active { - @apply gl-focus; + &:active, + &:focus-visible, + &:focus-visible:active { + @apply gl-focus; + } } /* diff --git a/packages/ui/src/base/broadcast-message/broadcast-message.css b/packages/ui/src/base/broadcast-message/broadcast-message.css index 7fa5f7a..58f5109 100644 --- a/packages/ui/src/base/broadcast-message/broadcast-message.css +++ b/packages/ui/src/base/broadcast-message/broadcast-message.css @@ -114,39 +114,39 @@ border-radius: var(--gl-broadcast-banner-border-radius); max-width: 18.75rem; } -} -.gl-broadcast-message-content { - @apply gl-flex; - @apply gl-justify-center; + &-content { + @apply gl-flex; + @apply gl-justify-center; - a { - @apply gl-text-inherit; - @apply gl-underline; - } + a { + @apply gl-text-inherit; + @apply gl-underline; + } - p:last-of-type { - @apply gl-mb-0; + p:last-of-type { + @apply gl-mb-0; + } } -} -.gl-broadcast-message-icon { - @apply gl-mr-5; - line-height: 1rem; + &-icon { + @apply gl-mr-5; + line-height: 1rem; - > svg { - @apply gl-align-bottom; + > svg { + @apply gl-align-bottom; + } } -} -.gl-broadcast-message-text { - margin-top: -0.125rem; - margin-bottom: -0.125rem; - @apply gl-hyphens-auto gl-break-anywhere; -} + &-text { + margin-top: -0.125rem; + margin-bottom: -0.125rem; + @apply gl-hyphens-auto gl-break-anywhere; + } -.gl-broadcast-message-dismiss { - @apply -gl-my-2; - @apply gl-ml-5; - color: inherit !important; + &-dismiss { + @apply -gl-my-2; + @apply gl-ml-5; + color: inherit !important; + } } diff --git a/packages/ui/src/base/button-group/button-group.css b/packages/ui/src/base/button-group/button-group.css index aa75904..ed6de4a 100644 --- a/packages/ui/src/base/button-group/button-group.css +++ b/packages/ui/src/base/button-group/button-group.css @@ -31,170 +31,88 @@ .gl-button-group:not(.gl-keyset-pagination), .btn-group:not(.gl-keyset-pagination), .gl-dropdown.btn-group -) > .gl-button:not(:first-child), -:is( - .gl-button-group:not(.gl-keyset-pagination), - .btn-group:not(.gl-keyset-pagination), - .gl-dropdown.btn-group -) > .btn-group:not(:first-child) > .gl-button, -:is( - .gl-button-group:not(.gl-keyset-pagination), - .btn-group:not(.gl-keyset-pagination), - .gl-dropdown.btn-group -) > .gl-new-dropdown:not(:first-child) > .gl-button { - @apply gl-rounded-l-none gl-border-l-0; -} - -:is( - .gl-button-group:not(.gl-keyset-pagination), - .btn-group:not(.gl-keyset-pagination), - .gl-dropdown.btn-group -) > .gl-button:not(:last-child):not(.dropdown-toggle), -:is( - .gl-button-group:not(.gl-keyset-pagination), - .btn-group:not(.gl-keyset-pagination), - .gl-dropdown.btn-group -) > .btn-group:not(:last-child) > .gl-button, -:is( - .gl-button-group:not(.gl-keyset-pagination), - .btn-group:not(.gl-keyset-pagination), - .gl-dropdown.btn-group -) > .gl-new-dropdown:not(:last-child) > .gl-button { - @apply gl-rounded-r-none gl-border-r-0; -} - -:is( - .gl-button-group:not(.gl-keyset-pagination), - .btn-group:not(.gl-keyset-pagination), - .gl-dropdown.btn-group -) > .gl-button:not(:first-child), -:is( - .gl-button-group:not(.gl-keyset-pagination), - .btn-group:not(.gl-keyset-pagination), - .gl-dropdown.btn-group -) > .btn-group:not(:first-child) > .gl-button, -:is( - .gl-button-group:not(.gl-keyset-pagination), - .btn-group:not(.gl-keyset-pagination), - .gl-dropdown.btn-group -) > .gl-new-dropdown:not(:first-child) > .gl-button { - @apply gl-relative gl-isolate gl-ml-[1px]; -} - -:is( - .gl-button-group:not(.gl-keyset-pagination), - .btn-group:not(.gl-keyset-pagination), - .gl-dropdown.btn-group -) > .gl-button:not(:first-child)::before, -:is( - .gl-button-group:not(.gl-keyset-pagination), - .btn-group:not(.gl-keyset-pagination), - .gl-dropdown.btn-group -) > .btn-group:not(:first-child) > .gl-button::before, -:is( - .gl-button-group:not(.gl-keyset-pagination), - .btn-group:not(.gl-keyset-pagination), - .gl-dropdown.btn-group -) > .gl-new-dropdown:not(:first-child) > .gl-button::before { - content: ""; - @apply gl-absolute gl-bottom-[-1px] gl-left-[-1px] gl-top-[-1px] gl-block gl-w-[1px]; - z-index: 4; -} +) { + > .gl-button:not(:first-child), + > .btn-group:not(:first-child) > .gl-button, + > .gl-new-dropdown:not(:first-child) > .gl-button { + @apply gl-rounded-l-none gl-border-l-0; + } -:is( - .gl-button-group:not(.gl-keyset-pagination), - .btn-group:not(.gl-keyset-pagination), - .gl-dropdown.btn-group -) > .gl-button:is(:focus-visible, :active, .active) { - z-index: 3; -} + > .gl-button:not(:last-child):not(.dropdown-toggle), + > .btn-group:not(:last-child) > .gl-button, + > .gl-new-dropdown:not(:last-child) > .gl-button { + @apply gl-rounded-r-none gl-border-r-0; + } + + > .gl-button:not(:first-child), + > .btn-group:not(:first-child) > .gl-button, + > .gl-new-dropdown:not(:first-child) > .gl-button { + @apply gl-relative gl-isolate gl-ml-[1px]; + + &::before { + content: ""; + @apply gl-absolute gl-bottom-[-1px] gl-left-[-1px] gl-top-[-1px] gl-block gl-w-[1px]; + z-index: 4; + } + } + + > .gl-button:is(:focus-visible, :active, .active) { + z-index: 3; + } -:is( - .gl-button-group:not(.gl-keyset-pagination), - .btn-group:not(.gl-keyset-pagination), - .gl-dropdown.btn-group -) :is(.btn-confirm, .btn-danger):not(.disabled):not([disabled])::before { - @apply gl-bg-transparent; -} + :is(.btn-confirm, .btn-danger):not(.disabled):not([disabled])::before { + @apply gl-bg-transparent; + } -:is( - .gl-button-group:not(.gl-keyset-pagination), - .btn-group:not(.gl-keyset-pagination), - .gl-dropdown.btn-group -) .gl-button.btn-icon .gl-button-text .gl-button-icon { - @apply gl-mr-[-1px]; -} + .gl-button.btn-icon .gl-button-text .gl-button-icon { + @apply gl-mr-[-1px]; + } -:is( - .gl-button-group:not(.gl-keyset-pagination), - .btn-group:not(.gl-keyset-pagination), - .gl-dropdown.btn-group -):is(.disabled, [disabled])::before { - background-color: var(--gl-button-disabled-border-color); -} + &:is(.disabled, [disabled])::before { + background-color: var(--gl-button-disabled-border-color); + } -:is( - .gl-button-group:not(.gl-keyset-pagination), - .btn-group:not(.gl-keyset-pagination), - .gl-dropdown.btn-group -) .btn-confirm-secondary:not(.disabled):not([disabled])::before { - background-color: var(--gl-button-confirm-secondary-border-color-default); -} + .btn-confirm-secondary:not(.disabled):not([disabled])::before { + background-color: var(--gl-button-confirm-secondary-border-color-default); + } -:is( - .gl-button-group:not(.gl-keyset-pagination), - .btn-group:not(.gl-keyset-pagination), - .gl-dropdown.btn-group -) .btn-danger-secondary:not(.disabled):not([disabled])::before { - background-color: var(--gl-button-danger-secondary-border-color-default); + .btn-danger-secondary:not(.disabled):not([disabled])::before { + background-color: var(--gl-button-danger-secondary-border-color-default); + } } :is(.gl-button-group-vertical, .btn-group-vertical) { @apply gl-flex-col gl-items-start gl-justify-center; -} -:is(.gl-button-group-vertical, .btn-group-vertical) > :is(.gl-button, .btn-group) { - @apply gl-relative gl-w-full; -} + > :is(.gl-button, .btn-group) { + @apply gl-relative gl-w-full; + } -:is(.gl-button-group-vertical, .btn-group-vertical) > .gl-button:not(:first-child), -:is(.gl-button-group-vertical, .btn-group-vertical) > .btn-group:not(:first-child) > .gl-button, -:is(.gl-button-group-vertical, .btn-group-vertical) - > .gl-new-dropdown:not(:first-child) - > .gl-button { - @apply gl-rounded-t-none gl-border-t-0; -} + > .gl-button:not(:first-child), + > .btn-group:not(:first-child) > .gl-button, + > .gl-new-dropdown:not(:first-child) > .gl-button { + @apply gl-rounded-t-none gl-border-t-0; + } -:is(.gl-button-group-vertical, .btn-group-vertical) > .gl-button:not(:last-child):not(.dropdown-toggle), -:is(.gl-button-group-vertical, .btn-group-vertical) > .btn-group:not(:last-child) > .gl-button, -:is(.gl-button-group-vertical, .btn-group-vertical) - > .gl-new-dropdown:not(:last-child) - > .gl-button { - @apply gl-rounded-b-none gl-border-b-0; -} - -:is(.gl-button-group-vertical, .btn-group-vertical) > .gl-button:not(:first-child), -:is(.gl-button-group-vertical, .btn-group-vertical) > .btn-group:not(:first-child) > .gl-button, -:is(.gl-button-group-vertical, .btn-group-vertical) - > .gl-new-dropdown:not(:first-child) - > .gl-button { - @apply gl-relative gl-mt-[1px]; -} - -:is(.gl-button-group-vertical, .btn-group-vertical) > .gl-button:not(:first-child)::before, -:is(.gl-button-group-vertical, .btn-group-vertical) - > .btn-group:not(:first-child) - > .gl-button::before, -:is(.gl-button-group-vertical, .btn-group-vertical) - > .gl-new-dropdown:not(:first-child) - > .gl-button::before { - content: ""; - @apply gl-absolute gl-left-[-1px] gl-right-[-1px] gl-top-[-1px] gl-block gl-h-[1px]; - z-index: 4; -} + > .btn-group:not(:last-child) > .gl-button, + > .gl-new-dropdown:not(:last-child) > .gl-button { + @apply gl-rounded-b-none gl-border-b-0; + } + + > .gl-button:not(:first-child), + > .btn-group:not(:first-child) > .gl-button, + > .gl-new-dropdown:not(:first-child) > .gl-button { + @apply gl-relative gl-mt-[1px]; + + &::before { + content: ""; + @apply gl-absolute gl-left-[-1px] gl-right-[-1px] gl-top-[-1px] gl-block gl-h-[1px]; + z-index: 4; + } + } -:is(.gl-button-group-vertical, .btn-group-vertical) :is(.btn-confirm, .btn-danger):not(.disabled):not([disabled])::before { - @apply gl-bg-transparent; + @apply gl-bg-transparent; + } } diff --git a/packages/ui/src/base/button/button.css b/packages/ui/src/base/button/button.css index 9a8a1a0..aa7f6e9 100644 --- a/packages/ui/src/base/button/button.css +++ b/packages/ui/src/base/button/button.css @@ -8,10 +8,12 @@ font-family: inherit; } -.gl-button:not(.btn-link):focus-visible, -.gl-button:not(.btn-link):active, -.gl-button:not(.btn-link):focus-visible:active { - @apply gl-no-underline; +.gl-button:not(.btn-link) { + &:focus-visible, + &:active, + &:focus-visible:active { + @apply gl-no-underline; + } } .gl-button.gl-button { @@ -41,34 +43,34 @@ border-color 0.2s cubic-bezier(0.22, 0.61, 0.36, 1), box-shadow 0.2s cubic-bezier(0.22, 0.61, 0.36, 1), text-decoration-color 0.2s cubic-bezier(0.22, 0.61, 0.36, 1); -} -.gl-button.gl-button::before { - background-color: var(--gl-button-variant-border); - transition: - background-color 0.2s cubic-bezier(0.22, 0.61, 0.36, 1), - border-color 0.2s cubic-bezier(0.22, 0.61, 0.36, 1); -} + &::before { + background-color: var(--gl-button-variant-border); + transition: + background-color 0.2s cubic-bezier(0.22, 0.61, 0.36, 1), + border-color 0.2s cubic-bezier(0.22, 0.61, 0.36, 1); + } -.gl-button.gl-button:hover { - color: var(--gl-button-variant-hover-foreground); - background-color: var(--gl-button-variant-hover-background); - border-color: var(--gl-button-variant-hover-border); -} + &:hover { + color: var(--gl-button-variant-hover-foreground); + background-color: var(--gl-button-variant-hover-background); + border-color: var(--gl-button-variant-hover-border); + } -.gl-button.gl-button:focus-visible, -.gl-button.gl-button:focus-visible:active { - @apply gl-focus; - color: var(--gl-button-variant-focus-foreground); - background-color: var(--gl-button-variant-focus-background); - border-color: var(--gl-button-variant-focus-border); -} + &:focus-visible, + &:focus-visible:active { + @apply gl-focus; + color: var(--gl-button-variant-focus-foreground); + background-color: var(--gl-button-variant-focus-background); + border-color: var(--gl-button-variant-focus-border); + } -.gl-button.gl-button:active, -.gl-button.gl-button.active { - color: var(--gl-button-variant-active-foreground); - background-color: var(--gl-button-variant-active-background); - border-color: var(--gl-button-variant-active-border); + &:active, + &.active { + color: var(--gl-button-variant-active-foreground); + background-color: var(--gl-button-variant-active-background); + border-color: var(--gl-button-variant-active-border); + } } .gl-button.btn-default, @@ -291,23 +293,23 @@ text-decoration-color: transparent; text-decoration-style: solid; text-decoration-thickness: auto; -} -.gl-button.gl-button.btn-link:hover { - @apply gl-bg-transparent; - color: var(--gl-button-link-text-color-hover); - text-decoration-color: var(--gl-button-link-text-color-hover); -} + &:hover { + @apply gl-bg-transparent; + color: var(--gl-button-link-text-color-hover); + text-decoration-color: var(--gl-button-link-text-color-hover); + } -.gl-button.gl-button.btn-link:active { - @apply gl-bg-transparent; - color: var(--gl-button-link-text-color-active); - text-decoration-color: var(--gl-button-link-text-color-active); -} + &:active { + @apply gl-bg-transparent; + color: var(--gl-button-link-text-color-active); + text-decoration-color: var(--gl-button-link-text-color-active); + } -.gl-button.gl-button.btn-link:focus-visible, -.gl-button.gl-button.btn-link:focus-visible:active { - @apply gl-bg-transparent; + &:focus-visible, + &:focus-visible:active { + @apply gl-bg-transparent; + } } .gl-button.gl-button.btn-block { diff --git a/packages/ui/src/base/disclosure-dropdown/disclosure-dropdown.css b/packages/ui/src/base/disclosure-dropdown/disclosure-dropdown.css index 76f8e2f..17fc1a8 100644 --- a/packages/ui/src/base/disclosure-dropdown/disclosure-dropdown.css +++ b/packages/ui/src/base/disclosure-dropdown/disclosure-dropdown.css @@ -3,15 +3,15 @@ * packages/gitlab-ui/src/components/base/new_dropdowns/disclosure/disclosure_dropdown.scss */ -.gl-disclosure-dropdown-panel .gl-new-dropdown-inner { - max-height: none; -} +.gl-disclosure-dropdown-panel { + .gl-new-dropdown-inner { + max-height: none; + } -.gl-disclosure-dropdown-panel - .gl-new-dropdown-item[data-disabled] - > .gl-new-dropdown-item-content { - color: var(--gl-dropdown-option-text-color-disabled); - cursor: not-allowed; - text-decoration: none; - background: none; + .gl-new-dropdown-item[data-disabled] > .gl-new-dropdown-item-content { + color: var(--gl-dropdown-option-text-color-disabled); + cursor: not-allowed; + text-decoration: none; + background: none; + } } diff --git a/packages/ui/src/base/form-checkbox/form-checkbox.css b/packages/ui/src/base/form-checkbox/form-checkbox.css index 4a5f3dd..d939d1a 100644 --- a/packages/ui/src/base/form-checkbox/form-checkbox.css +++ b/packages/ui/src/base/form-checkbox/form-checkbox.css @@ -29,56 +29,49 @@ @apply gl-rounded-base; } -.gl-form-checkbox.custom-control - .custom-control-input[type="checkbox"]:checked - ~ .custom-control-label::after { - mask-image: var(--gl-icon-check); -} +.gl-form-checkbox { + &.custom-control { + .custom-control-input[type="checkbox"]:checked ~ .custom-control-label::after { + mask-image: var(--gl-icon-check); + } -.gl-form-checkbox.custom-control - .custom-control-input[type="checkbox"]:indeterminate - ~ .custom-control-label::after { - mask-image: var(--gl-icon-indeterminate); -} + .custom-control-input[type="checkbox"]:indeterminate ~ .custom-control-label::after { + mask-image: var(--gl-icon-indeterminate); + } -.gl-form-checkbox.custom-control.custom-checkbox - .custom-control-input:indeterminate - ~ .custom-control-label::before { - background-color: var(--gl-control-background-color-selected-default); - border-color: var(--gl-control-border-color-selected-default); -} + &.custom-checkbox { + .custom-control-input:indeterminate ~ .custom-control-label::before { + background-color: var(--gl-control-background-color-selected-default); + border-color: var(--gl-control-border-color-selected-default); + } -@media (forced-colors: active) { - .gl-form-checkbox.custom-control.custom-checkbox - .custom-control-input:indeterminate - ~ .custom-control-label::before { - background-color: LinkText; - border-color: LinkText; - } -} + @media (forced-colors: active) { + .custom-control-input:indeterminate ~ .custom-control-label::before { + background-color: LinkText; + border-color: LinkText; + } + } -.gl-form-checkbox.custom-control.custom-checkbox - .custom-control-input:not(:disabled):indeterminate - ~ .custom-control-label:hover::before { - background-color: var(--gl-control-background-color-selected-hover); - border-color: var(--gl-control-border-color-selected-hover); -} + .custom-control-input:not(:disabled):indeterminate ~ .custom-control-label:hover::before { + background-color: var(--gl-control-background-color-selected-hover); + border-color: var(--gl-control-border-color-selected-hover); + } -.gl-form-checkbox.custom-control.custom-checkbox - .custom-control-input:not(:disabled):focus-visible:indeterminate - ~ .custom-control-label::before { - background-color: var(--gl-control-background-color-selected-focus); - border-color: var(--gl-control-border-color-selected-focus); -} + .custom-control-input:not(:disabled):focus-visible:indeterminate + ~ .custom-control-label::before { + background-color: var(--gl-control-background-color-selected-focus); + border-color: var(--gl-control-border-color-selected-focus); + } -@media (forced-colors: active) { - .gl-form-checkbox.custom-control.custom-checkbox - .custom-control-input:not(:disabled):indeterminate - ~ .custom-control-label:hover::before, - .gl-form-checkbox.custom-control.custom-checkbox - .custom-control-input:not(:disabled):focus-visible:indeterminate - ~ .custom-control-label::before { - background-color: LinkText; - border-color: LinkText; + @media (forced-colors: active) { + .custom-control-input:not(:disabled):indeterminate + ~ .custom-control-label:hover::before, + .custom-control-input:not(:disabled):focus-visible:indeterminate + ~ .custom-control-label::before { + background-color: LinkText; + border-color: LinkText; + } + } + } } } diff --git a/packages/ui/src/base/form-date/form-date.css b/packages/ui/src/base/form-date/form-date.css index c7dc5f9..c3b845a 100644 --- a/packages/ui/src/base/form-date/form-date.css +++ b/packages/ui/src/base/form-date/form-date.css @@ -8,8 +8,10 @@ * packages/styles/src/forms/). */ -.gl-form-date input::-webkit-datetime-edit { - line-height: 1; - padding: 0; - margin-bottom: -2px; +.gl-form-date { + input::-webkit-datetime-edit { + line-height: 1; + padding: 0; + margin-bottom: -2px; + } } diff --git a/packages/ui/src/base/form-input/form-input.css b/packages/ui/src/base/form-input/form-input.css index 8663975..2ac853b 100644 --- a/packages/ui/src/base/form-input/form-input.css +++ b/packages/ui/src/base/form-input/form-input.css @@ -41,60 +41,57 @@ input[type="color"].gl-form-input.form-control:disabled { } /* `` custom-range validation styling (standalone control only) */ -.gl-form-input.custom-range.is-valid:focus::-webkit-slider-thumb, -.gl-form-input.custom-range.is-invalid:focus::-webkit-slider-thumb { - box-shadow: 0 0 0 1px #fff, 0 0 0 0.2rem var(--_range-focus-color); -} - -.gl-form-input.custom-range.is-valid:focus::-moz-range-thumb, -.gl-form-input.custom-range.is-invalid:focus::-moz-range-thumb { - box-shadow: 0 0 0 1px #fff, 0 0 0 0.2rem var(--_range-focus-color); -} - -.gl-form-input.custom-range.is-valid::-webkit-slider-thumb, -.gl-form-input.custom-range.is-invalid::-webkit-slider-thumb { - background-color: var(--_range-color); - background-image: none; -} - -.gl-form-input.custom-range.is-valid::-webkit-slider-thumb:active, -.gl-form-input.custom-range.is-invalid::-webkit-slider-thumb:active { - background-color: var(--_range-focus-color); - background-image: none; -} - -.gl-form-input.custom-range.is-valid::-webkit-slider-runnable-track, -.gl-form-input.custom-range.is-invalid::-webkit-slider-runnable-track { - background-color: var(--_range-track-color); -} - -.gl-form-input.custom-range.is-valid::-moz-range-thumb, -.gl-form-input.custom-range.is-invalid::-moz-range-thumb { - background-color: var(--_range-color); - background-image: none; -} - -.gl-form-input.custom-range.is-valid::-moz-range-thumb:active, -.gl-form-input.custom-range.is-invalid::-moz-range-thumb:active { - background-color: var(--_range-focus-color); - background-image: none; -} - -.gl-form-input.custom-range.is-valid::-moz-range-track, -.gl-form-input.custom-range.is-invalid::-moz-range-track { - background: var(--_range-track-color); -} - -.gl-form-input.custom-range.is-valid { - --_range-color: #2f7549; - --_range-focus-color: #88cfa2; - --_range-track-color: rgba(47, 117, 73, 0.35); -} - -.gl-form-input.custom-range.is-invalid { - --_range-color: #c02f12; - --_range-focus-color: #f5a190; - --_range-track-color: rgba(192, 47, 18, 0.35); +.gl-form-input.custom-range { + &.is-valid, + &.is-invalid { + &:focus::-webkit-slider-thumb { + box-shadow: 0 0 0 1px #fff, 0 0 0 0.2rem var(--_range-focus-color); + } + + &:focus::-moz-range-thumb { + box-shadow: 0 0 0 1px #fff, 0 0 0 0.2rem var(--_range-focus-color); + } + + &::-webkit-slider-thumb { + background-color: var(--_range-color); + background-image: none; + + &:active { + background-color: var(--_range-focus-color); + background-image: none; + } + } + + &::-webkit-slider-runnable-track { + background-color: var(--_range-track-color); + } + + &::-moz-range-thumb { + background-color: var(--_range-color); + background-image: none; + + &:active { + background-color: var(--_range-focus-color); + background-image: none; + } + } + + &::-moz-range-track { + background: var(--_range-track-color); + } + } + + &.is-valid { + --_range-color: #2f7549; + --_range-focus-color: #88cfa2; + --_range-track-color: rgba(47, 117, 73, 0.35); + } + + &.is-invalid { + --_range-color: #c02f12; + --_range-focus-color: #f5a190; + --_range-track-color: rgba(192, 47, 18, 0.35); + } } /* `$gl-form-input-sizes` at `$grid-size: 8px` */ diff --git a/packages/ui/src/base/form-select/form-select.css b/packages/ui/src/base/form-select/form-select.css index 028da43..5bd7088 100644 --- a/packages/ui/src/base/form-select/form-select.css +++ b/packages/ui/src/base/form-select/form-select.css @@ -30,61 +30,59 @@ @apply gl-text-default; padding-right: calc(var(--gl-spacing-scale-2) + var(--gl-spacing-scale-6)); position: relative; -} -@media (forced-colors: active) { - .gl-form-select { + @media (forced-colors: active) { box-shadow: none; border: 1px solid; } -} - -.gl-form-select:hover { - box-shadow: inset 0 0 0 1px var(--gl-control-border-color-hover); -} - -.gl-form-select:focus-visible, -.gl-form-select:focus-visible:active { - box-shadow: - inset 0 0 0 1px var(--gl-control-border-color-focus), - 0 0 0 1px var(--gl-focus-ring-inner-color), - 0 0 0 3px var(--gl-focus-ring-outer-color) !important; - outline: none !important; -} -@media (forced-colors: active) { - .gl-form-select:focus-visible, - .gl-form-select:focus-visible:active { - outline: 2px solid LinkText !important; + &:hover { + box-shadow: inset 0 0 0 1px var(--gl-control-border-color-hover); } -} - -.gl-form-select:disabled { - @apply gl-cursor-not-allowed; - @apply gl-text-disabled; - background-color: var(--gl-control-background-color-disabled); - box-shadow: inset 0 0 0 1px var(--gl-control-border-color-disabled); -} -.gl-form-select.is-invalid:not(:disabled) { - box-shadow: inset 0 0 0 1px var(--gl-control-border-color-error); -} + &:focus-visible, + &:focus-visible:active { + box-shadow: + inset 0 0 0 1px var(--gl-control-border-color-focus), + 0 0 0 1px var(--gl-focus-ring-inner-color), + 0 0 0 3px var(--gl-focus-ring-outer-color) !important; + outline: none !important; + } -.gl-form-select.is-invalid:not(:disabled):hover { - box-shadow: inset 0 0 0 1px var(--gl-control-border-color-error); -} + @media (forced-colors: active) { + &:focus-visible, + &:focus-visible:active { + outline: 2px solid LinkText !important; + } + } -.gl-form-select.is-invalid:not(:disabled):focus-visible { - box-shadow: - inset 0 0 0 1px var(--gl-control-border-color-error), - 0 0 0 1px var(--gl-focus-ring-inner-color), - 0 0 0 3px var(--gl-focus-ring-outer-color) !important; - outline: none !important; -} + &:disabled { + @apply gl-cursor-not-allowed; + @apply gl-text-disabled; + background-color: var(--gl-control-background-color-disabled); + box-shadow: inset 0 0 0 1px var(--gl-control-border-color-disabled); + } -@media (forced-colors: active) { - .gl-form-select.is-invalid:not(:disabled):focus-visible { - outline: 2px solid LinkText !important; + &.is-invalid:not(:disabled) { + box-shadow: inset 0 0 0 1px var(--gl-control-border-color-error); + + &:hover { + box-shadow: inset 0 0 0 1px var(--gl-control-border-color-error); + } + + &:focus-visible { + box-shadow: + inset 0 0 0 1px var(--gl-control-border-color-error), + 0 0 0 1px var(--gl-focus-ring-inner-color), + 0 0 0 3px var(--gl-focus-ring-outer-color) !important; + outline: none !important; + } + + @media (forced-colors: active) { + &:focus-visible { + outline: 2px solid LinkText !important; + } + } } } @@ -94,39 +92,39 @@ position: relative; display: inline-block; width: 100%; -} -.gl-form-select-wrapper::after { - content: ""; - background-color: var(--gl-icon-color-default); - -webkit-mask-image: var(--gl-icon-select-chevron-down); - mask-image: var(--gl-icon-select-chevron-down); - -webkit-mask-repeat: no-repeat; - mask-repeat: no-repeat; - -webkit-mask-position: center center; - mask-position: center center; - pointer-events: none; - position: absolute; - top: 50%; - right: var(--gl-spacing-scale-4); - transform: translateY(-50%); - height: 5px; - width: 8px; -} + &::after { + content: ""; + background-color: var(--gl-icon-color-default); + -webkit-mask-image: var(--gl-icon-select-chevron-down); + mask-image: var(--gl-icon-select-chevron-down); + -webkit-mask-repeat: no-repeat; + mask-repeat: no-repeat; + -webkit-mask-position: center center; + mask-position: center center; + pointer-events: none; + position: absolute; + top: 50%; + right: var(--gl-spacing-scale-4); + transform: translateY(-50%); + height: 5px; + width: 8px; + } -@media (forced-colors: active) { - .gl-form-select-wrapper::after { - background-color: CanvasText; + @media (forced-colors: active) { + &::after { + background-color: CanvasText; + } } -} -.gl-form-select-wrapper:has(> .gl-form-select:disabled)::after { - background-color: var(--gl-icon-color-disabled); -} + &:has(> .gl-form-select:disabled)::after { + background-color: var(--gl-icon-color-disabled); + } -@media (forced-colors: active) { - .gl-form-select-wrapper:has(> .gl-form-select:disabled)::after { - background-color: GrayText; + @media (forced-colors: active) { + &:has(> .gl-form-select:disabled)::after { + background-color: GrayText; + } } } diff --git a/packages/ui/src/base/icon/icon.css b/packages/ui/src/base/icon/icon.css index d8551a7..d7bbae8 100644 --- a/packages/ui/src/base/icon/icon.css +++ b/packages/ui/src/base/icon/icon.css @@ -3,34 +3,36 @@ * packages/gitlab-ui/src/components/base/icon/icon.scss */ -.gl-icon.s8 { - @apply gl-w-[8px] gl-h-[8px]; -} - -.gl-icon.s12 { - @apply gl-w-[12px] gl-h-[12px]; -} - -.gl-icon.s14 { - @apply gl-w-[14px] gl-h-[14px]; -} - -.gl-icon.s16 { - @apply gl-w-[16px] gl-h-[16px]; -} - -.gl-icon.s24 { - @apply gl-w-[24px] gl-h-[24px]; -} - -.gl-icon.s32 { - @apply gl-w-[32px] gl-h-[32px]; -} - -.gl-icon.s48 { - @apply gl-w-[48px] gl-h-[48px]; -} - -.gl-icon.s72 { - @apply gl-w-[72px] gl-h-[72px]; +.gl-icon { + &.s8 { + @apply gl-w-[8px] gl-h-[8px]; + } + + &.s12 { + @apply gl-w-[12px] gl-h-[12px]; + } + + &.s14 { + @apply gl-w-[14px] gl-h-[14px]; + } + + &.s16 { + @apply gl-w-[16px] gl-h-[16px]; + } + + &.s24 { + @apply gl-w-[24px] gl-h-[24px]; + } + + &.s32 { + @apply gl-w-[32px] gl-h-[32px]; + } + + &.s48 { + @apply gl-w-[48px] gl-h-[48px]; + } + + &.s72 { + @apply gl-w-[72px] gl-h-[72px]; + } } diff --git a/packages/ui/src/base/label/label.css b/packages/ui/src/base/label/label.css index 119bd35..4ae1492 100644 --- a/packages/ui/src/base/label/label.css +++ b/packages/ui/src/base/label/label.css @@ -6,134 +6,132 @@ .gl-label { @apply gl-relative gl-inline-flex gl-items-center gl-max-w-full gl-overflow-hidden gl-rounded-pill gl-text-inherit gl-bg-default gl-text-sm gl-leading-normal; box-shadow: var(--label-inset-border) !important; -} -@media (forced-colors: active) { - .gl-label { + @media (forced-colors: active) { border: 1px solid; } -} -.gl-label:not(.gl-label-scoped) { - background-color: var(--label-background-color); -} - -.gl-label:has(> :first-child:focus-visible) { - box-shadow: - inset 0 0 0 1px var(--label-background-color, var(--gl-background-color-default)), - 0 0 0 1px var(--gl-focus-ring-inner-color), - 0 0 0 3px var(--gl-focus-ring-outer-color) !important; - outline: none !important; -} - -@media (forced-colors: active) { - .gl-label:has(> :first-child:focus-visible) { - outline: 2px solid LinkText !important; + &:not(.gl-label-scoped) { + background-color: var(--label-background-color); } -} - -.gl-label .gl-label-link { - @apply gl-flex gl-max-w-full gl-overflow-hidden gl-text-inherit gl-font-normal; -} -.gl-label .gl-label-link:hover, -.gl-label .gl-label-link:focus-visible, -.gl-label .gl-label-link:focus-visible:active { - @apply gl-text-inherit gl-shadow-none gl-outline-none; -} + &:has(> :first-child:focus-visible) { + box-shadow: + inset 0 0 0 1px var(--label-background-color, var(--gl-background-color-default)), + 0 0 0 1px var(--gl-focus-ring-inner-color), + 0 0 0 3px var(--gl-focus-ring-outer-color) !important; + outline: none !important; + } -.gl-label .gl-label-link-underline { - @apply gl-no-underline; -} + @media (forced-colors: active) { + &:has(> :first-child:focus-visible) { + outline: 2px solid LinkText !important; + } + } -.gl-label .gl-label-link-underline:hover .gl-label-text, -.gl-label .gl-label-link-underline:hover .gl-label-text-scoped, -.gl-label .gl-label-link-underline:focus-visible .gl-label-text, -.gl-label .gl-label-link-underline:focus-visible .gl-label-text-scoped, -.gl-label .gl-label-link-underline:focus-visible:active .gl-label-text, -.gl-label .gl-label-link-underline:focus-visible:active .gl-label-text-scoped { - @apply gl-underline; -} + .gl-label-link { + @apply gl-flex gl-max-w-full gl-overflow-hidden gl-text-inherit gl-font-normal; -.gl-label .gl-label-text, -.gl-label .gl-label-text-scoped { - @apply gl-inline-block gl-min-w-0 gl-max-w-full gl-overflow-x-clip gl-overflow-y-visible gl-text-ellipsis gl-align-top gl-whitespace-nowrap; - padding: var(--gl-spacing-scale-1) 0.375rem; -} + &:hover, + &:focus-visible, + &:focus-visible:active { + @apply gl-text-inherit gl-shadow-none gl-outline-none; + } + } -.gl-label > .gl-label-close.gl-button { - @apply gl-flex gl-border-0 gl-p-0 gl-rounded-full gl-shadow-none; - width: 0.875rem; - min-width: auto !important; - height: 0.875rem; - min-height: auto !important; - margin-right: 0.1875rem; - margin-left: -0.1875rem; -} + .gl-label-link-underline { + @apply gl-no-underline; + + &:hover .gl-label-text, + &:hover .gl-label-text-scoped, + &:focus-visible .gl-label-text, + &:focus-visible .gl-label-text-scoped, + &:focus-visible:active .gl-label-text, + &:focus-visible:active .gl-label-text-scoped { + @apply gl-underline; + } + } -.gl-label > .gl-label-close.gl-button:focus-visible, -.gl-label > .gl-label-close.gl-button:active { - @apply gl-focus; -} + .gl-label-text, + .gl-label-text-scoped { + @apply gl-inline-block gl-min-w-0 gl-max-w-full gl-overflow-x-clip gl-overflow-y-visible gl-text-ellipsis gl-align-top gl-whitespace-nowrap; + padding: var(--gl-spacing-scale-1) 0.375rem; + } -.gl-label > .gl-label-close.gl-button .gl-icon { - vertical-align: -1px; + > .gl-label-close.gl-button { + @apply gl-flex gl-border-0 gl-p-0 gl-rounded-full gl-shadow-none; + width: 0.875rem; + min-width: auto !important; + height: 0.875rem; + min-height: auto !important; + margin-right: 0.1875rem; + margin-left: -0.1875rem; + + &:focus-visible, + &:active { + @apply gl-focus; + } + + .gl-icon { + vertical-align: -1px; + } + } } .gl-label-text-dark { color: var(--gl-label-light-text-color); -} -.gl-label-text-dark .gl-label-close.gl-button { - color: var(--gl-label-light-button-icon-color-default); - background-color: var(--gl-label-light-button-background-color-default); -} + .gl-label-close.gl-button { + color: var(--gl-label-light-button-icon-color-default); + background-color: var(--gl-label-light-button-background-color-default); -.gl-label-text-dark .gl-label-close.gl-button:hover, -.gl-label-text-dark .gl-label-close.gl-button:focus-visible { - color: var(--label-background-color); - background-color: var(--gl-label-light-button-background-color-hover); + &:hover, + &:focus-visible { + color: var(--label-background-color); + background-color: var(--gl-label-light-button-background-color-hover); + } + } } .gl-label-text-light { color: var(--gl-label-dark-text-color); -} -.gl-label-text-light .gl-label-close.gl-button { - color: var(--gl-label-dark-button-icon-color-default); - background-color: var(--gl-label-dark-button-background-color-default); -} + .gl-label-close.gl-button { + color: var(--gl-label-dark-button-icon-color-default); + background-color: var(--gl-label-dark-button-background-color-default); -.gl-label-text-light .gl-label-close.gl-button:hover, -.gl-label-text-light .gl-label-close.gl-button:focus-visible { - color: var(--label-background-color); - background-color: var(--gl-label-dark-button-background-color-hover); + &:hover, + &:focus-visible { + color: var(--label-background-color); + background-color: var(--gl-label-dark-button-background-color-hover); + } + } } -.gl-label-scoped .gl-label-close.gl-button { - margin-left: -0.375rem; - color: var(--gl-label-scoped-button-icon-color-default); -} +.gl-label-scoped { + .gl-label-close.gl-button { + margin-left: -0.375rem; + color: var(--gl-label-scoped-button-icon-color-default); -.gl-label-scoped .gl-label-close.gl-button:hover, -.gl-label-scoped .gl-label-close.gl-button:focus-visible { - color: var(--gl-label-scoped-button-icon-color-hover); - background-color: var(--gl-label-scoped-button-background-color-hover); -} + &:hover, + &:focus-visible { + color: var(--gl-label-scoped-button-icon-color-hover); + background-color: var(--gl-label-scoped-button-background-color-hover); + } + } -.gl-label-scoped .gl-label-text { - background-color: var(--label-background-color); -} + .gl-label-text { + background-color: var(--label-background-color); -@media (forced-colors: active) { - .gl-label-scoped .gl-label-text { - border-right: 1px solid; + @media (forced-colors: active) { + border-right: 1px solid; + } } -} -.gl-label-scoped .gl-label-text-scoped { - @apply gl-pr-3 gl-pl-2; - color: var(--gl-label-scoped-text-color); + .gl-label-text-scoped { + @apply gl-pr-3 gl-pl-2; + color: var(--gl-label-scoped-text-color); + } } .gl-label-tooltip-title { diff --git a/packages/ui/src/base/link/link.css b/packages/ui/src/base/link/link.css index ea1b183..14d66db 100644 --- a/packages/ui/src/base/link/link.css +++ b/packages/ui/src/base/link/link.css @@ -5,34 +5,36 @@ .gl-link { text-underline-offset: var(--gl-spacing-scale-1); -} -.gl-link:hover { - @apply gl-cursor-pointer; -} + &:hover { + @apply gl-cursor-pointer; + } -.gl-link, -.gl-link:hover, -.gl-link:active, -.gl-link:focus-visible { - @apply gl-text-link; -} + &, + &:hover, + &:active, + &:focus-visible { + @apply gl-text-link; + } -.gl-link:active, -.gl-link:focus-visible, -.gl-link:focus-visible:active { - @apply gl-underline; -} + &:active, + &:focus-visible, + &:focus-visible:active { + @apply gl-underline; + } -.gl-link:focus-visible, -.gl-link:focus-visible:active { - outline: 2px solid var(--gl-focus-ring-outer-color); - outline-offset: 2px; + &:focus-visible, + &:focus-visible:active { + outline: 2px solid var(--gl-focus-ring-outer-color); + outline-offset: 2px; + } } -.gl-link-inline, -.gl-link-inline:hover { - @apply gl-underline; +.gl-link-inline { + &, + &:hover { + @apply gl-underline; + } } .gl-link-external::after { @@ -42,60 +44,56 @@ .gl-link-meta { @apply gl-no-underline; -} -.gl-link-meta:hover { - @apply gl-underline; -} + &:hover { + @apply gl-underline; + } -.gl-link-meta, -.gl-link-meta:hover, -.gl-link-meta:focus-visible, -.gl-link-meta:focus-visible:hover { - @apply gl-text-inherit; + &, + &:hover, + &:focus-visible, + &:focus-visible:hover { + @apply gl-text-inherit; + } } .gl-link-mention, .gl-link-mention-current { @apply gl-px-1 gl-rounded-default gl-no-underline; -} -.gl-link-mention:hover, -.gl-link-mention-current:hover { - @apply gl-underline; -} + &:hover { + @apply gl-underline; + } -.gl-link-mention:active, -.gl-link-mention:focus-visible, -.gl-link-mention:focus-visible:active, -.gl-link-mention-current:active, -.gl-link-mention-current:focus-visible, -.gl-link-mention-current:focus-visible:active { - @apply gl-no-underline; + &:active, + &:focus-visible, + &:focus-visible:active { + @apply gl-no-underline; + } } .gl-link-mention { background-color: var(--gl-link-mention-background-color-default); -} -.gl-link-mention, -.gl-link-mention:hover, -.gl-link-mention:active, -.gl-link-mention:focus-visible, -.gl-link-mention:focus-visible:active { - color: var(--gl-link-mention-text-color-default); + &, + &:hover, + &:active, + &:focus-visible, + &:focus-visible:active { + color: var(--gl-link-mention-text-color-default); + } } .gl-link-mention-current { background-color: var(--gl-link-mention-background-color-current); -} -.gl-link-mention-current, -.gl-link-mention-current:hover, -.gl-link-mention-current:active, -.gl-link-mention-current:focus-visible, -.gl-link-mention-current:focus-visible:active { - color: var(--gl-link-mention-text-color-current); + &, + &:hover, + &:active, + &:focus-visible, + &:focus-visible:active { + color: var(--gl-link-mention-text-color-current); + } } @media (forced-colors: active) { diff --git a/packages/ui/src/base/loading-icon/loading-icon.css b/packages/ui/src/base/loading-icon/loading-icon.css index 3570414..eaa157a 100644 --- a/packages/ui/src/base/loading-icon/loading-icon.css +++ b/packages/ui/src/base/loading-icon/loading-icon.css @@ -47,32 +47,32 @@ .gl-dots-loader { --gl-dots-loader-size: 0.375rem; -} -.gl-dots-loader::before, -.gl-dots-loader > span, -.gl-dots-loader::after { - @apply gl-inline-block; - width: var(--gl-dots-loader-size); - height: var(--gl-dots-loader-size); - margin-right: calc(var(--gl-dots-loader-size) / 2); - border-radius: 100%; - background-color: var(--gl-icon-color-subtle); - content: ""; - animation: gl-dots-loader-animation 1400ms ease-in-out infinite; - animation-fill-mode: both; -} + &::before, + > span, + &::after { + @apply gl-inline-block; + width: var(--gl-dots-loader-size); + height: var(--gl-dots-loader-size); + margin-right: calc(var(--gl-dots-loader-size) / 2); + border-radius: 100%; + background-color: var(--gl-icon-color-subtle); + content: ""; + animation: gl-dots-loader-animation 1400ms ease-in-out infinite; + animation-fill-mode: both; + } -.gl-dots-loader::before { - animation-delay: -0.3s; -} + &::before { + animation-delay: -0.3s; + } -.gl-dots-loader > span { - animation-delay: -0.15s; -} + > span { + animation-delay: -0.15s; + } -.gl-dots-loader::after { - margin-right: 0 !important; + &::after { + margin-right: 0 !important; + } } .gl-dots-loader-md { diff --git a/packages/ui/src/base/table/table.css b/packages/ui/src/base/table/table.css index 28750fd..0a03b70 100644 --- a/packages/ui/src/base/table/table.css +++ b/packages/ui/src/base/table/table.css @@ -9,109 +9,83 @@ table.gl-table { @apply gl-text-default; background-color: var(--gl-color-alpha-0); -} -table.gl-table tr th, -table.gl-table tr td { - @apply gl-border-b-1 gl-border-b-solid gl-border-default; - @apply gl-bg-transparent gl-p-5; - @apply gl-leading-normal gl-text-base; - @apply gl-align-top; - @apply gl-text-default gl-font-normal; -} + tr { + th, + td { + @apply gl-border-b-1 gl-border-b-solid gl-border-default; + @apply gl-bg-transparent gl-p-5; + @apply gl-leading-normal gl-text-base; + @apply gl-align-top; + @apply gl-text-default gl-font-normal; + } -table.gl-table tr:focus-visible { - @apply gl-focus; - position: relative; - z-index: 1; -} + &:focus-visible { + @apply gl-focus; + position: relative; + z-index: 1; + } + } -table.gl-table thead tr th { - @apply gl-font-bold gl-text-heading; -} + thead tr th { + @apply gl-font-bold gl-text-heading; + } -table.gl-table.gl-table--sticky-header thead tr { - @apply gl-bg-default; - position: sticky; - top: -1px; - z-index: 2; - box-shadow: inset 0 -1px 0 var(--gl-border-color-default); -} + &.gl-table--sticky-header thead tr { + @apply gl-bg-default; + position: sticky; + top: -1px; + z-index: 2; + box-shadow: inset 0 -1px 0 var(--gl-border-color-default); + } -table.gl-table caption { - @apply gl-pt-2; -} + caption { + @apply gl-pt-2; + } -table.gl-table.table-hover tbody tr:hover, -table.gl-table.table-hover td.table-secondary:hover { - background-color: var(--gl-table-row-background-color-hover); -} + &.table-hover tbody tr:hover, + &.table-hover td.table-secondary:hover { + background-color: var(--gl-table-row-background-color-hover); + } -table.gl-table:is( - .b-table-stacked, - .b-table-stacked-sm, - .b-table-stacked-md, - .b-table-stacked-lg, - .b-table-stacked-xl -) tbody > tr::after { - display: var(--gl-table-stacked-row-gap-display, none); - width: 100%; - height: 1.5rem; - content: ""; -} + &:is( + .b-table-stacked, + .b-table-stacked-sm, + .b-table-stacked-md, + .b-table-stacked-lg, + .b-table-stacked-xl + ) tbody > tr { + &::after { + display: var(--gl-table-stacked-row-gap-display, none); + width: 100%; + height: 1.5rem; + content: ""; + } -table.gl-table:is( - .b-table-stacked, - .b-table-stacked-sm, - .b-table-stacked-md, - .b-table-stacked-lg, - .b-table-stacked-xl -) tbody > tr > :is(td, th)[data-label] { - border-right: var(--gl-table-stacked-cell-side-border, 0 solid transparent); - border-left: var(--gl-table-stacked-cell-side-border, 0 solid transparent); -} + > :is(td, th)[data-label] { + border-right: var(--gl-table-stacked-cell-side-border, 0 solid transparent); + border-left: var(--gl-table-stacked-cell-side-border, 0 solid transparent); -table.gl-table:is( - .b-table-stacked, - .b-table-stacked-sm, - .b-table-stacked-md, - .b-table-stacked-lg, - .b-table-stacked-xl -) tbody > tr > :is(td, th)[data-label]::before { - text-align: var(--gl-table-stacked-label-align, right); -} + &::before { + text-align: var(--gl-table-stacked-label-align, right); + } -table.gl-table:is( - .b-table-stacked, - .b-table-stacked-sm, - .b-table-stacked-md, - .b-table-stacked-lg, - .b-table-stacked-xl -) tbody > tr > :is(td, th)[data-label]:first-child { - border-top-width: var(--gl-table-stacked-labelled-first-border-width, 1px); -} + &:first-child { + border-top-width: var(--gl-table-stacked-labelled-first-border-width, 1px); + } -table.gl-table:is( - .b-table-stacked, - .b-table-stacked-sm, - .b-table-stacked-md, - .b-table-stacked-lg, - .b-table-stacked-xl -) tbody > tr > :is(td, th)[data-label]:not(:first-child) { - border-top-width: var(--gl-table-stacked-labelled-border-width, 1px); -} + &:not(:first-child) { + border-top-width: var(--gl-table-stacked-labelled-border-width, 1px); + } + } -table.gl-table:is( - .b-table-stacked, - .b-table-stacked-sm, - .b-table-stacked-md, - .b-table-stacked-lg, - .b-table-stacked-xl -) tbody > tr .gl-table-cell-content { - overflow-wrap: var(--gl-table-stacked-content-wrap, normal); - text-align: var(--gl-table-stacked-content-align, inherit); -} + .gl-table-cell-content { + overflow-wrap: var(--gl-table-stacked-content-wrap, normal); + text-align: var(--gl-table-stacked-content-align, inherit); + } + } -table.gl-table.table-borderless tr > :is(th, td) { - border: 0; + &.table-borderless tr > :is(th, td) { + border: 0; + } } diff --git a/packages/ui/src/base/toggle/toggle.css b/packages/ui/src/base/toggle/toggle.css index 97dd8ca..651fa44 100644 --- a/packages/ui/src/base/toggle/toggle.css +++ b/packages/ui/src/base/toggle/toggle.css @@ -21,14 +21,14 @@ .gl-toggle-label-inline { @apply gl-flex-row gl-items-center; -} -.gl-toggle-label-inline .gl-toggle-label { - @apply gl-mr-3 gl-mb-0 gl-whitespace-nowrap; -} + .gl-toggle-label { + @apply gl-mr-3 gl-mb-0 gl-whitespace-nowrap; + } -.gl-toggle-label-inline .gl-help-label { - @apply gl-mt-0 gl-ml-3; + .gl-help-label { + @apply gl-mt-0 gl-ml-3; + } } .gl-toggle-label { @@ -46,276 +46,253 @@ color 0.2s cubic-bezier(0.22, 0.61, 0.36, 1), background-color 0.2s cubic-bezier(0.22, 0.61, 0.36, 1), box-shadow 0.2s cubic-bezier(0.22, 0.61, 0.36, 1); -} -@media (prefers-reduced-motion) { - .gl-toggle { + @media (prefers-reduced-motion) { transition-duration: 0.01ms !important; transition-delay: 0ms !important; } -} -@media (forced-colors: active) { - .gl-toggle { + @media (forced-colors: active) { outline: 1px solid CanvasText !important; outline-offset: -1px; transition: none; } -} -/* Upstream also lists `::before::selection` / `::after::selection`, which are - * invalid selectors that browsers ignore and lightningcss rejects. */ -.gl-toggle::selection { - @apply gl-bg-transparent; -} - -.gl-toggle:hover { - color: var(--gl-toggle-switch-icon-color-unchecked-hover); - background-color: var(--gl-toggle-switch-track-color-unchecked-hover); - box-shadow: inset 0 0 0 1px var(--gl-toggle-switch-track-border-color-unchecked-hover); -} - -.gl-toggle:focus-visible { - color: var(--gl-toggle-switch-icon-color-unchecked-focus); - background-color: var(--gl-toggle-switch-track-color-unchecked-focus); - box-shadow: - inset 0 0 0 1px var(--gl-toggle-switch-track-border-color-unchecked-focus), - 0 0 0 1px var(--gl-focus-ring-inner-color), - 0 0 0 3px var(--gl-focus-ring-outer-color) !important; - outline: none !important; -} - -.gl-toggle:active { - color: var(--gl-toggle-switch-icon-color-unchecked-active); - background-color: var(--gl-toggle-switch-track-color-unchecked-active); - box-shadow: - inset 0 0 0 1px var(--gl-toggle-switch-track-border-color-unchecked-active), - 0 0 0 1px var(--gl-focus-ring-inner-color), - 0 0 0 3px var(--gl-focus-ring-outer-color) !important; - outline: none !important; -} - -@media (forced-colors: active) { - .gl-toggle:focus-visible, - .gl-toggle:active { - outline: 2px solid LinkText !important; + /* Upstream also lists `::before::selection` / `::after::selection`, which are + * invalid selectors that browsers ignore and lightningcss rejects. */ + &::selection { + @apply gl-bg-transparent; } -} - -/* The thumb grows on hover and focus so the interaction reads on the thumb as - * well as on the track. */ -.gl-toggle:hover .toggle-icon::before, -.gl-toggle:focus-visible .toggle-icon::before { - transform: scale(0.875); -} - -.gl-toggle .toggle-loading { - @apply gl-h-5; -} - -.gl-toggle .toggle-icon { - @apply gl-absolute gl-top-1 gl-left-1 gl-w-5 gl-h-5; - transition: transform 0.2s cubic-bezier(0.22, 0.61, 0.36, 1); -} -@media (prefers-reduced-motion) { - .gl-toggle .toggle-icon { - transition-duration: 0.01ms !important; - transition-delay: 0ms !important; + &:hover { + color: var(--gl-toggle-switch-icon-color-unchecked-hover); + background-color: var(--gl-toggle-switch-track-color-unchecked-hover); + box-shadow: inset 0 0 0 1px var(--gl-toggle-switch-track-border-color-unchecked-hover); } -} -@media (forced-colors: active) { - .gl-toggle .toggle-icon { - transition: none; + &:focus-visible { + color: var(--gl-toggle-switch-icon-color-unchecked-focus); + background-color: var(--gl-toggle-switch-track-color-unchecked-focus); + box-shadow: + inset 0 0 0 1px var(--gl-toggle-switch-track-border-color-unchecked-focus), + 0 0 0 1px var(--gl-focus-ring-inner-color), + 0 0 0 3px var(--gl-focus-ring-outer-color) !important; + outline: none !important; } -} -.gl-toggle .toggle-icon::before { - @apply gl-absolute gl-inset-0 gl-rounded-full; - background-color: var(--gl-toggle-switch-background-color-unchecked-default); - content: ""; - transform: scale(0.75); - transition: - transform 0.2s cubic-bezier(0.22, 0.61, 0.36, 1), - background-color 0.2s cubic-bezier(0.22, 0.61, 0.36, 1); -} - -@media (prefers-reduced-motion) { - .gl-toggle .toggle-icon::before { - transition-duration: 0.01ms !important; - transition-delay: 0ms !important; + &:active { + color: var(--gl-toggle-switch-icon-color-unchecked-active); + background-color: var(--gl-toggle-switch-track-color-unchecked-active); + box-shadow: + inset 0 0 0 1px var(--gl-toggle-switch-track-border-color-unchecked-active), + 0 0 0 1px var(--gl-focus-ring-inner-color), + 0 0 0 3px var(--gl-focus-ring-outer-color) !important; + outline: none !important; } -} -@media (forced-colors: active) { - .gl-toggle .toggle-icon::before { - background-color: CanvasText; - transition: none; + @media (forced-colors: active) { + &:focus-visible, + &:active { + outline: 2px solid LinkText !important; + } } -} - -.gl-toggle .toggle-icon > svg { - @apply gl-absolute gl-w-4 gl-h-4; - top: 50%; - left: 50%; - /* Check/close icons are only rendered in Windows high contrast - * (forced-colors) mode so the toggle state remains distinguishable - * when background colors are overridden by the user agent. */ - display: none; - transform: translate(-50%, -50%); -} -@media (forced-colors: active) { - .gl-toggle .toggle-icon > svg { - display: block; - color: Canvas; + /* The thumb grows on hover and focus so the interaction reads on the thumb as + * well as on the track. */ + &:hover .toggle-icon::before, + &:focus-visible .toggle-icon::before { + transform: scale(0.875); } -} -.gl-toggle.is-checked { - color: var(--gl-toggle-switch-icon-color-checked-default); - background-color: var(--gl-toggle-switch-track-color-checked-default); - box-shadow: inset 0 0 0 1px var(--gl-toggle-switch-track-border-color-checked-default); -} - -.gl-toggle.is-checked:hover { - color: var(--gl-toggle-switch-icon-color-checked-hover); - background-color: var(--gl-toggle-switch-track-color-checked-hover); - box-shadow: inset 0 0 0 1px var(--gl-toggle-switch-track-border-color-checked-hover); -} - -.gl-toggle.is-checked:focus-visible { - color: var(--gl-toggle-switch-icon-color-checked-focus); - background-color: var(--gl-toggle-switch-track-color-checked-focus); - box-shadow: - inset 0 0 0 1px var(--gl-toggle-switch-track-border-color-checked-focus), - 0 0 0 1px var(--gl-focus-ring-inner-color), - 0 0 0 3px var(--gl-focus-ring-outer-color) !important; - outline: none !important; -} - -.gl-toggle.is-checked:active { - color: var(--gl-toggle-switch-icon-color-checked-active); - background-color: var(--gl-toggle-switch-track-color-checked-active); - box-shadow: - inset 0 0 0 1px var(--gl-toggle-switch-track-border-color-checked-active), - 0 0 0 1px var(--gl-focus-ring-inner-color), - 0 0 0 3px var(--gl-focus-ring-outer-color) !important; - outline: none !important; -} - -@media (forced-colors: active) { - .gl-toggle.is-checked { - background-color: CanvasText !important; + .toggle-loading { + @apply gl-h-5; } - .gl-toggle.is-checked svg { - color: CanvasText; + .toggle-icon { + @apply gl-absolute gl-top-1 gl-left-1 gl-w-5 gl-h-5; + transition: transform 0.2s cubic-bezier(0.22, 0.61, 0.36, 1); + + @media (prefers-reduced-motion) { + transition-duration: 0.01ms !important; + transition-delay: 0ms !important; + } + + @media (forced-colors: active) { + transition: none; + } + + &::before { + @apply gl-absolute gl-inset-0 gl-rounded-full; + background-color: var(--gl-toggle-switch-background-color-unchecked-default); + content: ""; + transform: scale(0.75); + transition: + transform 0.2s cubic-bezier(0.22, 0.61, 0.36, 1), + background-color 0.2s cubic-bezier(0.22, 0.61, 0.36, 1); + + @media (prefers-reduced-motion) { + transition-duration: 0.01ms !important; + transition-delay: 0ms !important; + } + + @media (forced-colors: active) { + background-color: CanvasText; + transition: none; + } + } + + > svg { + @apply gl-absolute gl-w-4 gl-h-4; + top: 50%; + left: 50%; + /* Check/close icons are only rendered in Windows high contrast + * (forced-colors) mode so the toggle state remains distinguishable + * when background colors are overridden by the user agent. */ + display: none; + transform: translate(-50%, -50%); + + @media (forced-colors: active) { + display: block; + color: Canvas; + } + } } -} - -.gl-toggle.is-checked .toggle-icon { - transform: translateX(1rem); -} - -.gl-toggle.is-checked .toggle-icon::before { - background-color: var(--gl-toggle-switch-background-color-checked-default); - transform: scale(1); -} - -/* Both disabled blocks must stay last. `.gl-toggle.is-checked` and - * `.gl-toggle.is-disabled` carry equal specificity, so source order is what - * lets the disabled styles win over the checked ones. */ -.gl-toggle.is-disabled { - @apply gl-cursor-not-allowed; - background-color: var(--gl-toggle-switch-track-color-unchecked-disabled); - box-shadow: inset 0 0 0 1px var(--gl-toggle-switch-track-border-color-unchecked-disabled); -} - -.gl-toggle.is-disabled .toggle-icon { - color: var(--gl-toggle-switch-icon-color-disabled); -} - -.gl-toggle.is-disabled .toggle-icon::before { - background-color: var(--gl-toggle-switch-background-color-unchecked-disabled); -} -@media (forced-colors: active) { - .gl-toggle.is-disabled .toggle-icon::before { - background-color: GrayText; + &.is-checked { + color: var(--gl-toggle-switch-icon-color-checked-default); + background-color: var(--gl-toggle-switch-track-color-checked-default); + box-shadow: inset 0 0 0 1px var(--gl-toggle-switch-track-border-color-checked-default); + + &:hover { + color: var(--gl-toggle-switch-icon-color-checked-hover); + background-color: var(--gl-toggle-switch-track-color-checked-hover); + box-shadow: inset 0 0 0 1px var(--gl-toggle-switch-track-border-color-checked-hover); + } + + &:focus-visible { + color: var(--gl-toggle-switch-icon-color-checked-focus); + background-color: var(--gl-toggle-switch-track-color-checked-focus); + box-shadow: + inset 0 0 0 1px var(--gl-toggle-switch-track-border-color-checked-focus), + 0 0 0 1px var(--gl-focus-ring-inner-color), + 0 0 0 3px var(--gl-focus-ring-outer-color) !important; + outline: none !important; + } + + &:active { + color: var(--gl-toggle-switch-icon-color-checked-active); + background-color: var(--gl-toggle-switch-track-color-checked-active); + box-shadow: + inset 0 0 0 1px var(--gl-toggle-switch-track-border-color-checked-active), + 0 0 0 1px var(--gl-focus-ring-inner-color), + 0 0 0 3px var(--gl-focus-ring-outer-color) !important; + outline: none !important; + } + + @media (forced-colors: active) { + background-color: CanvasText !important; + + svg { + color: CanvasText; + } + } + + .toggle-icon { + transform: translateX(1rem); + + &::before { + background-color: var(--gl-toggle-switch-background-color-checked-default); + transform: scale(1); + } + } } -} - -.gl-toggle.is-disabled:hover .toggle-icon::before, -.gl-toggle.is-disabled:focus-visible .toggle-icon::before { - transform: scale(0.75); -} - -.gl-toggle.is-disabled:active, -.gl-toggle.is-disabled:focus-visible, -.gl-toggle.is-disabled:focus-visible:active { - box-shadow: - inset 0 0 0 1px var(--gl-toggle-switch-track-border-color-unchecked-disabled), - 0 0 0 1px var(--gl-focus-ring-inner-color), - 0 0 0 3px var(--gl-focus-ring-outer-color) !important; - outline: none !important; -} - -.gl-toggle.is-checked.is-disabled { - background-color: var(--gl-toggle-switch-track-color-checked-disabled); - box-shadow: inset 0 0 0 1px var(--gl-toggle-switch-track-border-color-checked-disabled); -} - -.gl-toggle.is-checked.is-disabled .toggle-icon::before { - background-color: var(--gl-toggle-switch-background-color-checked-disabled); - transform: scale(1); -} -.gl-toggle.is-checked.is-disabled:hover .toggle-icon::before, -.gl-toggle.is-checked.is-disabled:focus-visible .toggle-icon::before { - transform: scale(1); -} - -.gl-toggle.is-checked.is-disabled:active, -.gl-toggle.is-checked.is-disabled:focus-visible, -.gl-toggle.is-checked.is-disabled:focus-visible:active { - box-shadow: - inset 0 0 0 1px var(--gl-toggle-switch-track-border-color-checked-disabled), - 0 0 0 1px var(--gl-focus-ring-inner-color), - 0 0 0 3px var(--gl-focus-ring-outer-color) !important; - outline: none !important; -} - -@media (forced-colors: active) { - .gl-toggle.is-checked.is-disabled { - background-color: GrayText !important; + /* Both disabled blocks must stay last. `.gl-toggle.is-checked` and + * `.gl-toggle.is-disabled` carry equal specificity, so source order is what + * lets the disabled styles win over the checked ones. */ + &.is-disabled { + @apply gl-cursor-not-allowed; + background-color: var(--gl-toggle-switch-track-color-unchecked-disabled); + box-shadow: inset 0 0 0 1px var(--gl-toggle-switch-track-border-color-unchecked-disabled); + + .toggle-icon { + color: var(--gl-toggle-switch-icon-color-disabled); + + &::before { + background-color: var(--gl-toggle-switch-background-color-unchecked-disabled); + + @media (forced-colors: active) { + background-color: GrayText; + } + } + } + + &:hover .toggle-icon::before, + &:focus-visible .toggle-icon::before { + transform: scale(0.75); + } + + &:active, + &:focus-visible, + &:focus-visible:active { + box-shadow: + inset 0 0 0 1px var(--gl-toggle-switch-track-border-color-unchecked-disabled), + 0 0 0 1px var(--gl-focus-ring-inner-color), + 0 0 0 3px var(--gl-focus-ring-outer-color) !important; + outline: none !important; + } } -} -/* A loading toggle renders a spinner in place of the thumb, so the track is - * the only thing left to look at and its value is still in flight. It gets a - * flat fill that ignores the checked state, which also keeps the spinner - * legible in both color modes. - * - * `.is-loading` is always accompanied by `.is-disabled`, so this block has to - * stay after both disabled blocks: the checked pairs tie on specificity and - * source order is what settles them. */ -.gl-toggle.is-loading, -.gl-toggle.is-checked.is-loading { - background-color: var(--gl-toggle-switch-track-color-loading); - box-shadow: inset 0 0 0 1px var(--gl-toggle-switch-track-border-color-loading); -} + &.is-checked.is-disabled { + background-color: var(--gl-toggle-switch-track-color-checked-disabled); + box-shadow: inset 0 0 0 1px var(--gl-toggle-switch-track-border-color-checked-disabled); + + .toggle-icon::before { + background-color: var(--gl-toggle-switch-background-color-checked-disabled); + transform: scale(1); + } + + &:hover .toggle-icon::before, + &:focus-visible .toggle-icon::before { + transform: scale(1); + } + + &:active, + &:focus-visible, + &:focus-visible:active { + box-shadow: + inset 0 0 0 1px var(--gl-toggle-switch-track-border-color-checked-disabled), + 0 0 0 1px var(--gl-focus-ring-inner-color), + 0 0 0 3px var(--gl-focus-ring-outer-color) !important; + outline: none !important; + } + + @media (forced-colors: active) { + background-color: GrayText !important; + } + } -.gl-toggle.is-loading:active, -.gl-toggle.is-loading:focus-visible, -.gl-toggle.is-loading:focus-visible:active, -.gl-toggle.is-checked.is-loading:active, -.gl-toggle.is-checked.is-loading:focus-visible, -.gl-toggle.is-checked.is-loading:focus-visible:active { - box-shadow: - inset 0 0 0 1px var(--gl-toggle-switch-track-border-color-loading), - 0 0 0 1px var(--gl-focus-ring-inner-color), - 0 0 0 3px var(--gl-focus-ring-outer-color) !important; - outline: none !important; + /* A loading toggle renders a spinner in place of the thumb, so the track is + * the only thing left to look at and its value is still in flight. It gets a + * flat fill that ignores the checked state, which also keeps the spinner + * legible in both color modes. + * + * `.is-loading` is always accompanied by `.is-disabled`, so this block has to + * stay after both disabled blocks: the checked pairs tie on specificity and + * source order is what settles them. */ + &.is-loading, + &.is-checked.is-loading { + background-color: var(--gl-toggle-switch-track-color-loading); + box-shadow: inset 0 0 0 1px var(--gl-toggle-switch-track-border-color-loading); + + &:active, + &:focus-visible, + &:focus-visible:active { + box-shadow: + inset 0 0 0 1px var(--gl-toggle-switch-track-border-color-loading), + 0 0 0 1px var(--gl-focus-ring-inner-color), + 0 0 0 3px var(--gl-focus-ring-outer-color) !important; + outline: none !important; + } + } } diff --git a/packages/ui/src/base/tooltip/tooltip.css b/packages/ui/src/base/tooltip/tooltip.css index 1975f26..46efe06 100644 --- a/packages/ui/src/base/tooltip/tooltip.css +++ b/packages/ui/src/base/tooltip/tooltip.css @@ -31,26 +31,30 @@ @apply gl-opacity-0; } -.gl-tooltip .tooltip-inner { - @apply gl-drop-shadow-md gl-leading-normal gl-font-normal gl-py-3 gl-px-4 gl-rounded-feedback gl-text-center; - max-width: 200px; - background: var(--gl-feedback-strong-background-color); - color: var(--gl-feedback-strong-text-color); - --gl-text-color-subtle: var(--gl-tooltip-text-color-subtle); -} - -.gl-tooltip .arrow { - @apply gl-block gl-w-2 gl-h-3; -} - -.gl-tooltip .arrow::before { - @apply gl-absolute gl-border-4 gl-border-solid gl-border-transparent; - content: ""; -} - -.gl-tooltip.bs-tooltip-top .arrow, -.gl-tooltip.bs-tooltip-bottom .arrow { - @apply gl-w-3 gl-h-2; +.gl-tooltip { + .tooltip-inner { + @apply gl-drop-shadow-md gl-leading-normal gl-font-normal gl-py-3 gl-px-4 gl-rounded-feedback gl-text-center; + max-width: 200px; + background: var(--gl-feedback-strong-background-color); + color: var(--gl-feedback-strong-text-color); + --gl-text-color-subtle: var(--gl-tooltip-text-color-subtle); + } + + .arrow { + @apply gl-block gl-w-2 gl-h-3; + + &::before { + @apply gl-absolute gl-border-4 gl-border-solid gl-border-transparent; + content: ""; + } + } +} + +.gl-tooltip.bs-tooltip-top, +.gl-tooltip.bs-tooltip-bottom { + .arrow { + @apply gl-w-3 gl-h-2; + } } /* The arrow lives inside the popup's 4px padding (like upstream, where the diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 9871fa9..4d49ab4 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -90,6 +90,9 @@ importers: postcss: specifier: ^8.5.26 version: 8.5.26 + postcss-nested: + specifier: ^8.0.1 + version: 8.0.1(postcss@8.5.26) postcss-selector-parser: specifier: 7.1.0 version: 7.1.0 @@ -2827,10 +2830,20 @@ packages: resolution: {integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==} engines: {node: '>= 0.4'} + postcss-nested@8.0.1: + resolution: {integrity: sha512-PvSIwDVh1NTw939iu4FBK+oeZfSm0cbErFAjXCTPiStammzobBNE2SiQNezy8Xp+Oud2uLXaLpTauv3UdxWjbQ==} + engines: {node: ^22.0.0 || ^24.0.0 || >= 26.0.0} + peerDependencies: + postcss: ^8.2.14 + postcss-selector-parser@7.1.0: resolution: {integrity: sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==} engines: {node: '>=4'} + postcss-selector-parser@7.1.6: + resolution: {integrity: sha512-7qASPzhKF2l2KLboRZux8CCTRMdGiV08vWmyKzPz22qZ7ZjQBOeY7rNzNoCLSUiftJ7HUq0GERHmxw/t0dCdMw==} + engines: {node: '>=4'} + postcss@8.5.26: resolution: {integrity: sha512-u82N74LFzG8ca+dD8puPnplTXoGH4fTPpVGuIbt36G3qvNlkvfD0lEAZSxaly3KX8TS/L1A1gsCEmvKmBcVbkQ==} engines: {node: ^10 || ^12 || >=14} @@ -5931,11 +5944,21 @@ snapshots: possible-typed-array-names@1.1.0: {} + postcss-nested@8.0.1(postcss@8.5.26): + dependencies: + postcss: 8.5.26 + postcss-selector-parser: 7.1.6 + postcss-selector-parser@7.1.0: dependencies: cssesc: 3.0.0 util-deprecate: 1.0.2 + postcss-selector-parser@7.1.6: + dependencies: + cssesc: 3.0.0 + util-deprecate: 1.0.2 + postcss@8.5.26: dependencies: nanoid: 3.3.18