@turnipxenon/pineapple 5.0.0 → 5.2.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/README.md +11 -11
- package/dist/remoteIndex.remote.d.ts +1 -0
- package/dist/remoteIndex.remote.d.ts.map +1 -1
- package/dist/remoteIndex.remote.js +1 -0
- package/dist/styles/color-tokens.css +2 -0
- package/dist/svelteIndex.svelte.d.ts +3 -0
- package/dist/svelteIndex.svelte.d.ts.map +1 -0
- package/dist/svelteIndex.svelte.js +13 -0
- package/dist/ui/components/FourPartCard.svelte +4 -0
- package/dist/ui/components/SortDropdown.svelte +50 -0
- package/dist/ui/components/SortDropdown.svelte.d.ts +9 -0
- package/dist/ui/components/SortDropdown.svelte.d.ts.map +1 -0
- package/dist/ui/components/TagFilter.svelte +32 -0
- package/dist/ui/components/TagFilter.svelte.d.ts +9 -0
- package/dist/ui/components/TagFilter.svelte.d.ts.map +1 -0
- package/dist/ui/components/accordion/PinyaAccordion.svelte +5 -3
- package/dist/ui/components/accordion/PinyaAccordion.svelte.d.ts.map +1 -1
- package/dist/ui/components/index.d.ts +2 -0
- package/dist/ui/components/index.d.ts.map +1 -1
- package/dist/ui/components/index.js +2 -0
- package/dist/ui/components/project-date-badge/ProjectDateBadge.svelte +160 -0
- package/dist/ui/components/project-date-badge/ProjectDateBadge.svelte.d.ts +5 -0
- package/dist/ui/components/project-date-badge/ProjectDateBadge.svelte.d.ts.map +1 -0
- package/dist/ui/components/project-date-badge/ProjectDateBageProps.d.ts +8 -0
- package/dist/ui/components/project-date-badge/ProjectDateBageProps.d.ts.map +1 -0
- package/dist/ui/components/project-date-badge/ProjectDateBageProps.js +1 -0
- package/dist/ui/elements/CodeBlock/CodeBlock.svelte +12 -6
- package/dist/ui/elements/PineappleSwitch.svelte +2 -2
- package/dist/ui/elements/PineappleSwitch.svelte.d.ts +1 -1
- package/dist/ui/elements/PineappleSwitch.svelte.d.ts.map +1 -1
- package/dist/ui/elements/pinya-combobox/PinyaCombobox.svelte +169 -26
- package/dist/ui/elements/pinya-combobox/PinyaCombobox.svelte.d.ts.map +1 -1
- package/dist/ui/elements/pinya-combobox/PinyaComboboxProps.d.ts +6 -7
- package/dist/ui/elements/pinya-combobox/PinyaComboboxProps.d.ts.map +1 -1
- package/dist/ui/modules/experience/ExampleJob1.svelte +79 -0
- package/dist/ui/modules/experience/ExampleJob1.svelte.d.ts +26 -0
- package/dist/ui/modules/experience/ExampleJob1.svelte.d.ts.map +1 -0
- package/dist/ui/modules/experience/ExampleJob2.svelte +74 -0
- package/dist/ui/modules/experience/ExampleJob2.svelte.d.ts +25 -0
- package/dist/ui/modules/experience/ExampleJob2.svelte.d.ts.map +1 -0
- package/dist/ui/modules/experience/index.d.ts +3 -0
- package/dist/ui/modules/experience/index.d.ts.map +1 -0
- package/dist/ui/modules/experience/index.js +2 -0
- package/dist/ui/modules/modals/general-settings/LanguagePicker.svelte +7 -9
- package/dist/ui/modules/modals/general-settings/LanguagePicker.svelte.d.ts.map +1 -1
- package/dist/ui/modules/projects/Hepcat.svelte +15 -1
- package/dist/ui/modules/projects/Hepcat.svelte.d.ts +5 -1
- package/dist/ui/modules/projects/Hepcat.svelte.d.ts.map +1 -1
- package/dist/ui/modules/projects/ObsidianPublisher.svelte +73 -0
- package/dist/ui/modules/projects/ObsidianPublisher.svelte.d.ts +26 -0
- package/dist/ui/modules/projects/ObsidianPublisher.svelte.d.ts.map +1 -0
- package/dist/ui/modules/projects/Pengi.svelte +15 -1
- package/dist/ui/modules/projects/Pengi.svelte.d.ts +6 -1
- package/dist/ui/modules/projects/Pengi.svelte.d.ts.map +1 -1
- package/dist/ui/modules/projects/Soulwork.svelte +14 -1
- package/dist/ui/modules/projects/Soulwork.svelte.d.ts +5 -1
- package/dist/ui/modules/projects/Soulwork.svelte.d.ts.map +1 -1
- package/dist/ui/modules/projects/ThisWebpage.svelte +20 -6
- package/dist/ui/modules/projects/ThisWebpage.svelte.d.ts +5 -1
- package/dist/ui/modules/projects/ThisWebpage.svelte.d.ts.map +1 -1
- package/dist/ui/modules/projects/index.d.ts.map +1 -1
- package/dist/ui/modules/universal-overlay/UniversalOverlay.svelte +0 -1
- package/dist/ui/modules/universal-overlay/UniversalOverlay.svelte.d.ts.map +1 -1
- package/dist/ui/templates/SeaweedLayout/EntryGroup.svelte +223 -29
- package/dist/ui/templates/SeaweedLayout/EntryGroup.svelte.d.ts.map +1 -1
- package/dist/ui/templates/SeaweedLayout/ProjectComponentProps.d.ts +2 -0
- package/dist/ui/templates/SeaweedLayout/ProjectComponentProps.d.ts.map +1 -1
- package/dist/ui/templates/SeaweedLayout/ProjectGroupConfig.svelte +1 -3
- package/dist/ui/templates/SeaweedLayout/SeaweedLayout.svelte +188 -44
- package/dist/ui/templates/SeaweedLayout/SeaweedLayout.svelte.d.ts.map +1 -1
- package/dist/ui/templates/SeaweedLayout/props.d.ts +23 -2
- package/dist/ui/templates/SeaweedLayout/props.d.ts.map +1 -1
- package/dist/ui/templates/SeaweedLayout/props.js +8 -1
- package/dist/util/getCommitDate.remote.d.ts +14 -0
- package/dist/util/getCommitDate.remote.d.ts.map +1 -0
- package/dist/util/getCommitDate.remote.js +133 -0
- package/package.json +8 -2
package/README.md
CHANGED
|
@@ -6,13 +6,13 @@ NPM package: https://www.npmjs.com/package/@turnipxenon/pineapple
|
|
|
6
6
|
|
|
7
7
|
## Developing
|
|
8
8
|
|
|
9
|
-
Once you've created a project and installed dependencies with `
|
|
9
|
+
Once you've created a project and installed dependencies with `pnpm`, start a development server:
|
|
10
10
|
|
|
11
11
|
```bash
|
|
12
|
-
|
|
12
|
+
pnpm dev
|
|
13
13
|
|
|
14
14
|
# or start the server and open the app in a new browser tab
|
|
15
|
-
|
|
15
|
+
pnpm dev -- --open
|
|
16
16
|
```
|
|
17
17
|
|
|
18
18
|
## Building
|
|
@@ -20,10 +20,10 @@ yarn dev -- --open
|
|
|
20
20
|
To create a production version of your app:
|
|
21
21
|
|
|
22
22
|
```bash
|
|
23
|
-
|
|
23
|
+
pnpm build
|
|
24
24
|
```
|
|
25
25
|
|
|
26
|
-
You can preview the production build with `
|
|
26
|
+
You can preview the production build with `pnpm preview`.
|
|
27
27
|
|
|
28
28
|
> To deploy your app, you may need to install an [adapter](https://kit.svelte.dev/docs/adapters) for your target environment.
|
|
29
29
|
|
|
@@ -35,7 +35,7 @@ TODO: If you're curious how to install this on a fresh package or a package not
|
|
|
35
35
|
## Migration from v2 to v3
|
|
36
36
|
|
|
37
37
|
```bash
|
|
38
|
-
|
|
38
|
+
pnpm add @turnipxenon2/pineapple
|
|
39
39
|
```
|
|
40
40
|
|
|
41
41
|
**Manual steps**
|
|
@@ -119,13 +119,13 @@ kit: {
|
|
|
119
119
|
|
|
120
120
|
## Local linking
|
|
121
121
|
|
|
122
|
-
1. In pineapple, run `
|
|
123
|
-
2. In seaweed2, run `
|
|
122
|
+
1. In pineapple, run `pnpm link`
|
|
123
|
+
2. In seaweed2, run `pnpm link @turnipxenon/pineapple`
|
|
124
124
|
|
|
125
125
|
**To unlink:**
|
|
126
126
|
|
|
127
|
-
1. In seaweed2, run `
|
|
128
|
-
2. In pineapple, run `
|
|
127
|
+
1. In seaweed2, run `pnpm unlink @turnipxenon/pineapple`
|
|
128
|
+
2. In pineapple, run `pnpm unlink`
|
|
129
129
|
3. **If unlinking, remember to restart PC cause Windows symlinking is tricky**
|
|
130
130
|
|
|
131
|
-
To reinstall a single package: `
|
|
131
|
+
To reinstall a single package: `pnpm add @turnipxenon/pineapple --no-package-lock --no-save`
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"remoteIndex.remote.d.ts","sourceRoot":"","sources":["../src/lib/remoteIndex.remote.ts"],"names":[],"mappings":"AAEA,cAAc,8BAA8B,CAAC"}
|
|
1
|
+
{"version":3,"file":"remoteIndex.remote.d.ts","sourceRoot":"","sources":["../src/lib/remoteIndex.remote.ts"],"names":[],"mappings":"AAEA,cAAc,8BAA8B,CAAC;AAC7C,cAAc,6BAA6B,CAAC"}
|
|
@@ -8,6 +8,7 @@ html {
|
|
|
8
8
|
--color-warning-700-400: var(--color-warning-700);
|
|
9
9
|
--color-surface-50-950: var(--color-surface-50);
|
|
10
10
|
--color-surface-700-600: var(--color-surface-700);
|
|
11
|
+
--color-surface-900-100: var(--color-surface-900);
|
|
11
12
|
}
|
|
12
13
|
|
|
13
14
|
html.dark {
|
|
@@ -20,4 +21,5 @@ html.dark {
|
|
|
20
21
|
--color-warning-700-400: var(--color-warning-400);
|
|
21
22
|
--color-surface-50-950: var(--color-surface-950);
|
|
22
23
|
--color-surface-700-600: var(--color-surface-600);
|
|
24
|
+
--color-surface-900-100: var(--color-surface-100);
|
|
23
25
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"svelteIndex.svelte.d.ts","sourceRoot":"","sources":["../src/lib/svelteIndex.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAM3D,eAAO,MAAM,WAAW,EAAE,WAAW,EAMpC,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
// noinspection JSUnusedGlobalSymbols
|
|
2
|
+
import * as ObsidianPublisher from "./ui/modules/projects/ObsidianPublisher.svelte";
|
|
3
|
+
import * as Hepcat from "./ui/modules/projects/Hepcat.svelte";
|
|
4
|
+
import * as Pengi from "./ui/modules/projects/Pengi.svelte";
|
|
5
|
+
import * as Soulwork from "./ui/modules/projects/Soulwork.svelte";
|
|
6
|
+
import * as ThisWebpage from "./ui/modules/projects/ThisWebpage.svelte";
|
|
7
|
+
export const projectList = [
|
|
8
|
+
ThisWebpage,
|
|
9
|
+
Hepcat,
|
|
10
|
+
Pengi,
|
|
11
|
+
Soulwork,
|
|
12
|
+
ObsidianPublisher
|
|
13
|
+
];
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import PinyaCombobox from "../elements/pinya-combobox/PinyaCombobox.svelte";
|
|
3
|
+
import type { GenericComboboxItem } from "../elements/pinya-combobox/PinyaComboboxProps";
|
|
4
|
+
import { SectionType } from "../templates/SeaweedLayout/props";
|
|
5
|
+
|
|
6
|
+
interface SortDropdownProps {
|
|
7
|
+
sortBy: string[]; // Current sort value (bindable)
|
|
8
|
+
sectionType: SectionType; // Determines available sort options
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
let {
|
|
12
|
+
sortBy = $bindable(["default"]),
|
|
13
|
+
sectionType = SectionType.Projects
|
|
14
|
+
}: SortDropdownProps = $props();
|
|
15
|
+
|
|
16
|
+
const projectSortOptions: GenericComboboxItem<string>[] = [
|
|
17
|
+
{ label: "Default order", value: "default" },
|
|
18
|
+
{ label: "Most recently finished", value: "date-desc" },
|
|
19
|
+
{ label: "Oldest finished", value: "date-asc" },
|
|
20
|
+
{ label: "Longest projects", value: "duration-desc" },
|
|
21
|
+
{ label: "Shortest projects", value: "duration-asc" }
|
|
22
|
+
];
|
|
23
|
+
|
|
24
|
+
const experienceSortOptions: GenericComboboxItem<string>[] = [
|
|
25
|
+
{ label: "Default order", value: "default" },
|
|
26
|
+
{ label: "Most recent first", value: "date-desc" },
|
|
27
|
+
{ label: "Oldest first", value: "date-asc" }
|
|
28
|
+
];
|
|
29
|
+
|
|
30
|
+
const sortOptions = $derived(
|
|
31
|
+
sectionType === SectionType.Experience
|
|
32
|
+
? experienceSortOptions
|
|
33
|
+
: projectSortOptions
|
|
34
|
+
);
|
|
35
|
+
</script>
|
|
36
|
+
|
|
37
|
+
<div class="sort-dropdown">
|
|
38
|
+
<PinyaCombobox
|
|
39
|
+
data={sortOptions}
|
|
40
|
+
bind:value={sortBy}
|
|
41
|
+
label="Sort by"
|
|
42
|
+
placeholder="Select sort order"
|
|
43
|
+
/>
|
|
44
|
+
</div>
|
|
45
|
+
|
|
46
|
+
<style>
|
|
47
|
+
.sort-dropdown {
|
|
48
|
+
min-width: 200px;
|
|
49
|
+
}
|
|
50
|
+
</style>
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { SectionType } from "../templates/SeaweedLayout/props";
|
|
2
|
+
interface SortDropdownProps {
|
|
3
|
+
sortBy: string[];
|
|
4
|
+
sectionType: SectionType;
|
|
5
|
+
}
|
|
6
|
+
declare const SortDropdown: import("svelte").Component<SortDropdownProps, {}, "sortBy">;
|
|
7
|
+
type SortDropdown = ReturnType<typeof SortDropdown>;
|
|
8
|
+
export default SortDropdown;
|
|
9
|
+
//# sourceMappingURL=SortDropdown.svelte.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SortDropdown.svelte.d.ts","sourceRoot":"","sources":["../../../src/lib/ui/components/SortDropdown.svelte.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,WAAW,EAAE,MAAM,uCAAuC,CAAC;AAGnE,UAAU,iBAAiB;IAC1B,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,WAAW,EAAE,WAAW,CAAC;CACzB;AAyCF,QAAA,MAAM,YAAY,6DAAwC,CAAC;AAC3D,KAAK,YAAY,GAAG,UAAU,CAAC,OAAO,YAAY,CAAC,CAAC;AACpD,eAAe,YAAY,CAAC"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import PinyaCombobox from "../elements/pinya-combobox/PinyaCombobox.svelte";
|
|
3
|
+
|
|
4
|
+
interface TagFilterProps {
|
|
5
|
+
allTags: string[]; // All available tags
|
|
6
|
+
selectedTags: string[]; // Currently selected tags (bindable)
|
|
7
|
+
label?: string; // Optional label
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
let {
|
|
11
|
+
allTags,
|
|
12
|
+
selectedTags = $bindable([]),
|
|
13
|
+
label = "Filter by tags"
|
|
14
|
+
}: TagFilterProps = $props();
|
|
15
|
+
</script>
|
|
16
|
+
|
|
17
|
+
<div class="tag-filter">
|
|
18
|
+
<PinyaCombobox
|
|
19
|
+
bind:value={selectedTags}
|
|
20
|
+
data={allTags.map(t => ({value: t, label: t}))}
|
|
21
|
+
multiple={true}
|
|
22
|
+
{label}
|
|
23
|
+
/>
|
|
24
|
+
</div>
|
|
25
|
+
|
|
26
|
+
<style>
|
|
27
|
+
.tag-filter {
|
|
28
|
+
display: flex;
|
|
29
|
+
flex-direction: column;
|
|
30
|
+
gap: 0.5rem;
|
|
31
|
+
}
|
|
32
|
+
</style>
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
interface TagFilterProps {
|
|
2
|
+
allTags: string[];
|
|
3
|
+
selectedTags: string[];
|
|
4
|
+
label?: string;
|
|
5
|
+
}
|
|
6
|
+
declare const TagFilter: import("svelte").Component<TagFilterProps, {}, "selectedTags">;
|
|
7
|
+
type TagFilter = ReturnType<typeof TagFilter>;
|
|
8
|
+
export default TagFilter;
|
|
9
|
+
//# sourceMappingURL=TagFilter.svelte.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TagFilter.svelte.d.ts","sourceRoot":"","sources":["../../../src/lib/ui/components/TagFilter.svelte.ts"],"names":[],"mappings":"AAMC,UAAU,cAAc;IACvB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;CACf;AAoBF,QAAA,MAAM,SAAS,gEAAwC,CAAC;AACxD,KAAK,SAAS,GAAG,UAAU,CAAC,OAAO,SAAS,CAAC,CAAC;AAC9C,eAAe,SAAS,CAAC"}
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
import { Accordion } from "melt/builders";
|
|
5
5
|
import { setContext } from "svelte";
|
|
6
6
|
import type { SvelteSet } from "svelte/reactivity";
|
|
7
|
-
import {
|
|
7
|
+
import { type AccordionContext, accordionContextKey } from "./accordionContext";
|
|
8
8
|
import type { PinyaAccordionProps } from "./PinyaAccordionProps";
|
|
9
9
|
|
|
10
10
|
let {
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
multiple = true,
|
|
14
14
|
...props
|
|
15
15
|
}: PinyaAccordionProps = $props();
|
|
16
|
+
|
|
16
17
|
let accordion = $derived(new Accordion({
|
|
17
18
|
value: (() => {
|
|
18
19
|
if (openItems) {
|
|
@@ -33,10 +34,11 @@
|
|
|
33
34
|
} else {
|
|
34
35
|
openItems = [];
|
|
35
36
|
}
|
|
36
|
-
},
|
|
37
|
+
},
|
|
38
|
+
multiple,
|
|
37
39
|
}));
|
|
38
40
|
setContext<AccordionContext>(accordionContextKey, (key) => accordion.getItem(key));
|
|
39
|
-
setContext<string[]>(
|
|
41
|
+
setContext<string[]>("accordionOpenItems", openItems);
|
|
40
42
|
</script>
|
|
41
43
|
|
|
42
44
|
<div {...props} class={`pinya-accordion-root ${props.class ?? ''}`} {...accordion.root}>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PinyaAccordion.svelte.d.ts","sourceRoot":"","sources":["../../../../src/lib/ui/components/accordion/PinyaAccordion.svelte.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"PinyaAccordion.svelte.d.ts","sourceRoot":"","sources":["../../../../src/lib/ui/components/accordion/PinyaAccordion.svelte.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAqDjE,QAAA,MAAM,cAAc,kEAAwC,CAAC;AAC7D,KAAK,cAAc,GAAG,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC;AACxD,eAAe,cAAc,CAAC"}
|
|
@@ -2,4 +2,6 @@ export * from "./accordion";
|
|
|
2
2
|
export { default as ModalBase } from "./ModalBase.svelte";
|
|
3
3
|
export { default as FourPartCard } from "./FourPartCard.svelte";
|
|
4
4
|
export { default as SocialSection } from "./SocialSection.svelte";
|
|
5
|
+
export { default as ProjectDateBadge } from "./project-date-badge/ProjectDateBadge.svelte";
|
|
6
|
+
export * from "./project-date-badge/ProjectDateBageProps";
|
|
5
7
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lib/ui/components/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAChE,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,wBAAwB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lib/ui/components/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAChE,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,EAAE,OAAO,IAAI,gBAAgB,EAAE,MAAM,8CAA8C,CAAC;AAC3F,cAAc,2CAA2C,CAAC"}
|
|
@@ -2,3 +2,5 @@ export * from "./accordion";
|
|
|
2
2
|
export { default as ModalBase } from "./ModalBase.svelte";
|
|
3
3
|
export { default as FourPartCard } from "./FourPartCard.svelte";
|
|
4
4
|
export { default as SocialSection } from "./SocialSection.svelte";
|
|
5
|
+
export { default as ProjectDateBadge } from "./project-date-badge/ProjectDateBadge.svelte";
|
|
6
|
+
export * from "./project-date-badge/ProjectDateBageProps";
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { slide } from 'svelte/transition';
|
|
3
|
+
import type { ProjectDateBageProps } from "./ProjectDateBageProps";
|
|
4
|
+
import { TextLink } from "../../elements/index";
|
|
5
|
+
|
|
6
|
+
let {
|
|
7
|
+
dateStarted,
|
|
8
|
+
dateFinished,
|
|
9
|
+
isOngoing = false,
|
|
10
|
+
commitCount,
|
|
11
|
+
gitRepoLink
|
|
12
|
+
}: ProjectDateBageProps = $props();
|
|
13
|
+
|
|
14
|
+
function formatDate(date: Date | string): string {
|
|
15
|
+
const d = date instanceof Date ? date : new Date(date);
|
|
16
|
+
return d.toLocaleDateString("en-US", { month: "short", year: "numeric" });
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function getDurationText(start: Date | string, end?: Date | string): string {
|
|
20
|
+
const startDate = start instanceof Date ? start : new Date(start);
|
|
21
|
+
const endDate = end ? (end instanceof Date ? end : new Date(end)) : new Date();
|
|
22
|
+
|
|
23
|
+
const totalMonths =
|
|
24
|
+
(endDate.getFullYear() - startDate.getFullYear()) * 12 +
|
|
25
|
+
(endDate.getMonth() - startDate.getMonth());
|
|
26
|
+
|
|
27
|
+
if (totalMonths < 1) {
|
|
28
|
+
const days = Math.max(1, Math.round((endDate.getTime() - startDate.getTime()) / (1000 * 60 * 60 * 24)));
|
|
29
|
+
return `${days} day${days !== 1 ? "s" : ""}`;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const years = Math.floor(totalMonths / 12);
|
|
33
|
+
const months = totalMonths % 12;
|
|
34
|
+
|
|
35
|
+
if (years === 0) return `${months} mo${months !== 1 ? "s" : ""}`;
|
|
36
|
+
if (months === 0) return `${years} yr${years !== 1 ? "s" : ""}`;
|
|
37
|
+
return `${years} yr${years !== 1 ? "s" : ""} ${months} mo${months !== 1 ? "s" : ""}`;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const hasData = $derived(!!dateStarted);
|
|
41
|
+
</script>
|
|
42
|
+
|
|
43
|
+
{#if hasData}
|
|
44
|
+
<section transition:slide class="project-date-badge">
|
|
45
|
+
<div class="badge-row">
|
|
46
|
+
<span class="date-info">
|
|
47
|
+
{formatDate(dateStarted!)}
|
|
48
|
+
<span class="separator">→</span>
|
|
49
|
+
{#if isOngoing}
|
|
50
|
+
<span class="ongoing-label">Present</span>
|
|
51
|
+
{:else if dateFinished}
|
|
52
|
+
{formatDate(dateFinished)}
|
|
53
|
+
{:else}
|
|
54
|
+
<span class="unknown-label">?</span>
|
|
55
|
+
{/if}
|
|
56
|
+
</span>
|
|
57
|
+
|
|
58
|
+
{#if dateStarted}
|
|
59
|
+
<span class="duration">
|
|
60
|
+
{getDurationText(dateStarted, isOngoing ? undefined : dateFinished)}
|
|
61
|
+
</span>
|
|
62
|
+
{/if}
|
|
63
|
+
</div>
|
|
64
|
+
|
|
65
|
+
{#if commitCount != null || isOngoing}
|
|
66
|
+
<div class="badge-row secondary-row">
|
|
67
|
+
{#if isOngoing}
|
|
68
|
+
<span class="ongoing-badge">ongoing</span>
|
|
69
|
+
{/if}
|
|
70
|
+
{#if commitCount != null && gitRepoLink}
|
|
71
|
+
<TextLink href={gitRepoLink} target="_blank" rel="noopener noreferrer" class="commit-count">
|
|
72
|
+
{commitCount} commit{commitCount !== 1 ? "s" : ""}
|
|
73
|
+
</TextLink>
|
|
74
|
+
{:else if commitCount != null}
|
|
75
|
+
<span class="commit-count">{commitCount} commit{commitCount !== 1 ? "s" : ""}</span>
|
|
76
|
+
{/if}
|
|
77
|
+
</div>
|
|
78
|
+
{/if}
|
|
79
|
+
</section>
|
|
80
|
+
{/if}
|
|
81
|
+
|
|
82
|
+
<style>
|
|
83
|
+
.project-date-badge {
|
|
84
|
+
display: flex;
|
|
85
|
+
flex-direction: column;
|
|
86
|
+
gap: 0.375rem;
|
|
87
|
+
padding: 0.75rem 0;
|
|
88
|
+
margin-top: 0.75rem;
|
|
89
|
+
border-top: 1px solid var(--color-surface-900-100);
|
|
90
|
+
font-size: 0.8125rem;
|
|
91
|
+
line-height: 1.4;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
.badge-row {
|
|
95
|
+
display: flex;
|
|
96
|
+
align-items: center;
|
|
97
|
+
justify-content: space-between;
|
|
98
|
+
flex-wrap: wrap;
|
|
99
|
+
gap: 0.5rem;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
.date-info {
|
|
103
|
+
color: var(--color-surface-900-100);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
.separator {
|
|
107
|
+
margin: 0 0.25rem;
|
|
108
|
+
color: var(--color-surface-900-100);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
.ongoing-label {
|
|
112
|
+
color: var(--color-primary-400-600);
|
|
113
|
+
font-weight: 600;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
.unknown-label {
|
|
117
|
+
color: var(--color-surface-900-100);
|
|
118
|
+
font-style: italic;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
.duration {
|
|
122
|
+
color: var(--color-surface-900-100);
|
|
123
|
+
font-weight: 500;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
.secondary-row {
|
|
127
|
+
justify-content: flex-start;
|
|
128
|
+
gap: 0.5rem;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
.ongoing-badge {
|
|
132
|
+
display: inline-block;
|
|
133
|
+
padding: 0.125rem 0.5rem;
|
|
134
|
+
border-radius: var(--radius-md, 0.375rem);
|
|
135
|
+
background-color: var(--color-primary-50-900);
|
|
136
|
+
color: var(--color-primary-700);
|
|
137
|
+
font-size: 0.75rem;
|
|
138
|
+
font-weight: 600;
|
|
139
|
+
text-transform: uppercase;
|
|
140
|
+
letter-spacing: 0.025em;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
:global(html.dark) .ongoing-badge {
|
|
144
|
+
color: var(--color-primary-300);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
.commit-count {
|
|
148
|
+
font-size: 0.75rem;
|
|
149
|
+
color: var(--color-surface-900-100);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
a.commit-count {
|
|
153
|
+
text-decoration: none;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
a.commit-count:hover {
|
|
157
|
+
text-decoration: underline;
|
|
158
|
+
color: var(--color-primary-400-600);
|
|
159
|
+
}
|
|
160
|
+
</style>
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { ProjectDateBageProps } from "./ProjectDateBageProps";
|
|
2
|
+
declare const ProjectDateBadge: import("svelte").Component<ProjectDateBageProps, {}, "">;
|
|
3
|
+
type ProjectDateBadge = ReturnType<typeof ProjectDateBadge>;
|
|
4
|
+
export default ProjectDateBadge;
|
|
5
|
+
//# sourceMappingURL=ProjectDateBadge.svelte.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ProjectDateBadge.svelte.d.ts","sourceRoot":"","sources":["../../../../src/lib/ui/components/project-date-badge/ProjectDateBadge.svelte.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,4DAA4D,CAAC;AAwFvG,QAAA,MAAM,gBAAgB,0DAAwC,CAAC;AAC/D,KAAK,gBAAgB,GAAG,UAAU,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAC5D,eAAe,gBAAgB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ProjectDateBageProps.d.ts","sourceRoot":"","sources":["../../../../src/lib/ui/components/project-date-badge/ProjectDateBageProps.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,oBAAoB;IACpC,WAAW,CAAC,EAAE,IAAI,GAAG,MAAM,CAAC;IAC5B,YAAY,CAAC,EAAE,IAAI,GAAG,MAAM,CAAC;IAC7B,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;CACrB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -95,7 +95,11 @@
|
|
|
95
95
|
font-style: var(--shiki-dark-font-style) !important;
|
|
96
96
|
font-weight: var(--shiki-dark-font-weight) !important;
|
|
97
97
|
-webkit-text-decoration: var(--shiki-dark-text-decoration) !important;
|
|
98
|
-
text-decoration: var(--shiki-dark-text-decoration) !important
|
|
98
|
+
text-decoration: var(--shiki-dark-text-decoration) !important;
|
|
99
|
+
|
|
100
|
+
span[style*="color:#4C4F69"] {
|
|
101
|
+
color: oklch(0.835 0.043 279.325) !important;
|
|
102
|
+
}
|
|
99
103
|
}
|
|
100
104
|
|
|
101
105
|
html.dark .shiki.has-diff span.diff.add {
|
|
@@ -119,15 +123,17 @@
|
|
|
119
123
|
padding-inline-end: 0;
|
|
120
124
|
|
|
121
125
|
code {
|
|
122
|
-
display:
|
|
123
|
-
flex-direction: column;
|
|
124
|
-
gap: 0.2lh;
|
|
126
|
+
display: block;
|
|
125
127
|
|
|
126
128
|
& > span {
|
|
127
|
-
display:
|
|
128
|
-
flex-wrap: wrap;
|
|
129
|
+
display: block;
|
|
129
130
|
padding-inline-start: 2em;
|
|
130
131
|
padding-inline-end: 1em;
|
|
132
|
+
margin-block-end: -1lh;
|
|
133
|
+
|
|
134
|
+
&:last-child {
|
|
135
|
+
margin-block-end: 0;
|
|
136
|
+
}
|
|
131
137
|
}
|
|
132
138
|
}
|
|
133
139
|
|
|
@@ -5,14 +5,14 @@
|
|
|
5
5
|
|
|
6
6
|
interface Props {
|
|
7
7
|
checked?: boolean;
|
|
8
|
-
name
|
|
8
|
+
name?: string;
|
|
9
9
|
onChange?: ((val: boolean) => void);
|
|
10
10
|
children?: Snippet;
|
|
11
11
|
}
|
|
12
12
|
|
|
13
13
|
let {
|
|
14
14
|
checked = $bindable(false),
|
|
15
|
-
name,
|
|
15
|
+
name = undefined,
|
|
16
16
|
onChange = undefined,
|
|
17
17
|
children = undefined
|
|
18
18
|
}: Props = $props();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PineappleSwitch.svelte.d.ts","sourceRoot":"","sources":["../../../src/lib/ui/elements/PineappleSwitch.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAGrC,UAAU,KAAK;IACd,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"PineappleSwitch.svelte.d.ts","sourceRoot":"","sources":["../../../src/lib/ui/elements/PineappleSwitch.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAGrC,UAAU,KAAK;IACd,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,CAAC,CAAC,GAAG,EAAE,OAAO,KAAK,IAAI,CAAC,CAAC;IACpC,QAAQ,CAAC,EAAE,OAAO,CAAC;CACnB;AA8BF,QAAA,MAAM,eAAe,kDAAwC,CAAC;AAC9D,KAAK,eAAe,GAAG,UAAU,CAAC,OAAO,eAAe,CAAC,CAAC;AAC1D,eAAe,eAAe,CAAC"}
|