erudit 4.0.0-dev.1 → 4.0.0-dev.2
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/app/app.vue +1 -2
- package/app/components/FancyBold.vue +0 -1
- package/app/components/FancyCard.vue +1 -2
- package/app/components/ads/AdsBannerAside.vue +1 -2
- package/app/components/ads/AdsReplacer.vue +2 -2
- package/app/components/aside/AsideListItem.vue +1 -1
- package/app/components/aside/AsideSwitch.vue +18 -8
- package/app/components/aside/major/PaneSwitcher.vue +1 -1
- package/app/components/aside/minor/AsideMinorPlainHeader.vue +2 -3
- package/app/components/aside/minor/content/AsideMinorContentTopic.vue +1 -4
- package/app/components/aside/minor/content/ButtonPaneContributions.vue +2 -4
- package/app/components/aside/minor/content/ButtonPaneImprove.vue +2 -3
- package/app/components/aside/minor/content/Contribution.vue +1 -1
- package/app/components/aside/minor/content/TocItem.vue +35 -21
- package/app/components/aside/minor/news/AsideMinorNews.vue +1 -2
- package/app/components/aside/minor/news/NewsItem.vue +2 -2
- package/app/components/aside/minor/news/elements/Ref.vue +1 -1
- package/app/components/main/MainContentChild.vue +2 -3
- package/app/components/main/MainDescription.vue +1 -1
- package/app/components/main/MainQuickLink.vue +20 -5
- package/app/components/main/MainQuickLinks.vue +1 -3
- package/app/components/main/MainQuote.vue +3 -6
- package/app/components/main/MainSection.vue +6 -21
- package/app/components/main/MainTitle.vue +1 -2
- package/app/components/main/MainTopicPartSwitch.vue +1 -1
- package/app/components/main/connections/Deps.vue +1 -1
- package/app/components/main/connections/Externals.vue +92 -34
- package/app/components/main/connections/MainConnections.vue +61 -8
- package/app/components/main/connections/MainConnectionsButton.vue +3 -2
- package/app/components/main/connections/ScrollPane.vue +2 -3
- package/app/components/main/contentStats/Item.vue +1 -2
- package/app/components/main/contentStats/MainContentStats.vue +6 -3
- package/app/components/preview/Preview.vue +1 -2
- package/app/components/preview/PreviewScreen.vue +1 -2
- package/app/components/site/SiteAside.vue +2 -4
- package/app/components/site/SiteMain.vue +1 -4
- package/app/components/tree/TreeItem.vue +1 -1
- package/app/composables/og.ts +19 -2
- package/app/pages/contributor/[contributorId].vue +1 -2
- package/app/pages/index.vue +1 -4
- package/app/styles/main.css +0 -1
- package/package.json +4 -4
- package/server/erudit/cameos/build.ts +77 -27
- package/server/erudit/content/global/build.ts +27 -1
- package/server/erudit/content/nav/build.ts +36 -4
- package/server/erudit/content/repository/elementSnippets.ts +51 -11
- package/server/erudit/content/repository/externals.ts +38 -9
- package/server/erudit/content/resolve/index.ts +172 -21
- package/server/erudit/content/resolve/topic.ts +93 -32
- package/server/erudit/content/resolve/utils/insertContentResolved.ts +48 -9
- package/server/erudit/content/search.ts +31 -3
- package/server/erudit/contributors/build.ts +106 -51
- package/server/erudit/db/repository/pushFile.ts +7 -4
- package/server/erudit/db/schema/content.ts +2 -2
- package/server/erudit/db/schema/contentSnippets.ts +3 -4
- package/server/erudit/language/list/en.ts +2 -0
- package/server/erudit/language/list/ru.ts +2 -0
- package/server/erudit/news/build.ts +85 -48
- package/server/erudit/sponsors/build.ts +77 -26
- package/shared/types/contentConnections.ts +2 -2
- package/shared/types/elementSnippet.ts +9 -3
- package/shared/types/language.ts +2 -0
package/app/app.vue
CHANGED
|
@@ -22,8 +22,7 @@ initAsideMajorPaneWatcher();
|
|
|
22
22
|
class="relative m-auto min-h-dvh max-w-(--w-max-content) overflow-clip
|
|
23
23
|
border-x
|
|
24
24
|
border-[light-dark(var(--color-neutral-300),var(--color-neutral-800))]
|
|
25
|
-
shadow-[0_0_3px_0px_light-dark(rgba(0,0,0,0.05),rgba(0,0,0,0.18))]
|
|
26
|
-
transition-[border]"
|
|
25
|
+
shadow-[0_0_3px_0px_light-dark(rgba(0,0,0,0.05),rgba(0,0,0,0.18))]"
|
|
27
26
|
>
|
|
28
27
|
<SiteMain>
|
|
29
28
|
<NuxtPage></NuxtPage>
|
|
@@ -9,7 +9,6 @@ const { color = 'var(--color-brand)' } = defineProps<{
|
|
|
9
9
|
<span
|
|
10
10
|
:style="{ '--titleColor': color }"
|
|
11
11
|
class="text-text-deep leading-tight font-extrabold
|
|
12
|
-
transition-[color,text-shadow]
|
|
13
12
|
text-shadow-[2px_2px_color-mix(in_srgb,var(--titleColor),transparent_65%)]"
|
|
14
13
|
>
|
|
15
14
|
{{ formatText(text) }}
|
|
@@ -31,8 +31,7 @@ defineProps<{
|
|
|
31
31
|
`p-small micro:p-normal not-last:mb-normal gap-small text-main-sm
|
|
32
32
|
relative flex w-full break-inside-avoid-column flex-col items-center
|
|
33
33
|
rounded border border-(--colorBorder) bg-linear-to-tr
|
|
34
|
-
from-(--colorBg)/30 to-(--colorBg)
|
|
35
|
-
transition-[background,border,box-shadow]`,
|
|
34
|
+
from-(--colorBg)/30 to-(--colorBg) transition-shadow`,
|
|
36
35
|
link && 'hocus:ring-(--colorBorder) ring-2 ring-transparent',
|
|
37
36
|
]"
|
|
38
37
|
>
|
|
@@ -33,8 +33,7 @@ onMounted(() => {
|
|
|
33
33
|
<template>
|
|
34
34
|
<section
|
|
35
35
|
v-if="adsData"
|
|
36
|
-
class="p-small border-border border-t
|
|
37
|
-
[@media(max-height:500px)]:hidden"
|
|
36
|
+
class="p-small border-border border-t [@media(max-height:500px)]:hidden"
|
|
38
37
|
>
|
|
39
38
|
<div
|
|
40
39
|
class="relative max-h-[300px] overflow-hidden
|
|
@@ -11,8 +11,8 @@ const phrase = await usePhrases('ads_replacer');
|
|
|
11
11
|
h-full w-full flex-row items-center justify-center
|
|
12
12
|
bg-neutral-200
|
|
13
13
|
shadow-[inset_0px_0px_5px_0px_light-dark(rgba(0,0,0,0.12),rgba(255,255,255,0.08))]
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
@max-[550px]:flex-col @max-[550px]:text-center
|
|
15
|
+
dark:bg-neutral-800"
|
|
16
16
|
>
|
|
17
17
|
<MyIcon
|
|
18
18
|
name="handshake"
|
|
@@ -19,7 +19,7 @@ const isExternalLink = computed(() => {
|
|
|
19
19
|
<EruditLink
|
|
20
20
|
:class="[
|
|
21
21
|
`border-border block min-h-(--h-min-aside-item) border-b
|
|
22
|
-
bg-transparent text-sm transition-[background,color
|
|
22
|
+
bg-transparent text-sm transition-[background,color]`,
|
|
23
23
|
hoverable && 'hocus:bg-bg-accent cursor-pointer',
|
|
24
24
|
active
|
|
25
25
|
? 'text-brand'
|
|
@@ -41,17 +41,27 @@ if (import.meta.client) {
|
|
|
41
41
|
`micro:[--_switchSize:110px] [--_switchGap:var(--spacing-main)]
|
|
42
42
|
[--_switchSize:80px]`,
|
|
43
43
|
/* */
|
|
44
|
-
`
|
|
44
|
+
`fixed bottom-0 flex size-(--_switchSize) items-center
|
|
45
45
|
justify-center pb-(--_switchGap) pl-(--_switchGap)
|
|
46
46
|
transition-[left,right,opacity]`,
|
|
47
47
|
{
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
'
|
|
54
|
-
|
|
48
|
+
//
|
|
49
|
+
// Major Global
|
|
50
|
+
//
|
|
51
|
+
'aside1:opacity-0': isMajor,
|
|
52
|
+
// Major Can Show
|
|
53
|
+
'left-0 opacity-100': isMajor && canShowSwitches,
|
|
54
|
+
// Major Cannot Show
|
|
55
|
+
'-left-(--_switchSize) opacity-0': isMajor && !canShowSwitches,
|
|
56
|
+
|
|
57
|
+
//
|
|
58
|
+
// Minor Global
|
|
59
|
+
//
|
|
60
|
+
'aside2:opacity-0 -scale-x-100': isMinor,
|
|
61
|
+
// Minor Can Show
|
|
62
|
+
'right-0 opacity-100': isMinor && canShowSwitches,
|
|
63
|
+
// Minor Cannot Show
|
|
64
|
+
'-right-(--_switchSize) opacity-0': isMinor && !canShowSwitches,
|
|
55
65
|
},
|
|
56
66
|
]"
|
|
57
67
|
>
|
|
@@ -22,7 +22,7 @@ const phrase = await usePhrases(
|
|
|
22
22
|
</script>
|
|
23
23
|
|
|
24
24
|
<template>
|
|
25
|
-
<section class="border-border z-1 border-b
|
|
25
|
+
<section class="border-border z-1 border-b">
|
|
26
26
|
<div
|
|
27
27
|
style="--_button-size: 56px; --_underline-p: 6px"
|
|
28
28
|
class="relative mx-auto flex w-max"
|
|
@@ -6,15 +6,14 @@ defineProps<{ icon: MyIconName; title: string; count?: number }>();
|
|
|
6
6
|
<template>
|
|
7
7
|
<section
|
|
8
8
|
class="gap-normal p-normal border-border bg-bg-aside flex items-center
|
|
9
|
-
justify-center border-b
|
|
9
|
+
justify-center border-b"
|
|
10
10
|
>
|
|
11
11
|
<MyIcon :name="icon" class="text-text-muted text-[1.3em]" />
|
|
12
12
|
<span class="font-semibold">{{ formatText(title) }}</span>
|
|
13
13
|
<span
|
|
14
14
|
v-if="count"
|
|
15
15
|
class="text-invert rounded-full bg-neutral-600 px-[8px] py-[2.5px]
|
|
16
|
-
text-xs font-semibold
|
|
17
|
-
dark:bg-neutral-300"
|
|
16
|
+
text-xs font-semibold dark:bg-neutral-300"
|
|
18
17
|
>{{ count }}</span
|
|
19
18
|
>
|
|
20
19
|
</section>
|
|
@@ -40,10 +40,7 @@ const contentRelativePath = computed(() => {
|
|
|
40
40
|
<template>
|
|
41
41
|
<AsideMinorPane>
|
|
42
42
|
<div class="flex h-full w-full flex-col">
|
|
43
|
-
<div
|
|
44
|
-
class="border-border gap-normal flex justify-center border-b
|
|
45
|
-
transition-[border]"
|
|
46
|
-
>
|
|
43
|
+
<div class="border-border gap-normal flex justify-center border-b">
|
|
47
44
|
<TopicPartButton
|
|
48
45
|
v-for="part of topicParts"
|
|
49
46
|
:part
|
|
@@ -37,8 +37,7 @@ const phrase = await usePhrases('contribution');
|
|
|
37
37
|
class="absolute top-0 left-0 z-10 h-full w-full"
|
|
38
38
|
>
|
|
39
39
|
<div
|
|
40
|
-
class="bg-bg-aside flex h-full w-full flex-col justify-end
|
|
41
|
-
transition-[background]"
|
|
40
|
+
class="bg-bg-aside flex h-full w-full flex-col justify-end"
|
|
42
41
|
>
|
|
43
42
|
<div
|
|
44
43
|
class="nice-scrollbars *:border-border overflow-auto
|
|
@@ -53,7 +52,7 @@ const phrase = await usePhrases('contribution');
|
|
|
53
52
|
</div>
|
|
54
53
|
<div
|
|
55
54
|
class="border-border flex items-center border-t py-1
|
|
56
|
-
pr-0
|
|
55
|
+
pr-0"
|
|
57
56
|
>
|
|
58
57
|
<div
|
|
59
58
|
class="pl-normal gap-small flex flex-1 items-center
|
|
@@ -63,7 +62,6 @@ const phrase = await usePhrases('contribution');
|
|
|
63
62
|
<span
|
|
64
63
|
class="text-invert rounded-full bg-neutral-600
|
|
65
64
|
px-[8px] py-[2.5px] text-xs font-semibold
|
|
66
|
-
transition-[color,background]
|
|
67
65
|
dark:bg-neutral-300"
|
|
68
66
|
>{{ contributions.length }}</span
|
|
69
67
|
>
|
|
@@ -55,8 +55,7 @@ const phrase = await usePhrases(
|
|
|
55
55
|
class="absolute top-0 left-0 z-10 h-full w-full"
|
|
56
56
|
>
|
|
57
57
|
<div
|
|
58
|
-
class="bg-bg-aside flex h-full w-full flex-col justify-end
|
|
59
|
-
transition-[background]"
|
|
58
|
+
class="bg-bg-aside flex h-full w-full flex-col justify-end"
|
|
60
59
|
>
|
|
61
60
|
<div
|
|
62
61
|
class="nice-scrollbars overflow-auto *:border-t
|
|
@@ -83,7 +82,7 @@ const phrase = await usePhrases(
|
|
|
83
82
|
</div>
|
|
84
83
|
<div
|
|
85
84
|
class="border-border flex items-center border-t py-1
|
|
86
|
-
pr-0
|
|
85
|
+
pr-0"
|
|
87
86
|
>
|
|
88
87
|
<div class="pl-normal flex-1 text-sm font-semibold">
|
|
89
88
|
{{ formatText(phrase.improve_material) }}
|
|
@@ -8,7 +8,7 @@ defineProps<{ contribution: ContentContribution }>();
|
|
|
8
8
|
<EruditLink
|
|
9
9
|
:to="PAGES.contributor(contribution.contributorId)"
|
|
10
10
|
class="p-normal hocus:bg-bg-accent block bg-transparent
|
|
11
|
-
transition-[
|
|
11
|
+
transition-[background]"
|
|
12
12
|
>
|
|
13
13
|
<div class="gap-normal flex items-center">
|
|
14
14
|
<SmartMedia
|
|
@@ -51,27 +51,41 @@ onMounted(() => {
|
|
|
51
51
|
</script>
|
|
52
52
|
|
|
53
53
|
<template>
|
|
54
|
-
<
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
<div v-if="item.type === 'heading'" class="relative overflow-hidden">
|
|
62
|
-
<div
|
|
63
|
-
:style="{ '--level': level ? +level : 0 }"
|
|
64
|
-
:class="[
|
|
65
|
-
`absolute top-0
|
|
66
|
-
left-[calc(var(--spacing-normal)*(var(--level)+1)+8px)] h-full
|
|
67
|
-
border-l opacity-40 transition-[border]`,
|
|
68
|
-
[active ? 'border-brand' : 'border-text-dimmed'],
|
|
69
|
-
]"
|
|
70
|
-
></div>
|
|
71
|
-
<TocItem
|
|
72
|
-
v-for="child of item.children"
|
|
73
|
-
:item="child"
|
|
74
|
-
:level="item.level"
|
|
54
|
+
<div :class="[$style.item, active && $style.activeItem]">
|
|
55
|
+
<TreeItem
|
|
56
|
+
:level
|
|
57
|
+
:icon="elementIcon"
|
|
58
|
+
:main="formatText(item.title)"
|
|
59
|
+
:state="active ? 'active' : undefined"
|
|
60
|
+
:to="'#' + item.elementId"
|
|
75
61
|
/>
|
|
62
|
+
<div
|
|
63
|
+
v-if="item.type === 'heading'"
|
|
64
|
+
class="group/children relative overflow-hidden"
|
|
65
|
+
>
|
|
66
|
+
<div
|
|
67
|
+
:style="{ '--level': level ? +level : 0 }"
|
|
68
|
+
:class="[
|
|
69
|
+
`border-text-dimmed absolute top-0
|
|
70
|
+
left-[calc(var(--spacing-normal)*(var(--level)+1)+6.5px)]
|
|
71
|
+
h-full border-l opacity-40 transition-[border]`,
|
|
72
|
+
$style.leftLine,
|
|
73
|
+
]"
|
|
74
|
+
></div>
|
|
75
|
+
<TocItem
|
|
76
|
+
v-for="child of item.children"
|
|
77
|
+
:item="child"
|
|
78
|
+
:level="item.level"
|
|
79
|
+
/>
|
|
80
|
+
</div>
|
|
76
81
|
</div>
|
|
77
82
|
</template>
|
|
83
|
+
|
|
84
|
+
<style module>
|
|
85
|
+
.item.activeItem,
|
|
86
|
+
.item:has(.activeItem) {
|
|
87
|
+
.leftLine {
|
|
88
|
+
border-color: var(--color-brand);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
</style>
|
|
@@ -120,8 +120,7 @@ const phrase = await usePhrases('news', 'no_news', 'show_more');
|
|
|
120
120
|
class="my-big px-normal py-small bg-bg-accent
|
|
121
121
|
hocus:border-text-disabled gap-normal m-auto flex
|
|
122
122
|
w-auto cursor-pointer items-center rounded border-2
|
|
123
|
-
border-transparent text-sm
|
|
124
|
-
transition-[border,background,color]"
|
|
123
|
+
border-transparent text-sm transition-[border]"
|
|
125
124
|
>
|
|
126
125
|
<MyRuntimeIcon v-if="newsLoading" :svg="loadingSvg" />
|
|
127
126
|
<span>{{ phrase.show_more }}</span>
|
|
@@ -37,9 +37,9 @@ await walkElements(item.content.proseElement, async (element) => {
|
|
|
37
37
|
</script>
|
|
38
38
|
|
|
39
39
|
<template>
|
|
40
|
-
<div class="p-normal border-border border-b text-sm
|
|
40
|
+
<div class="p-normal border-border border-b text-sm">
|
|
41
41
|
<div
|
|
42
|
-
class="mb-small gap-small flex items-center
|
|
42
|
+
class="mb-small gap-small flex items-center"
|
|
43
43
|
:class="
|
|
44
44
|
isNew
|
|
45
45
|
? 'font-semibold text-orange-700 dark:text-orange-300'
|
|
@@ -51,7 +51,7 @@ function linkClick() {
|
|
|
51
51
|
-mt-(--tGap) -mb-(--bGap) rounded-sm bg-transparent px-(--xGap)
|
|
52
52
|
pt-(--tGap) pb-(--bGap) text-(--linkColor) underline
|
|
53
53
|
decoration-[color-mix(in_srgb,var(--linkColor)30%,transparent)]
|
|
54
|
-
decoration-2 underline-offset-2 transition-[
|
|
54
|
+
decoration-2 underline-offset-2 transition-[background]"
|
|
55
55
|
>
|
|
56
56
|
{{ formatText(element.data.label) }}
|
|
57
57
|
</EruditLink>
|
|
@@ -8,7 +8,7 @@ const hasExtra = child.stats || child.quickLinks;
|
|
|
8
8
|
<div
|
|
9
9
|
class="border-border hocus:ring-brand/25 hocus:border-brand group
|
|
10
10
|
dark:bg-bg-aside rounded border bg-neutral-100 ring-2
|
|
11
|
-
ring-transparent transition-[border,box-shadow
|
|
11
|
+
ring-transparent transition-[border,box-shadow]"
|
|
12
12
|
>
|
|
13
13
|
<EruditLink :to="child.link" class="p-normal gap-small flex flex-col">
|
|
14
14
|
<div class="gap-small micro:gap-normal flex items-center">
|
|
@@ -31,8 +31,7 @@ const hasExtra = child.stats || child.quickLinks;
|
|
|
31
31
|
</EruditLink>
|
|
32
32
|
<div
|
|
33
33
|
v-if="hasExtra"
|
|
34
|
-
class="border-t-border p-normal gap-normal flex flex-col border-t
|
|
35
|
-
transition-[border]"
|
|
34
|
+
class="border-t-border p-normal gap-normal flex flex-col border-t"
|
|
36
35
|
>
|
|
37
36
|
<div v-if="child.quickLinks" class="relative top-[1px]">
|
|
38
37
|
<MainQuickLinks
|
|
@@ -40,6 +40,22 @@ onUnmounted(() => {
|
|
|
40
40
|
});
|
|
41
41
|
|
|
42
42
|
const elementIcon = await getElementIcon(quickLink.schemaName);
|
|
43
|
+
|
|
44
|
+
const title = computed(() => {
|
|
45
|
+
if (quickLink.quick?.title) {
|
|
46
|
+
return quickLink.quick.title;
|
|
47
|
+
} else {
|
|
48
|
+
return quickLink.title;
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
const description = computed(() => {
|
|
53
|
+
if (quickLink.quick?.description) {
|
|
54
|
+
return quickLink.quick.description;
|
|
55
|
+
} else {
|
|
56
|
+
return quickLink.description;
|
|
57
|
+
}
|
|
58
|
+
});
|
|
43
59
|
</script>
|
|
44
60
|
|
|
45
61
|
<template>
|
|
@@ -50,15 +66,14 @@ const elementIcon = await getElementIcon(quickLink.schemaName);
|
|
|
50
66
|
class="gap-small border-border px-small text-text-muted text-main-sm
|
|
51
67
|
hocus:text-brand hocus:border-brand hocus:ring-brand/25 flex
|
|
52
68
|
items-center rounded border bg-(--quickBg) py-1 ring-2
|
|
53
|
-
ring-transparent
|
|
54
|
-
transition-[background,color,border,box-shadow]"
|
|
69
|
+
ring-transparent transition-[color,border,box-shadow]"
|
|
55
70
|
>
|
|
56
71
|
<MaybeMyIcon :name="elementIcon" class="-mr-0.5 text-[1.2em]" />
|
|
57
|
-
<span>{{ formatText(
|
|
72
|
+
<span>{{ formatText(title) }}</span>
|
|
58
73
|
</EruditLink>
|
|
59
74
|
<TransitionFade>
|
|
60
75
|
<div
|
|
61
|
-
v-if="
|
|
76
|
+
v-if="description && popupVisible"
|
|
62
77
|
:style="floatingStyles"
|
|
63
78
|
ref="popup"
|
|
64
79
|
class="z-10 max-w-[300px] p-2"
|
|
@@ -68,7 +83,7 @@ const elementIcon = await getElementIcon(quickLink.schemaName);
|
|
|
68
83
|
text-white shadow-lg/30 dark:bg-neutral-400
|
|
69
84
|
dark:text-black dark:shadow-neutral-500"
|
|
70
85
|
>
|
|
71
|
-
{{ formatText(
|
|
86
|
+
{{ formatText(description) }}
|
|
72
87
|
</div>
|
|
73
88
|
</div>
|
|
74
89
|
</TransitionFade>
|
|
@@ -9,9 +9,7 @@ const quickLinks = (() => {
|
|
|
9
9
|
return;
|
|
10
10
|
}
|
|
11
11
|
|
|
12
|
-
const filtered = elementSnippets.filter(
|
|
13
|
-
(snippet) => snippet.quick === true,
|
|
14
|
-
);
|
|
12
|
+
const filtered = elementSnippets.filter((snippet) => !!snippet.quick);
|
|
15
13
|
|
|
16
14
|
return filtered.length > 0 ? filtered : undefined;
|
|
17
15
|
})();
|
|
@@ -74,28 +74,25 @@ const phrase = await usePhrases('add_quote', 'next_quote');
|
|
|
74
74
|
:url="avatarUrl"
|
|
75
75
|
class="border-bg-main micro:size-[60px] size-[40px]
|
|
76
76
|
rounded-full border-2
|
|
77
|
-
[box-shadow:0_0_16px_0_var(--color)]
|
|
77
|
+
[box-shadow:0_0_16px_0_var(--color)]
|
|
78
78
|
[--mediaColor:var(--color)]"
|
|
79
79
|
/>
|
|
80
80
|
</EruditLink>
|
|
81
81
|
</div>
|
|
82
82
|
<div
|
|
83
83
|
class="p-small micro:p-normal relative flex-1 rounded
|
|
84
|
-
rounded-tl-none border-2 border-(--colorBorder) bg-(--colorBg)
|
|
85
|
-
transition-[background,border]"
|
|
84
|
+
rounded-tl-none border-2 border-(--colorBorder) bg-(--colorBg)"
|
|
86
85
|
>
|
|
87
86
|
<div
|
|
88
87
|
class="micro:[--arrowSize:22px] absolute -top-[2px]
|
|
89
88
|
-left-(--arrowSize) h-(--arrowSize) w-(--arrowSize)
|
|
90
|
-
bg-(--colorBorder)
|
|
91
|
-
[--arrowSize:14px]
|
|
89
|
+
bg-(--colorBorder) [--arrowSize:14px]
|
|
92
90
|
[--arrowSizeSmall:calc(var(--arrowSize)-2px)]
|
|
93
91
|
[clip-path:polygon(110%_0,110%_110%,0_0)]"
|
|
94
92
|
>
|
|
95
93
|
<div
|
|
96
94
|
class="absolute top-[2px] -right-[3px] h-(--arrowSizeSmall)
|
|
97
95
|
w-(--arrowSizeSmall) bg-(--colorBg)
|
|
98
|
-
transition-[background]
|
|
99
96
|
[clip-path:polygon(100%_0,100%_100%,0_0)]"
|
|
100
97
|
></div>
|
|
101
98
|
</div>
|
|
@@ -1,27 +1,12 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<section :class="[$style.section, 'bg-bg-main
|
|
2
|
+
<section :class="[$style.section, 'bg-bg-main']">
|
|
3
3
|
<!-- Section Header -->
|
|
4
|
-
<div
|
|
5
|
-
:class="[
|
|
6
|
-
$style.header,
|
|
7
|
-
'border-border relative border-b-2 transition-[border]',
|
|
8
|
-
]"
|
|
9
|
-
>
|
|
4
|
+
<div :class="[$style.header, 'border-border relative border-b-2']">
|
|
10
5
|
<!-- Header Shade -->
|
|
11
|
-
<div
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
to-transparent opacity-100 transition-opacity
|
|
16
|
-
dark:opacity-0"
|
|
17
|
-
></div>
|
|
18
|
-
<!-- Dark mode gradient -->
|
|
19
|
-
<div
|
|
20
|
-
class="absolute inset-0 bg-linear-to-t from-[#1b1b1b]
|
|
21
|
-
to-transparent opacity-0 transition-opacity
|
|
22
|
-
dark:opacity-100"
|
|
23
|
-
></div>
|
|
24
|
-
</div>
|
|
6
|
+
<div
|
|
7
|
+
class="absolute bottom-0 h-[70px] w-full bg-linear-to-t
|
|
8
|
+
from-[#f7f7f7] to-transparent dark:from-[#1b1b1b]"
|
|
9
|
+
></div>
|
|
25
10
|
|
|
26
11
|
<!-- Header Content -->
|
|
27
12
|
<div :class="[$style.headerContent, 'relative z-1']">
|
|
@@ -22,8 +22,7 @@ const { color = 'var(--color-brand)' } = defineProps<{
|
|
|
22
22
|
<MaybeMyIcon
|
|
23
23
|
:name="icon"
|
|
24
24
|
class="max-micro:text-white micro:text-[38px] text-[30px]
|
|
25
|
-
text-[color-mix(in_srgb,var(--titleColor),var(--color-text)_70%)]
|
|
26
|
-
transition-[color]"
|
|
25
|
+
text-[color-mix(in_srgb,var(--titleColor),var(--color-text)_70%)]"
|
|
27
26
|
/>
|
|
28
27
|
</div>
|
|
29
28
|
<h1 class="text-size-h1 max-micro:text-center">
|
|
@@ -45,7 +45,7 @@ const data: Record<TopicPart, TopicPartSwitchData> = {
|
|
|
45
45
|
`micro:[--switchHeight:50px] micro:gap-small px-small
|
|
46
46
|
micro:px-normal border-border relative -bottom-[2px] flex
|
|
47
47
|
h-(--switchHeight) items-center gap-1 rounded rounded-b-none
|
|
48
|
-
border-2 transition-[
|
|
48
|
+
border-2 transition-[color]`,
|
|
49
49
|
partData.state === 'missing' &&
|
|
50
50
|
'text-text-disabled/75 border-b-border cursor-not-allowed',
|
|
51
51
|
partData.state === 'active' &&
|
|
@@ -1,44 +1,102 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
-
import type {
|
|
2
|
+
import type { ContentExternals } from '@erudit-js/core/content/externals';
|
|
3
3
|
import ScrollPane from './ScrollPane.vue';
|
|
4
4
|
|
|
5
|
-
defineProps<{ externals:
|
|
5
|
+
defineProps<{ externals: ContentExternals }>();
|
|
6
|
+
|
|
7
|
+
const phrase = await usePhrases('externals_own', 'externals_from');
|
|
6
8
|
</script>
|
|
7
9
|
|
|
8
10
|
<template>
|
|
9
|
-
<ScrollPane>
|
|
10
|
-
<div v-for="
|
|
11
|
-
<
|
|
12
|
-
:
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
11
|
+
<ScrollPane class="max-h-[800px]">
|
|
12
|
+
<div v-for="group of externals">
|
|
13
|
+
<div
|
|
14
|
+
:class="[
|
|
15
|
+
`border-border gap-small pl-small py-small bg-bg-main
|
|
16
|
+
relative sticky top-0 z-10 flex w-full items-center border-b
|
|
17
|
+
border-dashed`,
|
|
18
|
+
group.type === 'own'
|
|
19
|
+
? 'font-semibold text-amber-600 dark:text-amber-400'
|
|
20
|
+
: 'text-text-muted',
|
|
21
|
+
]"
|
|
22
|
+
>
|
|
23
|
+
<div
|
|
24
|
+
:class="[
|
|
25
|
+
`absolute top-0 left-0 h-full w-full bg-linear-to-t
|
|
26
|
+
to-transparent`,
|
|
27
|
+
group.type === 'own'
|
|
28
|
+
? 'from-amber-400/10'
|
|
29
|
+
: 'from-bg-aside/50',
|
|
30
|
+
]"
|
|
31
|
+
></div>
|
|
32
|
+
<MyIcon
|
|
33
|
+
:name="
|
|
34
|
+
group.type === 'own'
|
|
35
|
+
? 'arrow/left'
|
|
36
|
+
: 'arrow/up-to-right'
|
|
37
|
+
"
|
|
38
|
+
:class="[
|
|
39
|
+
'relative',
|
|
40
|
+
group.type === 'own' && '-scale-x-100',
|
|
41
|
+
]"
|
|
42
|
+
/>
|
|
43
|
+
<span>
|
|
44
|
+
{{
|
|
45
|
+
group.type === 'own'
|
|
46
|
+
? phrase.externals_own
|
|
47
|
+
: phrase.externals_from
|
|
48
|
+
}}
|
|
49
|
+
</span>
|
|
50
|
+
<span
|
|
51
|
+
v-if="group.type === 'parent'"
|
|
52
|
+
class="relative font-semibold"
|
|
53
|
+
>
|
|
54
|
+
{{ formatText(`"${group.title}"`) }}
|
|
55
|
+
</span>
|
|
56
|
+
</div>
|
|
57
|
+
<div>
|
|
58
|
+
<div
|
|
59
|
+
v-for="external of group.items"
|
|
60
|
+
class="gap-small py-normal flex"
|
|
61
|
+
>
|
|
62
|
+
<MyIcon
|
|
63
|
+
:name="external.type === 'physical' ? 'book' : 'globe'"
|
|
64
|
+
class="relative top-1 shrink-0"
|
|
65
|
+
/>
|
|
66
|
+
<div class="flex flex-col gap-0.5">
|
|
67
|
+
<div>
|
|
68
|
+
<template v-if="external.link">
|
|
69
|
+
<EruditLink
|
|
70
|
+
external
|
|
71
|
+
target="_blank"
|
|
72
|
+
:to="external.link"
|
|
73
|
+
:class="[
|
|
74
|
+
external.link && 'text-hover-underline',
|
|
75
|
+
]"
|
|
76
|
+
>
|
|
77
|
+
{{ formatText(external.title) }}
|
|
78
|
+
<MyIcon
|
|
79
|
+
v-if="external.link"
|
|
80
|
+
name="arrow/outward"
|
|
81
|
+
class="text-text-disabled text-main-sm
|
|
82
|
+
relative -top-1 inline"
|
|
83
|
+
/>
|
|
84
|
+
</EruditLink>
|
|
85
|
+
</template>
|
|
86
|
+
<template v-else>
|
|
87
|
+
<span>{{ formatText(external.title) }}</span>
|
|
88
|
+
</template>
|
|
89
|
+
</div>
|
|
90
|
+
<div
|
|
91
|
+
v-if="external.info"
|
|
92
|
+
class="text-text-muted text-main-sm"
|
|
23
93
|
>
|
|
24
|
-
{{ formatText(external.
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
/>
|
|
31
|
-
</EruditLink>
|
|
32
|
-
</template>
|
|
33
|
-
<template v-else>
|
|
34
|
-
<span>{{ formatText(external.title) }}</span>
|
|
35
|
-
</template>
|
|
36
|
-
</div>
|
|
37
|
-
<div v-if="external.info" class="text-text-muted text-main-sm">
|
|
38
|
-
{{ formatText(external.info) }}
|
|
39
|
-
</div>
|
|
40
|
-
<div class="text-text-muted text-main-sm italic">
|
|
41
|
-
{{ formatText(external.reason) }}
|
|
94
|
+
{{ formatText(external.info) }}
|
|
95
|
+
</div>
|
|
96
|
+
<div class="text-text-muted text-main-sm italic">
|
|
97
|
+
{{ formatText(external.reason) }}
|
|
98
|
+
</div>
|
|
99
|
+
</div>
|
|
42
100
|
</div>
|
|
43
101
|
</div>
|
|
44
102
|
</div>
|