@simple-reporting/base 1.0.39 → 1.0.40
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dev/package.json +1 -1
- package/dev/src/App.vue +1 -0
- package/dev/src/assets/scss/editor.scss +1 -0
- package/dev/src/assets/scss/general.scss +18 -0
- package/dev/src/assets/scss/margins.scss +4 -2
- package/dev/src/entries/pdf.ts +5 -0
- package/dev/srl.config.json +60 -6
- package/livingdocs/010.Titles/010.title-h1/scss/_spacing-variations.scss +0 -2
- package/livingdocs/010.Titles/010.title-h1/scss/web.scss +7 -0
- package/livingdocs/010.Titles/020.title-h2/scss/_spacing-variations.scss +0 -2
- package/livingdocs/010.Titles/020.title-h2/scss/general.scss +10 -0
- package/livingdocs/010.Titles/030.title-h3/scss/_spacing-variations.scss +0 -2
- package/livingdocs/010.Titles/040.title-h4/scss/_spacing-variations.scss +0 -2
- package/livingdocs/010.Titles/050.title-h5/scss/_spacing-variations.scss +0 -2
- package/livingdocs/010.Titles/060.title-h6/scss/_spacing-variations.scss +0 -2
- package/livingdocs/020.Text/020.paragraph/scss/_spacing-variations.scss +1 -2
- package/livingdocs/020.Text/020.paragraph/scss/general.scss +4 -0
- package/livingdocs/020.Text/040.link/scss/general.scss +8 -0
- package/livingdocs/020.Text/060.quote-with-portrait/scss/_spacing-variations.scss +1 -2
- package/livingdocs/020.Text/060.quote-with-portrait/scss/general.scss +12 -0
- package/livingdocs/020.Text/060.quote-with-portrait/scss/web.scss +7 -0
- package/livingdocs/020.Text/070.footnote-container/scss/_spacing-variations.scss +0 -2
- package/livingdocs/020.Text/080.footnote-item/scss/word.scss +8 -0
- package/livingdocs/030.Lists/010.unordered-list/scss/_spacing-variations.scss +0 -2
- package/livingdocs/040.Media/010.table/scss/_spacing-variations.scss +0 -2
- package/livingdocs/040.Media/020.image/scss/_spacing-variations.scss +0 -2
- package/livingdocs/040.Media/020.image/scss/web.scss +19 -5
- package/livingdocs/040.Media/030.video/ld-conf.json +1 -6
- package/livingdocs/040.Media/030.video/properties.json +7 -0
- package/livingdocs/040.Media/030.video/scss/_spacing-variations.scss +0 -2
- package/livingdocs/040.Media/030.video/scss/editor.scss +10 -0
- package/livingdocs/040.Media/030.video/scss/general.scss +6 -1
- package/livingdocs/040.Media/030.video/scss/pdf.scss +8 -0
- package/livingdocs/040.Media/030.video/video.html +27 -30
- package/livingdocs/040.Media/030.video/video.vue +71 -32
- package/livingdocs/060.Buttons/020.button/scss/general.scss +2 -2
- package/livingdocs/070.Container/010.aside-content-container/scss/pdf.scss +15 -0
- package/livingdocs/070.Container/010.aside-content-container/scss/web.scss +4 -0
- package/livingdocs/070.Container/020.columns-container/scss/app.scss +1 -0
- package/livingdocs/070.Container/020.columns-container/scss/editor.scss +1 -0
- package/livingdocs/070.Container/020.columns-container/scss/general.scss +5 -0
- package/livingdocs/070.Container/020.columns-container/scss/pdf.scss +8 -0
- package/livingdocs/070.Container/020.columns-container/scss/web.scss +1 -0
- package/livingdocs/070.Container/020.columns-container/scss/word.scss +1 -0
- package/livingdocs/070.Container/020.columns-container/scss/xbrl.scss +2 -0
- package/livingdocs/080.CV/010.cv/scss/editor.scss +10 -1
- package/livingdocs/080.CV/010.cv/scss/web.scss +1 -1
- package/livingdocs/080.CV/020.cv-time-span/scss/_spacing-variations.scss +0 -2
- package/livingdocs/100.Misc/010.anchor/scss/editor.scss +4 -0
- package/livingdocs/100.Misc/020.accordion/accordion.html +9 -9
- package/livingdocs/110.PDF/010.pdf-pagebreak/scss/editor.scss +1 -0
- package/livingdocs/110.PDF/021.pdf-columnbreak/scss/editor.scss +1 -0
- package/livingdocs/110.PDF/070.pdf-cover/properties.json +2 -2
- package/livingdocs/110.PDF/070.pdf-cover/scss/general.scss +3 -0
- package/livingdocs/110.PDF/100.pdf-toc-item/scss/general.scss +6 -8
- package/livingdocs/120.Startpage/010.hero-video/hero-video.html +10 -0
- package/livingdocs/120.Startpage/010.hero-video/ld-conf.json +5 -0
- package/livingdocs/120.Startpage/010.hero-video/properties.json +1 -0
- package/livingdocs/120.Startpage/010.hero-video/scss/_spacing-variations.scss +3 -0
- package/livingdocs/120.Startpage/010.hero-video/scss/app.scss +2 -0
- package/livingdocs/120.Startpage/010.hero-video/scss/editor.scss +9 -0
- package/livingdocs/120.Startpage/010.hero-video/scss/web.scss +78 -0
- package/livingdocs/120.Startpage/020.teaser-title-image-quote/ld-conf.json +18 -0
- package/livingdocs/120.Startpage/020.teaser-title-image-quote/properties.json +1 -0
- package/livingdocs/120.Startpage/020.teaser-title-image-quote/scss/_spacing-variations.scss +4 -0
- package/livingdocs/120.Startpage/020.teaser-title-image-quote/scss/app.scss +2 -0
- package/livingdocs/120.Startpage/020.teaser-title-image-quote/scss/editor.scss +22 -0
- package/livingdocs/120.Startpage/020.teaser-title-image-quote/scss/web.scss +41 -0
- package/livingdocs/120.Startpage/020.teaser-title-image-quote/teaser-title-image-quote.html +45 -0
- package/livingdocs/120.Startpage/030.teaser-quote/ld-conf.json +25 -0
- package/livingdocs/120.Startpage/030.teaser-quote/properties.json +1 -0
- package/livingdocs/120.Startpage/030.teaser-quote/scss/_spacing-variations.scss +3 -0
- package/livingdocs/120.Startpage/030.teaser-quote/scss/app.scss +2 -0
- package/livingdocs/120.Startpage/030.teaser-quote/scss/editor.scss +6 -0
- package/livingdocs/120.Startpage/030.teaser-quote/scss/web.scss +126 -0
- package/livingdocs/120.Startpage/030.teaser-quote/teaser-quote.html +48 -0
- package/livingdocs/120.Startpage/040.teaser/ld-conf.json +23 -0
- package/livingdocs/120.Startpage/040.teaser/scss/_spacing-variations.scss +3 -0
- package/livingdocs/120.Startpage/040.teaser/scss/app.scss +2 -0
- package/livingdocs/120.Startpage/040.teaser/scss/editor.scss +6 -0
- package/livingdocs/120.Startpage/040.teaser/scss/web.scss +73 -0
- package/livingdocs/120.Startpage/040.teaser/teaser.html +34 -0
- package/livingdocs/130.Hosting_Components/010.download-center/download-center.html +5 -1
- package/livingdocs/130.Hosting_Components/020.search/scss/web.scss +7 -44
- package/livingdocs/130.Hosting_Components/020.search/search.html +7 -1
- package/livingdocs/130.Hosting_Components/020.search/search.vue +1 -1
- package/livingdocs/130.Hosting_Components/020.search/searchHighlightOnTarget.vue +246 -0
- package/livingdocs/999.Properties/font-color/properties.json +15 -0
- package/package.json +1 -1
- package/scripts/config.js +2 -0
- package/scss/spacer/mixins.scss +64 -12
- package/srl/srl/fa/index.scss +2 -2
- package/srl/srl/fa/source-free.scss +1 -4
- package/srl/srl/pdf/PDFNestedContainers.ts +110 -0
- package/srl/srl/pdf/PDFNotes.ts +4 -2
- package/srl/srl/pdf/PDFSetPageNumbers.ts +3 -1
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
@use "srl";
|
|
2
|
+
@use "@/assets/scss/margins";
|
|
3
|
+
@use "spacing-variations";
|
|
4
|
+
|
|
5
|
+
@include margins.srl-component-margin(spacing-variations.$margins);
|
|
6
|
+
|
|
7
|
+
.srl-teaser-quote {
|
|
8
|
+
position: relative;
|
|
9
|
+
@extend %srl-breakout-grid-base;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
.srl-teaser-quote__image-container {
|
|
13
|
+
aspect-ratio: 393 / 702;
|
|
14
|
+
|
|
15
|
+
@include srl.grid-media-up(tablet-pt) {
|
|
16
|
+
position: relative;
|
|
17
|
+
z-index: 0;
|
|
18
|
+
aspect-ratio: 834 / 702;
|
|
19
|
+
overflow: clip;
|
|
20
|
+
grid-row: 1;
|
|
21
|
+
grid-column: full-start / full-end;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
@include srl.grid-media-up(desktop-large) {
|
|
25
|
+
aspect-ratio: 1728 / 702;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
.srl-teaser-quote__image {
|
|
30
|
+
width: 100%;
|
|
31
|
+
height: 100%;
|
|
32
|
+
object-fit: cover;
|
|
33
|
+
display: block;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
.srl-teaser-quote__image-container:has(.srl-teaser-quote__image--mobile) {
|
|
37
|
+
.srl-teaser-quote__image--desktop {
|
|
38
|
+
display: none;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
.srl-teaser-quote__image--mobile {
|
|
42
|
+
display: block;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
@include srl.grid-media-up(tablet-pt) {
|
|
46
|
+
.srl-teaser-quote__image--desktop {
|
|
47
|
+
display: block;
|
|
48
|
+
}
|
|
49
|
+
.srl-teaser-quote__image--mobile {
|
|
50
|
+
display: none;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
.srl-teaser-quote__title-container,
|
|
56
|
+
.srl-teaser-quote__content-container {
|
|
57
|
+
// Mobile
|
|
58
|
+
@include srl.grid-col(4);
|
|
59
|
+
|
|
60
|
+
// Mobile landscape
|
|
61
|
+
@include srl.grid-col(4, phone-ls);
|
|
62
|
+
|
|
63
|
+
// Tablet portrait
|
|
64
|
+
@include srl.grid-col(8, tablet-pt);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
.srl-teaser-quote__content-container {
|
|
68
|
+
position: absolute;
|
|
69
|
+
top: 0;
|
|
70
|
+
right: 0;
|
|
71
|
+
bottom: 0;
|
|
72
|
+
left: 0;
|
|
73
|
+
width: 100%;
|
|
74
|
+
display: flex;
|
|
75
|
+
flex-direction: column;
|
|
76
|
+
justify-content: space-between;
|
|
77
|
+
margin-top: var(--srl-container-padding, unset);
|
|
78
|
+
margin-bottom: var(--srl-container-padding, unset);
|
|
79
|
+
padding-inline: var(--srl-container-padding);
|
|
80
|
+
|
|
81
|
+
@include srl.grid-media-up(tablet-ls) {
|
|
82
|
+
padding-inline: 0;
|
|
83
|
+
grid-column: content-start / content-end;
|
|
84
|
+
display: grid;
|
|
85
|
+
grid-template-columns: subgrid;
|
|
86
|
+
position: relative;
|
|
87
|
+
top: auto;
|
|
88
|
+
right: auto;
|
|
89
|
+
bottom: auto;
|
|
90
|
+
left: auto;
|
|
91
|
+
grid-row: 1;
|
|
92
|
+
margin-top: srl.system-size-unit(106);
|
|
93
|
+
margin-bottom: srl.system-size-unit(106);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
@include srl.grid-media-up(desktop) {
|
|
97
|
+
margin-top: srl.spacer-get(800);
|
|
98
|
+
margin-bottom: srl.spacer-get(800);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
.srl-teaser-quote__content {
|
|
103
|
+
padding: srl.spacer-get(300);
|
|
104
|
+
|
|
105
|
+
@include srl.grid-media-up(tablet-ls) {
|
|
106
|
+
align-self: end;
|
|
107
|
+
grid-column: col 4 / content-end;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
@include srl.grid-media-up(desktop) {
|
|
111
|
+
align-self: end;
|
|
112
|
+
z-index: 1;
|
|
113
|
+
grid-column: col 7 / content-end;
|
|
114
|
+
border-radius: 16px;
|
|
115
|
+
|
|
116
|
+
.srl-reverse & {
|
|
117
|
+
grid-column: content-start / col 7;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
.srl-teaser-quote__title-container {
|
|
123
|
+
@include srl.grid-media-up(tablet-ls) {
|
|
124
|
+
grid-column: content-start / content-end;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
<div class="srl-teaser-quote">
|
|
2
|
+
<div class="srl-teaser-quote__alt-text" doc-editable="alt-tag" doc-toggle="show-alt-text"
|
|
3
|
+
data-alt-text-source="alt">
|
|
4
|
+
Write the alt text here (optional, but recommended)
|
|
5
|
+
</div>
|
|
6
|
+
|
|
7
|
+
<div class="srl-teaser-quote__image-container">
|
|
8
|
+
<img class="srl-teaser-quote__image srl-teaser-quote__image--desktop" doc-image="image" data-alt-text-target="alt">
|
|
9
|
+
<img class="srl-teaser-quote__image srl-teaser-quote__image--mobile" doc-image="image-mobile" data-alt-text-target="alt">
|
|
10
|
+
</div>
|
|
11
|
+
|
|
12
|
+
<div class="srl-teaser-quote__content-container">
|
|
13
|
+
<div class="srl-teaser-quote__title-container">
|
|
14
|
+
<h2 class="srl-title-h2">
|
|
15
|
+
<span class="srl-title-h2__number-text-container">
|
|
16
|
+
<span class="srl-title-h2__text" doc-editable="title-h2">
|
|
17
|
+
Continually coordinate interactive infrastructures for goal-oriented
|
|
18
|
+
</span>
|
|
19
|
+
</span>
|
|
20
|
+
</h2>
|
|
21
|
+
</div>
|
|
22
|
+
<div class="srl-teaser-quote__content srl-bg-sand-1000">
|
|
23
|
+
<blockquote class="srl-quote">
|
|
24
|
+
<div class="srl-quote__text">
|
|
25
|
+
<p class="srl-quote__quote srl-linkable" doc-editable="quote-text">
|
|
26
|
+
Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse
|
|
27
|
+
</p>
|
|
28
|
+
<cite class="srl-quote__cite">
|
|
29
|
+
<p class="srl-quote__name" doc-editable="quote-name" doc-optional>
|
|
30
|
+
Max Mustermann
|
|
31
|
+
</p>
|
|
32
|
+
<p class="srl-quote__position" doc-editable="quote-position" doc-optional>
|
|
33
|
+
CEO
|
|
34
|
+
</p>
|
|
35
|
+
</cite>
|
|
36
|
+
</div>
|
|
37
|
+
</blockquote>
|
|
38
|
+
<div class="srl-button-container">
|
|
39
|
+
<div class="srl-button-container__inner">
|
|
40
|
+
<a doc-link="href" class="srl-button srl-button-icon-arrow-right-after">
|
|
41
|
+
<i class="srl-button__icon srl-icon srl-icon-arrow-right" aria-hidden="true"></i>
|
|
42
|
+
<span class="srl-button__text" doc-editable="button-text">Button</span>
|
|
43
|
+
</a>
|
|
44
|
+
</div>
|
|
45
|
+
</div>
|
|
46
|
+
</div>
|
|
47
|
+
</div>
|
|
48
|
+
</div>
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "teaser",
|
|
3
|
+
"label": "Teaser",
|
|
4
|
+
"properties": [
|
|
5
|
+
"icon",
|
|
6
|
+
"reverse"
|
|
7
|
+
],
|
|
8
|
+
"directives": {
|
|
9
|
+
"show-alt-text": {
|
|
10
|
+
"type": "toggle",
|
|
11
|
+
"label": "Show alt text",
|
|
12
|
+
"default": false
|
|
13
|
+
},
|
|
14
|
+
"image-mobile": {
|
|
15
|
+
"imageRatios": ["16:9"],
|
|
16
|
+
"allowOriginalRatio": false
|
|
17
|
+
},
|
|
18
|
+
"image": {
|
|
19
|
+
"imageRatios": ["16:9"],
|
|
20
|
+
"allowOriginalRatio": false
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
@use "srl";
|
|
2
|
+
@use "@/assets/scss/margins";
|
|
3
|
+
@use "spacing-variations";
|
|
4
|
+
|
|
5
|
+
.srl-teaser {
|
|
6
|
+
@extend %srl-breakout-grid-base;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
@include margins.srl-component-margin(spacing-variations.$margins);
|
|
10
|
+
|
|
11
|
+
.srl-teaser__image-container {
|
|
12
|
+
@include srl.grid-media-up(desktop) {
|
|
13
|
+
position: relative;
|
|
14
|
+
z-index: 0;
|
|
15
|
+
aspect-ratio: 16 / 9;
|
|
16
|
+
overflow: clip;
|
|
17
|
+
grid-row: 1;
|
|
18
|
+
grid-column: full-start / col 11;
|
|
19
|
+
|
|
20
|
+
.srl-reverse & {
|
|
21
|
+
grid-column: col 3 / full-end;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
.srl-teaser__image-container:has(.srl-teaser__image--mobile) {
|
|
27
|
+
.srl-teaser__image--desktop {
|
|
28
|
+
display: none;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
.srl-teaser__image--mobile {
|
|
32
|
+
display: block;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
@include srl.grid-media-up(tablet-pt) {
|
|
36
|
+
.srl-teaser__image--desktop {
|
|
37
|
+
display: block;
|
|
38
|
+
}
|
|
39
|
+
.srl-teaser__image--mobile {
|
|
40
|
+
display: none;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
.srl-teaser__content-container {
|
|
46
|
+
@include srl.grid-media-up(desktop) {
|
|
47
|
+
margin: 0;
|
|
48
|
+
padding: 0;
|
|
49
|
+
grid-column: content-start / content-end;
|
|
50
|
+
display: grid;
|
|
51
|
+
grid-template-columns: subgrid;
|
|
52
|
+
position: relative;
|
|
53
|
+
grid-row: 1;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
.srl-teaser__content {
|
|
58
|
+
padding: var(--srl-container-padding, unset);
|
|
59
|
+
width: auto;
|
|
60
|
+
grid-column-end: span 4;
|
|
61
|
+
|
|
62
|
+
@include srl.grid-media-up(desktop) {
|
|
63
|
+
padding: var(--srl-spacer-300, unset);
|
|
64
|
+
border-radius: 16px;
|
|
65
|
+
align-self: center;
|
|
66
|
+
z-index: 1;
|
|
67
|
+
grid-column: col 6 / content-end;
|
|
68
|
+
|
|
69
|
+
.srl-reverse & {
|
|
70
|
+
grid-column: content-start / col 8;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
<div class="srl-teaser">
|
|
2
|
+
<div class="srl-teaser__alt-text" doc-editable="alt-tag" doc-toggle="show-alt-text"
|
|
3
|
+
data-alt-text-source="alt">
|
|
4
|
+
Write the alt text here (optional, but recommended)
|
|
5
|
+
</div>
|
|
6
|
+
|
|
7
|
+
<div class="srl-teaser__image-container">
|
|
8
|
+
<img class="srl-teaser__image srl-teaser__image--desktop" doc-image="image" data-alt-text-target="alt">
|
|
9
|
+
<img class="srl-teaser__image srl-teaser__image--mobile" doc-image="image-mobile" data-alt-text-target="alt">
|
|
10
|
+
</div>
|
|
11
|
+
|
|
12
|
+
<div class="srl-teaser__content-container">
|
|
13
|
+
<div class="srl-teaser__content srl-bg-sand-1000">
|
|
14
|
+
<h2 class="srl-title-h2">
|
|
15
|
+
<span class="srl-title-h2__number-text-container">
|
|
16
|
+
<span class="srl-title-h2__text" doc-editable="title-h2">Vorsorge</span>
|
|
17
|
+
</span>
|
|
18
|
+
</h2>
|
|
19
|
+
<div class="srl-lead">
|
|
20
|
+
<p class="srl-lead__text" doc-editable="lead">
|
|
21
|
+
Lorem ipsum dolor sit amet, consete ur sadipscing elitr, sed diam nonumy.
|
|
22
|
+
</p>
|
|
23
|
+
</div>
|
|
24
|
+
<div class="srl-button-container">
|
|
25
|
+
<div class="srl-button-container__inner">
|
|
26
|
+
<a doc-link="href" class="srl-button srl-button-icon-arrow-right-after">
|
|
27
|
+
<i class="srl-button__icon srl-icon srl-icon-arrow-right" aria-hidden="true"></i>
|
|
28
|
+
<span class="srl-button__text" doc-editable="button-text">Button</span>
|
|
29
|
+
</a>
|
|
30
|
+
</div>
|
|
31
|
+
</div>
|
|
32
|
+
</div>
|
|
33
|
+
</div>
|
|
34
|
+
</div>
|
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
<srl-ld-download-center
|
|
1
|
+
<srl-ld-download-center
|
|
2
|
+
data-remove-from-pdf="complete"
|
|
3
|
+
data-remove-from-word="complete"
|
|
4
|
+
data-remove-from-xhtml="complete"
|
|
5
|
+
>
|
|
2
6
|
<div class="srl-download-center" data-remove-from-web="complete">
|
|
3
7
|
<span class="srl-download-center__editor-text" data-remove-from-pdf="complete">
|
|
4
8
|
Placeholder for download list
|
|
@@ -16,12 +16,16 @@ Search form
|
|
|
16
16
|
display: flex;
|
|
17
17
|
justify-content: flex-end;
|
|
18
18
|
align-items: center;
|
|
19
|
-
background-color: srl.colors-
|
|
19
|
+
background-color: srl.colors-white-1000();
|
|
20
|
+
border: 1px solid srl.colors-grey-200();
|
|
20
21
|
border-radius: srl.system-root-style(srl-default-border-radius);
|
|
21
22
|
overflow: hidden;
|
|
22
23
|
|
|
23
24
|
&:hover {
|
|
24
25
|
@extend %srl-button__switch-hover;
|
|
26
|
+
//background: srl.colors-white-1000();
|
|
27
|
+
|
|
28
|
+
/*
|
|
25
29
|
background-color: srl.colors-secondary-1000();
|
|
26
30
|
.srl-search-form__button {
|
|
27
31
|
background-color: srl.colors-secondary-1000();
|
|
@@ -31,48 +35,13 @@ Search form
|
|
|
31
35
|
color: srl.colors-grey-800();
|
|
32
36
|
}
|
|
33
37
|
}
|
|
38
|
+
*/
|
|
34
39
|
}
|
|
35
40
|
|
|
36
41
|
&:has(input:focus) {
|
|
42
|
+
background: srl.colors-sand-600();
|
|
37
43
|
@extend %srl-button__switch-focus;
|
|
38
|
-
background-color: srl.colors-secondary-1000();
|
|
39
|
-
.srl-search-form__input {
|
|
40
|
-
color: srl.colors-primary-1000();
|
|
41
|
-
&::placeholder {
|
|
42
|
-
color: srl.colors-primary-800();
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
.srl-search-form__button {
|
|
46
|
-
background-color: srl.colors-secondary-1000();
|
|
47
|
-
border-color: srl.colors-primary-1000();
|
|
48
|
-
|
|
49
|
-
svg {
|
|
50
|
-
color: srl.colors-primary-1000();
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
44
|
}
|
|
54
|
-
|
|
55
|
-
/*
|
|
56
|
-
&:has(input:focus-visible) {
|
|
57
|
-
background-color: srl.colors-primary-200();
|
|
58
|
-
border: srl.system-size-unit(1) solid srl.colors-primary-1000();
|
|
59
|
-
.srl-search-form__input {
|
|
60
|
-
color: srl.colors-grey-600();
|
|
61
|
-
&::placeholder {
|
|
62
|
-
color: srl.colors-grey-400();
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
.srl-search-form__button {
|
|
66
|
-
background-color: srl.colors-primary-200();
|
|
67
|
-
border-color: srl.colors-grey-600();
|
|
68
|
-
|
|
69
|
-
svg {
|
|
70
|
-
color: srl.colors-grey-600();
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
*/
|
|
76
45
|
}
|
|
77
46
|
|
|
78
47
|
.srl-search-form__label {
|
|
@@ -118,12 +87,6 @@ Search form
|
|
|
118
87
|
.srl-search-form__button {
|
|
119
88
|
position: absolute;
|
|
120
89
|
right: srl.spacer-get(400);
|
|
121
|
-
background-color: srl.colors-grey-600();
|
|
122
|
-
border-color: srl.colors-grey-800();
|
|
123
|
-
|
|
124
|
-
svg {
|
|
125
|
-
color: srl.colors-grey-800();
|
|
126
|
-
}
|
|
127
90
|
}
|
|
128
91
|
|
|
129
92
|
/*
|
|
@@ -1,4 +1,10 @@
|
|
|
1
|
-
<srl-ld-search
|
|
1
|
+
<srl-ld-search
|
|
2
|
+
use-auto-search
|
|
3
|
+
use-more-results
|
|
4
|
+
data-remove-from-pdf="complete"
|
|
5
|
+
data-remove-from-word="complete"
|
|
6
|
+
data-remove-from-xhtml="complete"
|
|
7
|
+
>
|
|
2
8
|
<div class="srl-search" data-remove-from-web="complete">
|
|
3
9
|
<span class="srl-search__editor-text">
|
|
4
10
|
Placeholder for search form
|
|
@@ -391,7 +391,7 @@ function setWindowState(index: number) {
|
|
|
391
391
|
/>
|
|
392
392
|
<button
|
|
393
393
|
tabindex="-2"
|
|
394
|
-
class="srl-button srl-button--icon"
|
|
394
|
+
class="srl-search-form__button srl-button srl-button--icon"
|
|
395
395
|
type="button"
|
|
396
396
|
:aria-label="$t('search.search')"
|
|
397
397
|
@click="submitSearch"
|
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { nextTick, onBeforeUnmount, onMounted, watch } from 'vue'
|
|
3
|
+
import { useRoute } from 'vue-router'
|
|
4
|
+
|
|
5
|
+
const props = withDefaults(defineProps<{
|
|
6
|
+
rootSelector?: string
|
|
7
|
+
highlightClass?: string
|
|
8
|
+
queryParam?: string
|
|
9
|
+
}>(), {
|
|
10
|
+
rootSelector: '#srl-page-main',
|
|
11
|
+
highlightClass: 'searchTarget',
|
|
12
|
+
queryParam: 'searchTarget'
|
|
13
|
+
})
|
|
14
|
+
|
|
15
|
+
const route = useRoute()
|
|
16
|
+
|
|
17
|
+
let mutationObserver: MutationObserver | null = null
|
|
18
|
+
let highlightTimeout: ReturnType<typeof setTimeout> | null = null
|
|
19
|
+
let isApplyingHighlight = false
|
|
20
|
+
let hasScrolledToHighlight = false
|
|
21
|
+
|
|
22
|
+
function getRootElement(): HTMLElement | null {
|
|
23
|
+
return document.querySelector(props.rootSelector)
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function escapeRegExp(value: string): string {
|
|
27
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function removeHighlights(root: HTMLElement): void {
|
|
31
|
+
const highlights = root.querySelectorAll(`span.${props.highlightClass}`)
|
|
32
|
+
|
|
33
|
+
highlights.forEach((highlight) => {
|
|
34
|
+
const parent = highlight.parentNode
|
|
35
|
+
if (!parent) return
|
|
36
|
+
|
|
37
|
+
parent.replaceChild(document.createTextNode(highlight.textContent ?? ''), highlight)
|
|
38
|
+
parent.normalize()
|
|
39
|
+
})
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function highlightTextNodes(root: HTMLElement, term: string): number {
|
|
43
|
+
const safeTermPattern = escapeRegExp(term)
|
|
44
|
+
const regex = new RegExp(`(${safeTermPattern})`, 'gi')
|
|
45
|
+
|
|
46
|
+
const walker = document.createTreeWalker(
|
|
47
|
+
root,
|
|
48
|
+
NodeFilter.SHOW_TEXT,
|
|
49
|
+
{
|
|
50
|
+
acceptNode(node) {
|
|
51
|
+
const parent = node.parentElement
|
|
52
|
+
if (!parent) return NodeFilter.FILTER_REJECT
|
|
53
|
+
|
|
54
|
+
const tag = parent.tagName.toLowerCase()
|
|
55
|
+
if (
|
|
56
|
+
tag === 'script' ||
|
|
57
|
+
tag === 'style' ||
|
|
58
|
+
tag === 'noscript' ||
|
|
59
|
+
tag === 'textarea'
|
|
60
|
+
) {
|
|
61
|
+
return NodeFilter.FILTER_REJECT
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
if (parent.closest(`.${props.highlightClass}`)) {
|
|
65
|
+
return NodeFilter.FILTER_REJECT
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const text = node.textContent
|
|
69
|
+
if (!text || !text.trim()) return NodeFilter.FILTER_SKIP
|
|
70
|
+
|
|
71
|
+
regex.lastIndex = 0
|
|
72
|
+
if (!regex.test(text)) return NodeFilter.FILTER_SKIP
|
|
73
|
+
|
|
74
|
+
return NodeFilter.FILTER_ACCEPT
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
)
|
|
78
|
+
|
|
79
|
+
const textNodes: Text[] = []
|
|
80
|
+
let node: Node | null = null
|
|
81
|
+
|
|
82
|
+
while ((node = walker.nextNode())) {
|
|
83
|
+
textNodes.push(node as Text)
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
let hitCount = 0
|
|
87
|
+
|
|
88
|
+
for (const textNode of textNodes) {
|
|
89
|
+
const text = textNode.textContent ?? ''
|
|
90
|
+
regex.lastIndex = 0
|
|
91
|
+
|
|
92
|
+
const matches = [...text.matchAll(regex)]
|
|
93
|
+
if (!matches.length) continue
|
|
94
|
+
|
|
95
|
+
const fragment = document.createDocumentFragment()
|
|
96
|
+
let lastIndex = 0
|
|
97
|
+
|
|
98
|
+
for (const match of matches) {
|
|
99
|
+
const matchText = match[0]
|
|
100
|
+
const index = match.index ?? 0
|
|
101
|
+
|
|
102
|
+
if (index > lastIndex) {
|
|
103
|
+
fragment.appendChild(document.createTextNode(text.slice(lastIndex, index)))
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
const span = document.createElement('span')
|
|
107
|
+
span.className = props.highlightClass
|
|
108
|
+
span.textContent = matchText
|
|
109
|
+
fragment.appendChild(span)
|
|
110
|
+
|
|
111
|
+
lastIndex = index + matchText.length
|
|
112
|
+
hitCount++
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
if (lastIndex < text.length) {
|
|
116
|
+
fragment.appendChild(document.createTextNode(text.slice(lastIndex)))
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
textNode.parentNode?.replaceChild(fragment, textNode)
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
return hitCount
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
function scrollToFirstHighlight(root: HTMLElement): void {
|
|
126
|
+
const firstHighlight = root.querySelector<HTMLElement>(`.${props.highlightClass}`)
|
|
127
|
+
if (!firstHighlight) return
|
|
128
|
+
|
|
129
|
+
firstHighlight.scrollIntoView({
|
|
130
|
+
behavior: 'smooth',
|
|
131
|
+
block: 'center',
|
|
132
|
+
inline: 'nearest'
|
|
133
|
+
})
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
function stopObserver(): void {
|
|
137
|
+
mutationObserver?.disconnect()
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
function startObserver(): void {
|
|
141
|
+
const root = getRootElement()
|
|
142
|
+
if (!root) return
|
|
143
|
+
|
|
144
|
+
stopObserver()
|
|
145
|
+
|
|
146
|
+
mutationObserver = new MutationObserver(() => {
|
|
147
|
+
if (isApplyingHighlight) return
|
|
148
|
+
scheduleHighlight()
|
|
149
|
+
})
|
|
150
|
+
|
|
151
|
+
mutationObserver.observe(root, {
|
|
152
|
+
childList: true,
|
|
153
|
+
subtree: true,
|
|
154
|
+
characterData: true
|
|
155
|
+
})
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
function scheduleHighlight(): void {
|
|
159
|
+
if (highlightTimeout) {
|
|
160
|
+
clearTimeout(highlightTimeout)
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
highlightTimeout = setTimeout(() => {
|
|
164
|
+
void applySearchHighlight()
|
|
165
|
+
}, 0)
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
async function applySearchHighlight(): Promise<void> {
|
|
169
|
+
const root = getRootElement()
|
|
170
|
+
if (!root || isApplyingHighlight) return
|
|
171
|
+
|
|
172
|
+
const rawSearchTarget = route.query[props.queryParam]
|
|
173
|
+
const searchTarget =
|
|
174
|
+
typeof rawSearchTarget === 'string'
|
|
175
|
+
? decodeURIComponent(rawSearchTarget).trim()
|
|
176
|
+
: ''
|
|
177
|
+
|
|
178
|
+
isApplyingHighlight = true
|
|
179
|
+
stopObserver()
|
|
180
|
+
|
|
181
|
+
try {
|
|
182
|
+
removeHighlights(root)
|
|
183
|
+
|
|
184
|
+
if (!searchTarget) {
|
|
185
|
+
hasScrolledToHighlight = false
|
|
186
|
+
return
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
await nextTick()
|
|
190
|
+
|
|
191
|
+
const hitCount = highlightTextNodes(root, searchTarget)
|
|
192
|
+
|
|
193
|
+
if (hitCount > 0 && !hasScrolledToHighlight) {
|
|
194
|
+
await nextTick()
|
|
195
|
+
scrollToFirstHighlight(root)
|
|
196
|
+
hasScrolledToHighlight = true
|
|
197
|
+
}
|
|
198
|
+
} finally {
|
|
199
|
+
isApplyingHighlight = false
|
|
200
|
+
startObserver()
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
onMounted(async () => {
|
|
205
|
+
await nextTick()
|
|
206
|
+
startObserver()
|
|
207
|
+
await applySearchHighlight()
|
|
208
|
+
})
|
|
209
|
+
|
|
210
|
+
watch(
|
|
211
|
+
() => route.fullPath,
|
|
212
|
+
async () => {
|
|
213
|
+
hasScrolledToHighlight = false
|
|
214
|
+
await nextTick()
|
|
215
|
+
scheduleHighlight()
|
|
216
|
+
}
|
|
217
|
+
)
|
|
218
|
+
|
|
219
|
+
watch(
|
|
220
|
+
() => props.rootSelector,
|
|
221
|
+
async () => {
|
|
222
|
+
hasScrolledToHighlight = false
|
|
223
|
+
await nextTick()
|
|
224
|
+
startObserver()
|
|
225
|
+
scheduleHighlight()
|
|
226
|
+
}
|
|
227
|
+
)
|
|
228
|
+
|
|
229
|
+
onBeforeUnmount(() => {
|
|
230
|
+
stopObserver()
|
|
231
|
+
|
|
232
|
+
if (highlightTimeout) {
|
|
233
|
+
clearTimeout(highlightTimeout)
|
|
234
|
+
}
|
|
235
|
+
})
|
|
236
|
+
</script>
|
|
237
|
+
|
|
238
|
+
<template />
|
|
239
|
+
|
|
240
|
+
<style lang="scss">
|
|
241
|
+
@use "srl";
|
|
242
|
+
.searchTarget {
|
|
243
|
+
background-color: srl.colors-primary-1000();
|
|
244
|
+
color: srl.colors-white-1000();
|
|
245
|
+
}
|
|
246
|
+
</style>
|