@turnipxenon/pineapple 2.4.33 → 2.4.35
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/.idea/workspace.xml +21 -16
- package/.svelte-kit/__package__/components/navigation_component/NavigationComponent.svelte +40 -18
- package/.svelte-kit/__package__/components/navigation_component/PageMeta.d.ts +25 -7
- package/.svelte-kit/__package__/components/navigation_component/PageMeta.js +42 -0
- package/.svelte-kit/generated/server/internal.js +1 -1
- package/dist/components/navigation_component/NavigationComponent.svelte +40 -18
- package/dist/components/navigation_component/PageMeta.d.ts +25 -7
- package/dist/components/navigation_component/PageMeta.js +42 -0
- package/package.json +1 -1
- package/src/lib/components/navigation_component/NavigationComponent.svelte +39 -17
- package/src/lib/components/navigation_component/PageMeta.ts +61 -10
- package/src/routes/(pineapple)/pineapple/(extra-pages)/page1/meta.json +22 -3
- package/src/routes/(pineapple)/pineapple/(extra-pages)/page2/meta.json +6 -3
package/.idea/workspace.xml
CHANGED
|
@@ -4,8 +4,9 @@
|
|
|
4
4
|
<option name="autoReloadType" value="SELECTIVE" />
|
|
5
5
|
</component>
|
|
6
6
|
<component name="ChangeListManager">
|
|
7
|
-
<list default="true" id="accb6ba2-c343-4f84-ad30-6e2d71eceee5" name="Changes" comment="
|
|
8
|
-
<change beforePath="$PROJECT_DIR$/
|
|
7
|
+
<list default="true" id="accb6ba2-c343-4f84-ad30-6e2d71eceee5" name="Changes" comment="Add default sorter for NavigationComponent">
|
|
8
|
+
<change beforePath="$PROJECT_DIR$/src/lib/components/navigation_component/NavigationComponent.svelte" beforeDir="false" afterPath="$PROJECT_DIR$/src/lib/components/navigation_component/NavigationComponent.svelte" afterDir="false" />
|
|
9
|
+
<change beforePath="$PROJECT_DIR$/src/routes/(pineapple)/pineapple/(extra-pages)/page1/meta.json" beforeDir="false" afterPath="$PROJECT_DIR$/src/routes/(pineapple)/pineapple/(extra-pages)/page1/meta.json" afterDir="false" />
|
|
9
10
|
</list>
|
|
10
11
|
<option name="SHOW_DIALOG" value="false" />
|
|
11
12
|
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
|
@@ -120,11 +121,11 @@
|
|
|
120
121
|
<recent name="C:\Users\Pumpkin\Projects\Web\pineapple\src\routes\(pineapple)\pineapple\page3" />
|
|
121
122
|
</key>
|
|
122
123
|
<key name="MoveFile.RECENT_KEYS">
|
|
124
|
+
<recent name="C:\Users\Pumpkin\Projects\Web\pineapple\src\routes\(pineapple)\pineapple\(extra-pages)\page1" />
|
|
125
|
+
<recent name="C:\Users\Pumpkin\Projects\Web\pineapple\src\routes\(pineapple)\pineapple\(extra-pages)\page2" />
|
|
126
|
+
<recent name="C:\Users\Pumpkin\Projects\Web\pineapple\src\routes\(pineapple)\pineapple\(extra-pages)\page3" />
|
|
123
127
|
<recent name="C:\Users\Pumpkin\Projects\Web\pineapple\src\routes\(pineapple)\pineapple\(extra-pages)" />
|
|
124
128
|
<recent name="C:\Users\Pumpkin\Projects\Web\pineapple\src\routes\(pineapple)\pineapple\page3\page7\(test_layout)" />
|
|
125
|
-
<recent name="C:\Users\Pumpkin\Projects\Web\pineapple\src\lib\components\navigation_component" />
|
|
126
|
-
<recent name="C:\Users\Pumpkin\Projects\Web\pineapple\src\lib\components\dialog_overlay" />
|
|
127
|
-
<recent name="C:\Users\Pumpkin\Projects\Web\pineapple\src\lib\components\overrideable_meta" />
|
|
128
129
|
</key>
|
|
129
130
|
<key name="es6.move.members.recent.items">
|
|
130
131
|
<recent name="C:\Users\Pumpkin\Projects\Web\pineapple\src\routes\types\RootLayoutProps.ts" />
|
|
@@ -243,14 +244,10 @@
|
|
|
243
244
|
<workItem from="1711487798169" duration="264000" />
|
|
244
245
|
<workItem from="1711488375110" duration="856000" />
|
|
245
246
|
<workItem from="1711490061858" duration="2823000" />
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
<
|
|
249
|
-
<
|
|
250
|
-
<option name="number" value="00062" />
|
|
251
|
-
<option name="presentableId" value="LOCAL-00062" />
|
|
252
|
-
<option name="project" value="LOCAL" />
|
|
253
|
-
<updated>1710376338512</updated>
|
|
247
|
+
<workItem from="1711492999560" duration="85000" />
|
|
248
|
+
<workItem from="1711493260312" duration="1518000" />
|
|
249
|
+
<workItem from="1711494820779" duration="11000" />
|
|
250
|
+
<workItem from="1711495822479" duration="2498000" />
|
|
254
251
|
</task>
|
|
255
252
|
<task id="LOCAL-00063" summary="Add animation to dynamically added button in social section">
|
|
256
253
|
<option name="closed" value="true" />
|
|
@@ -636,7 +633,15 @@
|
|
|
636
633
|
<option name="project" value="LOCAL" />
|
|
637
634
|
<updated>1711492747331</updated>
|
|
638
635
|
</task>
|
|
639
|
-
<
|
|
636
|
+
<task id="LOCAL-00111" summary="Add default sorter for NavigationComponent">
|
|
637
|
+
<option name="closed" value="true" />
|
|
638
|
+
<created>1711494655396</created>
|
|
639
|
+
<option name="number" value="00111" />
|
|
640
|
+
<option name="presentableId" value="LOCAL-00111" />
|
|
641
|
+
<option name="project" value="LOCAL" />
|
|
642
|
+
<updated>1711494655396</updated>
|
|
643
|
+
</task>
|
|
644
|
+
<option name="localTasksCounter" value="112" />
|
|
640
645
|
<servers />
|
|
641
646
|
</component>
|
|
642
647
|
<component name="TypeScriptGeneratedFilesManager">
|
|
@@ -694,7 +699,6 @@
|
|
|
694
699
|
</option>
|
|
695
700
|
</component>
|
|
696
701
|
<component name="VcsManagerConfiguration">
|
|
697
|
-
<MESSAGE value="Add external link warning stub" />
|
|
698
702
|
<MESSAGE value="Refactor Game Section to separate component" />
|
|
699
703
|
<MESSAGE value="Refactor GameSection out of SeaweedTemplate" />
|
|
700
704
|
<MESSAGE value="Remove unnecessary imports and variables in SeaweedTemplate" />
|
|
@@ -719,6 +723,7 @@
|
|
|
719
723
|
<MESSAGE value="Export NavigationComponent" />
|
|
720
724
|
<MESSAGE value="Add a way to hide an entry in NavigationComponent" />
|
|
721
725
|
<MESSAGE value="Migrate from relying on json instead of comments for meta" />
|
|
722
|
-
<
|
|
726
|
+
<MESSAGE value="Add default sorter for NavigationComponent" />
|
|
727
|
+
<option name="LAST_COMMIT_MESSAGE" value="Add default sorter for NavigationComponent" />
|
|
723
728
|
</component>
|
|
724
729
|
</project>
|
|
@@ -35,7 +35,8 @@ $:
|
|
|
35
35
|
title={fullPath}
|
|
36
36
|
on:click={createGoToFunction(fullPath)}>
|
|
37
37
|
{#if pageMeta.imageUrl}
|
|
38
|
-
<img src={pageMeta.imageUrl}
|
|
38
|
+
<img src={pageMeta.imageUrl}
|
|
39
|
+
alt={pageMeta.imageAlt ?? "placeholder alt text please replace me or report me!"} />
|
|
39
40
|
{/if}
|
|
40
41
|
<section class="blurb-text">
|
|
41
42
|
<h2>{pageMeta.title}</h2>
|
|
@@ -44,7 +45,7 @@ $:
|
|
|
44
45
|
Tags:
|
|
45
46
|
{#if (pageMeta.tags && pageMeta.tags.length !== 0)}
|
|
46
47
|
{#each pageMeta.tags as tagValue}
|
|
47
|
-
<span class="badge variant-filled">{tagValue}</span>
|
|
48
|
+
<span class="badge variant-filled tag-container">{tagValue}</span>
|
|
48
49
|
{/each}
|
|
49
50
|
{:else}
|
|
50
51
|
None
|
|
@@ -67,28 +68,27 @@ $:
|
|
|
67
68
|
</div>
|
|
68
69
|
|
|
69
70
|
<style>
|
|
70
|
-
|
|
71
|
-
height: 20em;
|
|
72
|
-
width: 20em;
|
|
73
|
-
-o-object-fit: cover;
|
|
74
|
-
object-fit: cover;
|
|
75
|
-
padding: var(--theme-border-base);
|
|
76
|
-
border-radius: var(--theme-rounded-container) 0 0 var(--theme-rounded-container);
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
@media (max-width: 50rem) {
|
|
71
|
+
@media (max-width: 800px) {
|
|
80
72
|
img {
|
|
81
73
|
max-height: 20rem;
|
|
82
74
|
width: 100%;
|
|
83
75
|
flex-basis: 100%;
|
|
84
76
|
border-radius: var(--theme-rounded-container) var(--theme-rounded-container) 0 0;
|
|
85
77
|
}
|
|
78
|
+
|
|
79
|
+
.navigation-element {
|
|
80
|
+
flex-direction: column;
|
|
81
|
+
}
|
|
86
82
|
}
|
|
87
83
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
84
|
+
@media (min-width: 801px) {
|
|
85
|
+
.navigation-element {
|
|
86
|
+
flex-direction: row;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
img {
|
|
90
|
+
width: 20em;
|
|
91
|
+
}
|
|
92
92
|
}
|
|
93
93
|
|
|
94
94
|
.dark .navigation-element {
|
|
@@ -210,22 +210,44 @@ $:
|
|
|
210
210
|
|
|
211
211
|
.navigation-element {
|
|
212
212
|
display: flex;
|
|
213
|
-
flex-
|
|
213
|
+
/*flex-direction: row;*/
|
|
214
214
|
text-align: start;
|
|
215
|
+
align-items: flex-start;
|
|
215
216
|
padding: 0;
|
|
216
217
|
}
|
|
217
218
|
|
|
219
|
+
img {
|
|
220
|
+
height: 20em;
|
|
221
|
+
-o-object-fit: cover;
|
|
222
|
+
object-fit: cover;
|
|
223
|
+
padding: var(--theme-border-base);
|
|
224
|
+
border-radius: var(--theme-rounded-container) 0 0 var(--theme-rounded-container);
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
.navigation-component {
|
|
228
|
+
display: flex;
|
|
229
|
+
flex-direction: column;
|
|
230
|
+
gap: 2em;
|
|
231
|
+
}
|
|
232
|
+
|
|
218
233
|
.navigation-title {
|
|
219
234
|
text-align: center;
|
|
220
235
|
}
|
|
221
236
|
|
|
222
237
|
.blurb-text {
|
|
223
|
-
flex: 1;
|
|
224
238
|
padding: 2em;
|
|
239
|
+
flex-grow: 1;
|
|
240
|
+
white-space: initial;
|
|
241
|
+
min-width: 0;
|
|
225
242
|
}
|
|
226
243
|
|
|
227
244
|
.navigation-wrapper {
|
|
228
245
|
display: flex;
|
|
229
246
|
flex-direction: column;
|
|
247
|
+
max-width: 1000px;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
.tag-container {
|
|
251
|
+
margin: 0.25lh 0;
|
|
230
252
|
}
|
|
231
253
|
</style>
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
export interface PageMeta {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
tags: string[];
|
|
2
|
+
datePublished?: string;
|
|
3
|
+
description?: string;
|
|
4
|
+
imageAlt?: string;
|
|
6
5
|
/**
|
|
7
6
|
* imageID is an ID that NavigationComponent can use to identify imported images
|
|
8
7
|
*
|
|
@@ -17,18 +16,29 @@ export interface PageMeta {
|
|
|
17
16
|
* - Your image map typescript: ImageMap.ts
|
|
18
17
|
* - The page you want with an image represented in the navigation: ./topic1/+page.svelte
|
|
19
18
|
* - The meta for that page: ./topic1/meta.json
|
|
19
|
+
*
|
|
20
|
+
* imageID takes precedence over imageURL
|
|
20
21
|
*/
|
|
21
22
|
imageID?: string;
|
|
22
23
|
/**
|
|
23
24
|
* imageURL is only limited to absolute paths (includes files in static folder)
|
|
25
|
+
*
|
|
26
|
+
* if imageID is defined, this will be ignored
|
|
24
27
|
*/
|
|
25
28
|
imageUrl?: string;
|
|
26
|
-
imageAlt?: string;
|
|
27
|
-
description?: string;
|
|
28
|
-
datePublished?: string;
|
|
29
29
|
lastUpdated?: string;
|
|
30
|
+
nestedPages: PageMeta[];
|
|
31
|
+
/**
|
|
32
|
+
* relativeLink is generated automatically. This will be ignored in meta.json.
|
|
33
|
+
*/
|
|
34
|
+
relativeLink: string;
|
|
30
35
|
shouldGroup?: boolean;
|
|
31
36
|
shouldHide?: boolean;
|
|
37
|
+
tags: string[];
|
|
38
|
+
/**
|
|
39
|
+
* title defaults to the directory name if it's an empty string.
|
|
40
|
+
*/
|
|
41
|
+
title: string;
|
|
32
42
|
}
|
|
33
43
|
/**
|
|
34
44
|
* todo: doc
|
|
@@ -38,3 +48,11 @@ export interface PageMeta {
|
|
|
38
48
|
export declare const findPageMetaParent: (parentList: PageMeta[], child: PageMeta) => boolean;
|
|
39
49
|
export type ParsePageMetaCompareFn = ((a: PageMeta, b: PageMeta) => number);
|
|
40
50
|
export declare const parsePageMeta: (fileList: Record<string, unknown>, jsonList: Record<string, unknown>, imageMap: Map<string, string>, compareFn?: ParsePageMetaCompareFn) => PageMeta[];
|
|
51
|
+
/**
|
|
52
|
+
* Prioritizes, in order, lastUpdated, datePublished, has description, then title
|
|
53
|
+
*
|
|
54
|
+
* @param a
|
|
55
|
+
* @param b
|
|
56
|
+
* @constructor
|
|
57
|
+
*/
|
|
58
|
+
export declare const DefaultPageMetaSorter: ParsePageMetaCompareFn;
|
|
@@ -75,6 +75,9 @@ export const parsePageMeta = (fileList, jsonList, imageMap, compareFn) => {
|
|
|
75
75
|
}
|
|
76
76
|
}
|
|
77
77
|
}
|
|
78
|
+
if (meta.shouldHide) {
|
|
79
|
+
continue;
|
|
80
|
+
}
|
|
78
81
|
pageFlatList.push(meta);
|
|
79
82
|
}
|
|
80
83
|
pageFlatList.sort((a, b) => a.relativeLink.localeCompare(b.relativeLink));
|
|
@@ -89,5 +92,44 @@ export const parsePageMeta = (fileList, jsonList, imageMap, compareFn) => {
|
|
|
89
92
|
if (compareFn) {
|
|
90
93
|
pageFlatList.sort(compareFn);
|
|
91
94
|
}
|
|
95
|
+
else {
|
|
96
|
+
pageFlatList.sort(DefaultPageMetaSorter);
|
|
97
|
+
}
|
|
92
98
|
return pageFlatList;
|
|
93
99
|
};
|
|
100
|
+
const AWins = -1;
|
|
101
|
+
const BWins = 1;
|
|
102
|
+
/**
|
|
103
|
+
* Prioritizes, in order, lastUpdated, datePublished, has description, then title
|
|
104
|
+
*
|
|
105
|
+
* @param a
|
|
106
|
+
* @param b
|
|
107
|
+
* @constructor
|
|
108
|
+
*/
|
|
109
|
+
export const DefaultPageMetaSorter = (a, b) => {
|
|
110
|
+
if (a.lastUpdated && !b.lastUpdated) {
|
|
111
|
+
return AWins;
|
|
112
|
+
}
|
|
113
|
+
else if (!a.lastUpdated && b.lastUpdated) {
|
|
114
|
+
return BWins;
|
|
115
|
+
}
|
|
116
|
+
else if (a.lastUpdated && b.lastUpdated) {
|
|
117
|
+
return a.lastUpdated.localeCompare(b.lastUpdated);
|
|
118
|
+
}
|
|
119
|
+
if (a.datePublished && !b.datePublished) {
|
|
120
|
+
return AWins;
|
|
121
|
+
}
|
|
122
|
+
else if (!a.lastUpdated && b.datePublished) {
|
|
123
|
+
return BWins;
|
|
124
|
+
}
|
|
125
|
+
else if (a.datePublished && b.datePublished) {
|
|
126
|
+
return a.datePublished.localeCompare(b.datePublished);
|
|
127
|
+
}
|
|
128
|
+
if (a.description && !b.description) {
|
|
129
|
+
return AWins;
|
|
130
|
+
}
|
|
131
|
+
else if (!a.description && b.description) {
|
|
132
|
+
return BWins;
|
|
133
|
+
}
|
|
134
|
+
return a.title.localeCompare(b.title);
|
|
135
|
+
};
|
|
@@ -21,7 +21,7 @@ export const options = {
|
|
|
21
21
|
app: ({ head, body, assets, nonce, env }) => "<!DOCTYPE html>\n<html lang=\"en\">\n\t<head>\n\t\t<meta charset=\"utf-8\" />\n\t\t<link rel=\"icon\" href=\"" + assets + "/favicon.png\" />\n\t\t<meta name=\"viewport\" content=\"width=device-width\" />\n\t\t" + head + "\n\t</head>\n\n\t<body data-sveltekit-preload-data=\"hover\" data-theme=\"crimson\">\n\t\t<div style=\"display: contents\" class=\"h-full overflow-hidden\">" + body + "</div>\n\t</body>\n</html>\n",
|
|
22
22
|
error: ({ status, message }) => "<!doctype html>\n<html lang=\"en\">\n\t<head>\n\t\t<meta charset=\"utf-8\" />\n\t\t<title>" + message + "</title>\n\n\t\t<style>\n\t\t\tbody {\n\t\t\t\t--bg: white;\n\t\t\t\t--fg: #222;\n\t\t\t\t--divider: #ccc;\n\t\t\t\tbackground: var(--bg);\n\t\t\t\tcolor: var(--fg);\n\t\t\t\tfont-family:\n\t\t\t\t\tsystem-ui,\n\t\t\t\t\t-apple-system,\n\t\t\t\t\tBlinkMacSystemFont,\n\t\t\t\t\t'Segoe UI',\n\t\t\t\t\tRoboto,\n\t\t\t\t\tOxygen,\n\t\t\t\t\tUbuntu,\n\t\t\t\t\tCantarell,\n\t\t\t\t\t'Open Sans',\n\t\t\t\t\t'Helvetica Neue',\n\t\t\t\t\tsans-serif;\n\t\t\t\tdisplay: flex;\n\t\t\t\talign-items: center;\n\t\t\t\tjustify-content: center;\n\t\t\t\theight: 100vh;\n\t\t\t\tmargin: 0;\n\t\t\t}\n\n\t\t\t.error {\n\t\t\t\tdisplay: flex;\n\t\t\t\talign-items: center;\n\t\t\t\tmax-width: 32rem;\n\t\t\t\tmargin: 0 1rem;\n\t\t\t}\n\n\t\t\t.status {\n\t\t\t\tfont-weight: 200;\n\t\t\t\tfont-size: 3rem;\n\t\t\t\tline-height: 1;\n\t\t\t\tposition: relative;\n\t\t\t\ttop: -0.05rem;\n\t\t\t}\n\n\t\t\t.message {\n\t\t\t\tborder-left: 1px solid var(--divider);\n\t\t\t\tpadding: 0 0 0 1rem;\n\t\t\t\tmargin: 0 0 0 1rem;\n\t\t\t\tmin-height: 2.5rem;\n\t\t\t\tdisplay: flex;\n\t\t\t\talign-items: center;\n\t\t\t}\n\n\t\t\t.message h1 {\n\t\t\t\tfont-weight: 400;\n\t\t\t\tfont-size: 1em;\n\t\t\t\tmargin: 0;\n\t\t\t}\n\n\t\t\t@media (prefers-color-scheme: dark) {\n\t\t\t\tbody {\n\t\t\t\t\t--bg: #222;\n\t\t\t\t\t--fg: #ddd;\n\t\t\t\t\t--divider: #666;\n\t\t\t\t}\n\t\t\t}\n\t\t</style>\n\t</head>\n\t<body>\n\t\t<div class=\"error\">\n\t\t\t<span class=\"status\">" + status + "</span>\n\t\t\t<div class=\"message\">\n\t\t\t\t<h1>" + message + "</h1>\n\t\t\t</div>\n\t\t</div>\n\t</body>\n</html>\n"
|
|
23
23
|
},
|
|
24
|
-
version_hash: "
|
|
24
|
+
version_hash: "73g83g"
|
|
25
25
|
};
|
|
26
26
|
|
|
27
27
|
export async function get_hooks() {
|
|
@@ -35,7 +35,8 @@ $:
|
|
|
35
35
|
title={fullPath}
|
|
36
36
|
on:click={createGoToFunction(fullPath)}>
|
|
37
37
|
{#if pageMeta.imageUrl}
|
|
38
|
-
<img src={pageMeta.imageUrl}
|
|
38
|
+
<img src={pageMeta.imageUrl}
|
|
39
|
+
alt={pageMeta.imageAlt ?? "placeholder alt text please replace me or report me!"} />
|
|
39
40
|
{/if}
|
|
40
41
|
<section class="blurb-text">
|
|
41
42
|
<h2>{pageMeta.title}</h2>
|
|
@@ -44,7 +45,7 @@ $:
|
|
|
44
45
|
Tags:
|
|
45
46
|
{#if (pageMeta.tags && pageMeta.tags.length !== 0)}
|
|
46
47
|
{#each pageMeta.tags as tagValue}
|
|
47
|
-
<span class="badge variant-filled">{tagValue}</span>
|
|
48
|
+
<span class="badge variant-filled tag-container">{tagValue}</span>
|
|
48
49
|
{/each}
|
|
49
50
|
{:else}
|
|
50
51
|
None
|
|
@@ -67,28 +68,27 @@ $:
|
|
|
67
68
|
</div>
|
|
68
69
|
|
|
69
70
|
<style>
|
|
70
|
-
|
|
71
|
-
height: 20em;
|
|
72
|
-
width: 20em;
|
|
73
|
-
-o-object-fit: cover;
|
|
74
|
-
object-fit: cover;
|
|
75
|
-
padding: var(--theme-border-base);
|
|
76
|
-
border-radius: var(--theme-rounded-container) 0 0 var(--theme-rounded-container);
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
@media (max-width: 50rem) {
|
|
71
|
+
@media (max-width: 800px) {
|
|
80
72
|
img {
|
|
81
73
|
max-height: 20rem;
|
|
82
74
|
width: 100%;
|
|
83
75
|
flex-basis: 100%;
|
|
84
76
|
border-radius: var(--theme-rounded-container) var(--theme-rounded-container) 0 0;
|
|
85
77
|
}
|
|
78
|
+
|
|
79
|
+
.navigation-element {
|
|
80
|
+
flex-direction: column;
|
|
81
|
+
}
|
|
86
82
|
}
|
|
87
83
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
84
|
+
@media (min-width: 801px) {
|
|
85
|
+
.navigation-element {
|
|
86
|
+
flex-direction: row;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
img {
|
|
90
|
+
width: 20em;
|
|
91
|
+
}
|
|
92
92
|
}
|
|
93
93
|
|
|
94
94
|
.dark .navigation-element {
|
|
@@ -210,22 +210,44 @@ $:
|
|
|
210
210
|
|
|
211
211
|
.navigation-element {
|
|
212
212
|
display: flex;
|
|
213
|
-
flex-
|
|
213
|
+
/*flex-direction: row;*/
|
|
214
214
|
text-align: start;
|
|
215
|
+
align-items: flex-start;
|
|
215
216
|
padding: 0;
|
|
216
217
|
}
|
|
217
218
|
|
|
219
|
+
img {
|
|
220
|
+
height: 20em;
|
|
221
|
+
-o-object-fit: cover;
|
|
222
|
+
object-fit: cover;
|
|
223
|
+
padding: var(--theme-border-base);
|
|
224
|
+
border-radius: var(--theme-rounded-container) 0 0 var(--theme-rounded-container);
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
.navigation-component {
|
|
228
|
+
display: flex;
|
|
229
|
+
flex-direction: column;
|
|
230
|
+
gap: 2em;
|
|
231
|
+
}
|
|
232
|
+
|
|
218
233
|
.navigation-title {
|
|
219
234
|
text-align: center;
|
|
220
235
|
}
|
|
221
236
|
|
|
222
237
|
.blurb-text {
|
|
223
|
-
flex: 1;
|
|
224
238
|
padding: 2em;
|
|
239
|
+
flex-grow: 1;
|
|
240
|
+
white-space: initial;
|
|
241
|
+
min-width: 0;
|
|
225
242
|
}
|
|
226
243
|
|
|
227
244
|
.navigation-wrapper {
|
|
228
245
|
display: flex;
|
|
229
246
|
flex-direction: column;
|
|
247
|
+
max-width: 1000px;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
.tag-container {
|
|
251
|
+
margin: 0.25lh 0;
|
|
230
252
|
}
|
|
231
253
|
</style>
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
export interface PageMeta {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
tags: string[];
|
|
2
|
+
datePublished?: string;
|
|
3
|
+
description?: string;
|
|
4
|
+
imageAlt?: string;
|
|
6
5
|
/**
|
|
7
6
|
* imageID is an ID that NavigationComponent can use to identify imported images
|
|
8
7
|
*
|
|
@@ -17,18 +16,29 @@ export interface PageMeta {
|
|
|
17
16
|
* - Your image map typescript: ImageMap.ts
|
|
18
17
|
* - The page you want with an image represented in the navigation: ./topic1/+page.svelte
|
|
19
18
|
* - The meta for that page: ./topic1/meta.json
|
|
19
|
+
*
|
|
20
|
+
* imageID takes precedence over imageURL
|
|
20
21
|
*/
|
|
21
22
|
imageID?: string;
|
|
22
23
|
/**
|
|
23
24
|
* imageURL is only limited to absolute paths (includes files in static folder)
|
|
25
|
+
*
|
|
26
|
+
* if imageID is defined, this will be ignored
|
|
24
27
|
*/
|
|
25
28
|
imageUrl?: string;
|
|
26
|
-
imageAlt?: string;
|
|
27
|
-
description?: string;
|
|
28
|
-
datePublished?: string;
|
|
29
29
|
lastUpdated?: string;
|
|
30
|
+
nestedPages: PageMeta[];
|
|
31
|
+
/**
|
|
32
|
+
* relativeLink is generated automatically. This will be ignored in meta.json.
|
|
33
|
+
*/
|
|
34
|
+
relativeLink: string;
|
|
30
35
|
shouldGroup?: boolean;
|
|
31
36
|
shouldHide?: boolean;
|
|
37
|
+
tags: string[];
|
|
38
|
+
/**
|
|
39
|
+
* title defaults to the directory name if it's an empty string.
|
|
40
|
+
*/
|
|
41
|
+
title: string;
|
|
32
42
|
}
|
|
33
43
|
/**
|
|
34
44
|
* todo: doc
|
|
@@ -38,3 +48,11 @@ export interface PageMeta {
|
|
|
38
48
|
export declare const findPageMetaParent: (parentList: PageMeta[], child: PageMeta) => boolean;
|
|
39
49
|
export type ParsePageMetaCompareFn = ((a: PageMeta, b: PageMeta) => number);
|
|
40
50
|
export declare const parsePageMeta: (fileList: Record<string, unknown>, jsonList: Record<string, unknown>, imageMap: Map<string, string>, compareFn?: ParsePageMetaCompareFn) => PageMeta[];
|
|
51
|
+
/**
|
|
52
|
+
* Prioritizes, in order, lastUpdated, datePublished, has description, then title
|
|
53
|
+
*
|
|
54
|
+
* @param a
|
|
55
|
+
* @param b
|
|
56
|
+
* @constructor
|
|
57
|
+
*/
|
|
58
|
+
export declare const DefaultPageMetaSorter: ParsePageMetaCompareFn;
|
|
@@ -75,6 +75,9 @@ export const parsePageMeta = (fileList, jsonList, imageMap, compareFn) => {
|
|
|
75
75
|
}
|
|
76
76
|
}
|
|
77
77
|
}
|
|
78
|
+
if (meta.shouldHide) {
|
|
79
|
+
continue;
|
|
80
|
+
}
|
|
78
81
|
pageFlatList.push(meta);
|
|
79
82
|
}
|
|
80
83
|
pageFlatList.sort((a, b) => a.relativeLink.localeCompare(b.relativeLink));
|
|
@@ -89,5 +92,44 @@ export const parsePageMeta = (fileList, jsonList, imageMap, compareFn) => {
|
|
|
89
92
|
if (compareFn) {
|
|
90
93
|
pageFlatList.sort(compareFn);
|
|
91
94
|
}
|
|
95
|
+
else {
|
|
96
|
+
pageFlatList.sort(DefaultPageMetaSorter);
|
|
97
|
+
}
|
|
92
98
|
return pageFlatList;
|
|
93
99
|
};
|
|
100
|
+
const AWins = -1;
|
|
101
|
+
const BWins = 1;
|
|
102
|
+
/**
|
|
103
|
+
* Prioritizes, in order, lastUpdated, datePublished, has description, then title
|
|
104
|
+
*
|
|
105
|
+
* @param a
|
|
106
|
+
* @param b
|
|
107
|
+
* @constructor
|
|
108
|
+
*/
|
|
109
|
+
export const DefaultPageMetaSorter = (a, b) => {
|
|
110
|
+
if (a.lastUpdated && !b.lastUpdated) {
|
|
111
|
+
return AWins;
|
|
112
|
+
}
|
|
113
|
+
else if (!a.lastUpdated && b.lastUpdated) {
|
|
114
|
+
return BWins;
|
|
115
|
+
}
|
|
116
|
+
else if (a.lastUpdated && b.lastUpdated) {
|
|
117
|
+
return a.lastUpdated.localeCompare(b.lastUpdated);
|
|
118
|
+
}
|
|
119
|
+
if (a.datePublished && !b.datePublished) {
|
|
120
|
+
return AWins;
|
|
121
|
+
}
|
|
122
|
+
else if (!a.lastUpdated && b.datePublished) {
|
|
123
|
+
return BWins;
|
|
124
|
+
}
|
|
125
|
+
else if (a.datePublished && b.datePublished) {
|
|
126
|
+
return a.datePublished.localeCompare(b.datePublished);
|
|
127
|
+
}
|
|
128
|
+
if (a.description && !b.description) {
|
|
129
|
+
return AWins;
|
|
130
|
+
}
|
|
131
|
+
else if (!a.description && b.description) {
|
|
132
|
+
return BWins;
|
|
133
|
+
}
|
|
134
|
+
return a.title.localeCompare(b.title);
|
|
135
|
+
};
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@turnipxenon/pineapple",
|
|
3
3
|
"description": "personal package for base styling for other personal projects",
|
|
4
|
-
"version": "2.4.
|
|
4
|
+
"version": "2.4.35",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"dev": "vite dev",
|
|
7
7
|
"build": "npm run check-requirements && vite build && yarn package",
|
|
@@ -43,7 +43,8 @@
|
|
|
43
43
|
title={fullPath}
|
|
44
44
|
on:click={createGoToFunction(fullPath)}>
|
|
45
45
|
{#if pageMeta.imageUrl}
|
|
46
|
-
<img src={pageMeta.imageUrl}
|
|
46
|
+
<img src={pageMeta.imageUrl}
|
|
47
|
+
alt={pageMeta.imageAlt ?? "placeholder alt text please replace me or report me!"} />
|
|
47
48
|
{/if}
|
|
48
49
|
<section class="blurb-text">
|
|
49
50
|
<h2>{pageMeta.title}</h2>
|
|
@@ -52,7 +53,7 @@
|
|
|
52
53
|
Tags:
|
|
53
54
|
{#if (pageMeta.tags && pageMeta.tags.length !== 0)}
|
|
54
55
|
{#each pageMeta.tags as tagValue}
|
|
55
|
-
<span class="badge variant-filled">{tagValue}</span>
|
|
56
|
+
<span class="badge variant-filled tag-container">{tagValue}</span>
|
|
56
57
|
{/each}
|
|
57
58
|
{:else}
|
|
58
59
|
None
|
|
@@ -75,48 +76,69 @@
|
|
|
75
76
|
</div>
|
|
76
77
|
|
|
77
78
|
<style lang="postcss">
|
|
78
|
-
|
|
79
|
-
height: 20em;
|
|
80
|
-
width: 20em;
|
|
81
|
-
object-fit: cover;
|
|
82
|
-
padding: var(--theme-border-base);
|
|
83
|
-
border-radius: var(--theme-rounded-container) 0 0 var(--theme-rounded-container);
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
@media (max-width: 50rem) {
|
|
79
|
+
@media (max-width: 800px) {
|
|
87
80
|
img {
|
|
88
81
|
max-height: 20rem;
|
|
89
82
|
width: 100%;
|
|
90
83
|
flex-basis: 100%;
|
|
91
84
|
border-radius: var(--theme-rounded-container) var(--theme-rounded-container) 0 0;
|
|
92
85
|
}
|
|
86
|
+
|
|
87
|
+
.navigation-element {
|
|
88
|
+
flex-direction: column;
|
|
89
|
+
}
|
|
93
90
|
}
|
|
94
91
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
92
|
+
@media (min-width: 801px) {
|
|
93
|
+
.navigation-element {
|
|
94
|
+
flex-direction: row;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
img {
|
|
98
|
+
width: 20em;
|
|
99
|
+
}
|
|
99
100
|
}
|
|
100
101
|
|
|
101
102
|
.navigation-element {
|
|
102
103
|
@apply btn card card-hover bg-surface-100 dark:bg-surface-900;
|
|
103
104
|
display: flex;
|
|
104
|
-
flex-
|
|
105
|
+
/*flex-direction: row;*/
|
|
105
106
|
text-align: start;
|
|
107
|
+
align-items: flex-start;
|
|
106
108
|
padding: 0;
|
|
107
109
|
}
|
|
108
110
|
|
|
111
|
+
img {
|
|
112
|
+
height: 20em;
|
|
113
|
+
object-fit: cover;
|
|
114
|
+
padding: var(--theme-border-base);
|
|
115
|
+
border-radius: var(--theme-rounded-container) 0 0 var(--theme-rounded-container);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
.navigation-component {
|
|
119
|
+
display: flex;
|
|
120
|
+
flex-direction: column;
|
|
121
|
+
gap: 2em;
|
|
122
|
+
}
|
|
123
|
+
|
|
109
124
|
.navigation-title {
|
|
110
125
|
text-align: center;
|
|
111
126
|
}
|
|
112
127
|
|
|
113
128
|
.blurb-text {
|
|
114
|
-
flex: 1;
|
|
115
129
|
padding: 2em;
|
|
130
|
+
flex-grow: 1;
|
|
131
|
+
white-space: initial;
|
|
132
|
+
min-width: 0;
|
|
116
133
|
}
|
|
117
134
|
|
|
118
135
|
.navigation-wrapper {
|
|
119
136
|
display: flex;
|
|
120
137
|
flex-direction: column;
|
|
138
|
+
max-width: 1000px;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
.tag-container {
|
|
142
|
+
margin: 0.25lh 0;
|
|
121
143
|
}
|
|
122
144
|
</style>
|
|
@@ -1,14 +1,10 @@
|
|
|
1
1
|
import type { RawGlob } from "$pkg/util/util";
|
|
2
2
|
|
|
3
3
|
export interface PageMeta {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
nestedPages: PageMeta[];
|
|
7
|
-
|
|
8
|
-
// defined meta
|
|
9
|
-
title: string; // defaults to directory name
|
|
10
|
-
tags: string[];
|
|
4
|
+
datePublished?: string;
|
|
5
|
+
description?: string;
|
|
11
6
|
|
|
7
|
+
imageAlt?: string; // defaults to directory name
|
|
12
8
|
/**
|
|
13
9
|
* imageID is an ID that NavigationComponent can use to identify imported images
|
|
14
10
|
*
|
|
@@ -23,19 +19,33 @@ export interface PageMeta {
|
|
|
23
19
|
* - Your image map typescript: ImageMap.ts
|
|
24
20
|
* - The page you want with an image represented in the navigation: ./topic1/+page.svelte
|
|
25
21
|
* - The meta for that page: ./topic1/meta.json
|
|
22
|
+
*
|
|
23
|
+
* imageID takes precedence over imageURL
|
|
26
24
|
*/
|
|
27
25
|
imageID?: string;
|
|
28
26
|
|
|
29
27
|
/**
|
|
30
28
|
* imageURL is only limited to absolute paths (includes files in static folder)
|
|
29
|
+
*
|
|
30
|
+
* if imageID is defined, this will be ignored
|
|
31
31
|
*/
|
|
32
32
|
imageUrl?: string;
|
|
33
|
-
|
|
34
|
-
description?: string;
|
|
35
|
-
datePublished?: string;
|
|
33
|
+
|
|
36
34
|
lastUpdated?: string;
|
|
35
|
+
nestedPages: PageMeta[];
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* relativeLink is generated automatically. This will be ignored in meta.json.
|
|
39
|
+
*/
|
|
40
|
+
relativeLink: string;
|
|
37
41
|
shouldGroup?: boolean;
|
|
38
42
|
shouldHide?: boolean;
|
|
43
|
+
tags: string[];
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* title defaults to the directory name if it's an empty string.
|
|
47
|
+
*/
|
|
48
|
+
title: string;
|
|
39
49
|
}
|
|
40
50
|
|
|
41
51
|
/**
|
|
@@ -135,7 +145,10 @@ export const parsePageMeta = (fileList: Record<string, unknown>,
|
|
|
135
145
|
console.warn(`Accessibility issues: image alt missing for image ${meta.imageUrl}`);
|
|
136
146
|
}
|
|
137
147
|
}
|
|
148
|
+
}
|
|
138
149
|
|
|
150
|
+
if (meta.shouldHide) {
|
|
151
|
+
continue;
|
|
139
152
|
}
|
|
140
153
|
|
|
141
154
|
pageFlatList.push(meta);
|
|
@@ -154,7 +167,45 @@ export const parsePageMeta = (fileList: Record<string, unknown>,
|
|
|
154
167
|
|
|
155
168
|
if (compareFn) {
|
|
156
169
|
pageFlatList.sort(compareFn);
|
|
170
|
+
} else {
|
|
171
|
+
pageFlatList.sort(DefaultPageMetaSorter);
|
|
157
172
|
}
|
|
158
173
|
|
|
159
174
|
return pageFlatList;
|
|
175
|
+
};
|
|
176
|
+
|
|
177
|
+
const AWins = -1;
|
|
178
|
+
const BWins = 1;
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* Prioritizes, in order, lastUpdated, datePublished, has description, then title
|
|
182
|
+
*
|
|
183
|
+
* @param a
|
|
184
|
+
* @param b
|
|
185
|
+
* @constructor
|
|
186
|
+
*/
|
|
187
|
+
export const DefaultPageMetaSorter: ParsePageMetaCompareFn = (a, b) => {
|
|
188
|
+
if (a.lastUpdated && !b.lastUpdated) {
|
|
189
|
+
return AWins;
|
|
190
|
+
} else if (!a.lastUpdated && b.lastUpdated) {
|
|
191
|
+
return BWins;
|
|
192
|
+
} else if (a.lastUpdated && b.lastUpdated) {
|
|
193
|
+
return a.lastUpdated.localeCompare(b.lastUpdated);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
if (a.datePublished && !b.datePublished) {
|
|
197
|
+
return AWins;
|
|
198
|
+
} else if (!a.lastUpdated && b.datePublished) {
|
|
199
|
+
return BWins;
|
|
200
|
+
} else if (a.datePublished && b.datePublished) {
|
|
201
|
+
return a.datePublished.localeCompare(b.datePublished);
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
if (a.description && !b.description) {
|
|
205
|
+
return AWins;
|
|
206
|
+
} else if (!a.description && b.description) {
|
|
207
|
+
return BWins;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
return a.title.localeCompare(b.title);
|
|
160
211
|
};
|
|
@@ -1,5 +1,24 @@
|
|
|
1
1
|
{
|
|
2
|
-
"
|
|
3
|
-
"
|
|
4
|
-
"
|
|
2
|
+
"datePublished": "23-01-01",
|
|
3
|
+
"description": "random description but look at Ares! Let's try out a long-ish text to see how things would wrap and all that. I don't know what else to say. Please stream Umpah Umpah.",
|
|
4
|
+
"imageAlt": "Image of Ares being excited",
|
|
5
|
+
"imageID": "testImageID",
|
|
6
|
+
"imageURL": "./favicon.png/?q=imageIDTakesPrecedence",
|
|
7
|
+
"lastUpdated": "23-02-02",
|
|
8
|
+
"shouldGroup": false,
|
|
9
|
+
"shouldHide": false,
|
|
10
|
+
"tags": [
|
|
11
|
+
"random",
|
|
12
|
+
"random8",
|
|
13
|
+
"random2",
|
|
14
|
+
"random5",
|
|
15
|
+
"random5",
|
|
16
|
+
"random5",
|
|
17
|
+
"random5",
|
|
18
|
+
"random5",
|
|
19
|
+
"random5",
|
|
20
|
+
"random5",
|
|
21
|
+
"random4"
|
|
22
|
+
],
|
|
23
|
+
"title": "Custom title for page 1!!!"
|
|
5
24
|
}
|