astro-pure 1.2.7 → 1.2.9
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/components/basic/Header.astro +11 -6
- package/components/pages/BackToTop.astro +59 -20
- package/components/pages/Hero.astro +8 -1
- package/components/pages/TOC.astro +6 -0
- package/components/pages/TOCHeading.astro +1 -1
- package/libs/icons.ts +2 -0
- package/package.json +1 -1
- package/bunfig.toml +0 -2
|
@@ -5,12 +5,8 @@ import { Icon } from '../user'
|
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
<header-component
|
|
8
|
-
class='group sticky top-4 z-30 mb-12 flex items-center justify-between rounded-xl border border-transparent max-sm:py-1 sm:rounded-2xl
|
|
8
|
+
class='group sticky top-4 z-30 mb-12 flex items-center justify-between rounded-xl border border-transparent max-sm:py-1 sm:rounded-2xl'
|
|
9
9
|
>
|
|
10
|
-
<!-- <div
|
|
11
|
-
class='absolute -left-4 -top-8 -z-10 box-content hidden h-20 w-[calc(100%+2rem)] !duration-0 max-sm:group-[.expanded]:block max-sm:group-[.expanded.not-top]:hidden max-sm:group-[.expanded]:bg-white dark:max-sm:group-[.expanded]:bg-muted'
|
|
12
|
-
>
|
|
13
|
-
</div> -->
|
|
14
10
|
<a
|
|
15
11
|
class='z-30 text-xl font-semibold group-[.not-top]:ms-2 sm:group-[.not-top]:ms-3'
|
|
16
12
|
style='transition:margin-inline 0.3s'
|
|
@@ -45,7 +41,7 @@ import { Icon } from '../user'
|
|
|
45
41
|
</div>
|
|
46
42
|
</div>
|
|
47
43
|
|
|
48
|
-
|
|
44
|
+
{/* buttons */}
|
|
49
45
|
<div class='z-30 flex gap-x-4 group-[.not-top]:gap-x-2' style='transition:gap 0.3s'>
|
|
50
46
|
<button
|
|
51
47
|
id='toggleDarkMode'
|
|
@@ -125,6 +121,12 @@ import { Icon } from '../user'
|
|
|
125
121
|
background-color 0.15s;
|
|
126
122
|
|
|
127
123
|
&.not-top {
|
|
124
|
+
--un-border-opacity: 1;
|
|
125
|
+
border-color: hsl(var(--border) / var(--un-border-opacity));
|
|
126
|
+
--un-bg-opacity: 1;
|
|
127
|
+
background-color: hsl(var(--background) / var(--un-bg-opacity));
|
|
128
|
+
padding-left: 0.375rem;
|
|
129
|
+
padding-right: 0.375rem;
|
|
128
130
|
box-shadow:
|
|
129
131
|
rgb(255, 255, 255) 0px 0px 0px 0px,
|
|
130
132
|
rgba(24, 24, 27, 0.08) 0px 0px 0px 1px,
|
|
@@ -140,6 +142,9 @@ import { Icon } from '../user'
|
|
|
140
142
|
margin-inline: 8%;
|
|
141
143
|
}
|
|
142
144
|
}
|
|
145
|
+
:global(.dark) header-component.not-top {
|
|
146
|
+
background-color: hsl(var(--muted) / var(--un-bg-opacity));
|
|
147
|
+
}
|
|
143
148
|
|
|
144
149
|
/* header menu */
|
|
145
150
|
@media (max-width: 640px) {
|
|
@@ -4,25 +4,28 @@ import { Icon } from '../user'
|
|
|
4
4
|
const { header: headerName, content: contentName, needPercent = true } = Astro.props
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
<
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
data-show='false'
|
|
11
|
-
id='to-top-btn'
|
|
7
|
+
<div
|
|
8
|
+
class='z-10 group fixed bottom-8 end-4 transition-all flex flex-col gap-y-4 sm:end-8'
|
|
9
|
+
id='action-buttons'
|
|
12
10
|
>
|
|
13
|
-
<
|
|
14
|
-
|
|
11
|
+
<slot name='other-icons' />
|
|
12
|
+
<button
|
|
13
|
+
aria-label='Back to Top'
|
|
14
|
+
class='relative size-10 flex items-center justify-center rounded-full border-2 border-transparent bg-muted text-muted-foreground duration-300 hover:border-border/75 sm:size-12 opacity-0'
|
|
15
|
+
id='to-top-btn'
|
|
15
16
|
>
|
|
16
|
-
<
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
</button>
|
|
17
|
+
<div
|
|
18
|
+
class='top-text absolute bottom-0 end-0 start-0 top-0 flex items-center justify-center group-[.ended]:opacity-0'
|
|
19
|
+
>
|
|
20
|
+
<span class='text'>10</span>
|
|
21
|
+
<span class='text-xs'>%</span>
|
|
22
|
+
</div>
|
|
23
|
+
<Icon name='up' class='top-icon group-[.ended]:opacity-100' />
|
|
24
|
+
</button>
|
|
25
|
+
</div>
|
|
24
26
|
|
|
25
27
|
<script is:inline define:vars={{ headerName, contentName, needPercent }}>
|
|
28
|
+
const actionBtns = document.getElementById('action-buttons')
|
|
26
29
|
const scrollBtn = document.getElementById('to-top-btn')
|
|
27
30
|
const scrollPercentEl = scrollBtn.children[0].children[0]
|
|
28
31
|
const targetHeader = document.getElementById(headerName)
|
|
@@ -31,8 +34,8 @@ const { header: headerName, content: contentName, needPercent = true } = Astro.p
|
|
|
31
34
|
// scroll to top
|
|
32
35
|
function callback(entries) {
|
|
33
36
|
entries.forEach((entry) => {
|
|
34
|
-
// only show the
|
|
35
|
-
|
|
37
|
+
// only show the action buttons when the heading is out of view
|
|
38
|
+
actionBtns.classList.toggle('show', !entry.isIntersecting)
|
|
36
39
|
})
|
|
37
40
|
}
|
|
38
41
|
scrollBtn.addEventListener('click', () => {
|
|
@@ -44,7 +47,6 @@ const { header: headerName, content: contentName, needPercent = true } = Astro.p
|
|
|
44
47
|
} else {
|
|
45
48
|
console.error(`Element with ID ${headerName} not found.`)
|
|
46
49
|
}
|
|
47
|
-
|
|
48
50
|
if (needPercent) {
|
|
49
51
|
// scroll percentage
|
|
50
52
|
const scrollHeight = articleElement.scrollHeight // total height
|
|
@@ -63,9 +65,46 @@ const { header: headerName, content: contentName, needPercent = true } = Astro.p
|
|
|
63
65
|
scrollPercentEl.innerText = scrollPercent.toString()
|
|
64
66
|
|
|
65
67
|
// If percent is 100, percent won't need to show
|
|
66
|
-
|
|
68
|
+
actionBtns.classList.toggle('ended', scrollPercent > 100)
|
|
67
69
|
})
|
|
68
70
|
} else {
|
|
69
|
-
|
|
71
|
+
actionBtns.classList.add('ended')
|
|
70
72
|
}
|
|
71
73
|
</script>
|
|
74
|
+
|
|
75
|
+
<style>
|
|
76
|
+
#action-buttons {
|
|
77
|
+
transform: translateY(4rem);
|
|
78
|
+
&.show {
|
|
79
|
+
transform: translateY(0);
|
|
80
|
+
& #to-top-btn {
|
|
81
|
+
opacity: 1;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/* To top button status change */
|
|
86
|
+
& #to-top-btn {
|
|
87
|
+
& .top-text,
|
|
88
|
+
& .top-icon {
|
|
89
|
+
transition-property: opacity;
|
|
90
|
+
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
|
|
91
|
+
transition-duration: 150ms;
|
|
92
|
+
}
|
|
93
|
+
& .top-text {
|
|
94
|
+
opacity: 1;
|
|
95
|
+
}
|
|
96
|
+
& .top-icon {
|
|
97
|
+
opacity: 0;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
&.ended #to-top-btn,
|
|
101
|
+
& #to-top-btn:hover {
|
|
102
|
+
& .top-text {
|
|
103
|
+
opacity: 0;
|
|
104
|
+
}
|
|
105
|
+
& .top-icon {
|
|
106
|
+
opacity: 1;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
</style>
|
|
@@ -45,7 +45,7 @@ const dateTimeOptions: Intl.DateTimeFormatOptions = {
|
|
|
45
45
|
fetchpriority='high'
|
|
46
46
|
loading='eager'
|
|
47
47
|
id='blurImage'
|
|
48
|
-
class='absolute end-0 top-4 z-0 mt-0 h-full max-w-[65ch] rounded-3xl opacity-60
|
|
48
|
+
class='absolute end-0 top-4 z-0 mt-0 h-full max-w-[65ch] rounded-3xl opacity-60 transition-opacity duration-300'
|
|
49
49
|
{...heroImage}
|
|
50
50
|
/>
|
|
51
51
|
</div>
|
|
@@ -148,3 +148,10 @@ const dateTimeOptions: Intl.DateTimeFormatOptions = {
|
|
|
148
148
|
})
|
|
149
149
|
}
|
|
150
150
|
</script>
|
|
151
|
+
|
|
152
|
+
<style>
|
|
153
|
+
#blurImage {
|
|
154
|
+
--un-blur: blur(24px);
|
|
155
|
+
filter: var(--un-blur);
|
|
156
|
+
}
|
|
157
|
+
</style>
|
|
@@ -21,7 +21,7 @@ const text = rawText.endsWith('#') ? rawText.slice(0, -1) : rawText
|
|
|
21
21
|
<a
|
|
22
22
|
aria-label={`Scroll to section: ${text}`}
|
|
23
23
|
class={cn(
|
|
24
|
-
'line-clamp-2 px-3 py-1 ms-2
|
|
24
|
+
'toc-item line-clamp-2 px-3 py-1 ms-2 text-foreground/75 transition-all hover:text-foreground [&.highlight]:font-medium [&.highlight]:text-primary [&.readed]:text-input [&.highlight-bg-translucent]:bg-muted',
|
|
25
25
|
depth > 2 && 'ps-7'
|
|
26
26
|
)}
|
|
27
27
|
href={`#${slug}`}>{text}</a
|
package/libs/icons.ts
CHANGED
|
@@ -103,6 +103,8 @@ export const BuiltInIcons = {
|
|
|
103
103
|
// mingcute:tag-2-line
|
|
104
104
|
'tag-2':
|
|
105
105
|
'<g fill="none"><path d="m12.593 23.258l-.011.002l-.071.035l-.02.004l-.014-.004l-.071-.035q-.016-.005-.024.005l-.004.01l-.017.428l.005.02l.01.013l.104.074l.015.004l.012-.004l.104-.074l.012-.016l.004-.017l-.017-.427q-.004-.016-.017-.018m.265-.113l-.013.002l-.185.093l-.01.01l-.003.011l.018.43l.005.012l.008.007l.201.093q.019.005.029-.008l.004-.014l-.034-.614q-.005-.018-.02-.022m-.715.002a.02.02 0 0 0-.027.006l-.006.014l-.034.614q.001.018.017.024l.015-.002l.201-.093l.01-.008l.004-.011l.017-.43l-.003-.012l-.01-.01z"/><path fill="currentColor" d="M10.238 4.827a3 3 0 0 1 2.122.878l6.485 6.486a3 3 0 0 1 0 4.242l-4.243 4.243a3 3 0 0 1-4.242 0l-6.486-6.485a3 3 0 0 1-.878-2.122V7.327a2.5 2.5 0 0 1 2.5-2.5zm0 2H5.496a.5.5 0 0 0-.5.5v4.742a1 1 0 0 0 .292.707l6.486 6.486a1 1 0 0 0 1.414 0l4.243-4.243a1 1 0 0 0 0-1.414L10.945 7.12a1 1 0 0 0-.707-.293M7.531 9.362a1.5 1.5 0 1 1 2.121 2.122a1.5 1.5 0 0 1-2.121-2.122M11.652 2a3 3 0 0 1 2.122.878l7.192 7.193a1 1 0 0 1-1.414 1.414L12.36 4.29a1 1 0 0 0-.708-.29H7a1 1 0 0 1 0-2z"/></g>',
|
|
106
|
+
// mingcute:list-check-line
|
|
107
|
+
list: '<g fill="none"><path d="m12.593 23.258l-.011.002l-.071.035l-.02.004l-.014-.004l-.071-.035q-.016-.005-.024.005l-.004.01l-.017.428l.005.02l.01.013l.104.074l.015.004l.012-.004l.104-.074l.012-.016l.004-.017l-.017-.427q-.004-.016-.017-.018m.265-.113l-.013.002l-.185.093l-.01.01l-.003.011l.018.43l.005.012l.008.007l.201.093q.019.005.029-.008l.004-.014l-.034-.614q-.005-.018-.02-.022m-.715.002a.02.02 0 0 0-.027.006l-.006.014l-.034.614q.001.018.017.024l.015-.002l.201-.093l.01-.008l.004-.011l.017-.43l-.003-.012l-.01-.01z"/><path fill="currentColor" d="M4.5 17.5a1.5 1.5 0 1 1 0 3a1.5 1.5 0 0 1 0-3M20 18a1 1 0 1 1 0 2H9a1 1 0 1 1 0-2zM4.5 10.5a1.5 1.5 0 1 1 0 3a1.5 1.5 0 0 1 0-3M20 11a1 1 0 0 1 .117 1.993L20 13H9a1 1 0 0 1-.117-1.993L9 11zM4.5 3.5a1.5 1.5 0 1 1 0 3a1.5 1.5 0 0 1 0-3M20 4a1 1 0 0 1 .117 1.993L20 6H9a1 1 0 0 1-.117-1.993L9 4z"/></g>',
|
|
106
108
|
|
|
107
109
|
// === Project ===
|
|
108
110
|
'github-circle':
|
package/package.json
CHANGED
package/bunfig.toml
DELETED