@erudit-js/prose 4.0.0-dev.4 → 4.0.0-dev.5

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.
Files changed (83) hide show
  1. package/dist/app/default/Inliners.vue +11 -11
  2. package/dist/app/default/Mix.vue +11 -11
  3. package/dist/app/default/Text.vue +25 -25
  4. package/dist/app/shared/Prose.vue +40 -40
  5. package/dist/app/shared/Render.vue +51 -51
  6. package/dist/app/shared/block/AsideMenu.vue +44 -44
  7. package/dist/app/shared/block/AsideMenuButton.vue +51 -53
  8. package/dist/app/shared/block/AsideMenuCopyLink.vue +40 -40
  9. package/dist/app/shared/block/AsideMenuSeparator.vue +3 -3
  10. package/dist/app/shared/block/Block.vue +270 -275
  11. package/dist/app/shared/inliner/Inliner.vue +11 -11
  12. package/dist/app/shared/photoswipe/style.css +22 -26
  13. package/dist/elements/accent/Accent.vue +88 -92
  14. package/dist/elements/accent/AccentColumnSection.vue +61 -61
  15. package/dist/elements/accent/AccentRowSections.vue +64 -65
  16. package/dist/elements/callout/Callout.vue +81 -85
  17. package/dist/elements/callout/_global.d.ts +15 -15
  18. package/dist/elements/caption/Caption.vue +44 -47
  19. package/dist/elements/caption/_global.d.ts +26 -26
  20. package/dist/elements/details/Details.vue +49 -50
  21. package/dist/elements/details/_global.d.ts +27 -27
  22. package/dist/elements/diagram/Diagram.vue +360 -374
  23. package/dist/elements/diagram/_global.d.ts +19 -19
  24. package/dist/elements/diagram/core.d.ts +0 -4
  25. package/dist/elements/diagram/core.js +1 -7
  26. package/dist/elements/emphasis/Emphasis.vue +25 -25
  27. package/dist/elements/emphasis/_global.d.ts +18 -18
  28. package/dist/elements/flex/Flex.vue +36 -38
  29. package/dist/elements/flex/_global.d.ts +23 -23
  30. package/dist/elements/gallery/Gallery.vue +56 -56
  31. package/dist/elements/gallery/_global.d.ts +18 -18
  32. package/dist/elements/heading/Heading.vue +44 -44
  33. package/dist/elements/heading/_global.d.ts +42 -45
  34. package/dist/elements/heading/core.js +7 -14
  35. package/dist/elements/horizontalLine/HorizontalLine.vue +6 -6
  36. package/dist/elements/horizontalLine/_global.d.ts +17 -17
  37. package/dist/elements/image/Image.vue +15 -15
  38. package/dist/elements/image/ImageElement.vue +80 -80
  39. package/dist/elements/image/_global.d.ts +18 -18
  40. package/dist/elements/lineBreak/LineBreak.vue +3 -3
  41. package/dist/elements/lineBreak/_global.d.ts +18 -18
  42. package/dist/elements/link/BlockLink.vue +108 -110
  43. package/dist/elements/link/Link.vue +92 -96
  44. package/dist/elements/link/dependency/_global.d.ts +47 -47
  45. package/dist/elements/link/reference/_global.d.ts +49 -49
  46. package/dist/elements/list/List.vue +58 -65
  47. package/dist/elements/list/_global.d.ts +50 -50
  48. package/dist/elements/math/_global.d.ts +72 -72
  49. package/dist/elements/math/_global.ts +3 -3
  50. package/dist/elements/math/components/BlockMath.vue +30 -30
  51. package/dist/elements/math/components/InlinerMath.vue +65 -65
  52. package/dist/elements/math/components/Katex.vue +88 -89
  53. package/dist/elements/math/components/MathGroup.vue +41 -41
  54. package/dist/elements/math/katex.js +17 -6
  55. package/dist/elements/paragraph/Paragraph.vue +25 -27
  56. package/dist/elements/paragraph/_global.d.ts +27 -27
  57. package/dist/elements/problem/_global.d.ts +112 -112
  58. package/dist/elements/problem/components/Problem.vue +22 -22
  59. package/dist/elements/problem/components/ProblemButton.vue +20 -21
  60. package/dist/elements/problem/components/ProblemContainer.vue +8 -8
  61. package/dist/elements/problem/components/ProblemContent.vue +356 -371
  62. package/dist/elements/problem/components/ProblemExpander.vue +7 -7
  63. package/dist/elements/problem/components/ProblemExpanderSection.vue +57 -57
  64. package/dist/elements/problem/components/ProblemHeader.vue +100 -102
  65. package/dist/elements/problem/components/Problems.vue +83 -87
  66. package/dist/elements/problem/components/SubProblem.vue +14 -14
  67. package/dist/elements/problem/components/expanders/Check.vue +153 -150
  68. package/dist/elements/problem/components/expanders/Checks.vue +146 -83
  69. package/dist/elements/problem/components/expanders/DefaultPlusSections.vue +38 -38
  70. package/dist/elements/problem/components/expanders/Hint.vue +26 -26
  71. package/dist/elements/problem/core.d.ts +23 -23
  72. package/dist/elements/problem/problemContent.d.ts +134 -30
  73. package/dist/elements/problem/problemContent.js +157 -197
  74. package/dist/elements/problem/problemScript.d.ts +2 -2
  75. package/dist/elements/problem/problemScript.js +2 -2
  76. package/dist/elements/problem/rng.d.ts +1 -1
  77. package/dist/elements/problem/rng.js +1 -1
  78. package/dist/elements/table/Table.vue +100 -102
  79. package/dist/elements/table/_global.d.ts +36 -36
  80. package/dist/elements/video/Video.vue +110 -109
  81. package/dist/elements/video/_global.d.ts +18 -18
  82. package/package.json +42 -43
  83. package/types.d.ts +4 -4
@@ -1,92 +1,88 @@
1
- <script lang="ts" setup>
2
- import { shallowRef } from 'vue';
3
- import { type ProseElement } from '@jsprose/core';
4
-
5
- import {
6
- isAccentMainElement,
7
- type AccentMainSchema,
8
- type AccentSchema,
9
- type AccentSectionSchema,
10
- } from './core.js';
11
- import { accentSectionNamePhrase, type AccentAppOptions } from './app.js';
12
- import { useAppElement } from '../../app/composables/appElement.js';
13
- import { useElementPhrase } from '../../app/composables/language.js';
14
- import { useElementIcon } from '../../app/composables/elementIcon.js';
15
- import { useProseContext, type ElementPhrases } from '../../app/index.js';
16
- import { useFormatText } from '../../app/composables/formatText.js';
17
- import Block from '../../app/shared/block/Block.vue';
18
- import Render from '../../app/shared/Render.vue';
19
- import AccentColumnSection from './AccentColumnSection.vue';
20
- import AccentRowSections from './AccentRowSections.vue';
21
-
22
- const { element } = defineProps<{ element: ProseElement<AccentSchema> }>();
23
-
24
- const { EruditIcon } = useProseContext();
25
- const formatText = useFormatText();
26
- const appElement = useAppElement(element);
27
- const accentIcon = await useElementIcon(element);
28
- const phrase =
29
- await useElementPhrase<ElementPhrases<Record<string, string>>>(element);
30
-
31
- const mainSection = shallowRef<ProseElement<AccentMainSchema>>();
32
- const sections = shallowRef<ProseElement<AccentSectionSchema>[]>([]);
33
-
34
- for (const child of element.children) {
35
- if (isAccentMainElement(child)) {
36
- mainSection.value = child;
37
- } else {
38
- sections.value.push(child);
39
- }
40
- }
41
-
42
- const sectionTitles = sections.value.map((section) => {
43
- if (section.data.type === 'manual') {
44
- return formatText(section.data.title);
45
- }
46
-
47
- return formatText(phrase[accentSectionNamePhrase(section.data.name)]);
48
- });
49
-
50
- const accentOptions = (appElement as any)['accent'] as AccentAppOptions;
51
- </script>
52
-
53
- <template>
54
- <Block :element>
55
- <div
56
- :style="{
57
- '--accentText': accentOptions.colors.text,
58
- '--accentBackground': accentOptions.colors.background,
59
- '--accentBorder': accentOptions.colors.border,
60
- }"
61
- :class="[
62
- `rounded-xl border border-(--accentBorder)
63
- bg-(--accentBackground)`,
64
- ]"
65
- >
66
- <div
67
- class="text-main-lg flex items-center gap-(--proseAsideWidth)
68
- px-(--proseAsideWidth) py-(--proseAsideWidth) font-semibold
69
- text-(--accentText)"
70
- >
71
- <EruditIcon
72
- :name="accentIcon"
73
- class="-mr-1 shrink-0 text-[1.3em]"
74
- />
75
- <h2>{{ formatText(element.data.title) }}</h2>
76
- </div>
77
- <div class="pb-(--proseAsideWidth)">
78
- <Render
79
- v-for="sectionChild of mainSection!.children"
80
- :element="sectionChild"
81
- />
82
- </div>
83
- <AccentColumnSection
84
- v-if="element.data.layout === 'column'"
85
- v-for="(section, i) of sections"
86
- :section
87
- :title="sectionTitles[i]"
88
- />
89
- <AccentRowSections v-else :sections :sectionTitles />
90
- </div>
91
- </Block>
92
- </template>
1
+ <script lang="ts" setup>
2
+ import { shallowRef } from 'vue';
3
+ import { type ProseElement } from '@jsprose/core';
4
+
5
+ import {
6
+ isAccentMainElement,
7
+ type AccentMainSchema,
8
+ type AccentSchema,
9
+ type AccentSectionSchema,
10
+ } from './core.js';
11
+ import { accentSectionNamePhrase, type AccentAppOptions } from './app.js';
12
+ import { useAppElement } from '../../app/composables/appElement.js';
13
+ import { useElementPhrase } from '../../app/composables/language.js';
14
+ import { useElementIcon } from '../../app/composables/elementIcon.js';
15
+ import { useProseContext, type ElementPhrases } from '../../app/index.js';
16
+ import { useFormatText } from '../../app/composables/formatText.js';
17
+ import Block from '../../app/shared/block/Block.vue';
18
+ import Render from '../../app/shared/Render.vue';
19
+ import AccentColumnSection from './AccentColumnSection.vue';
20
+ import AccentRowSections from './AccentRowSections.vue';
21
+
22
+ const { element } = defineProps<{ element: ProseElement<AccentSchema> }>();
23
+
24
+ const { EruditIcon } = useProseContext();
25
+ const formatText = useFormatText();
26
+ const appElement = useAppElement(element);
27
+ const accentIcon = await useElementIcon(element);
28
+ const phrase =
29
+ await useElementPhrase<ElementPhrases<Record<string, string>>>(element);
30
+
31
+ const mainSection = shallowRef<ProseElement<AccentMainSchema>>();
32
+ const sections = shallowRef<ProseElement<AccentSectionSchema>[]>([]);
33
+
34
+ for (const child of element.children) {
35
+ if (isAccentMainElement(child)) {
36
+ mainSection.value = child;
37
+ } else {
38
+ sections.value.push(child);
39
+ }
40
+ }
41
+
42
+ const sectionTitles = sections.value.map((section) => {
43
+ if (section.data.type === 'manual') {
44
+ return formatText(section.data.title);
45
+ }
46
+
47
+ return formatText(phrase[accentSectionNamePhrase(section.data.name)]);
48
+ });
49
+
50
+ const accentOptions = (appElement as any)['accent'] as AccentAppOptions;
51
+ </script>
52
+
53
+ <template>
54
+ <Block :element>
55
+ <div
56
+ :style="{
57
+ '--accentText': accentOptions.colors.text,
58
+ '--accentBackground': accentOptions.colors.background,
59
+ '--accentBorder': accentOptions.colors.border,
60
+ }"
61
+ :class="[
62
+ 'rounded-xl border border-(--accentBorder) bg-(--accentBackground)',
63
+ ]"
64
+ >
65
+ <div
66
+ class="text-main-lg flex items-center gap-(--proseAsideWidth)
67
+ px-(--proseAsideWidth) py-(--proseAsideWidth) font-semibold
68
+ text-(--accentText)"
69
+ >
70
+ <EruditIcon :name="accentIcon" class="-mr-1 shrink-0 text-[1.3em]" />
71
+ <h2>{{ formatText(element.data.title) }}</h2>
72
+ </div>
73
+ <div class="pb-(--proseAsideWidth)">
74
+ <Render
75
+ v-for="sectionChild of mainSection!.children"
76
+ :element="sectionChild"
77
+ />
78
+ </div>
79
+ <AccentColumnSection
80
+ v-if="element.data.layout === 'column'"
81
+ v-for="(section, i) of sections"
82
+ :section
83
+ :title="sectionTitles[i]"
84
+ />
85
+ <AccentRowSections v-else :sections :sectionTitles />
86
+ </div>
87
+ </Block>
88
+ </template>
@@ -1,61 +1,61 @@
1
- <script lang="ts" setup>
2
- import { ref, watchEffect } from 'vue';
3
- import type { ProseElement } from '@jsprose/core';
4
-
5
- import type { AccentSectionSchema } from './core.js';
6
- import { useProseContext } from '../../app/composables/context.js';
7
- import { useContainsAnchor } from '../../app/composables/anchor.js';
8
- import plusIcon from '../../app/shared/assets/plus.svg?raw';
9
- import Render from '../../app/shared/Render.vue';
10
-
11
- const { section } = defineProps<{
12
- title: string;
13
- section: ProseElement<AccentSectionSchema>;
14
- }>();
15
-
16
- const { EruditIcon } = useProseContext();
17
- const containsAnchor = useContainsAnchor(section);
18
-
19
- const opened = ref(false);
20
-
21
- watchEffect(() => {
22
- if (containsAnchor.value) {
23
- opened.value = true;
24
- }
25
- });
26
- </script>
27
-
28
- <template>
29
- <div>
30
- <div
31
- @click="opened = !opened"
32
- class="group relative flex cursor-pointer items-center border-t
33
- border-(--accentBorder) p-(--proseAsideWidth) font-medium
34
- text-(--accentText)"
35
- >
36
- <div class="flex-1">{{ title }}</div>
37
- <button
38
- class="group-hocus:bg-(--accentBorder)/70 shrink-0 rounded
39
- bg-transparent p-0.5 transition-[background]"
40
- >
41
- <EruditIcon
42
- :name="plusIcon"
43
- :class="[
44
- 'micro:text-[26px] text-[22px] transition-[rotate]',
45
- opened ? 'rotate-45' : '',
46
- ]"
47
- />
48
- </button>
49
- <div
50
- :class="[
51
- `absolute bottom-0 left-0 w-full border-b border-dashed
52
- border-(--accentBorder)`,
53
- opened ? 'opacity-100' : 'opacity-0',
54
- ]"
55
- ></div>
56
- </div>
57
- <div class="py-(--proseAsideWidth)" v-if="opened">
58
- <Render v-for="child of section.children" :element="child" />
59
- </div>
60
- </div>
61
- </template>
1
+ <script lang="ts" setup>
2
+ import { ref, watchEffect } from 'vue';
3
+ import type { ProseElement } from '@jsprose/core';
4
+
5
+ import type { AccentSectionSchema } from './core.js';
6
+ import { useProseContext } from '../../app/composables/context.js';
7
+ import { useContainsAnchor } from '../../app/composables/anchor.js';
8
+ import plusIcon from '../../app/shared/assets/plus.svg?raw';
9
+ import Render from '../../app/shared/Render.vue';
10
+
11
+ const { section } = defineProps<{
12
+ title: string;
13
+ section: ProseElement<AccentSectionSchema>;
14
+ }>();
15
+
16
+ const { EruditIcon } = useProseContext();
17
+ const containsAnchor = useContainsAnchor(section);
18
+
19
+ const opened = ref(false);
20
+
21
+ watchEffect(() => {
22
+ if (containsAnchor.value) {
23
+ opened.value = true;
24
+ }
25
+ });
26
+ </script>
27
+
28
+ <template>
29
+ <div>
30
+ <div
31
+ @click="opened = !opened"
32
+ class="group relative flex cursor-pointer items-center border-t
33
+ border-(--accentBorder) p-(--proseAsideWidth) font-medium
34
+ text-(--accentText)"
35
+ >
36
+ <div class="flex-1">{{ title }}</div>
37
+ <button
38
+ class="group-hocus:bg-(--accentBorder)/70 shrink-0 rounded
39
+ bg-transparent p-0.5 transition-[background]"
40
+ >
41
+ <EruditIcon
42
+ :name="plusIcon"
43
+ :class="[
44
+ 'micro:text-[26px] text-[22px] transition-[rotate]',
45
+ opened ? 'rotate-45' : '',
46
+ ]"
47
+ />
48
+ </button>
49
+ <div
50
+ :class="[
51
+ `absolute bottom-0 left-0 w-full border-b border-dashed
52
+ border-(--accentBorder)`,
53
+ opened ? 'opacity-100' : 'opacity-0',
54
+ ]"
55
+ ></div>
56
+ </div>
57
+ <div class="py-(--proseAsideWidth)" v-if="opened">
58
+ <Render v-for="child of section.children" :element="child" />
59
+ </div>
60
+ </div>
61
+ </template>
@@ -1,65 +1,64 @@
1
- <script lang="ts" setup>
2
- import { ref, watchEffect } from 'vue';
3
- import type { ProseElement } from '@jsprose/core';
4
-
5
- import type { AccentSectionSchema } from './core.js';
6
- import { useArrayContainsAnchor } from '../../app/composables/anchor.js';
7
- import Render from '../../app/shared/Render.vue';
8
-
9
- const { sections } = defineProps<{
10
- sectionTitles: string[];
11
- sections: ProseElement<AccentSectionSchema>[];
12
- }>();
13
-
14
- const openedSectionI = ref<number>();
15
- const containsAnchorI = useArrayContainsAnchor(sections);
16
-
17
- watchEffect(() => {
18
- if (containsAnchorI.value !== undefined) {
19
- openedSectionI.value = containsAnchorI.value;
20
- }
21
- });
22
- </script>
23
-
24
- <template>
25
- <div
26
- :class="[
27
- `relative flex flex-wrap items-center gap-(--proseAsideWidth)
28
- p-(--proseAsideWidth) pt-0`,
29
- ]"
30
- >
31
- <button
32
- v-for="(_section, i) of sections"
33
- @click="openedSectionI = i === openedSectionI ? undefined : i"
34
- :class="[
35
- `text-main-sm micro:py-2 micro:px-2.5 cursor-pointer rounded-xl
36
- px-2 py-1.5 font-medium transition-[color,background]`,
37
- i === openedSectionI
38
- ? 'bg-(--accentText)/80 text-white'
39
- : `hocus:bg-(--accentText)/30 bg-(--accentText)/15
40
- text-(--accentText)`,
41
- ]"
42
- >
43
- {{ sectionTitles[i] }}
44
- </button>
45
- <div
46
- :class="[
47
- `absolute bottom-0 left-0 w-full border-b
48
- border-(--accentBorder)`,
49
- openedSectionI === undefined ? 'opacity-0' : 'opacity-100',
50
- ]"
51
- ></div>
52
- </div>
53
- <Suspense>
54
- <div
55
- v-if="openedSectionI !== undefined"
56
- :key="openedSectionI"
57
- class="py-(--proseAsideWidth)"
58
- >
59
- <Render
60
- v-for="child of sections[openedSectionI].children"
61
- :element="child"
62
- />
63
- </div>
64
- </Suspense>
65
- </template>
1
+ <script lang="ts" setup>
2
+ import { ref, watchEffect } from 'vue';
3
+ import type { ProseElement } from '@jsprose/core';
4
+
5
+ import type { AccentSectionSchema } from './core.js';
6
+ import { useArrayContainsAnchor } from '../../app/composables/anchor.js';
7
+ import Render from '../../app/shared/Render.vue';
8
+
9
+ const { sections } = defineProps<{
10
+ sectionTitles: string[];
11
+ sections: ProseElement<AccentSectionSchema>[];
12
+ }>();
13
+
14
+ const openedSectionI = ref<number>();
15
+ const containsAnchorI = useArrayContainsAnchor(sections);
16
+
17
+ watchEffect(() => {
18
+ if (containsAnchorI.value !== undefined) {
19
+ openedSectionI.value = containsAnchorI.value;
20
+ }
21
+ });
22
+ </script>
23
+
24
+ <template>
25
+ <div
26
+ :class="[
27
+ `relative flex flex-wrap items-center gap-(--proseAsideWidth)
28
+ p-(--proseAsideWidth) pt-0`,
29
+ ]"
30
+ >
31
+ <button
32
+ v-for="(_section, i) of sections"
33
+ @click="openedSectionI = i === openedSectionI ? undefined : i"
34
+ :class="[
35
+ `text-main-sm micro:py-2 micro:px-2.5 cursor-pointer rounded-xl px-2
36
+ py-1.5 font-medium transition-[color,background]`,
37
+ i === openedSectionI
38
+ ? 'bg-(--accentText)/80 text-white'
39
+ : `hocus:bg-(--accentText)/30 bg-(--accentText)/15
40
+ text-(--accentText)`,
41
+ ]"
42
+ >
43
+ {{ sectionTitles[i] }}
44
+ </button>
45
+ <div
46
+ :class="[
47
+ 'absolute bottom-0 left-0 w-full border-b border-(--accentBorder)',
48
+ openedSectionI === undefined ? 'opacity-0' : 'opacity-100',
49
+ ]"
50
+ ></div>
51
+ </div>
52
+ <Suspense>
53
+ <div
54
+ v-if="openedSectionI !== undefined"
55
+ :key="openedSectionI"
56
+ class="py-(--proseAsideWidth)"
57
+ >
58
+ <Render
59
+ v-for="child of sections[openedSectionI].children"
60
+ :element="child"
61
+ />
62
+ </div>
63
+ </Suspense>
64
+ </template>
@@ -1,85 +1,81 @@
1
- <script lang="ts" setup>
2
- import type { ProseElement } from '@jsprose/core';
3
-
4
- import type { calloutSchema } from './core.js';
5
- import { useElementStorage } from '../../app/composables/storage.js';
6
- import { useFormatText } from '../../app/composables/formatText.js';
7
- import Block from '../../app/shared/block/Block.vue';
8
- import Render from '../../app/shared/Render.vue';
9
-
10
- const { element } = defineProps<{
11
- element: ProseElement<typeof calloutSchema>;
12
- }>();
13
- const calloutStorage = await useElementStorage<typeof calloutSchema>(element);
14
- const formatText = useFormatText();
15
- </script>
16
-
17
- <template>
18
- <Block :element>
19
- <div
20
- :style="{ '--calloutBg': 'light-dark(#f7f7f7, #1c1c1c)' }"
21
- class="gap-big flex"
22
- >
23
- <div class="max-micro:hidden shrink-0">
24
- <img
25
- :src="calloutStorage.resolvedIconSrc"
26
- loading="lazy"
27
- class="outline-border size-[60px] rounded-full border-2
28
- border-transparent outline-2"
29
- />
30
- </div>
31
- <div
32
- class="border-border/90 relative flex-1 rounded-xl border
33
- bg-(--calloutBg) py-(--proseAsideWidth) font-serif
34
- shadow-md"
35
- >
36
- <div :class="$style.arrow" class="max-micro:hidden">
37
- <div :class="$style.fill"></div>
38
- </div>
39
- <header
40
- class="gap-small mb-(--proseAsideWidth) flex items-center
41
- px-(--proseAsideWidth) font-semibold"
42
- >
43
- <img
44
- :src="calloutStorage.resolvedIconSrc"
45
- class="micro:hidden size-[30px] shrink-0 rounded-full"
46
- />
47
- <div class="text-text-deep flex-1">
48
- {{ formatText(element.data.title) }}
49
- </div>
50
- </header>
51
- <main class="text-main-sm">
52
- <Render
53
- v-for="child of element.children"
54
- :element="child"
55
- />
56
- </main>
57
- </div>
58
- </div>
59
- </Block>
60
- </template>
61
-
62
- <style module>
63
- .arrow {
64
- --arrowSize: 18px;
65
- border-bottom: var(--arrowSize) solid transparent;
66
- border-right: var(--arrowSize) solid var(--color-border);
67
- border-top: var(--arrowSize) solid transparent;
68
- height: 0;
69
- position: absolute;
70
- left: calc(-1 * var(--arrowSize));
71
- top: calc(var(--proseAsideWidth) - var(--arrowSize) / 4);
72
- width: 0;
73
-
74
- .fill {
75
- border-bottom: calc(var(--arrowSize) - 1px) solid transparent;
76
- border-right: calc(var(--arrowSize) - 1px) solid var(--calloutBg);
77
- border-top: calc(var(--arrowSize) - 1px) solid transparent;
78
- height: 0;
79
- left: 1.5px;
80
- position: absolute;
81
- transform: translateY(-50%);
82
- width: 0;
83
- }
84
- }
85
- </style>
1
+ <script lang="ts" setup>
2
+ import type { ProseElement } from '@jsprose/core';
3
+
4
+ import type { calloutSchema } from './core.js';
5
+ import { useElementStorage } from '../../app/composables/storage.js';
6
+ import { useFormatText } from '../../app/composables/formatText.js';
7
+ import Block from '../../app/shared/block/Block.vue';
8
+ import Render from '../../app/shared/Render.vue';
9
+
10
+ const { element } = defineProps<{
11
+ element: ProseElement<typeof calloutSchema>;
12
+ }>();
13
+ const calloutStorage = await useElementStorage<typeof calloutSchema>(element);
14
+ const formatText = useFormatText();
15
+ </script>
16
+
17
+ <template>
18
+ <Block :element>
19
+ <div
20
+ :style="{ '--calloutBg': 'light-dark(#f7f7f7, #1c1c1c)' }"
21
+ class="gap-big flex"
22
+ >
23
+ <div class="max-micro:hidden shrink-0">
24
+ <img
25
+ :src="calloutStorage.resolvedIconSrc"
26
+ loading="lazy"
27
+ class="outline-border size-[60px] rounded-full border-2
28
+ border-transparent outline-2"
29
+ />
30
+ </div>
31
+ <div
32
+ class="border-border/90 relative flex-1 rounded-xl border
33
+ bg-(--calloutBg) py-(--proseAsideWidth) font-serif shadow-md"
34
+ >
35
+ <div :class="$style.arrow" class="max-micro:hidden">
36
+ <div :class="$style.fill"></div>
37
+ </div>
38
+ <header
39
+ class="gap-small mb-(--proseAsideWidth) flex items-center
40
+ px-(--proseAsideWidth) font-semibold"
41
+ >
42
+ <img
43
+ :src="calloutStorage.resolvedIconSrc"
44
+ class="micro:hidden size-[30px] shrink-0 rounded-full"
45
+ />
46
+ <div class="text-text-deep flex-1">
47
+ {{ formatText(element.data.title) }}
48
+ </div>
49
+ </header>
50
+ <main class="text-main-sm">
51
+ <Render v-for="child of element.children" :element="child" />
52
+ </main>
53
+ </div>
54
+ </div>
55
+ </Block>
56
+ </template>
57
+
58
+ <style module>
59
+ .arrow {
60
+ --arrowSize: 18px;
61
+ border-bottom: var(--arrowSize) solid transparent;
62
+ border-right: var(--arrowSize) solid var(--color-border);
63
+ border-top: var(--arrowSize) solid transparent;
64
+ height: 0;
65
+ position: absolute;
66
+ left: calc(-1 * var(--arrowSize));
67
+ top: calc(var(--proseAsideWidth) - var(--arrowSize) / 4);
68
+ width: 0;
69
+
70
+ .fill {
71
+ border-bottom: calc(var(--arrowSize) - 1px) solid transparent;
72
+ border-right: calc(var(--arrowSize) - 1px) solid var(--calloutBg);
73
+ border-top: calc(var(--arrowSize) - 1px) solid transparent;
74
+ height: 0;
75
+ left: 1.5px;
76
+ position: absolute;
77
+ transform: translateY(-50%);
78
+ width: 0;
79
+ }
80
+ }
81
+ </style>
@@ -1,15 +1,15 @@
1
- /**
2
- * Callouts are used to highlight important information, warnings, or tips within the content.
3
- *
4
- * @title Callout
5
- * @layout block
6
- * @example
7
- * ```tsx
8
- * // import warningIcon from './assets/warning-icon.svg';
9
- *
10
- * <Callout icon={warningIcon} title="Important Notice" invert="dark">
11
- * <P>Please be aware of the upcoming changes to the schedule.</P>
12
- * </Callout>
13
- * ```
14
- */
15
- export const Callout = '_tag_';
1
+ /**
2
+ * Callouts are used to highlight important information, warnings, or tips within the content.
3
+ *
4
+ * @title Callout
5
+ * @layout block
6
+ * @example
7
+ * ```tsx
8
+ * // import warningIcon from './assets/warning-icon.svg';
9
+ *
10
+ * <Callout icon={warningIcon} title="Important Notice" invert="dark">
11
+ * <P>Please be aware of the upcoming changes to the schedule.</P>
12
+ * </Callout>
13
+ * ```
14
+ */
15
+ export const Callout = '_tag_';