@turnipxenon/pineapple 2.4.29 → 2.4.31
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 +171 -159
- package/.svelte-kit/__package__/components/navigation_component/NavigationComponent.svelte +229 -0
- package/.svelte-kit/__package__/components/navigation_component/NavigationComponent.svelte.d.ts +24 -0
- package/.svelte-kit/__package__/components/navigation_component/NavigationControl.svelte +121 -0
- package/.svelte-kit/__package__/components/navigation_component/NavigationControl.svelte.d.ts +18 -0
- package/.svelte-kit/__package__/components/navigation_component/PageMeta.d.ts +23 -0
- package/.svelte-kit/__package__/components/navigation_component/PageMeta.js +76 -0
- package/.svelte-kit/__package__/components/navigation_component/index.d.ts +2 -0
- package/.svelte-kit/__package__/components/navigation_component/index.js +3 -0
- package/.svelte-kit/__package__/index.d.ts +1 -0
- package/.svelte-kit/__package__/index.js +1 -0
- package/.svelte-kit/generated/client/app.js +19 -3
- package/.svelte-kit/generated/client/nodes/10.js +1 -0
- package/.svelte-kit/generated/client/nodes/11.js +1 -0
- package/.svelte-kit/generated/client/nodes/12.js +1 -0
- package/.svelte-kit/generated/client/nodes/13.js +1 -0
- package/.svelte-kit/generated/client/nodes/14.js +3 -0
- package/.svelte-kit/generated/client/nodes/15.js +3 -0
- package/.svelte-kit/generated/client/nodes/6.js +1 -3
- package/.svelte-kit/generated/client/nodes/7.js +1 -3
- package/.svelte-kit/generated/client/nodes/8.js +1 -1
- package/.svelte-kit/generated/client/nodes/9.js +1 -1
- package/.svelte-kit/generated/server/internal.js +1 -1
- package/.svelte-kit/types/route_meta_data.json +8 -0
- package/.svelte-kit/types/src/routes/$types.d.ts +1 -1
- package/.svelte-kit/types/src/routes/(pineapple)/$types.d.ts +1 -1
- package/.svelte-kit/types/src/routes/(pineapple)/pineapple/(extra-pages)/page1/$types.d.ts +17 -0
- package/.svelte-kit/types/src/routes/(pineapple)/pineapple/(extra-pages)/page2/$types.d.ts +17 -0
- package/.svelte-kit/types/src/routes/(pineapple)/pineapple/(extra-pages)/page3/$types.d.ts +17 -0
- package/.svelte-kit/types/src/routes/(pineapple)/pineapple/(extra-pages)/page3/page5/$types.d.ts +17 -0
- package/.svelte-kit/types/src/routes/(pineapple)/pineapple/(extra-pages)/page3/page6/$types.d.ts +17 -0
- package/.svelte-kit/types/src/routes/(pineapple)/pineapple/(extra-pages)/page3/page7/$types.d.ts +17 -0
- package/.svelte-kit/types/src/routes/(pineapple)/pineapple/(extra-pages)/page3/page7/(test_layout)/page8/$types.d.ts +17 -0
- package/.svelte-kit/types/src/routes/(pineapple)/pineapple/(extra-pages)/page4/$types.d.ts +17 -0
- package/dist/components/navigation_component/NavigationComponent.svelte +229 -0
- package/dist/components/navigation_component/NavigationComponent.svelte.d.ts +24 -0
- package/dist/components/navigation_component/NavigationControl.svelte +121 -0
- package/dist/components/navigation_component/NavigationControl.svelte.d.ts +18 -0
- package/dist/components/navigation_component/PageMeta.d.ts +23 -0
- package/dist/components/navigation_component/PageMeta.js +76 -0
- package/dist/components/navigation_component/index.d.ts +2 -0
- package/dist/components/navigation_component/index.js +3 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/package.json +1 -1
- package/src/lib/components/navigation_component/NavigationComponent.svelte +118 -0
- package/src/lib/components/navigation_component/NavigationControl.svelte +61 -0
- package/src/lib/components/navigation_component/PageMeta.ts +118 -0
- package/src/lib/components/navigation_component/index.ts +4 -0
- package/src/lib/index.ts +1 -0
- package/src/routes/(pineapple)/+page.svelte +1 -1
- package/src/routes/(pineapple)/pineapple/(extra-pages)/page1/+page.svelte +13 -0
- package/src/routes/(pineapple)/pineapple/(extra-pages)/page2/+page.svelte +8 -0
- package/src/routes/(pineapple)/pineapple/(extra-pages)/page3/+page.svelte +8 -0
- package/src/routes/(pineapple)/pineapple/(extra-pages)/page3/page5/+page.svelte +8 -0
- package/src/routes/(pineapple)/pineapple/(extra-pages)/page3/page6/+page.svelte +8 -0
- package/src/routes/(pineapple)/pineapple/(extra-pages)/page3/page7/(test_layout)/page8/+page.svelte +8 -0
- package/src/routes/(pineapple)/pineapple/(extra-pages)/page3/page7/+page.svelte +8 -0
- package/src/routes/(pineapple)/pineapple/(extra-pages)/page4/+page.svelte +7 -0
- package/src/routes/(pineapple)/pineapple/+page.svelte +12 -7
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
<script>import NavigationControl from "./NavigationControl.svelte";
|
|
2
|
+
import { Card, createGoToFunction } from "../..";
|
|
3
|
+
import { parsePageMeta } from "./PageMeta";
|
|
4
|
+
export let title = void 0;
|
|
5
|
+
export let fileList;
|
|
6
|
+
export let parentSubpath;
|
|
7
|
+
export let compareFn;
|
|
8
|
+
export let pageSize = 5;
|
|
9
|
+
export let currentIndex = 0;
|
|
10
|
+
const pageFlatList = parsePageMeta(fileList, compareFn);
|
|
11
|
+
$:
|
|
12
|
+
visiblePages = pageFlatList.slice(currentIndex * pageSize, currentIndex * pageSize + pageSize);
|
|
13
|
+
</script>
|
|
14
|
+
|
|
15
|
+
<div class="navigation-wrapper">
|
|
16
|
+
|
|
17
|
+
<NavigationControl bind:currentIndex={currentIndex}
|
|
18
|
+
bind:contentLength={pageFlatList.length}
|
|
19
|
+
bind:pageSize={pageSize}></NavigationControl>
|
|
20
|
+
|
|
21
|
+
<div class="navigation-component">
|
|
22
|
+
{#if (title)}
|
|
23
|
+
<Card>
|
|
24
|
+
<h1 slot="content" class="default-card navigation-title">
|
|
25
|
+
{title}
|
|
26
|
+
</h1>
|
|
27
|
+
</Card>
|
|
28
|
+
{/if}
|
|
29
|
+
<!-- all the misc routes-->
|
|
30
|
+
{#each visiblePages as pageMeta}
|
|
31
|
+
{@const fullPath=`${parentSubpath}${pageMeta.relativeLink}`}
|
|
32
|
+
<button class="navigation-element"
|
|
33
|
+
title={fullPath}
|
|
34
|
+
on:click={createGoToFunction(fullPath)}>
|
|
35
|
+
{#if pageMeta.image}
|
|
36
|
+
<img src={pageMeta.image} alt={pageMeta.imageAlt ?? "placeholder alt text please replace me or report me!"} />
|
|
37
|
+
{/if}
|
|
38
|
+
<section class="blurb-text">
|
|
39
|
+
<h2>{pageMeta.title}</h2>
|
|
40
|
+
<p>Published: {pageMeta.datePublished ?? "N/A"} | Last updated: {pageMeta.lastUpdated ?? "N/A"}</p>
|
|
41
|
+
<p>{pageMeta.description ?? ""}</p>
|
|
42
|
+
Tags:
|
|
43
|
+
{#if (pageMeta.tags && pageMeta.tags.length !== 0)}
|
|
44
|
+
{#each pageMeta.tags as tagValue}
|
|
45
|
+
<span class="badge variant-filled">{tagValue}</span>
|
|
46
|
+
{/each}
|
|
47
|
+
{:else}
|
|
48
|
+
None
|
|
49
|
+
{/if}
|
|
50
|
+
</section>
|
|
51
|
+
</button>
|
|
52
|
+
{/each}
|
|
53
|
+
|
|
54
|
+
{#if visiblePages.length === 0}
|
|
55
|
+
<Card>
|
|
56
|
+
<p class="default-card" slot="content">Sorry, no content was found</p>
|
|
57
|
+
</Card>
|
|
58
|
+
{/if}
|
|
59
|
+
</div>
|
|
60
|
+
|
|
61
|
+
<NavigationControl bind:currentIndex={currentIndex}
|
|
62
|
+
bind:contentLength={pageFlatList.length}
|
|
63
|
+
bind:pageSize={pageSize}></NavigationControl>
|
|
64
|
+
|
|
65
|
+
</div>
|
|
66
|
+
|
|
67
|
+
<style>
|
|
68
|
+
img {
|
|
69
|
+
height: 20em;
|
|
70
|
+
width: 20em;
|
|
71
|
+
-o-object-fit: cover;
|
|
72
|
+
object-fit: cover;
|
|
73
|
+
padding: var(--theme-border-base);
|
|
74
|
+
border-radius: var(--theme-rounded-container) 0 0 var(--theme-rounded-container);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
@media (max-width: 50rem) {
|
|
78
|
+
img {
|
|
79
|
+
max-height: 20rem;
|
|
80
|
+
width: 100%;
|
|
81
|
+
flex-basis: 100%;
|
|
82
|
+
border-radius: var(--theme-rounded-container) var(--theme-rounded-container) 0 0;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
.navigation-component {
|
|
87
|
+
display: flex;
|
|
88
|
+
flex-direction: column;
|
|
89
|
+
gap: 2em;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
.dark .navigation-element {
|
|
93
|
+
background-color: rgb(var(--color-surface-800));
|
|
94
|
+
--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);
|
|
95
|
+
--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);
|
|
96
|
+
box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);
|
|
97
|
+
--tw-ring-inset: inset;
|
|
98
|
+
--tw-ring-color: rgb(250 250 250 / 0.05);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
.navigation-element:disabled {
|
|
102
|
+
cursor: not-allowed;
|
|
103
|
+
opacity: 0.5;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
.navigation-element:disabled:hover {
|
|
107
|
+
--tw-brightness: brightness(1);
|
|
108
|
+
filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
.navigation-element:disabled:active {
|
|
112
|
+
--tw-scale-x: 1;
|
|
113
|
+
--tw-scale-y: 1;
|
|
114
|
+
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
.navigation-element {
|
|
118
|
+
font-size: 1rem;
|
|
119
|
+
line-height: 1.5rem;
|
|
120
|
+
padding-left: 1.25rem;
|
|
121
|
+
padding-right: 1.25rem;
|
|
122
|
+
padding-top: 9px;
|
|
123
|
+
padding-bottom: 9px;
|
|
124
|
+
white-space: nowrap;
|
|
125
|
+
text-align: center;
|
|
126
|
+
display: inline-flex;
|
|
127
|
+
align-items: center;
|
|
128
|
+
justify-content: center;
|
|
129
|
+
transition-property: all;
|
|
130
|
+
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
|
|
131
|
+
transition-duration: 150ms;
|
|
132
|
+
border-radius: var(--theme-rounded-base);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
.navigation-element > :not([hidden]) ~ :not([hidden]) {
|
|
136
|
+
--tw-space-x-reverse: 0;
|
|
137
|
+
margin-right: calc(0.5rem * var(--tw-space-x-reverse));
|
|
138
|
+
margin-left: calc(0.5rem * calc(1 - var(--tw-space-x-reverse)));
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
.navigation-element:hover {
|
|
142
|
+
--tw-brightness: brightness(1.15);
|
|
143
|
+
filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
.navigation-element:active {
|
|
147
|
+
--tw-scale-x: 95%;
|
|
148
|
+
--tw-scale-y: 95%;
|
|
149
|
+
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
|
|
150
|
+
--tw-brightness: brightness(.9);
|
|
151
|
+
filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
.navigation-element {
|
|
155
|
+
background-color: rgb(var(--color-surface-100));
|
|
156
|
+
--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);
|
|
157
|
+
--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);
|
|
158
|
+
box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);
|
|
159
|
+
--tw-ring-inset: inset;
|
|
160
|
+
--tw-ring-color: rgb(23 23 23 / 0.05);
|
|
161
|
+
border-radius: var(--theme-rounded-container);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
.dark .navigation-element {
|
|
165
|
+
background-color: rgb(var(--color-surface-800));
|
|
166
|
+
--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);
|
|
167
|
+
--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);
|
|
168
|
+
box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);
|
|
169
|
+
--tw-ring-inset: inset;
|
|
170
|
+
--tw-ring-color: rgb(250 250 250 / 0.05);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
a.navigation-element {
|
|
174
|
+
transition-property: all;
|
|
175
|
+
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
|
|
176
|
+
transition-duration: 150ms;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
a.navigation-element:hover {
|
|
180
|
+
--tw-brightness: brightness(1.05);
|
|
181
|
+
filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
.navigation-element {
|
|
185
|
+
transition-property: all;
|
|
186
|
+
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
|
|
187
|
+
transition-duration: 150ms;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
.navigation-element:hover {
|
|
191
|
+
--tw-scale-x: 101%;
|
|
192
|
+
--tw-scale-y: 101%;
|
|
193
|
+
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
|
|
194
|
+
--tw-shadow: 0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1);
|
|
195
|
+
--tw-shadow-colored: 0 20px 25px -5px var(--tw-shadow-color), 0 8px 10px -6px var(--tw-shadow-color);
|
|
196
|
+
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
.navigation-element {
|
|
200
|
+
--tw-bg-opacity: 1;
|
|
201
|
+
background-color: rgb(var(--color-surface-100) / var(--tw-bg-opacity));
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
:is(.dark .navigation-element) {
|
|
205
|
+
--tw-bg-opacity: 1;
|
|
206
|
+
background-color: rgb(var(--color-surface-900) / var(--tw-bg-opacity));
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
.navigation-element {
|
|
210
|
+
display: flex;
|
|
211
|
+
flex-wrap: wrap;
|
|
212
|
+
text-align: start;
|
|
213
|
+
padding: 0;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
.navigation-title {
|
|
217
|
+
text-align: center;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
.blurb-text {
|
|
221
|
+
flex: 1;
|
|
222
|
+
padding: 2em;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
.navigation-wrapper {
|
|
226
|
+
display: flex;
|
|
227
|
+
flex-direction: column;
|
|
228
|
+
}
|
|
229
|
+
</style>
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { SvelteComponent } from "svelte";
|
|
2
|
+
import { type ParsePageMetaCompareFn } from "./PageMeta";
|
|
3
|
+
declare const __propDef: {
|
|
4
|
+
props: {
|
|
5
|
+
title?: string | undefined;
|
|
6
|
+
fileList: Record<string, unknown>;
|
|
7
|
+
/**
|
|
8
|
+
* Should include a slash before and after the path
|
|
9
|
+
*/ parentSubpath: string;
|
|
10
|
+
compareFn: undefined | ParsePageMetaCompareFn;
|
|
11
|
+
pageSize?: number | undefined;
|
|
12
|
+
currentIndex?: number | undefined;
|
|
13
|
+
};
|
|
14
|
+
events: {
|
|
15
|
+
[evt: string]: CustomEvent<any>;
|
|
16
|
+
};
|
|
17
|
+
slots: {};
|
|
18
|
+
};
|
|
19
|
+
export type NavigationComponentProps = typeof __propDef.props;
|
|
20
|
+
export type NavigationComponentEvents = typeof __propDef.events;
|
|
21
|
+
export type NavigationComponentSlots = typeof __propDef.slots;
|
|
22
|
+
export default class NavigationComponent extends SvelteComponent<NavigationComponentProps, NavigationComponentEvents, NavigationComponentSlots> {
|
|
23
|
+
}
|
|
24
|
+
export {};
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
<script>import { onMount } from "svelte";
|
|
2
|
+
export let currentIndex = 0;
|
|
3
|
+
export let contentLength;
|
|
4
|
+
export let pageSize;
|
|
5
|
+
import { Card } from "../..";
|
|
6
|
+
import { page } from "$app/stores";
|
|
7
|
+
import { goto } from "$app/navigation";
|
|
8
|
+
const queryIndex = $page.url.searchParams.get("index");
|
|
9
|
+
if (queryIndex) {
|
|
10
|
+
currentIndex = parseInt(queryIndex) || 0;
|
|
11
|
+
}
|
|
12
|
+
const queryPageSize = $page.url.searchParams.get("pageSize");
|
|
13
|
+
if (queryPageSize) {
|
|
14
|
+
pageSize = parseInt(queryPageSize) || 5;
|
|
15
|
+
}
|
|
16
|
+
const movePage = (isNext) => {
|
|
17
|
+
if (isNext) {
|
|
18
|
+
currentIndex = currentIndex + 1;
|
|
19
|
+
} else {
|
|
20
|
+
currentIndex = currentIndex - 1;
|
|
21
|
+
}
|
|
22
|
+
const query = new URLSearchParams($page.url.searchParams.toString());
|
|
23
|
+
query.set("index", currentIndex.toString());
|
|
24
|
+
goto(`?${query.toString()}`);
|
|
25
|
+
};
|
|
26
|
+
onMount(() => {
|
|
27
|
+
const query = new URLSearchParams($page.url.searchParams.toString());
|
|
28
|
+
query.set("index", currentIndex.toString());
|
|
29
|
+
query.set("pageSize", pageSize.toString());
|
|
30
|
+
goto(`?${query.toString()}`);
|
|
31
|
+
});
|
|
32
|
+
</script>
|
|
33
|
+
|
|
34
|
+
<div class="navigation-control-container">
|
|
35
|
+
<button class="navigation-control-button"
|
|
36
|
+
disabled={currentIndex <= 0}
|
|
37
|
+
on:click={() => {movePage(false)}}>{"<"}</button>
|
|
38
|
+
<Card marginBottom="0"><p slot="content" style="margin: 1em">Page {currentIndex + 1}</p></Card>
|
|
39
|
+
<button class="navigation-control-button"
|
|
40
|
+
disabled={(currentIndex + 1) * pageSize >= contentLength}
|
|
41
|
+
on:click={() => {movePage(true)}}>{">"}</button>
|
|
42
|
+
</div>
|
|
43
|
+
|
|
44
|
+
<style>
|
|
45
|
+
.navigation-control-container {
|
|
46
|
+
display: flex;
|
|
47
|
+
justify-content: space-between;
|
|
48
|
+
margin: 1lh 0;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
:is(.dark .navigation-control-button) {
|
|
52
|
+
--tw-bg-opacity: 1;
|
|
53
|
+
background-color: rgb(var(--color-secondary-500) / var(--tw-bg-opacity));
|
|
54
|
+
color: rgb(var(--on-secondary));
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
.navigation-control-button:disabled {
|
|
58
|
+
cursor: not-allowed;
|
|
59
|
+
opacity: 0.5;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
.navigation-control-button:disabled:hover {
|
|
63
|
+
--tw-brightness: brightness(1);
|
|
64
|
+
filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
.navigation-control-button:disabled:active {
|
|
68
|
+
--tw-scale-x: 1;
|
|
69
|
+
--tw-scale-y: 1;
|
|
70
|
+
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
.navigation-control-button {
|
|
74
|
+
font-size: 1rem;
|
|
75
|
+
line-height: 1.5rem;
|
|
76
|
+
padding-left: 1.25rem;
|
|
77
|
+
padding-right: 1.25rem;
|
|
78
|
+
padding-top: 9px;
|
|
79
|
+
padding-bottom: 9px;
|
|
80
|
+
white-space: nowrap;
|
|
81
|
+
text-align: center;
|
|
82
|
+
display: inline-flex;
|
|
83
|
+
align-items: center;
|
|
84
|
+
justify-content: center;
|
|
85
|
+
transition-property: all;
|
|
86
|
+
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
|
|
87
|
+
transition-duration: 150ms;
|
|
88
|
+
border-radius: var(--theme-rounded-base);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
.navigation-control-button > :not([hidden]) ~ :not([hidden]) {
|
|
92
|
+
--tw-space-x-reverse: 0;
|
|
93
|
+
margin-right: calc(0.5rem * var(--tw-space-x-reverse));
|
|
94
|
+
margin-left: calc(0.5rem * calc(1 - var(--tw-space-x-reverse)));
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
.navigation-control-button:hover {
|
|
98
|
+
--tw-brightness: brightness(1.15);
|
|
99
|
+
filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
.navigation-control-button:active {
|
|
103
|
+
--tw-scale-x: 95%;
|
|
104
|
+
--tw-scale-y: 95%;
|
|
105
|
+
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
|
|
106
|
+
--tw-brightness: brightness(.9);
|
|
107
|
+
filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
.navigation-control-button {
|
|
111
|
+
--tw-bg-opacity: 1;
|
|
112
|
+
background-color: rgb(var(--color-secondary-500) / var(--tw-bg-opacity));
|
|
113
|
+
color: rgb(var(--on-secondary));
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
:is(.dark .navigation-control-button) {
|
|
117
|
+
--tw-bg-opacity: 1;
|
|
118
|
+
background-color: rgb(var(--color-secondary-500) / var(--tw-bg-opacity));
|
|
119
|
+
color: rgb(var(--on-secondary));
|
|
120
|
+
}
|
|
121
|
+
</style>
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { SvelteComponent } from "svelte";
|
|
2
|
+
declare const __propDef: {
|
|
3
|
+
props: {
|
|
4
|
+
currentIndex?: number | undefined;
|
|
5
|
+
contentLength: number;
|
|
6
|
+
pageSize: number;
|
|
7
|
+
};
|
|
8
|
+
events: {
|
|
9
|
+
[evt: string]: CustomEvent<any>;
|
|
10
|
+
};
|
|
11
|
+
slots: {};
|
|
12
|
+
};
|
|
13
|
+
export type NavigationControlProps = typeof __propDef.props;
|
|
14
|
+
export type NavigationControlEvents = typeof __propDef.events;
|
|
15
|
+
export type NavigationControlSlots = typeof __propDef.slots;
|
|
16
|
+
export default class NavigationControl extends SvelteComponent<NavigationControlProps, NavigationControlEvents, NavigationControlSlots> {
|
|
17
|
+
}
|
|
18
|
+
export {};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export interface PageMeta {
|
|
2
|
+
relativeLink: string;
|
|
3
|
+
nestedPages: PageMeta[];
|
|
4
|
+
title: string;
|
|
5
|
+
tags: string[];
|
|
6
|
+
/**
|
|
7
|
+
* Images are only limited to absolute paths (includes files in static folder)
|
|
8
|
+
*/
|
|
9
|
+
image?: string;
|
|
10
|
+
imageAlt?: string;
|
|
11
|
+
description?: string;
|
|
12
|
+
datePublished?: string;
|
|
13
|
+
lastUpdated?: string;
|
|
14
|
+
shouldGroup?: boolean;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* todo: doc
|
|
18
|
+
* @param parentList
|
|
19
|
+
* @param child
|
|
20
|
+
*/
|
|
21
|
+
export declare const findPageMetaParent: (parentList: PageMeta[], child: PageMeta) => boolean;
|
|
22
|
+
export type ParsePageMetaCompareFn = ((a: PageMeta, b: PageMeta) => number);
|
|
23
|
+
export declare const parsePageMeta: (fileList: Record<string, unknown>, compareFn?: ParsePageMetaCompareFn) => PageMeta[];
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* todo: doc
|
|
3
|
+
* @param parentList
|
|
4
|
+
* @param child
|
|
5
|
+
*/
|
|
6
|
+
export const findPageMetaParent = (parentList, child) => {
|
|
7
|
+
let isChild = false;
|
|
8
|
+
parentList.every(parent => {
|
|
9
|
+
if (child.relativeLink.startsWith(`${parent.relativeLink}/`)) {
|
|
10
|
+
const isNestedChild = findPageMetaParent(parent.nestedPages, child);
|
|
11
|
+
if (!isNestedChild) {
|
|
12
|
+
parent.nestedPages.push(child);
|
|
13
|
+
}
|
|
14
|
+
isChild = true;
|
|
15
|
+
return false;
|
|
16
|
+
}
|
|
17
|
+
return true;
|
|
18
|
+
});
|
|
19
|
+
return isChild;
|
|
20
|
+
};
|
|
21
|
+
export const parsePageMeta = (fileList, compareFn) => {
|
|
22
|
+
const pageFlatList = [];
|
|
23
|
+
// save for the future
|
|
24
|
+
// let pageGroupedList: PageMeta[] = [];
|
|
25
|
+
for (const path in fileList) {
|
|
26
|
+
const pathParts = path.split("/");
|
|
27
|
+
pathParts.pop();
|
|
28
|
+
// get title
|
|
29
|
+
const title = pathParts[pathParts.length - 1].replaceAll("-", " ");
|
|
30
|
+
// get url path
|
|
31
|
+
const subPath = pathParts.filter(s => {
|
|
32
|
+
return s !== "." && s.indexOf("(") !== 0;
|
|
33
|
+
});
|
|
34
|
+
// todo: consider
|
|
35
|
+
// subPath.unshift("/misc");
|
|
36
|
+
const meta = {
|
|
37
|
+
relativeLink: subPath.join("/"),
|
|
38
|
+
title,
|
|
39
|
+
tags: [],
|
|
40
|
+
nestedPages: []
|
|
41
|
+
// todo: transform the data in server.ts?
|
|
42
|
+
};
|
|
43
|
+
const body = fileList[path].default;
|
|
44
|
+
// let metadata : undefined | Map<string, string | string[]>;
|
|
45
|
+
if (body.startsWith("<!--")) {
|
|
46
|
+
// todo: absorb more metadata
|
|
47
|
+
const metadata = JSON.parse(body.slice("<!--".length, body.indexOf("-->")));
|
|
48
|
+
meta.title = metadata["title"] ?? meta.title;
|
|
49
|
+
meta.tags = metadata["tags"];
|
|
50
|
+
meta.description = metadata["description"];
|
|
51
|
+
meta.datePublished = metadata["datePublished"];
|
|
52
|
+
meta.lastUpdated = metadata["lastUpdated"];
|
|
53
|
+
meta.shouldGroup = metadata["shouldGroup"];
|
|
54
|
+
meta.image = metadata["image"];
|
|
55
|
+
if (meta.image) {
|
|
56
|
+
meta.imageAlt = metadata["imageAlt"];
|
|
57
|
+
if (!meta.imageAlt) {
|
|
58
|
+
console.warn(`Accessibility issues: image alt missing for image ${meta.image}`);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
pageFlatList.push(meta);
|
|
63
|
+
}
|
|
64
|
+
pageFlatList.sort((a, b) => a.relativeLink.localeCompare(b.relativeLink));
|
|
65
|
+
// find groupings
|
|
66
|
+
// todo: we don't even have use for this yet!
|
|
67
|
+
// pageFlatList.forEach(p => {
|
|
68
|
+
// if (!findPageMetaParent(pageGroupedList, p)) {
|
|
69
|
+
// pageGroupedList.push(p);
|
|
70
|
+
// }
|
|
71
|
+
// });
|
|
72
|
+
if (compareFn) {
|
|
73
|
+
pageFlatList.sort(compareFn);
|
|
74
|
+
}
|
|
75
|
+
return pageFlatList;
|
|
76
|
+
};
|
package/dist/index.d.ts
CHANGED
|
@@ -3,6 +3,7 @@ export { default as SeaweedTemplate } from "./template/Seaweed/SeaweedTemplate.s
|
|
|
3
3
|
export { default as LazyAsset } from "./components/LazyAsset.svelte";
|
|
4
4
|
export { default as Card } from "./components/Card.svelte";
|
|
5
5
|
export * from "./components/overrideable_meta/index";
|
|
6
|
+
export * from "./components/navigation_component/index";
|
|
6
7
|
export * from "./components/dialog_manager/DialogManagerStore";
|
|
7
8
|
export * from "./components/dialog_manager/DialogManager";
|
|
8
9
|
export * from "./components/dialog_manager/DialogUtils";
|
package/dist/index.js
CHANGED
|
@@ -4,6 +4,7 @@ export { default as SeaweedTemplate } from "./template/Seaweed/SeaweedTemplate.s
|
|
|
4
4
|
export { default as LazyAsset } from "./components/LazyAsset.svelte";
|
|
5
5
|
export { default as Card } from "./components/Card.svelte";
|
|
6
6
|
export * from "./components/overrideable_meta/index";
|
|
7
|
+
export * from "./components/navigation_component/index";
|
|
7
8
|
export * from "./components/dialog_manager/DialogManagerStore";
|
|
8
9
|
export * from "./components/dialog_manager/DialogManager";
|
|
9
10
|
export * from "./components/dialog_manager/DialogUtils";
|
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.31",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"dev": "vite dev",
|
|
7
7
|
"build": "npm run check-requirements && vite build && yarn package",
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import NavigationControl from "$pkg/components/navigation_component/NavigationControl.svelte";
|
|
3
|
+
import { Card, createGoToFunction } from "$pkg";
|
|
4
|
+
import { parsePageMeta, type ParsePageMetaCompareFn } from "$pkg/components/navigation_component/PageMeta";
|
|
5
|
+
|
|
6
|
+
export let title: string | undefined = undefined;
|
|
7
|
+
export let fileList: Record<string, unknown>;
|
|
8
|
+
/**
|
|
9
|
+
* Should include a slash before and after the path
|
|
10
|
+
*/
|
|
11
|
+
export let parentSubpath: string;
|
|
12
|
+
export let compareFn: undefined | ParsePageMetaCompareFn;
|
|
13
|
+
export let pageSize = 5;
|
|
14
|
+
export let currentIndex = 0;
|
|
15
|
+
|
|
16
|
+
const pageFlatList = parsePageMeta(fileList, compareFn);
|
|
17
|
+
|
|
18
|
+
$: visiblePages = pageFlatList.slice(currentIndex * pageSize, (currentIndex * pageSize) + pageSize);
|
|
19
|
+
</script>
|
|
20
|
+
|
|
21
|
+
<div class="navigation-wrapper">
|
|
22
|
+
|
|
23
|
+
<NavigationControl bind:currentIndex={currentIndex}
|
|
24
|
+
bind:contentLength={pageFlatList.length}
|
|
25
|
+
bind:pageSize={pageSize}></NavigationControl>
|
|
26
|
+
|
|
27
|
+
<div class="navigation-component">
|
|
28
|
+
{#if (title)}
|
|
29
|
+
<Card>
|
|
30
|
+
<h1 slot="content" class="default-card navigation-title">
|
|
31
|
+
{title}
|
|
32
|
+
</h1>
|
|
33
|
+
</Card>
|
|
34
|
+
{/if}
|
|
35
|
+
<!-- all the misc routes-->
|
|
36
|
+
{#each visiblePages as pageMeta}
|
|
37
|
+
{@const fullPath=`${parentSubpath}${pageMeta.relativeLink}`}
|
|
38
|
+
<button class="navigation-element"
|
|
39
|
+
title={fullPath}
|
|
40
|
+
on:click={createGoToFunction(fullPath)}>
|
|
41
|
+
{#if pageMeta.image}
|
|
42
|
+
<img src={pageMeta.image} alt={pageMeta.imageAlt ?? "placeholder alt text please replace me or report me!"} />
|
|
43
|
+
{/if}
|
|
44
|
+
<section class="blurb-text">
|
|
45
|
+
<h2>{pageMeta.title}</h2>
|
|
46
|
+
<p>Published: {pageMeta.datePublished ?? "N/A"} | Last updated: {pageMeta.lastUpdated ?? "N/A"}</p>
|
|
47
|
+
<p>{pageMeta.description ?? ""}</p>
|
|
48
|
+
Tags:
|
|
49
|
+
{#if (pageMeta.tags && pageMeta.tags.length !== 0)}
|
|
50
|
+
{#each pageMeta.tags as tagValue}
|
|
51
|
+
<span class="badge variant-filled">{tagValue}</span>
|
|
52
|
+
{/each}
|
|
53
|
+
{:else}
|
|
54
|
+
None
|
|
55
|
+
{/if}
|
|
56
|
+
</section>
|
|
57
|
+
</button>
|
|
58
|
+
{/each}
|
|
59
|
+
|
|
60
|
+
{#if visiblePages.length === 0}
|
|
61
|
+
<Card>
|
|
62
|
+
<p class="default-card" slot="content">Sorry, no content was found</p>
|
|
63
|
+
</Card>
|
|
64
|
+
{/if}
|
|
65
|
+
</div>
|
|
66
|
+
|
|
67
|
+
<NavigationControl bind:currentIndex={currentIndex}
|
|
68
|
+
bind:contentLength={pageFlatList.length}
|
|
69
|
+
bind:pageSize={pageSize}></NavigationControl>
|
|
70
|
+
|
|
71
|
+
</div>
|
|
72
|
+
|
|
73
|
+
<style lang="postcss">
|
|
74
|
+
img {
|
|
75
|
+
height: 20em;
|
|
76
|
+
width: 20em;
|
|
77
|
+
object-fit: cover;
|
|
78
|
+
padding: var(--theme-border-base);
|
|
79
|
+
border-radius: var(--theme-rounded-container) 0 0 var(--theme-rounded-container);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
@media (max-width: 50rem) {
|
|
83
|
+
img {
|
|
84
|
+
max-height: 20rem;
|
|
85
|
+
width: 100%;
|
|
86
|
+
flex-basis: 100%;
|
|
87
|
+
border-radius: var(--theme-rounded-container) var(--theme-rounded-container) 0 0;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
.navigation-component {
|
|
92
|
+
display: flex;
|
|
93
|
+
flex-direction: column;
|
|
94
|
+
gap: 2em;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
.navigation-element {
|
|
98
|
+
@apply btn card card-hover bg-surface-100 dark:bg-surface-900;
|
|
99
|
+
display: flex;
|
|
100
|
+
flex-wrap: wrap;
|
|
101
|
+
text-align: start;
|
|
102
|
+
padding: 0;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
.navigation-title {
|
|
106
|
+
text-align: center;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
.blurb-text {
|
|
110
|
+
flex: 1;
|
|
111
|
+
padding: 2em;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
.navigation-wrapper {
|
|
115
|
+
display: flex;
|
|
116
|
+
flex-direction: column;
|
|
117
|
+
}
|
|
118
|
+
</style>
|