erudit 3.0.0-dev.4 → 3.0.0-dev.6

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 (243) hide show
  1. package/app/app.vue +195 -172
  2. package/app/components/Loading.vue +23 -23
  3. package/app/components/SiteAside.vue +393 -382
  4. package/app/components/SiteMain.vue +35 -35
  5. package/app/components/ads/BannerTemplate.vue +51 -51
  6. package/app/components/ads/BottomBanner.vue +45 -45
  7. package/app/components/ads/LeftBanner.vue +50 -50
  8. package/app/components/aside/AsideListItem.vue +74 -74
  9. package/app/components/aside/AsideMajor.vue +56 -56
  10. package/app/components/aside/AsideMinor.vue +71 -71
  11. package/app/components/aside/major/PaneContentScroll.vue +23 -23
  12. package/app/components/aside/major/PaneSwitch.vue +54 -54
  13. package/app/components/aside/major/PaneSwitchButton.vue +63 -63
  14. package/app/components/aside/major/SiteInfo.vue +85 -85
  15. package/app/components/aside/major/panes/Language.vue +79 -79
  16. package/app/components/aside/major/panes/Pages.vue +34 -34
  17. package/app/components/aside/major/panes/Search.vue +11 -11
  18. package/app/components/aside/major/panes/nav/Nav.vue +87 -91
  19. package/app/components/aside/major/panes/nav/NavBook.vue +87 -87
  20. package/app/components/aside/major/panes/nav/NavBookLoading.vue +24 -24
  21. package/app/components/aside/major/panes/nav/NavGlobal.vue +16 -16
  22. package/app/components/aside/major/panes/nav/fnav/FNav.vue +105 -105
  23. package/app/components/aside/major/panes/nav/fnav/FNavBook.vue +32 -32
  24. package/app/components/aside/major/panes/nav/fnav/FNavFlags.vue +40 -40
  25. package/app/components/aside/major/panes/nav/fnav/FNavFolder.vue +60 -60
  26. package/app/components/aside/major/panes/nav/fnav/FNavItem.vue +34 -34
  27. package/app/components/aside/major/panes/nav/fnav/FNavSeparator.vue +80 -80
  28. package/app/components/aside/major/panes/nav/fnav/FNavTopic.vue +24 -24
  29. package/app/components/aside/major/panes/other/ItemContent.vue +29 -29
  30. package/app/components/aside/major/panes/other/ItemGenerator.vue +15 -15
  31. package/app/components/aside/major/panes/other/ItemTheme.vue +54 -54
  32. package/app/components/aside/major/panes/other/Other.vue +16 -16
  33. package/app/components/aside/minor/AsideMinorContributor.vue +5 -5
  34. package/app/components/aside/minor/AsideMinorNews.vue +11 -11
  35. package/app/components/aside/minor/AsideMinorPane.vue +15 -15
  36. package/app/components/aside/minor/AsideMinorTopLink.vue +67 -67
  37. package/app/components/aside/minor/Contribute.vue +145 -145
  38. package/app/components/aside/minor/content/AsideMinorContent.vue +92 -92
  39. package/app/components/aside/minor/topic/AsideMinorTopic.vue +32 -32
  40. package/app/components/aside/minor/topic/TopicContributors.vue +177 -177
  41. package/app/components/aside/minor/topic/TopicNav.vue +49 -49
  42. package/app/components/aside/minor/topic/TopicToc.vue +219 -203
  43. package/app/components/aside/minor/topic/TopicTocItem.vue +30 -31
  44. package/app/components/aside/utils/AsideOverlayPane.vue +40 -40
  45. package/app/components/bitran/BitranContent.vue +70 -63
  46. package/app/components/bitran/RenderWrapper.vue +10 -10
  47. package/app/components/contributor/ContributorAvatar.vue +43 -43
  48. package/app/components/contributor/ContributorListItem.vue +35 -35
  49. package/app/components/main/topic/MainTopic.vue +79 -79
  50. package/app/components/main/topic/TopicPartSwitch.vue +118 -118
  51. package/app/components/main/utils/Breadcrumb.vue +75 -75
  52. package/app/components/main/utils/ContentDecoration.vue +29 -29
  53. package/app/components/main/utils/ContentDescription.vue +19 -19
  54. package/app/components/main/utils/ContentPopover.vue +188 -176
  55. package/app/components/main/utils/ContentPopovers.vue +105 -105
  56. package/app/components/main/utils/ContentReferences.vue +70 -70
  57. package/app/components/main/utils/ContentSection.vue +45 -45
  58. package/app/components/main/utils/ContentTitle.vue +63 -39
  59. package/app/components/main/utils/reference/ReferenceGroup.vue +38 -38
  60. package/app/components/main/utils/reference/ReferenceItem.vue +68 -68
  61. package/app/components/main/utils/reference/ReferenceSource.vue +116 -116
  62. package/app/components/preview/Preview.vue +186 -177
  63. package/app/components/preview/PreviewDisplay.vue +139 -139
  64. package/app/components/preview/PreviewFooterAction.vue +73 -73
  65. package/app/components/preview/PreviewLoading.vue +14 -14
  66. package/app/components/preview/PreviewScreen.vue +141 -99
  67. package/app/components/preview/display/Alert.vue +50 -50
  68. package/app/components/preview/display/Custom.vue +18 -18
  69. package/app/components/preview/display/GenericLink.vue +48 -48
  70. package/app/components/preview/display/PageLink.vue +20 -20
  71. package/app/components/preview/display/Unique.vue +49 -49
  72. package/app/components/transition/Fade.vue +19 -19
  73. package/app/components/tree/TreeContainer.vue +11 -11
  74. package/app/components/tree/TreeItem.vue +89 -89
  75. package/app/composables/bitran.ts +129 -127
  76. package/app/composables/bitranContent.ts +39 -39
  77. package/app/composables/bitranLocation.ts +7 -7
  78. package/app/composables/contentData.ts +36 -36
  79. package/app/composables/contentPage.ts +157 -156
  80. package/app/composables/contentRoute.ts +45 -45
  81. package/app/composables/darkMagic.ts +24 -24
  82. package/app/composables/externalApi.ts +63 -63
  83. package/app/composables/favicon.ts +8 -8
  84. package/app/composables/formatText.ts +86 -86
  85. package/app/composables/majorPane.ts +60 -60
  86. package/app/composables/phrases.ts +81 -81
  87. package/app/composables/theme.ts +29 -29
  88. package/app/composables/url.ts +33 -33
  89. package/app/pages/_test/preview.vue +110 -110
  90. package/app/pages/article/[...articleId].vue +3 -3
  91. package/app/pages/book/[...bookId].vue +47 -47
  92. package/app/pages/group/[...groupId].vue +65 -65
  93. package/app/pages/index.vue +32 -32
  94. package/app/pages/members.vue +6 -6
  95. package/app/pages/practice/[...practice].vue +3 -3
  96. package/app/pages/summary/[...summaryId].vue +3 -3
  97. package/app/public/favicon/article.svg +5 -5
  98. package/app/public/favicon/default.svg +3 -3
  99. package/app/public/favicon/practice.svg +3 -3
  100. package/app/public/favicon/summary.svg +4 -4
  101. package/app/public/logotype.svg +2 -2
  102. package/app/scripts/_immediate.js +9 -9
  103. package/app/scripts/aside/index.ts +59 -59
  104. package/app/scripts/aside/major/nav.ts +26 -26
  105. package/app/scripts/aside/minor/state.ts +37 -37
  106. package/app/scripts/aside/minor/topic.ts +3 -3
  107. package/app/scripts/flag.ts +28 -28
  108. package/app/scripts/og.ts +27 -27
  109. package/app/scripts/preview/build.ts +73 -73
  110. package/app/scripts/preview/data/alert.ts +19 -19
  111. package/app/scripts/preview/data/custom.ts +8 -8
  112. package/app/scripts/preview/data/genericLink.ts +24 -24
  113. package/app/scripts/preview/data/pageLink.ts +22 -22
  114. package/app/scripts/preview/data/unique.ts +71 -71
  115. package/app/scripts/preview/data.ts +24 -24
  116. package/app/scripts/preview/display.ts +37 -37
  117. package/app/scripts/preview/footer.ts +9 -9
  118. package/app/scripts/preview/request.ts +51 -51
  119. package/app/scripts/preview/state.ts +63 -63
  120. package/app/styles/_immediate.css +7 -7
  121. package/app/styles/_util.scss +43 -43
  122. package/app/styles/_utils.scss +44 -44
  123. package/app/styles/app.scss +91 -91
  124. package/app/styles/def/_bp.scss +27 -27
  125. package/app/styles/def/_size.scss +7 -7
  126. package/app/styles/def/_z.scss +5 -5
  127. package/app/styles/normalize.scss +63 -63
  128. package/app/styles/partials/_darkMagic.scss +5 -5
  129. package/app/styles/partials/_fnav.scss +15 -15
  130. package/app/styles/partials/_preview.scss +5 -5
  131. package/globalPath.ts +21 -21
  132. package/globals/bitran.ts +2 -47
  133. package/globals/content.ts +22 -22
  134. package/globals/contributor.ts +5 -5
  135. package/globals/erudit.ts +5 -5
  136. package/globals/register.ts +18 -18
  137. package/languages/en.ts +95 -95
  138. package/languages/ru.ts +99 -99
  139. package/module/bitran.ts +35 -34
  140. package/module/config.ts +34 -34
  141. package/module/imports.ts +50 -46
  142. package/module/index.ts +47 -47
  143. package/module/logger.ts +10 -10
  144. package/module/paths.ts +22 -22
  145. package/module/restart.ts +61 -61
  146. package/nuxt.config.ts +99 -112
  147. package/package.json +10 -8
  148. package/server/api/aside/major/nav/bookIds.ts +5 -5
  149. package/server/api/aside/major/nav/bookNav/[...bookId].ts +20 -20
  150. package/server/api/aside/major/nav/global.ts +7 -7
  151. package/server/api/aside/minor/news.ts +7 -7
  152. package/server/api/aside/minor/path.ts +78 -78
  153. package/server/api/bitran/content/[location].ts +8 -8
  154. package/server/api/bitran/toc/[location].ts +7 -7
  155. package/server/api/content/data.ts +72 -72
  156. package/server/api/contributor/count.ts +6 -6
  157. package/server/api/fake/content.ts +11 -11
  158. package/server/api/fake/shared/languages.ts +12 -12
  159. package/server/api/language/functions.ts +12 -12
  160. package/server/api/language/phrase/[phraseId].ts +19 -19
  161. package/server/api/language/phraseIds.ts +8 -8
  162. package/server/api/preview/page/[...parts].ts +51 -51
  163. package/server/api/preview/unique/[location].ts +57 -57
  164. package/server/plugin/bitran/content.ts +187 -187
  165. package/server/plugin/bitran/location.ts +25 -25
  166. package/server/plugin/bitran/products/include.ts +230 -230
  167. package/server/plugin/bitran/products/link.ts +116 -116
  168. package/server/plugin/bitran/setup.ts +11 -9
  169. package/server/plugin/bitran/toc.ts +83 -83
  170. package/server/plugin/bitran/transpiler.ts +48 -46
  171. package/server/plugin/build/close.ts +10 -10
  172. package/server/plugin/build/jobs/content/builderArgs.ts +8 -8
  173. package/server/plugin/build/jobs/content/generic.ts +176 -176
  174. package/server/plugin/build/jobs/content/parse.ts +100 -100
  175. package/server/plugin/build/jobs/content/path.ts +6 -6
  176. package/server/plugin/build/jobs/content/type/book.ts +9 -9
  177. package/server/plugin/build/jobs/content/type/group.ts +37 -37
  178. package/server/plugin/build/jobs/content/type/topic.ts +36 -36
  179. package/server/plugin/build/jobs/contributors.ts +66 -66
  180. package/server/plugin/build/jobs/language.ts +36 -36
  181. package/server/plugin/build/jobs/nav.ts +214 -210
  182. package/server/plugin/build/process.ts +25 -25
  183. package/server/plugin/build/rebuild.ts +55 -55
  184. package/server/plugin/build/setup.ts +21 -21
  185. package/server/plugin/content/absoluteId.ts +94 -94
  186. package/server/plugin/content/context.ts +116 -112
  187. package/server/plugin/db/entities/Book.ts +7 -7
  188. package/server/plugin/db/entities/Content.ts +49 -49
  189. package/server/plugin/db/entities/Contribution.ts +10 -10
  190. package/server/plugin/db/entities/Contributor.ts +16 -16
  191. package/server/plugin/db/entities/Group.ts +14 -14
  192. package/server/plugin/db/entities/Hash.ts +15 -15
  193. package/server/plugin/db/entities/Topic.ts +20 -20
  194. package/server/plugin/db/entities/Unique.ts +21 -21
  195. package/server/plugin/db/setup.ts +34 -34
  196. package/server/plugin/global.ts +17 -18
  197. package/server/plugin/importer.ts +12 -12
  198. package/server/plugin/index.ts +9 -9
  199. package/server/plugin/logger.ts +23 -23
  200. package/server/plugin/nav/node.ts +26 -26
  201. package/server/plugin/nav/utils.ts +129 -129
  202. package/server/plugin/repository/book.ts +21 -21
  203. package/server/plugin/repository/content.ts +238 -238
  204. package/server/plugin/repository/contributor.ts +8 -8
  205. package/server/plugin/repository/frontNav.ts +148 -148
  206. package/server/plugin/repository/topic.ts +32 -32
  207. package/server/tsconfig.json +9 -9
  208. package/shared/aside/minor.ts +50 -50
  209. package/shared/asset.ts +15 -15
  210. package/shared/bitran/context.ts +8 -8
  211. package/shared/bitran/default.ts +46 -46
  212. package/shared/bitran/link/Link.vue +166 -167
  213. package/shared/bitran/link/factory.ts +24 -24
  214. package/shared/bitran/link/languages/en.ts +7 -7
  215. package/shared/bitran/link/languages/ru.ts +7 -7
  216. package/shared/bitran/link/renderer.ts +21 -21
  217. package/shared/bitran/link/shared.ts +17 -17
  218. package/shared/bitran/link/target.ts +134 -134
  219. package/shared/bitran/link/transpiler.ts +10 -10
  220. package/shared/bitran/location.ts +166 -166
  221. package/shared/bitran/toc.ts +8 -8
  222. package/shared/content/context.ts +9 -9
  223. package/shared/content/data/base.ts +32 -32
  224. package/shared/content/data/index.ts +5 -5
  225. package/shared/content/data/type/book.ts +5 -5
  226. package/shared/content/data/type/group.ts +6 -6
  227. package/shared/content/data/type/topic.ts +11 -11
  228. package/shared/content/previousNext.ts +9 -9
  229. package/shared/contributor.ts +5 -5
  230. package/shared/frontNav.ts +41 -41
  231. package/shared/icons.ts +38 -38
  232. package/shared/image.ts +5 -5
  233. package/shared/link.ts +25 -25
  234. package/shared/popover.ts +8 -0
  235. package/shared/types/language.ts +75 -75
  236. package/shared/utils/objectsEqual.ts +4 -4
  237. package/shared/utils/stringColor.ts +9 -9
  238. package/test/bitran/link/target.test.ts +141 -141
  239. package/test/bitran/location.test.ts +143 -143
  240. package/tsconfig.json +8 -8
  241. package/utils/stress.ts +9 -9
  242. package/app/components/main/utils/ContentFlag.vue +0 -15
  243. package/app/styles/default.scss +0 -83
@@ -1,382 +1,393 @@
1
- <script lang="ts" setup>
2
- import { previewVisible } from '@app/scripts/preview/state';
3
- import {
4
- AsideType,
5
- clickTargets,
6
- forcedAside,
7
- switchVisible,
8
- } from '@app/scripts/aside';
9
-
10
- const props = defineProps<{
11
- type: AsideType;
12
- }>();
13
-
14
- const $style = useCssModule();
15
-
16
- const switchElement = ref<HTMLElement>();
17
- const asideElement = ref<HTMLElement>();
18
-
19
- const canShowSwitch = computed(
20
- () => switchVisible.value && !forcedAside.value && !previewVisible.value,
21
- );
22
- const asideForceVisible = computed(() => props.type === forcedAside.value);
23
-
24
- const typeClass = props.type === AsideType.Major ? $style.major : $style.minor;
25
-
26
- onMounted(() => {
27
- clickTargets[props.type].push(
28
- ...[switchElement.value!, asideElement.value!],
29
- );
30
- });
31
-
32
- function switchClick() {
33
- forcedAside.value = props.type;
34
- }
35
- </script>
36
-
37
- <template>
38
- <div
39
- ref="switchElement"
40
- @click="switchClick"
41
- :class="[
42
- $style.asideSwitch,
43
- typeClass,
44
- canShowSwitch ? $style.visible : '',
45
- ]"
46
- >
47
- <MyIcon name="aside-open" />
48
- </div>
49
-
50
- <aside
51
- ref="asideElement"
52
- :class="[
53
- $style.aside,
54
- typeClass,
55
- asideForceVisible ? $style.forceVisible : '',
56
- ]"
57
- >
58
- <slot></slot>
59
- <div :class="$style.innerShadow"></div>
60
- </aside>
61
- </template>
62
-
63
- <style lang="scss" module>
64
- @use '$/def/bp';
65
- @use '$/def/z';
66
- @use '$/def/size';
67
-
68
- // !!
69
- // !!
70
- // !! Rewrite the whole logic based on coords relative to main content. It will be 1000% easier. See how <Preview> is implemented!
71
- // !!
72
- // !!
73
-
74
- @function maxLayoutEdge() {
75
- @return calc(
76
- 50% - min(var(--wMainMax), calc(100% - 2 * var(--wAside))) / 2
77
- );
78
- }
79
-
80
- @mixin ___asidePositionLogic {
81
- /* For God's sake, don't ever touch this code */
82
-
83
- --_pos: var(--_posHidden); // Start with hidden position (mobile first)
84
-
85
- --_posHidden: calc(-1 * var(--wAside));
86
- --_posVisible: var(--_posVisibleCorner);
87
-
88
- --_posVisibleCorner: 0;
89
- --_posVisibleMax: calc(#{maxLayoutEdge()} - var(--wAside));
90
-
91
- &.major.forceVisible,
92
- &.minor.forceVisible {
93
- --_pos: var(--_posVisible); // Always visible when forced
94
- }
95
-
96
- &.major {
97
- left: var(--_pos);
98
-
99
- @include bp.above('aside1') {
100
- --_posVisible: var(--_posVisibleCorner);
101
- --_pos: var(--_posVisible);
102
- }
103
-
104
- @include bp.above('aside2') {
105
- --_posVisible: var(--_posVisibleMax);
106
- }
107
- }
108
-
109
- &.minor {
110
- right: var(--_pos);
111
-
112
- @include bp.above('aside2') {
113
- --_posVisible: var(--_posVisibleMax);
114
- --_pos: var(--_posVisible);
115
- }
116
- }
117
- }
118
-
119
- .aside {
120
- //
121
- // Global
122
- //
123
-
124
- position: fixed;
125
- z-index: z.$aside;
126
- top: 0;
127
-
128
- width: var(--wAside);
129
- height: 100dvh;
130
-
131
- background: var(--bgAside);
132
- backdrop-filter: initial;
133
-
134
- --shadowColor: #{rgba(black, 0.065)};
135
-
136
- @include transition(left, right, background, backdrop-filter, box-shadow);
137
-
138
- @include dark {
139
- --shadowColor: #{rgba(white, 0.075)};
140
- }
141
-
142
- //
143
-
144
- @include ___asidePositionLogic;
145
-
146
- //
147
- // Global States
148
- //
149
-
150
- @mixin asideVisible {
151
- }
152
-
153
- @mixin asideHidden {
154
- }
155
-
156
- @mixin asideModal {
157
- background: color-mix(
158
- in srgb,
159
- color-mix(in srgb, var(--bgAside), black 0%),
160
- transparent 22%
161
- );
162
- backdrop-filter: blur(10px);
163
-
164
- box-shadow:
165
- 0px 0px 15px 15px rgba(0, 0, 0, 0.1),
166
- 0px 0px 8px 0px rgba(0, 0, 0, 0.1);
167
-
168
- @include dark {
169
- background: color-mix(in srgb, var(--bgAside), transparent 10%);
170
-
171
- box-shadow:
172
- 0px 0px 15px 15px rgba(255, 255, 255, 0.025),
173
- 0px 0px 8px 0px rgba(255, 255, 255, 0.03);
174
- }
175
- }
176
-
177
- &.major {
178
- //
179
- // Major Aside
180
- //
181
-
182
- box-shadow: -1px 0px 2px 0px var(--shadowColor);
183
-
184
- @include bp.above('aside1') {
185
- //
186
- // Major Visible
187
- //
188
-
189
- @include asideVisible;
190
- }
191
-
192
- @include bp.below('aside1') {
193
- //
194
- // Major Hidden
195
- //
196
-
197
- @include asideHidden;
198
-
199
- &.forceVisible {
200
- //
201
- // Major Modal
202
- //
203
-
204
- @include asideModal;
205
- }
206
- }
207
- }
208
-
209
- &.minor {
210
- //
211
- // Minor Aside
212
- //
213
-
214
- box-shadow: 1px 0px 2px 0px var(--shadowColor);
215
-
216
- @include bp.above('aside2') {
217
- //
218
- // Minor Visible
219
- //
220
-
221
- @include asideVisible;
222
- }
223
-
224
- @include bp.below('aside2') {
225
- //
226
- // Minor Hidden
227
- //
228
-
229
- @include asideHidden;
230
-
231
- &.forceVisible {
232
- //
233
- // Minor Modal
234
- //
235
-
236
- @include asideModal;
237
- }
238
- }
239
- }
240
- }
241
-
242
- //
243
- //
244
- //
245
-
246
- @mixin ___switchPositionLogic {
247
- /* For God's sake, don't ever touch this code */
248
-
249
- --_switchSize: calc(var(--iconSize) + 2 * var(--p) + var(--m));
250
-
251
- --_pos: var(--_posHidden);
252
-
253
- --_posVisible: calc(var(--_posHidden) + var(--_switchSize));
254
- --_posHidden: var(--_posBehindCorner);
255
-
256
- --_posBehindCorner: calc(-1 * var(--_switchSize));
257
- --_posBehindMajorAside: calc(var(--wAside) - var(--_switchSize));
258
- --_posBehindFullLayout: calc(#{maxLayoutEdge()} - var(--_switchSize));
259
-
260
- &.visible {
261
- --_pos: var(--_posVisible);
262
- }
263
-
264
- &.major {
265
- left: var(--_pos);
266
-
267
- @include bp.above('aside1') {
268
- --_posHidden: var(--_posBehindMajorAside);
269
- --_posVisible: var(--_posHidden);
270
- }
271
- }
272
-
273
- &.minor {
274
- right: var(--_pos);
275
-
276
- @include bp.above('aside2') {
277
- --_posVisible: var(--_posHidden);
278
- }
279
- }
280
-
281
- &.major,
282
- &.minor {
283
- @include bp.above('aside2') {
284
- --_posHidden: var(--_posBehindFullLayout);
285
- }
286
- }
287
- }
288
-
289
- .asideSwitch {
290
- --iconSize: 36px;
291
- --p: 12px;
292
- --m: var(--gapBig);
293
-
294
- //
295
-
296
- position: fixed;
297
- z-index: z.$asideSwitch;
298
- bottom: 0;
299
-
300
- font-size: var(--iconSize);
301
- padding: var(--p);
302
- margin: var(--gapBig);
303
-
304
- background: #8c8c8c;
305
- color: var(--bgMain);
306
- box-shadow: 0px 0px 20px 20px var(--bgMain);
307
- opacity: 0.95;
308
-
309
- cursor: pointer;
310
-
311
- @include transition(left, right, opacity, box-shadow);
312
-
313
- @include dark {
314
- background: #8c8c8c;
315
- }
316
-
317
- &:hover {
318
- opacity: 1;
319
- }
320
-
321
- &.minor {
322
- svg {
323
- transform: scaleX(-1);
324
- }
325
- }
326
-
327
- @mixin invisible {
328
- box-shadow: none; /* TODO: Fix missing fade-out transition! */
329
- }
330
-
331
- //
332
-
333
- @include ___switchPositionLogic;
334
-
335
- &:not(.visible) {
336
- @include invisible;
337
- }
338
- &.major {
339
- @include bp.above('aside1') {
340
- @include invisible;
341
- }
342
- }
343
- @include bp.above('aside2') {
344
- @include invisible;
345
- }
346
- }
347
-
348
- //
349
- //
350
- //
351
-
352
- .innerShadow {
353
- position: absolute;
354
- z-index: 9999;
355
- top: 0;
356
- width: 30px;
357
- height: 100%;
358
- pointer-events: none;
359
- touch-action: none;
360
- box-shadow: -1px 0px 2px 0px
361
- color-mix(in srgb, var(--invert), transparent 93%) inset;
362
-
363
- @include transition(box-shadow);
364
-
365
- .major & {
366
- right: 0;
367
-
368
- @include bp.below('aside1') {
369
- box-shadow: none;
370
- }
371
- }
372
-
373
- .minor & {
374
- left: 0;
375
- transform: scaleX(-1);
376
-
377
- @include bp.below('aside2') {
378
- box-shadow: none;
379
- }
380
- }
381
- }
382
- </style>
1
+ <script lang="ts" setup>
2
+ import { previewVisible } from '@app/scripts/preview/state';
3
+ import {
4
+ AsideType,
5
+ clickTargets,
6
+ forcedAside,
7
+ switchVisible,
8
+ } from '@app/scripts/aside';
9
+
10
+ const props = defineProps<{
11
+ type: AsideType;
12
+ }>();
13
+
14
+ const $style = useCssModule();
15
+
16
+ const switchElement = useTemplateRef('switchElement');
17
+ const asideElement = useTemplateRef('asideElement');
18
+
19
+ const mounted = ref(false);
20
+
21
+ const canShowSwitch = computed(
22
+ () =>
23
+ mounted.value &&
24
+ switchVisible.value &&
25
+ !forcedAside.value &&
26
+ !previewVisible.value,
27
+ );
28
+
29
+ const asideForceVisible = computed(
30
+ () => props.type === forcedAside.value && !previewVisible.value,
31
+ );
32
+
33
+ const typeClass = props.type === AsideType.Major ? $style.major : $style.minor;
34
+
35
+ onMounted(() => {
36
+ mounted.value = true;
37
+
38
+ clickTargets[props.type].push(
39
+ ...[switchElement.value!, asideElement.value!],
40
+ );
41
+ });
42
+
43
+ function switchClick() {
44
+ forcedAside.value = props.type;
45
+ }
46
+ </script>
47
+
48
+ <template>
49
+ <div
50
+ ref="switchElement"
51
+ @click="switchClick"
52
+ :class="[
53
+ $style.asideSwitch,
54
+ typeClass,
55
+ canShowSwitch ? $style.visible : '',
56
+ ]"
57
+ >
58
+ <MyIcon name="aside-open" />
59
+ </div>
60
+
61
+ <aside
62
+ ref="asideElement"
63
+ :class="[
64
+ $style.aside,
65
+ typeClass,
66
+ asideForceVisible ? $style.forceVisible : '',
67
+ ]"
68
+ >
69
+ <slot></slot>
70
+ <div :class="$style.innerShadow"></div>
71
+ </aside>
72
+ </template>
73
+
74
+ <style lang="scss" module>
75
+ @use '$/def/bp';
76
+ @use '$/def/z';
77
+ @use '$/def/size';
78
+
79
+ // !!
80
+ // !!
81
+ // !! Rewrite the whole logic based on coords relative to main content. It will be 1000% easier. See how <Preview> is implemented!
82
+ // !!
83
+ // !!
84
+
85
+ @function maxLayoutEdge() {
86
+ @return calc(
87
+ 50% - min(var(--wMainMax), calc(100% - 2 * var(--wAside))) / 2
88
+ );
89
+ }
90
+
91
+ @mixin ___asidePositionLogic {
92
+ /* For God's sake, don't ever touch this code */
93
+
94
+ --_pos: var(--_posHidden); // Start with hidden position (mobile first)
95
+
96
+ --_posHidden: calc(-1 * var(--wAside));
97
+ --_posVisible: var(--_posVisibleCorner);
98
+
99
+ --_posVisibleCorner: 0;
100
+ --_posVisibleMax: calc(#{maxLayoutEdge()} - var(--wAside));
101
+
102
+ &.major.forceVisible,
103
+ &.minor.forceVisible {
104
+ --_pos: var(--_posVisible); // Always visible when forced
105
+ }
106
+
107
+ &.major {
108
+ left: var(--_pos);
109
+
110
+ @include bp.above('aside1') {
111
+ --_posVisible: var(--_posVisibleCorner);
112
+ --_pos: var(--_posVisible);
113
+ }
114
+
115
+ @include bp.above('aside2') {
116
+ --_posVisible: var(--_posVisibleMax);
117
+ }
118
+ }
119
+
120
+ &.minor {
121
+ right: var(--_pos);
122
+
123
+ @include bp.above('aside2') {
124
+ --_posVisible: var(--_posVisibleMax);
125
+ --_pos: var(--_posVisible);
126
+ }
127
+ }
128
+ }
129
+
130
+ .aside {
131
+ //
132
+ // Global
133
+ //
134
+
135
+ position: fixed;
136
+ z-index: z.$aside;
137
+ top: 0;
138
+
139
+ width: var(--wAside);
140
+ height: 100dvh;
141
+
142
+ background: var(--bgAside);
143
+ backdrop-filter: initial;
144
+
145
+ --shadowColor: #{rgba(black, 0.065)};
146
+
147
+ @include transition(left, right, background, backdrop-filter, box-shadow);
148
+
149
+ @include dark {
150
+ --shadowColor: #{rgba(white, 0.075)};
151
+ }
152
+
153
+ //
154
+
155
+ @include ___asidePositionLogic;
156
+
157
+ //
158
+ // Global States
159
+ //
160
+
161
+ @mixin asideVisible {
162
+ }
163
+
164
+ @mixin asideHidden {
165
+ }
166
+
167
+ @mixin asideModal {
168
+ background: color-mix(
169
+ in srgb,
170
+ color-mix(in srgb, var(--bgAside), black 0%),
171
+ transparent 22%
172
+ );
173
+ backdrop-filter: blur(10px);
174
+
175
+ box-shadow:
176
+ 0px 0px 15px 15px rgba(0, 0, 0, 0.1),
177
+ 0px 0px 8px 0px rgba(0, 0, 0, 0.1);
178
+
179
+ @include dark {
180
+ background: color-mix(in srgb, var(--bgAside), transparent 10%);
181
+
182
+ box-shadow:
183
+ 0px 0px 15px 15px rgba(255, 255, 255, 0.025),
184
+ 0px 0px 8px 0px rgba(255, 255, 255, 0.03);
185
+ }
186
+ }
187
+
188
+ &.major {
189
+ //
190
+ // Major Aside
191
+ //
192
+
193
+ box-shadow: -1px 0px 2px 0px var(--shadowColor);
194
+
195
+ @include bp.above('aside1') {
196
+ //
197
+ // Major Visible
198
+ //
199
+
200
+ @include asideVisible;
201
+ }
202
+
203
+ @include bp.below('aside1') {
204
+ //
205
+ // Major Hidden
206
+ //
207
+
208
+ @include asideHidden;
209
+
210
+ &.forceVisible {
211
+ //
212
+ // Major Modal
213
+ //
214
+
215
+ @include asideModal;
216
+ }
217
+ }
218
+ }
219
+
220
+ &.minor {
221
+ //
222
+ // Minor Aside
223
+ //
224
+
225
+ box-shadow: 1px 0px 2px 0px var(--shadowColor);
226
+
227
+ @include bp.above('aside2') {
228
+ //
229
+ // Minor Visible
230
+ //
231
+
232
+ @include asideVisible;
233
+ }
234
+
235
+ @include bp.below('aside2') {
236
+ //
237
+ // Minor Hidden
238
+ //
239
+
240
+ @include asideHidden;
241
+
242
+ &.forceVisible {
243
+ //
244
+ // Minor Modal
245
+ //
246
+
247
+ @include asideModal;
248
+ }
249
+ }
250
+ }
251
+ }
252
+
253
+ //
254
+ //
255
+ //
256
+
257
+ @mixin ___switchPositionLogic {
258
+ /* For God's sake, don't ever touch this code */
259
+
260
+ --_switchSize: calc(var(--iconSize) + 2 * var(--p) + var(--m));
261
+
262
+ --_pos: var(--_posHidden);
263
+
264
+ --_posVisible: calc(var(--_posHidden) + var(--_switchSize));
265
+ --_posHidden: var(--_posBehindCorner);
266
+
267
+ --_posBehindCorner: calc(-1 * var(--_switchSize));
268
+ --_posBehindMajorAside: calc(var(--wAside) - var(--_switchSize));
269
+ --_posBehindFullLayout: calc(#{maxLayoutEdge()} - var(--_switchSize));
270
+
271
+ &.visible {
272
+ --_pos: var(--_posVisible);
273
+ }
274
+
275
+ &.major {
276
+ left: var(--_pos);
277
+
278
+ @include bp.above('aside1') {
279
+ --_posHidden: var(--_posBehindMajorAside);
280
+ --_posVisible: var(--_posHidden);
281
+ }
282
+ }
283
+
284
+ &.minor {
285
+ right: var(--_pos);
286
+
287
+ @include bp.above('aside2') {
288
+ --_posVisible: var(--_posHidden);
289
+ }
290
+ }
291
+
292
+ &.major,
293
+ &.minor {
294
+ @include bp.above('aside2') {
295
+ --_posHidden: var(--_posBehindFullLayout);
296
+ }
297
+ }
298
+ }
299
+
300
+ .asideSwitch {
301
+ --iconSize: 36px;
302
+ --p: 12px;
303
+ --m: var(--gapBig);
304
+
305
+ //
306
+
307
+ position: fixed;
308
+ z-index: z.$asideSwitch;
309
+ bottom: 0;
310
+
311
+ font-size: var(--iconSize);
312
+ padding: var(--p);
313
+ margin: var(--gapBig);
314
+
315
+ background: #8c8c8c;
316
+ color: var(--bgMain);
317
+ box-shadow: 0px 0px 20px 20px var(--bgMain);
318
+ opacity: 0.95;
319
+
320
+ cursor: pointer;
321
+
322
+ @include transition(left, right, opacity, box-shadow);
323
+
324
+ @include dark {
325
+ background: #8c8c8c;
326
+ }
327
+
328
+ &:hover {
329
+ opacity: 1;
330
+ }
331
+
332
+ &.minor {
333
+ svg {
334
+ transform: scaleX(-1);
335
+ }
336
+ }
337
+
338
+ @mixin invisible {
339
+ box-shadow: none; /* TODO: Fix missing fade-out transition! */
340
+ }
341
+
342
+ //
343
+
344
+ @include ___switchPositionLogic;
345
+
346
+ &:not(.visible) {
347
+ @include invisible;
348
+ }
349
+ &.major {
350
+ @include bp.above('aside1') {
351
+ @include invisible;
352
+ }
353
+ }
354
+ @include bp.above('aside2') {
355
+ @include invisible;
356
+ }
357
+ }
358
+
359
+ //
360
+ //
361
+ //
362
+
363
+ .innerShadow {
364
+ position: absolute;
365
+ z-index: 9999;
366
+ top: 0;
367
+ width: 30px;
368
+ height: 100%;
369
+ pointer-events: none;
370
+ touch-action: none;
371
+ box-shadow: -1px 0px 2px 0px
372
+ color-mix(in srgb, var(--invert), transparent 93%) inset;
373
+
374
+ @include transition(box-shadow);
375
+
376
+ .major & {
377
+ right: 0;
378
+
379
+ @include bp.below('aside1') {
380
+ box-shadow: none;
381
+ }
382
+ }
383
+
384
+ .minor & {
385
+ left: 0;
386
+ transform: scaleX(-1);
387
+
388
+ @include bp.below('aside2') {
389
+ box-shadow: none;
390
+ }
391
+ }
392
+ }
393
+ </style>