@turnipxenon/pineapple 3.0.0 → 3.1.0-alpha.1
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/dist/components/blog_template/BlogTemplate.svelte +1 -1
- package/dist/components/blog_template/BlogTemplate.svelte.d.ts +1 -1
- package/dist/components/blog_template/BlogTemplateInner.svelte +1 -1
- package/dist/components/blog_template/BlogTemplateInner.svelte.d.ts +1 -1
- package/dist/components/dialog_manager/DialogMangerInit.d.ts +1 -1
- package/dist/components/dialog_manager/IDialogManager.d.ts +1 -1
- package/dist/components/dialog_overlay/DialogOverlay.svelte +127 -17
- package/dist/components/layouts/SeaweedBaseLayout.svelte +0 -6
- package/dist/components/pineapple/PineappleBaseLayout.svelte +0 -19
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/styles/app.css +9 -14
- package/dist/ui/components/ModalBase.svelte +74 -74
- package/dist/ui/components/accordion/PinyaAccordion.svelte +20 -20
- package/dist/ui/components/accordion/PinyaAccordionItem.svelte +28 -28
- package/dist/ui/elements/CodeBlock/CodeBlock.svelte +64 -64
- package/dist/ui/elements/ImageIcon.svelte +53 -53
- package/dist/ui/elements/{pinya-card/component.svelte → PinyaCard/PinyaCard.svelte} +21 -20
- package/dist/ui/elements/PinyaCard/PinyaCard.svelte.d.ts +7 -0
- package/dist/ui/elements/PinyaCard/index.d.ts +2 -0
- package/dist/ui/elements/PinyaCard/index.js +2 -0
- package/dist/ui/elements/Placeholder.svelte +17 -17
- package/dist/ui/elements/TextLink.svelte +16 -16
- package/dist/ui/elements/index.d.ts +1 -1
- package/dist/ui/elements/index.js +1 -1
- package/dist/ui/elements/pinya-combobox/PinyaCombobox.svelte +34 -34
- package/dist/ui/elements/text-chip/TextChip.svelte +14 -14
- package/dist/{components/navigation_component → ui/modules/NavigationMenu}/NavigationControl.svelte +24 -20
- package/dist/{components/navigation_component/NavigationComponent.svelte → ui/modules/NavigationMenu/NavigationMenu.svelte} +69 -43
- package/dist/{components/navigation_component/NavigationComponent.svelte.d.ts → ui/modules/NavigationMenu/NavigationMenu.svelte.d.ts} +6 -6
- package/dist/{components/navigation_component → ui/modules/NavigationMenu}/PageMeta.d.ts +4 -4
- package/dist/ui/modules/NavigationMenu/index.d.ts +2 -0
- package/dist/ui/modules/NavigationMenu/index.js +2 -0
- package/dist/ui/modules/index.d.ts +1 -1
- package/dist/ui/modules/index.js +1 -1
- package/dist/ui/modules/modals/general-settings/GeneralSettingsModal.svelte +109 -109
- package/dist/ui/modules/modals/general-settings/LanguagePicker.svelte +42 -42
- package/dist/ui/modules/projects/Pengi.svelte +61 -61
- package/dist/ui/modules/projects/ThisWebpage.svelte +10 -8
- package/dist/ui/templates/PinyaPageLayout/runes.svelte.d.ts +2 -0
- package/dist/ui/{modules/seaweed → templates/SeaweedLayout}/ChumBucket.svelte +1 -1
- package/dist/ui/templates/SeaweedLayout/EntryGroup.svelte +65 -88
- package/dist/ui/templates/SeaweedLayout/ProjectComponentProps.d.ts +1 -0
- package/dist/ui/templates/SeaweedLayout/ProjectGroupConfig.svelte +316 -316
- package/dist/ui/templates/SeaweedLayout/SeaweedLayout.md +3 -3
- package/dist/ui/templates/SeaweedLayout/SeaweedLayout.svelte +278 -276
- package/dist/ui/templates/SeaweedLayout/props.d.ts +2 -2
- package/dist/ui/templates/confirmation-modal/component.svelte +46 -46
- package/package.json +1 -1
- package/src/lib/styles/app.css +9 -14
- package/dist/components/navigation_component/index.d.ts +0 -2
- package/dist/components/navigation_component/index.js +0 -3
- package/dist/ui/elements/pinya-card/component.svelte.d.ts +0 -7
- package/dist/ui/elements/pinya-card/index.d.ts +0 -2
- package/dist/ui/elements/pinya-card/index.js +0 -2
- package/dist/ui/modules/seaweed/index.d.ts +0 -3
- package/dist/ui/modules/seaweed/index.js +0 -4
- /package/dist/ui/elements/{pinya-card/props.d.ts → PinyaCard/PinyaCardProps.d.ts} +0 -0
- /package/dist/ui/elements/{pinya-card/props.js → PinyaCard/PinyaCardProps.js} +0 -0
- /package/dist/{components/navigation_component → ui/modules/NavigationMenu}/NavigationControl.svelte.d.ts +0 -0
- /package/dist/{components/navigation_component → ui/modules/NavigationMenu}/PageMeta.js +0 -0
- /package/dist/ui/{modules/seaweed → templates/SeaweedLayout}/ChumBucket.svelte.d.ts +0 -0
|
@@ -1,20 +1,19 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import NavigationControl from "./NavigationControl.svelte";
|
|
3
3
|
import { parsePageMeta, type ParsePageMetaCompareFn } from "./PageMeta";
|
|
4
|
-
import { Card } from "
|
|
5
|
-
import {
|
|
4
|
+
import { Card } from "../../../components/index";
|
|
5
|
+
import { PinyaCard } from "../../elements/index";
|
|
6
|
+
import { localizeHref } from "../../../paraglide/runtime.js";
|
|
6
7
|
|
|
7
|
-
|
|
8
|
-
|
|
9
8
|
interface Props {
|
|
10
9
|
fileList: Record<string, unknown>;
|
|
11
10
|
jsonList: Record<string, unknown>;
|
|
12
11
|
title?: string | undefined;
|
|
13
|
-
imageMap?:
|
|
12
|
+
imageMap?: Map<string, string>;
|
|
14
13
|
shouldAllowControl?: boolean;
|
|
15
14
|
/**
|
|
16
|
-
|
|
17
|
-
|
|
15
|
+
* Should include a slash before and after the path
|
|
16
|
+
*/
|
|
18
17
|
parentSubpath: string;
|
|
19
18
|
allowUpperControl?: boolean;
|
|
20
19
|
compareFn?: undefined | ParsePageMetaCompareFn;
|
|
@@ -42,60 +41,65 @@
|
|
|
42
41
|
|
|
43
42
|
<div class="navigation-wrapper">
|
|
44
43
|
{#if (title)}
|
|
45
|
-
<
|
|
46
|
-
|
|
47
|
-
|
|
44
|
+
<div>
|
|
45
|
+
<PinyaCard widthClass="">
|
|
46
|
+
<h1 class="navigation-title">
|
|
48
47
|
{title}
|
|
49
48
|
</h1>
|
|
50
|
-
|
|
51
|
-
</
|
|
49
|
+
</PinyaCard>
|
|
50
|
+
</div>
|
|
52
51
|
{/if}
|
|
53
52
|
|
|
54
53
|
{#if allowUpperControl && shouldAllowControl}
|
|
55
|
-
<NavigationControl
|
|
56
|
-
|
|
57
|
-
|
|
54
|
+
<NavigationControl
|
|
55
|
+
bind:currentIndex={currentIndex}
|
|
56
|
+
contentLength={pageFlatList.length}
|
|
57
|
+
bind:pageSize={pageSize}></NavigationControl
|
|
58
|
+
>
|
|
58
59
|
{/if}
|
|
59
60
|
|
|
60
61
|
<div class="navigation-component">
|
|
61
62
|
<!-- all the misc routes-->
|
|
62
|
-
{#each visiblePages as pageMeta}
|
|
63
|
+
{#each visiblePages as pageMeta (pageMeta.title)}
|
|
63
64
|
{@const fullPath=`${parentSubpath}${pageMeta.relativeLink}`}
|
|
64
|
-
<
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
<h2>{pageMeta.title}</h2>
|
|
73
|
-
<p>Published: {pageMeta.datePublished ?? "N/A"} | Last updated: {pageMeta.lastUpdated ?? "N/A"}</p>
|
|
74
|
-
<p>{pageMeta.description ?? ""}</p>
|
|
75
|
-
Tags:
|
|
76
|
-
{#if (pageMeta.tags && pageMeta.tags.length !== 0)}
|
|
77
|
-
{#each pageMeta.tags as tagValue}
|
|
78
|
-
<span class="badge variant-filled tag-container">{tagValue}</span>
|
|
79
|
-
{/each}
|
|
80
|
-
{:else}
|
|
81
|
-
None
|
|
65
|
+
<a href={localizeHref(fullPath)} class="card-anchor">
|
|
66
|
+
<PinyaCard
|
|
67
|
+
widthClass="w-full"
|
|
68
|
+
className="navigation-element"
|
|
69
|
+
>
|
|
70
|
+
{#if pageMeta.imageUrl}
|
|
71
|
+
<img src={pageMeta.imageUrl}
|
|
72
|
+
alt={pageMeta.imageAlt ?? "placeholder alt text please replace me or report me!"} />
|
|
82
73
|
{/if}
|
|
83
|
-
|
|
84
|
-
|
|
74
|
+
<section class="blurb-text">
|
|
75
|
+
<h2>{pageMeta.title}</h2>
|
|
76
|
+
<p>Published: {pageMeta.datePublished ?? "N/A"} | Last updated: {pageMeta.lastUpdated ?? "N/A"}</p>
|
|
77
|
+
<p>{pageMeta.description ?? ""}</p>
|
|
78
|
+
Tags:
|
|
79
|
+
{#if (pageMeta.tags && pageMeta.tags.length !== 0)}
|
|
80
|
+
{#each pageMeta.tags as tagValue, idx (idx)}
|
|
81
|
+
<span class="badge variant-filled tag-container">{tagValue}</span>
|
|
82
|
+
{/each}
|
|
83
|
+
{:else}
|
|
84
|
+
None
|
|
85
|
+
{/if}
|
|
86
|
+
</section>
|
|
87
|
+
</PinyaCard>
|
|
88
|
+
</a>
|
|
85
89
|
{/each}
|
|
86
90
|
|
|
87
91
|
{#if visiblePages.length === 0}
|
|
88
92
|
<Card>
|
|
89
93
|
{#snippet content()}
|
|
90
|
-
|
|
91
|
-
|
|
94
|
+
<p class="default-card">Sorry, no content was found</p>
|
|
95
|
+
{/snippet}
|
|
92
96
|
</Card>
|
|
93
97
|
{/if}
|
|
94
98
|
</div>
|
|
95
99
|
|
|
96
100
|
{#if shouldAllowControl}
|
|
97
101
|
<NavigationControl bind:currentIndex={currentIndex}
|
|
98
|
-
|
|
102
|
+
contentLength={pageFlatList.length}
|
|
99
103
|
bind:pageSize={pageSize}></NavigationControl>
|
|
100
104
|
{/if}
|
|
101
105
|
|
|
@@ -110,13 +114,13 @@
|
|
|
110
114
|
border-radius: var(--theme-rounded-container) var(--theme-rounded-container) 0 0;
|
|
111
115
|
}
|
|
112
116
|
|
|
113
|
-
.navigation-element {
|
|
117
|
+
:global(.navigation-element) {
|
|
114
118
|
flex-direction: column;
|
|
115
119
|
}
|
|
116
120
|
}
|
|
117
121
|
|
|
118
122
|
@container (min-width: 801px) {
|
|
119
|
-
.navigation-element {
|
|
123
|
+
:global(.navigation-element) {
|
|
120
124
|
flex-direction: row;
|
|
121
125
|
}
|
|
122
126
|
|
|
@@ -125,8 +129,8 @@
|
|
|
125
129
|
}
|
|
126
130
|
}
|
|
127
131
|
|
|
128
|
-
.navigation-element {
|
|
129
|
-
|
|
132
|
+
:global(.navigation-element) {
|
|
133
|
+
/* todo: migration */
|
|
130
134
|
/*@apply btn card card-hover bg-surface-100 dark:bg-surface-900;*/
|
|
131
135
|
container-type: inline-size;
|
|
132
136
|
display: flex;
|
|
@@ -166,9 +170,31 @@
|
|
|
166
170
|
flex-direction: column;
|
|
167
171
|
max-width: 1000px;
|
|
168
172
|
width: 100%;
|
|
173
|
+
gap: 1lh;
|
|
169
174
|
}
|
|
170
175
|
|
|
171
176
|
.tag-container {
|
|
172
177
|
margin: 0.25lh 0;
|
|
173
178
|
}
|
|
179
|
+
|
|
180
|
+
a.card-anchor {
|
|
181
|
+
filter: none;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
:global(.navigation-element) {
|
|
185
|
+
transition: 0.3s;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
:global(.navigation-element:hover) {
|
|
189
|
+
transform: scale(1.02);
|
|
190
|
+
box-shadow: 10px 5px 5px rgba(49, 8, 0, 0.25);
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
:global(.dark .navigation-element:hover) {
|
|
194
|
+
box-shadow: 10px 5px 5px rgba(16, 0, 0, 0.35);
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
h2 {
|
|
198
|
+
text-align: start;
|
|
199
|
+
}
|
|
174
200
|
</style>
|
|
@@ -3,17 +3,17 @@ interface Props {
|
|
|
3
3
|
fileList: Record<string, unknown>;
|
|
4
4
|
jsonList: Record<string, unknown>;
|
|
5
5
|
title?: string | undefined;
|
|
6
|
-
imageMap?:
|
|
6
|
+
imageMap?: Map<string, string>;
|
|
7
7
|
shouldAllowControl?: boolean;
|
|
8
8
|
/**
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
* Should include a slash before and after the path
|
|
10
|
+
*/
|
|
11
11
|
parentSubpath: string;
|
|
12
12
|
allowUpperControl?: boolean;
|
|
13
13
|
compareFn?: undefined | ParsePageMetaCompareFn;
|
|
14
14
|
pageSize?: number;
|
|
15
15
|
currentIndex?: number;
|
|
16
16
|
}
|
|
17
|
-
declare const
|
|
18
|
-
type
|
|
19
|
-
export default
|
|
17
|
+
declare const NavigationMenu: import("svelte").Component<Props, {}, "currentIndex" | "pageSize">;
|
|
18
|
+
type NavigationMenu = ReturnType<typeof NavigationMenu>;
|
|
19
|
+
export default NavigationMenu;
|
|
@@ -3,14 +3,14 @@ export interface PageMeta {
|
|
|
3
3
|
description?: string;
|
|
4
4
|
imageAlt?: string;
|
|
5
5
|
/**
|
|
6
|
-
* imageID is an ID that
|
|
6
|
+
* imageID is an ID that NavigationMenu can use to identify imported images
|
|
7
7
|
*
|
|
8
8
|
* To use imageID:
|
|
9
9
|
* 1. Add the imageID entry to the meta.json for the page
|
|
10
10
|
* 2. Create a typescript file with the variable ImageMap: Map<string, string>
|
|
11
11
|
* 3. Add a new entry with your imageID as key, and the image url as the value. Since this is
|
|
12
12
|
* Typescript, you can use import ImageUrl from "./path.png" as you would normally do.N
|
|
13
|
-
* 4. Add ImageMap as an argument to your
|
|
13
|
+
* 4. Add ImageMap as an argument to your NavigationMenu.
|
|
14
14
|
* Overall, this involves four files
|
|
15
15
|
* - Your navigation page: ./+page.svelte
|
|
16
16
|
* - Your image map typescript: ImageMap.ts
|
|
@@ -45,14 +45,14 @@ export interface SimplePageMeta {
|
|
|
45
45
|
description?: string;
|
|
46
46
|
imageAlt?: string;
|
|
47
47
|
/**
|
|
48
|
-
* imageID is an ID that
|
|
48
|
+
* imageID is an ID that NavigationMenu can use to identify imported images
|
|
49
49
|
*
|
|
50
50
|
* To use imageID:
|
|
51
51
|
* 1. Add the imageID entry to the meta.json for the page
|
|
52
52
|
* 2. Create a typescript file with the variable ImageMap: Map<string, string>
|
|
53
53
|
* 3. Add a new entry with your imageID as key, and the image url as the value. Since this is
|
|
54
54
|
* Typescript, you can use import ImageUrl from "./path.png" as you would normally do.N
|
|
55
|
-
* 4. Add ImageMap as an argument to your
|
|
55
|
+
* 4. Add ImageMap as an argument to your NavigationMenu.
|
|
56
56
|
* Overall, this involves four files
|
|
57
57
|
* - Your navigation page: ./+page.svelte
|
|
58
58
|
* - Your image map typescript: ImageMap.ts
|
package/dist/ui/modules/index.js
CHANGED
|
@@ -1,110 +1,110 @@
|
|
|
1
|
-
<script lang="ts">
|
|
2
|
-
import type { ModalProps } from 'svelte-modals';
|
|
3
|
-
import { setMode, userPrefersMode } from 'mode-watcher';
|
|
4
|
-
|
|
5
|
-
import { m } from '../../../../paraglide/messages';
|
|
6
|
-
import ModalBase from '../../../components/ModalBase.svelte';
|
|
7
|
-
import DarkIcon from '../../../../assets/icons/icon-dark-mode.svg';
|
|
8
|
-
import LightIcon from '../../../../assets/icons/icon-light-mode.svg';
|
|
9
|
-
import ConstrastIcon from '../../../../assets/icons/icon-contrast.svg';
|
|
10
|
-
import LanguagePicker from './LanguagePicker.svelte';
|
|
11
|
-
|
|
12
|
-
let props: ModalProps = $props();
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
interface ToggleItem {
|
|
16
|
-
key: 'light' | 'dark' | 'system'
|
|
17
|
-
imageSrc: string,
|
|
18
|
-
label: string,
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
const modes: ToggleItem[] = [
|
|
22
|
-
{ key: 'light', imageSrc: LightIcon, label: 'Light' },
|
|
23
|
-
{ key: 'dark', imageSrc: DarkIcon, label: 'Dark' },
|
|
24
|
-
{ key: 'system', imageSrc: ConstrastIcon, label: 'System' }
|
|
25
|
-
];
|
|
26
|
-
|
|
27
|
-
let selectedItem: ToggleItem = $state(modes[0]);
|
|
28
|
-
|
|
29
|
-
// when mode is edited outside, adjust toggle button
|
|
30
|
-
// do not use runes here because we only want explicit changes outside
|
|
31
|
-
// our control here!
|
|
32
|
-
userPrefersMode.subscribe((value) => {
|
|
33
|
-
const si = modes.find(m => m.key === value);
|
|
34
|
-
if (selectedItem !== si && si) {
|
|
35
|
-
selectedItem = si;
|
|
36
|
-
}
|
|
37
|
-
});
|
|
38
|
-
|
|
39
|
-
// when mode is changed inside the button, adjust the mode
|
|
40
|
-
$effect(() => {
|
|
41
|
-
switch (selectedItem?.key) {
|
|
42
|
-
case 'dark':
|
|
43
|
-
setMode('dark');
|
|
44
|
-
break;
|
|
45
|
-
case 'light':
|
|
46
|
-
setMode('light');
|
|
47
|
-
break;
|
|
48
|
-
case 'system':
|
|
49
|
-
setMode('system');
|
|
50
|
-
break;
|
|
51
|
-
default:
|
|
52
|
-
break;
|
|
53
|
-
}
|
|
54
|
-
});
|
|
55
|
-
</script>
|
|
56
|
-
|
|
57
|
-
<ModalBase {...props}>
|
|
58
|
-
<div class="wrapper">
|
|
59
|
-
<h2>{m.settings()}</h2>
|
|
60
|
-
|
|
61
|
-
<fieldset class="btn-group border-primary-500 border-2 flex-col p-2 md:flex-row">
|
|
62
|
-
<legend class="bg-surface-100-900 pl-4 pr-4">Mode</legend>
|
|
63
|
-
{#each modes as mode (mode)}
|
|
64
|
-
<button
|
|
65
|
-
type="button"
|
|
66
|
-
title={mode.label}
|
|
67
|
-
class={`btn pt-3 pb-3 hover:brightness-125
|
|
68
|
-
${mode.key === selectedItem.key ? 'bg-secondary-400 dark:bg-secondary-800' : 'preset-outlined-primary-300-700'}
|
|
69
|
-
`}
|
|
70
|
-
onclick={() => { setMode(mode.key) }}
|
|
71
|
-
>
|
|
72
|
-
<img
|
|
73
|
-
src={mode.imageSrc}
|
|
74
|
-
aria-hidden="true"
|
|
75
|
-
alt=""
|
|
76
|
-
class={`icon
|
|
77
|
-
${mode.key === selectedItem.key ? 'reverse' : ''}
|
|
78
|
-
`}
|
|
79
|
-
>
|
|
80
|
-
{mode.label}
|
|
81
|
-
</button>
|
|
82
|
-
{/each}
|
|
83
|
-
</fieldset>
|
|
84
|
-
|
|
85
|
-
<LanguagePicker />
|
|
86
|
-
|
|
87
|
-
<div class="actions">
|
|
88
|
-
<button class="btn preset-filled-primary-400-600 text-surface-100" onclick={() => props.close()}
|
|
89
|
-
title="Close modal">
|
|
90
|
-
Close
|
|
91
|
-
</button>
|
|
92
|
-
</div>
|
|
93
|
-
</div>
|
|
94
|
-
</ModalBase>
|
|
95
|
-
|
|
96
|
-
<style>
|
|
97
|
-
.actions {
|
|
98
|
-
display: flex;
|
|
99
|
-
flex-direction: row-reverse;
|
|
100
|
-
margin-top: 1.4lh;
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
.wrapper {
|
|
104
|
-
display: flex;
|
|
105
|
-
flex-direction: column;
|
|
106
|
-
justify-content: start;
|
|
107
|
-
text-align: start;
|
|
108
|
-
gap: 1lh;
|
|
109
|
-
}
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { ModalProps } from 'svelte-modals';
|
|
3
|
+
import { setMode, userPrefersMode } from 'mode-watcher';
|
|
4
|
+
|
|
5
|
+
import { m } from '../../../../paraglide/messages';
|
|
6
|
+
import ModalBase from '../../../components/ModalBase.svelte';
|
|
7
|
+
import DarkIcon from '../../../../assets/icons/icon-dark-mode.svg';
|
|
8
|
+
import LightIcon from '../../../../assets/icons/icon-light-mode.svg';
|
|
9
|
+
import ConstrastIcon from '../../../../assets/icons/icon-contrast.svg';
|
|
10
|
+
import LanguagePicker from './LanguagePicker.svelte';
|
|
11
|
+
|
|
12
|
+
let props: ModalProps = $props();
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
interface ToggleItem {
|
|
16
|
+
key: 'light' | 'dark' | 'system'
|
|
17
|
+
imageSrc: string,
|
|
18
|
+
label: string,
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const modes: ToggleItem[] = [
|
|
22
|
+
{ key: 'light', imageSrc: LightIcon, label: 'Light' },
|
|
23
|
+
{ key: 'dark', imageSrc: DarkIcon, label: 'Dark' },
|
|
24
|
+
{ key: 'system', imageSrc: ConstrastIcon, label: 'System' }
|
|
25
|
+
];
|
|
26
|
+
|
|
27
|
+
let selectedItem: ToggleItem = $state(modes[0]);
|
|
28
|
+
|
|
29
|
+
// when mode is edited outside, adjust toggle button
|
|
30
|
+
// do not use runes here because we only want explicit changes outside
|
|
31
|
+
// our control here!
|
|
32
|
+
userPrefersMode.subscribe((value) => {
|
|
33
|
+
const si = modes.find(m => m.key === value);
|
|
34
|
+
if (selectedItem !== si && si) {
|
|
35
|
+
selectedItem = si;
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
// when mode is changed inside the button, adjust the mode
|
|
40
|
+
$effect(() => {
|
|
41
|
+
switch (selectedItem?.key) {
|
|
42
|
+
case 'dark':
|
|
43
|
+
setMode('dark');
|
|
44
|
+
break;
|
|
45
|
+
case 'light':
|
|
46
|
+
setMode('light');
|
|
47
|
+
break;
|
|
48
|
+
case 'system':
|
|
49
|
+
setMode('system');
|
|
50
|
+
break;
|
|
51
|
+
default:
|
|
52
|
+
break;
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
</script>
|
|
56
|
+
|
|
57
|
+
<ModalBase {...props}>
|
|
58
|
+
<div class="wrapper">
|
|
59
|
+
<h2>{m.settings()}</h2>
|
|
60
|
+
|
|
61
|
+
<fieldset class="btn-group border-primary-500 border-2 flex-col p-2 md:flex-row">
|
|
62
|
+
<legend class="bg-surface-100-900 pl-4 pr-4">Mode</legend>
|
|
63
|
+
{#each modes as mode (mode)}
|
|
64
|
+
<button
|
|
65
|
+
type="button"
|
|
66
|
+
title={mode.label}
|
|
67
|
+
class={`btn pt-3 pb-3 hover:brightness-125
|
|
68
|
+
${mode.key === selectedItem.key ? 'bg-secondary-400 dark:bg-secondary-800' : 'preset-outlined-primary-300-700'}
|
|
69
|
+
`}
|
|
70
|
+
onclick={() => { setMode(mode.key) }}
|
|
71
|
+
>
|
|
72
|
+
<img
|
|
73
|
+
src={mode.imageSrc}
|
|
74
|
+
aria-hidden="true"
|
|
75
|
+
alt=""
|
|
76
|
+
class={`icon
|
|
77
|
+
${mode.key === selectedItem.key ? 'reverse' : ''}
|
|
78
|
+
`}
|
|
79
|
+
>
|
|
80
|
+
{mode.label}
|
|
81
|
+
</button>
|
|
82
|
+
{/each}
|
|
83
|
+
</fieldset>
|
|
84
|
+
|
|
85
|
+
<LanguagePicker />
|
|
86
|
+
|
|
87
|
+
<div class="actions">
|
|
88
|
+
<button class="btn preset-filled-primary-400-600 text-surface-100" onclick={() => props.close()}
|
|
89
|
+
title="Close modal">
|
|
90
|
+
Close
|
|
91
|
+
</button>
|
|
92
|
+
</div>
|
|
93
|
+
</div>
|
|
94
|
+
</ModalBase>
|
|
95
|
+
|
|
96
|
+
<style>
|
|
97
|
+
.actions {
|
|
98
|
+
display: flex;
|
|
99
|
+
flex-direction: row-reverse;
|
|
100
|
+
margin-top: 1.4lh;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
.wrapper {
|
|
104
|
+
display: flex;
|
|
105
|
+
flex-direction: column;
|
|
106
|
+
justify-content: start;
|
|
107
|
+
text-align: start;
|
|
108
|
+
gap: 1lh;
|
|
109
|
+
}
|
|
110
110
|
</style>
|
|
@@ -1,43 +1,43 @@
|
|
|
1
|
-
<script lang="ts">
|
|
2
|
-
import { deLocalizeHref, getLocale, localizeHref } from "../../../../paraglide/runtime";
|
|
3
|
-
import PinyaCombobox from "../../../elements/pinya-combobox/PinyaCombobox.svelte";
|
|
4
|
-
import { appState } from "../../../templates/PinyaPageLayout/runes.svelte";
|
|
5
|
-
|
|
6
|
-
interface ComboxData {
|
|
7
|
-
label: string;
|
|
8
|
-
value: "en" | "fr" | "tl";
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
const comboboxData: ComboxData[] = [
|
|
12
|
-
{ label: "English", value: "en" },
|
|
13
|
-
{ label: "French", value: "fr" },
|
|
14
|
-
{ label: "Tagalog", value: "tl" }
|
|
15
|
-
];
|
|
16
|
-
|
|
17
|
-
let selectedCountry = $state([getLocale()]);
|
|
18
|
-
|
|
19
|
-
interface ValueDetail {
|
|
20
|
-
value: string[];
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
const onValueChange = (e: ValueDetail) => {
|
|
24
|
-
const data = comboboxData.find((d) => d.value === e.value[0]);
|
|
25
|
-
if (data) {
|
|
26
|
-
selectedCountry = [data.value];
|
|
27
|
-
const pathname = deLocalizeHref(location.href);
|
|
28
|
-
location.href = localizeHref(pathname, { locale: data.value });
|
|
29
|
-
}
|
|
30
|
-
};
|
|
31
|
-
|
|
32
|
-
let disabled = $derived(!appState.isLanguagePickerAvailable);
|
|
33
|
-
</script>
|
|
34
|
-
|
|
35
|
-
<PinyaCombobox
|
|
36
|
-
data={comboboxData}
|
|
37
|
-
value={selectedCountry}
|
|
38
|
-
defaultValue={selectedCountry}
|
|
39
|
-
label="Select Language"
|
|
40
|
-
placeholder="Select Language"
|
|
41
|
-
{onValueChange}
|
|
42
|
-
{disabled}
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { deLocalizeHref, getLocale, localizeHref } from "../../../../paraglide/runtime";
|
|
3
|
+
import PinyaCombobox from "../../../elements/pinya-combobox/PinyaCombobox.svelte";
|
|
4
|
+
import { appState } from "../../../templates/PinyaPageLayout/runes.svelte";
|
|
5
|
+
|
|
6
|
+
interface ComboxData {
|
|
7
|
+
label: string;
|
|
8
|
+
value: "en" | "fr" | "tl";
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
const comboboxData: ComboxData[] = [
|
|
12
|
+
{ label: "English", value: "en" },
|
|
13
|
+
{ label: "French", value: "fr" },
|
|
14
|
+
{ label: "Tagalog", value: "tl" }
|
|
15
|
+
];
|
|
16
|
+
|
|
17
|
+
let selectedCountry = $state([getLocale()]);
|
|
18
|
+
|
|
19
|
+
interface ValueDetail {
|
|
20
|
+
value: string[];
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const onValueChange = (e: ValueDetail) => {
|
|
24
|
+
const data = comboboxData.find((d) => d.value === e.value[0]);
|
|
25
|
+
if (data) {
|
|
26
|
+
selectedCountry = [data.value];
|
|
27
|
+
const pathname = deLocalizeHref(location.href);
|
|
28
|
+
location.href = localizeHref(pathname, { locale: data.value });
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
let disabled = $derived(!appState.isLanguagePickerAvailable);
|
|
33
|
+
</script>
|
|
34
|
+
|
|
35
|
+
<PinyaCombobox
|
|
36
|
+
data={comboboxData}
|
|
37
|
+
value={selectedCountry}
|
|
38
|
+
defaultValue={selectedCountry}
|
|
39
|
+
label="Select Language"
|
|
40
|
+
placeholder="Select Language"
|
|
41
|
+
{onValueChange}
|
|
42
|
+
{disabled}
|
|
43
43
|
/>
|