diff --git a/app/assets/javascripts/components/annotations/annotation_marker.ts b/app/assets/javascripts/components/annotations/annotation_marker.ts
index 8032b97f68..460f4e06f5 100644
--- a/app/assets/javascripts/components/annotations/annotation_marker.ts
+++ b/app/assets/javascripts/components/annotations/annotation_marker.ts
@@ -1,5 +1,5 @@
import { customElement, property } from "lit/decorators.js";
-import { html, LitElement, TemplateResult } from "lit";
+import { css, html, LitElement, TemplateResult, CSSResultGroup } from "lit";
import {
Annotation,
compareAnnotationOrders,
@@ -19,37 +19,46 @@ import { StateController } from "state/state_system/StateController";
export class AnnotationMarker extends LitElement {
@property({ type: Array })
annotations: Annotation[];
+ @property({ type: Boolean, attribute: "full-width" })
+ fullWidth = false;
state = new StateController(this);
+ static get styles(): CSSResultGroup {
+ // order matters here, the last defined class determines the color if multiple apply
+ return css`
+ .info, .warning, .error,
+ .info-intense, .warning-intense, .error-intense {
+ background-position: left bottom;
+ background-repeat: repeat-x;
+ }
+ .info { background-image: var(--d-annotation-info-background) }
+ .warning { background-image: var(--d-annotation-warning-background) }
+ .error { background-image: var(--d-annotation-error-background) }
+ .info-intense { background-image: var(--d-annotation-info-background-intense) }
+ .warning-intense { background-image: var(--d-annotation-warning-background-intense) }
+ .error-intense { background-image: var(--d-annotation-error-background-intense) }
+ .annotation { background-color: var(--annotation-color) }
+ .question { background-color: var(--question-color) }
+ .annotation-intense { background-color: var(--annotation-intense-color) }
+ .question-intense { background-color: var(--question-intense-color) }
+ `;
+ }
+
+ static getClass(annotation: Annotation): string {
+ return annotation.isHovered ? `${annotation.type}-intense` : annotation.type;
+ }
+
static colors = {
- "error": "var(--error-color, red)",
- "warning": "var(--warning-color, yellow)",
- "info": "var(--info-color, blue)",
+ "error": "var(--d-annotation-error, red)",
+ "warning": "var(--d-annotation-warning, yellow)",
+ "info": "var(--d-annotation-info, blue)",
"annotation": "var(--annotation-color, green)",
"question": "var(--question-color, orange)",
"annotation-intense": "var(--annotation-intense-color, green)",
"question-intense": "var(--question-intense-color, orange)",
};
- static getStyle(annotation: Annotation): string {
- if (["error", "warning", "info"].includes(annotation.type)) {
- // shorthand notation does not work in safari
- return `
- text-decoration-line: underline;
- text-decoration-color: ${AnnotationMarker.colors[annotation.type]};
- text-decoration-thickness: ${annotation.isHovered ? 2 : 1}px;
- text-decoration-style: wavy;
- text-decoration-skip-ink: none;
- `;
- } else {
- const key = annotation.isHovered ? `${annotation.type}-intense` : annotation.type;
- return `
- background: ${AnnotationMarker.colors[key]};
- `;
- }
- }
-
/**
* Returns the annotations sorted in order of importance.
* Hovered annotations are prioritized over non-hovered annotations.
@@ -79,16 +88,11 @@ export class AnnotationMarker extends LitElement {
`;
}
- get annotationStyles(): string {
- return this.sortedAnnotations.reverse().map(a => AnnotationMarker.getStyle(a)).join(" ");
+ get annotationClasses(): string {
+ return this.annotations.map(a => AnnotationMarker.getClass(a)).join(" ");
}
render(): TemplateResult {
- return html`
${backgroundLayer}
${backgroundLayer}diff --git a/app/assets/stylesheets/base.css.scss b/app/assets/stylesheets/base.css.scss index a6a822661b..4bd3144e4f 100644 --- a/app/assets/stylesheets/base.css.scss +++ b/app/assets/stylesheets/base.css.scss @@ -2,10 +2,10 @@ @import "../../../node_modules/bootstrap/scss/functions"; // 2. Include any default variable overrides here +@import "mixins.css.scss"; @import "theme/m3-theme-light.css.scss"; @import "theme/m3-theme-dark.css.scss"; @import "bootstrap_variable_overrides.css.scss"; -@import "mixins.css.scss"; @import "theme/rouge.css.scss"; @import "theme/ace.css.scss"; diff --git a/app/assets/stylesheets/components/code_listing.css.scss b/app/assets/stylesheets/components/code_listing.css.scss index f7b3b27d00..aa63b57535 100644 --- a/app/assets/stylesheets/components/code_listing.css.scss +++ b/app/assets/stylesheets/components/code_listing.css.scss @@ -527,9 +527,6 @@ d-annotation-marker, d-selection-marker { - --info-color: var(--d-annotation-info); - --warning-color: var(--d-annotation-warning); - --error-color: var(--d-annotation-error); --question-color: var(--d-annotation-question-background); --annotation-color: var(--d-annotation-user-background); --question-intense-color: var(--d-annotation-question-background-intense); diff --git a/app/assets/stylesheets/mixins.css.scss b/app/assets/stylesheets/mixins.css.scss index dd58029260..c150a79812 100644 --- a/app/assets/stylesheets/mixins.css.scss +++ b/app/assets/stylesheets/mixins.css.scss @@ -1,3 +1,6 @@ +@use "sass:string"; +@use "sass:color"; + @mixin shadow-z0 { box-shadow: none; } @@ -27,3 +30,10 @@ 0 16px 24px 2px rgba(0, 0, 0, 0.098), 0 6px 30px 5px rgba(0, 0, 0, 0.084); } + +// sets the variable equal to the url of a wavy svg with the specified color and stroke-width +@mixin wavy-underline($variable, $color, $stroke-width) { + // this is a custom wavy svg that can be used as a background image + // the color is slightly hacked to get a proper url encode version of the color + #{$variable}: url('data:image/svg+xml,'); +} diff --git a/app/assets/stylesheets/theme/m3-theme-dark.css.scss b/app/assets/stylesheets/theme/m3-theme-dark.css.scss index 40bdba365a..2b40af3e8b 100644 --- a/app/assets/stylesheets/theme/m3-theme-dark.css.scss +++ b/app/assets/stylesheets/theme/m3-theme-dark.css.scss @@ -203,6 +203,13 @@ --d-annotation-question-background-intense: #{color.mix($purple-80, $neutral-25, 20%)}; --d-annotation-user-background-intense: #{color.mix($success-70, $neutral-25, 20%)}; + @include wavy-underline(--d-annotation-warning-background, $warning-80, 0.7); + @include wavy-underline(--d-annotation-warning-background-intense, $warning-80, 1.7); + @include wavy-underline(--d-annotation-error-background, $danger-70, 0.7); + @include wavy-underline(--d-annotation-error-background-intense, $danger-70, 1.7); + @include wavy-underline(--d-annotation-info-background, $info-80, 0.7); + @include wavy-underline(--d-annotation-info-background-intense, $info-80, 1.7); + .image-bright { // $gray-90 converted to filter using https://codepen.io/sosuke/pen/Pjoqqp filter: invert(86%) sepia(3%) saturate(218%) hue-rotate(242deg) brightness(107%) contrast(90%); diff --git a/app/assets/stylesheets/theme/m3-theme-light.css.scss b/app/assets/stylesheets/theme/m3-theme-light.css.scss index 69ecbc3ab2..583c789aff 100644 --- a/app/assets/stylesheets/theme/m3-theme-light.css.scss +++ b/app/assets/stylesheets/theme/m3-theme-light.css.scss @@ -3,6 +3,7 @@ @use "sass:color"; @import "theme/m3-theme.css.scss"; +@import "mixins.css.scss"; :root, [data-bs-theme="light"] { @@ -217,6 +218,13 @@ --d-annotation-question-background-intense: #{color.mix($purple-40, $neutral-98, 20%)}; --d-annotation-user-background-intense: #{color.mix($success-60, $neutral-98, 20%)}; + @include wavy-underline(--d-annotation-warning-background, $warning-70, 0.7); + @include wavy-underline(--d-annotation-warning-background-intense, $warning-70, 1.7); + @include wavy-underline(--d-annotation-error-background, $danger-60, 0.7); + @include wavy-underline(--d-annotation-error-background-intense, $danger-60, 1.7); + @include wavy-underline(--d-annotation-info-background, $info-40, 0.7); + @include wavy-underline(--d-annotation-info-background-intense, $info-40, 1.7); + .image-bright { // $gray-10 converted to filter using https://codepen.io/sosuke/pen/Pjoqqp filter: invert(8%) sepia(10%) saturate(679%) hue-rotate(201deg) brightness(93%) contrast(92%);