@turnipxenon/pineapple 5.0.0-alpha.9 → 5.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (92) hide show
  1. package/README.md +11 -11
  2. package/dist/index.d.ts +1 -0
  3. package/dist/index.d.ts.map +1 -1
  4. package/dist/index.js +1 -0
  5. package/dist/remoteIndex.remote.d.ts +2 -0
  6. package/dist/remoteIndex.remote.d.ts.map +1 -0
  7. package/dist/remoteIndex.remote.js +2 -0
  8. package/dist/styles/app.css +0 -82
  9. package/dist/styles/tailwind.css +0 -12
  10. package/dist/styles/turnip-theme.css +1 -0
  11. package/dist/ui/components/FourPartCard.svelte +9 -0
  12. package/dist/ui/components/MeltToaster/MeltToaster.svelte +4 -1
  13. package/dist/ui/components/MeltToaster/MeltToaster.svelte.d.ts.map +1 -1
  14. package/dist/ui/components/NestedNavigation.svelte +0 -1
  15. package/dist/ui/components/NestedNavigation.svelte.d.ts.map +1 -1
  16. package/dist/ui/components/SortDropdown.svelte +50 -0
  17. package/dist/ui/components/SortDropdown.svelte.d.ts +9 -0
  18. package/dist/ui/components/SortDropdown.svelte.d.ts.map +1 -0
  19. package/dist/ui/components/TagFilter.svelte +32 -0
  20. package/dist/ui/components/TagFilter.svelte.d.ts +9 -0
  21. package/dist/ui/components/TagFilter.svelte.d.ts.map +1 -0
  22. package/dist/ui/components/accordion/PinyaAccordion.svelte +5 -3
  23. package/dist/ui/components/accordion/PinyaAccordion.svelte.d.ts.map +1 -1
  24. package/dist/ui/elements/CodeBlock/CodeBlock.svelte +167 -18
  25. package/dist/ui/elements/CodeBlock/CodeBlock.svelte.d.ts.map +1 -1
  26. package/dist/ui/elements/PineappleSwitch.svelte +2 -2
  27. package/dist/ui/elements/PineappleSwitch.svelte.d.ts +1 -1
  28. package/dist/ui/elements/PineappleSwitch.svelte.d.ts.map +1 -1
  29. package/dist/ui/elements/pinya-combobox/PinyaCombobox.svelte +170 -27
  30. package/dist/ui/elements/pinya-combobox/PinyaCombobox.svelte.d.ts.map +1 -1
  31. package/dist/ui/elements/pinya-combobox/PinyaComboboxProps.d.ts +6 -7
  32. package/dist/ui/elements/pinya-combobox/PinyaComboboxProps.d.ts.map +1 -1
  33. package/dist/ui/modules/experience/ExampleJob1.svelte +79 -0
  34. package/dist/ui/modules/experience/ExampleJob1.svelte.d.ts +26 -0
  35. package/dist/ui/modules/experience/ExampleJob1.svelte.d.ts.map +1 -0
  36. package/dist/ui/modules/experience/ExampleJob2.svelte +74 -0
  37. package/dist/ui/modules/experience/ExampleJob2.svelte.d.ts +25 -0
  38. package/dist/ui/modules/experience/ExampleJob2.svelte.d.ts.map +1 -0
  39. package/dist/ui/modules/experience/index.d.ts +3 -0
  40. package/dist/ui/modules/experience/index.d.ts.map +1 -0
  41. package/dist/ui/modules/experience/index.js +2 -0
  42. package/dist/ui/modules/modals/general-settings/LanguagePicker.svelte +7 -9
  43. package/dist/ui/modules/modals/general-settings/LanguagePicker.svelte.d.ts.map +1 -1
  44. package/dist/ui/modules/projects/Hepcat.svelte +5 -1
  45. package/dist/ui/modules/projects/Hepcat.svelte.d.ts +4 -1
  46. package/dist/ui/modules/projects/Hepcat.svelte.d.ts.map +1 -1
  47. package/dist/ui/modules/projects/Pengi.svelte +4 -1
  48. package/dist/ui/modules/projects/Pengi.svelte.d.ts +4 -1
  49. package/dist/ui/modules/projects/Pengi.svelte.d.ts.map +1 -1
  50. package/dist/ui/modules/projects/Soulwork.svelte +4 -1
  51. package/dist/ui/modules/projects/Soulwork.svelte.d.ts +4 -1
  52. package/dist/ui/modules/projects/Soulwork.svelte.d.ts.map +1 -1
  53. package/dist/ui/modules/projects/ThisWebpage.svelte +13 -2
  54. package/dist/ui/modules/projects/ThisWebpage.svelte.d.ts +3 -1
  55. package/dist/ui/modules/projects/ThisWebpage.svelte.d.ts.map +1 -1
  56. package/dist/ui/modules/universal-overlay/SettingsPanel.svelte +29 -24
  57. package/dist/ui/modules/universal-overlay/SettingsPanel.svelte.d.ts.map +1 -1
  58. package/dist/ui/modules/universal-overlay/UniversalOverlay.svelte +6 -2
  59. package/dist/ui/templates/PinyaPageLayout/PinyaPageLayout.svelte +32 -21
  60. package/dist/ui/templates/PinyaPageLayout/PinyaPageLayout.svelte.d.ts +1 -1
  61. package/dist/ui/templates/PinyaPageLayout/PinyaPageLayout.svelte.d.ts.map +1 -1
  62. package/dist/ui/templates/PinyaPageLayout/pinyaPageLayoutRunes.svelte.d.ts.map +1 -1
  63. package/dist/ui/templates/SeaweedLayout/EntryGroup.svelte +177 -29
  64. package/dist/ui/templates/SeaweedLayout/EntryGroup.svelte.d.ts.map +1 -1
  65. package/dist/ui/templates/SeaweedLayout/ProjectGroupConfig.svelte +1 -3
  66. package/dist/ui/templates/SeaweedLayout/SeaweedLayout.svelte +188 -44
  67. package/dist/ui/templates/SeaweedLayout/SeaweedLayout.svelte.d.ts.map +1 -1
  68. package/dist/ui/templates/SeaweedLayout/props.d.ts +18 -2
  69. package/dist/ui/templates/SeaweedLayout/props.d.ts.map +1 -1
  70. package/dist/ui/templates/SeaweedLayout/props.js +8 -1
  71. package/dist/ui/templates/blog_template/BlogTemplate.svelte +5 -2
  72. package/dist/ui/templates/blog_template/BlogTemplate.svelte.d.ts.map +1 -1
  73. package/dist/ui/templates/pinya-base/PinyaBase.svelte +45 -4
  74. package/dist/ui/templates/pinya-base/PinyaBase.svelte.d.ts +15 -3
  75. package/dist/ui/templates/pinya-base/PinyaBase.svelte.d.ts.map +1 -1
  76. package/dist/ui/templates/pinya-base/menuPageServerLoadRemote.remote.svelte +1 -0
  77. package/dist/ui/templates/pinya-base/menuPageServerLoadRemote.remote.svelte.d.ts +27 -0
  78. package/dist/ui/templates/pinya-base/menuPageServerLoadRemote.remote.svelte.d.ts.map +1 -0
  79. package/dist/util/context/PineappleBaseContext.svelte +20 -8
  80. package/dist/util/context/PineappleBaseContext.svelte.d.ts.map +1 -1
  81. package/dist/util/context/pineappleBaseContextDefinitions.svelte.d.ts +21 -13
  82. package/dist/util/context/pineappleBaseContextDefinitions.svelte.d.ts.map +1 -1
  83. package/dist/util/context/pineappleBaseContextDefinitions.svelte.js +21 -19
  84. package/dist/util/getParsnipData.remote.d.ts +12 -0
  85. package/dist/util/getParsnipData.remote.d.ts.map +1 -0
  86. package/dist/util/getParsnipData.remote.js +3 -0
  87. package/dist/util/localStore.svelte.d.ts +10 -3
  88. package/dist/util/localStore.svelte.d.ts.map +1 -1
  89. package/dist/util/localStore.svelte.js +56 -38
  90. package/dist/util/util.js +1 -1
  91. package/package.json +17 -8
  92. package/src/lib/styles/app.css +0 -82
@@ -11,7 +11,10 @@
11
11
  import { ButtonVariant } from "../../elements/PinyaButtonCommon/ButtonVariant";
12
12
 
13
13
  const key = "Soulwork";
14
- export { component, key };
14
+ const dateStarted = "2019-11-09";
15
+ const dateFinished = "2019-11-10";
16
+ const tags = ["unity", "csharp", "game", "gamejam", "physics"];
17
+ export { component, key, dateStarted, dateFinished, tags };
15
18
  </script>
16
19
 
17
20
  {#snippet component(props: ProjectComponentProps)}
@@ -1,7 +1,10 @@
1
1
  import type { ProjectComponentProps } from "../../templates/SeaweedLayout";
2
2
  declare const component: (props: ProjectComponentProps) => ReturnType<import("svelte").Snippet>;
3
3
  declare const key = "Soulwork";
4
- export { component, key };
4
+ declare const dateStarted = "2019-11-09";
5
+ declare const dateFinished = "2019-11-10";
6
+ declare const tags: string[];
7
+ export { component, key, dateStarted, dateFinished, tags };
5
8
  interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
6
9
  new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
7
10
  $$bindings?: Bindings;
@@ -1 +1 @@
1
- {"version":3,"file":"Soulwork.svelte.d.ts","sourceRoot":"","sources":["../../../../src/lib/ui/modules/projects/Soulwork.svelte.ts"],"names":[],"mappings":"AAKC,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,iCAAiC,CAAC;AAM7E,QAAA,MAAM,SAAS,GAAyB,OAAO,qBAAqB,KAAqB,UAAU,CAAC,OAAO,QAAQ,EAAE,OAAO,CAiChG,CAAC;AAE7B,QAAA,MAAM,GAAG,aAAa,CAAC;AACvB,OAAO,EAAE,SAAS,EAAE,GAAG,EAAE,CAAC;AAS3B,UAAU,kCAAkC,CAAC,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,EAAE,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,EAAE,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,EAAE,OAAO,GAAG,EAAE,EAAE,QAAQ,GAAG,MAAM;IACpM,KAAK,OAAO,EAAE,OAAO,QAAQ,EAAE,2BAA2B,CAAC,KAAK,CAAC,GAAG,OAAO,QAAQ,EAAE,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,GAAG;QAAE,UAAU,CAAC,EAAE,QAAQ,CAAA;KAAE,GAAG,OAAO,CAAC;IACjK,CAAC,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,KAAK,CAAA;KAAC,GAAG,OAAO,GAAG;QAAE,IAAI,CAAC,EAAE,GAAG,CAAC;QAAC,GAAG,CAAC,EAAE,GAAG,CAAA;KAAE,CAAC;IACtG,YAAY,CAAC,EAAE,QAAQ,CAAC;CAC3B;AAKD,QAAA,MAAM,QAAQ;;kBAA+E,CAAC;AAC5E,KAAK,QAAQ,GAAG,YAAY,CAAC,OAAO,QAAQ,CAAC,CAAC;AAChD,eAAe,QAAQ,CAAC"}
1
+ {"version":3,"file":"Soulwork.svelte.d.ts","sourceRoot":"","sources":["../../../../src/lib/ui/modules/projects/Soulwork.svelte.ts"],"names":[],"mappings":"AAKC,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,iCAAiC,CAAC;AAM7E,QAAA,MAAM,SAAS,GAAyB,OAAO,qBAAqB,KAAqB,UAAU,CAAC,OAAO,QAAQ,EAAE,OAAO,CAiChG,CAAC;AAE7B,QAAA,MAAM,GAAG,aAAa,CAAC;AACvB,QAAA,MAAM,WAAW,eAAe,CAAC;AACjC,QAAA,MAAM,YAAY,eAAe,CAAC;AAClC,QAAA,MAAM,IAAI,UAAoD,CAAC;AAC/D,OAAO,EAAE,SAAS,EAAE,GAAG,EAAE,WAAW,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC;AAS5D,UAAU,kCAAkC,CAAC,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,EAAE,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,EAAE,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,EAAE,OAAO,GAAG,EAAE,EAAE,QAAQ,GAAG,MAAM;IACpM,KAAK,OAAO,EAAE,OAAO,QAAQ,EAAE,2BAA2B,CAAC,KAAK,CAAC,GAAG,OAAO,QAAQ,EAAE,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,GAAG;QAAE,UAAU,CAAC,EAAE,QAAQ,CAAA;KAAE,GAAG,OAAO,CAAC;IACjK,CAAC,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,KAAK,CAAA;KAAC,GAAG,OAAO,GAAG;QAAE,IAAI,CAAC,EAAE,GAAG,CAAC;QAAC,GAAG,CAAC,EAAE,GAAG,CAAA;KAAE,CAAC;IACtG,YAAY,CAAC,EAAE,QAAQ,CAAC;CAC3B;AAKD,QAAA,MAAM,QAAQ;;kBAA+E,CAAC;AAC5E,KAAK,QAAQ,GAAG,YAAY,CAAC,OAAO,QAAQ,CAAC,CAAC;AAChD,eAAe,QAAQ,CAAC"}
@@ -3,6 +3,7 @@
3
3
  <script module lang="ts">
4
4
  import GithubIcon from "../../../assets/icons/github-mark.svg";
5
5
  import ThisWebsiteFootage from "../../../assets/others/seaweed-showcase.mp4";
6
+ import LinkIcon from "../../../assets/icons/link-icon.svg";
6
7
  import type { ProjectComponentProps } from "../../templates/SeaweedLayout/ProjectComponentProps";
7
8
  import { default as FourPartCard } from "../../components/FourPartCard.svelte";
8
9
  import { default as ImageIcon } from "../../elements/ImageIcon.svelte";
@@ -11,7 +12,9 @@
11
12
  import { ButtonVariant } from "../../elements/PinyaButtonCommon/ButtonVariant";
12
13
 
13
14
  const key = "This Webpage";
14
- export { component, key };
15
+ const dateStarted = "2023-06-01";
16
+ const tags = ["svelte", "typescript", "web", "tailwind", "postgres", "prisma", "ongoing", "database"];
17
+ export { component, key, dateStarted, tags };
15
18
  </script>
16
19
 
17
20
  {#snippet component(props: ProjectComponentProps)}
@@ -47,7 +50,7 @@
47
50
  <TextChip queryClass="qt-svelte">Svelte 5</TextChip>
48
51
  <TextChip queryClass="qt-tailwind">Tailwind 4</TextChip>
49
52
  <TextChip queryClass="qt-skeleton">Skeleton (Svelte UI library)</TextChip>
50
- <TextChip queryClass="qt-ts">Typescript</TextChip>
53
+ <TextChip queryClass="qt-typescript">Typescript</TextChip>
51
54
  <TextChip queryClass="qt-vercel qt-cicd">Vercel</TextChip>
52
55
  <TextChip queryClass="qt-gamedev">YarnSpinner</TextChip>
53
56
  <TextChip queryClass="qt-postgres qt-db">Postgres (SQL database)</TextChip>
@@ -62,6 +65,14 @@
62
65
  onclick={() => window.open("https://github.com/TurnipXenon/pineapple")}>
63
66
  <ImageIcon src={GithubIcon} class="long-btn-image" alt="github icon" />
64
67
  </PinyaButton>
68
+ <PinyaButton
69
+ data-nosnippet
70
+ buttonVariant={ButtonVariant.SmallIcon}
71
+ title="https://pineapple.turnipxenon.com/documentation"
72
+ onclick={() => window.open("https://pineapple.turnipxenon.com/documentation")}>
73
+ <ImageIcon src={LinkIcon} aria-hidden />
74
+ <span>pineapple.turnipxenon.com</span>
75
+ </PinyaButton>
65
76
  </section>
66
77
  </FourPartCard>
67
78
  {/snippet}
@@ -1,7 +1,9 @@
1
1
  import type { ProjectComponentProps } from "../../templates/SeaweedLayout/ProjectComponentProps";
2
2
  declare const component: (props: ProjectComponentProps) => ReturnType<import("svelte").Snippet>;
3
3
  declare const key = "This Webpage";
4
- export { component, key };
4
+ declare const dateStarted = "2023-06-01";
5
+ declare const tags: string[];
6
+ export { component, key, dateStarted, tags };
5
7
  interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
6
8
  new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
7
9
  $$bindings?: Bindings;
@@ -1 +1 @@
1
- {"version":3,"file":"ThisWebpage.svelte.d.ts","sourceRoot":"","sources":["../../../../src/lib/ui/modules/projects/ThisWebpage.svelte.ts"],"names":[],"mappings":"AAKC,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,uDAAuD,CAAC;AAMnG,QAAA,MAAM,SAAS,GAAyB,OAAO,qBAAqB,KAAqB,UAAU,CAAC,OAAO,QAAQ,EAAE,OAAO,CA4ChG,CAAC;AAE7B,QAAA,MAAM,GAAG,iBAAiB,CAAC;AAC3B,OAAO,EAAE,SAAS,EAAE,GAAG,EAAE,CAAC;AAS3B,UAAU,kCAAkC,CAAC,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,EAAE,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,EAAE,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,EAAE,OAAO,GAAG,EAAE,EAAE,QAAQ,GAAG,MAAM;IACpM,KAAK,OAAO,EAAE,OAAO,QAAQ,EAAE,2BAA2B,CAAC,KAAK,CAAC,GAAG,OAAO,QAAQ,EAAE,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,GAAG;QAAE,UAAU,CAAC,EAAE,QAAQ,CAAA;KAAE,GAAG,OAAO,CAAC;IACjK,CAAC,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,KAAK,CAAA;KAAC,GAAG,OAAO,GAAG;QAAE,IAAI,CAAC,EAAE,GAAG,CAAC;QAAC,GAAG,CAAC,EAAE,GAAG,CAAA;KAAE,CAAC;IACtG,YAAY,CAAC,EAAE,QAAQ,CAAC;CAC3B;AAKD,QAAA,MAAM,WAAW;;kBAA+E,CAAC;AAC/E,KAAK,WAAW,GAAG,YAAY,CAAC,OAAO,WAAW,CAAC,CAAC;AACtD,eAAe,WAAW,CAAC"}
1
+ {"version":3,"file":"ThisWebpage.svelte.d.ts","sourceRoot":"","sources":["../../../../src/lib/ui/modules/projects/ThisWebpage.svelte.ts"],"names":[],"mappings":"AAMC,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,uDAAuD,CAAC;AAMnG,QAAA,MAAM,SAAS,GAAyB,OAAO,qBAAqB,KAAqB,UAAU,CAAC,OAAO,QAAQ,EAAE,OAAO,CAgDhG,CAAC;AAE7B,QAAA,MAAM,GAAG,iBAAiB,CAAC;AAC3B,QAAA,MAAM,WAAW,eAAe,CAAC;AACjC,QAAA,MAAM,IAAI,UAA2F,CAAC;AACtG,OAAO,EAAE,SAAS,EAAE,GAAG,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC;AAS9C,UAAU,kCAAkC,CAAC,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,EAAE,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,EAAE,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,EAAE,OAAO,GAAG,EAAE,EAAE,QAAQ,GAAG,MAAM;IACpM,KAAK,OAAO,EAAE,OAAO,QAAQ,EAAE,2BAA2B,CAAC,KAAK,CAAC,GAAG,OAAO,QAAQ,EAAE,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,GAAG;QAAE,UAAU,CAAC,EAAE,QAAQ,CAAA;KAAE,GAAG,OAAO,CAAC;IACjK,CAAC,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,KAAK,CAAA;KAAC,GAAG,OAAO,GAAG;QAAE,IAAI,CAAC,EAAE,GAAG,CAAC;QAAC,GAAG,CAAC,EAAE,GAAG,CAAA;KAAE,CAAC;IACtG,YAAY,CAAC,EAAE,QAAQ,CAAC;CAC3B;AAKD,QAAA,MAAM,WAAW;;kBAA+E,CAAC;AAC/E,KAAK,WAAW,GAAG,YAAY,CAAC,OAAO,WAAW,CAAC,CAAC;AACtD,eAAe,WAAW,CAAC"}
@@ -13,6 +13,7 @@ TODO: delete GeneralSettingsModal.svelte
13
13
  import PineappleSwitch from "../../elements/PineappleSwitch.svelte";
14
14
 
15
15
  import LanguagePicker from "../modals/general-settings/LanguagePicker.svelte";
16
+ import { appState } from "../../templates/index";
16
17
  import {
17
18
  getEnableDialogPreferenceContext,
18
19
  getEnablePortraitContext
@@ -93,26 +94,30 @@ TODO: delete GeneralSettingsModal.svelte
93
94
  </div>
94
95
  </fieldset>
95
96
 
96
- <LanguagePicker />
97
-
98
- <div class="switch-default">
99
- <PineappleSwitch
100
- name="conversation-preference"
101
- bind:checked={$enableDialogPreference}>
102
- </PineappleSwitch>
103
- <label for="conversation-preference">
104
- Conversation preference: {$enableDialogPreference ? "Always on" : "Always off"}
105
- </label>
106
- </div>
107
- <div class="switch-default">
108
- <PineappleSwitch
109
- name="portrait-preference"
110
- bind:checked={$enablePortraitContext}>
111
- </PineappleSwitch>
112
- <label for="portrait-preference">
113
- Show conversation portrait: {$enablePortraitContext ? "Always on" : "Always off"}
114
- </label>
115
- </div>
97
+ {#if appState.isLanguagePickerAvailable}
98
+ <LanguagePicker />
99
+ {/if}
100
+
101
+ {#if appState.allowDialog}
102
+ <div class="switch-default">
103
+ <PineappleSwitch
104
+ name="conversation-preference"
105
+ bind:checked={enableDialogPreference.value}>
106
+ </PineappleSwitch>
107
+ <label for="conversation-preference">
108
+ Conversation preference: {enableDialogPreference.value ? "Always on" : "Always off"}
109
+ </label>
110
+ </div>
111
+ <div class="switch-default">
112
+ <PineappleSwitch
113
+ name="portrait-preference"
114
+ bind:checked={enablePortraitContext.value}>
115
+ </PineappleSwitch>
116
+ <label for="portrait-preference">
117
+ Show conversation portrait: {enablePortraitContext.value ? "Always on" : "Always off"}
118
+ </label>
119
+ </div>
120
+ {/if}
116
121
  </div>
117
122
 
118
123
  <style>
@@ -149,7 +154,7 @@ TODO: delete GeneralSettingsModal.svelte
149
154
 
150
155
  #field-flex {
151
156
  display: flex;
152
- flex-wrap: wrap;
157
+ flex-wrap: wrap;
153
158
  gap: 1rem;
154
159
  padding: 0.25lh 1rem;
155
160
  }
@@ -170,8 +175,8 @@ TODO: delete GeneralSettingsModal.svelte
170
175
  }
171
176
 
172
177
  .switch-default {
173
- display: flex;
174
- justify-items: center;
175
- gap: 1em;
178
+ display: flex;
179
+ justify-items: center;
180
+ gap: 1em;
176
181
  }
177
182
  </style>
@@ -1 +1 @@
1
- {"version":3,"file":"SettingsPanel.svelte.d.ts","sourceRoot":"","sources":["../../../../src/lib/ui/modules/universal-overlay/SettingsPanel.svelte.ts"],"names":[],"mappings":"AAmHA;;;;GAIG;AACH,QAAA,MAAM,aAAa,2DAAwC,CAAC;AAC5D,KAAK,aAAa,GAAG,UAAU,CAAC,OAAO,aAAa,CAAC,CAAC;AACtD,eAAe,aAAa,CAAC"}
1
+ {"version":3,"file":"SettingsPanel.svelte.d.ts","sourceRoot":"","sources":["../../../../src/lib/ui/modules/universal-overlay/SettingsPanel.svelte.ts"],"names":[],"mappings":"AAyHA;;;;GAIG;AACH,QAAA,MAAM,aAAa,2DAAwC,CAAC;AAC5D,KAAK,aAAa,GAAG,UAAU,CAAC,OAAO,aAAa,CAAC,CAAC;AACtD,eAAe,aAAa,CAAC"}
@@ -57,10 +57,10 @@ See panels:
57
57
  </script>
58
58
 
59
59
  <div class="dialog-elements"
60
- hidden={isHidden}
60
+ aria-hidden={hidePercent >= (99 * 0.4)}
61
61
  style="--hidePercentWidth: -{hidePercent}vw;
62
62
  --hidePercentHeight: {hidePercentLinear}vh;">
63
- <div class="dialog-portrait-container" class:is-portrait-enabled={$enablePortrait}>
63
+ <div class="dialog-portrait-container" class:is-portrait-enabled={enablePortrait.value}>
64
64
  <img src={currentPortrait} alt="Ares" class="dialog-portrait" />
65
65
  </div>
66
66
  <div id="main-dialog-box-container">
@@ -163,6 +163,10 @@ See panels:
163
163
  position: fixed;
164
164
  z-index: 10;
165
165
  }
166
+ .dialog-elements[aria-hidden=true] {
167
+ opacity: 0;
168
+ pointer-events: none;
169
+ }
166
170
 
167
171
  .dialog-elements:dir(ltr) {
168
172
  left: 0;
@@ -3,9 +3,9 @@
3
3
  <script lang="ts">
4
4
  import { dialogManager } from "../../..";
5
5
  import AresLogo from "../../../assets/characters/ares/ares_logo.webp";
6
- import SettingsLogo from "../../../assets/icons/icon-settings.svg";
7
- import HamburgerIcon from "../../../assets/icons/icon-menu.svg";
8
6
  import DialogIcon from "../../../assets/icons/icon-chat.svg";
7
+ import HamburgerIcon from "../../../assets/icons/icon-menu.svg";
8
+ import SettingsLogo from "../../../assets/icons/icon-settings.svg";
9
9
 
10
10
  import { m } from "../../../external/paraglide/messages";
11
11
  import { localizeHref } from "../../../external/paraglide/runtime";
@@ -16,7 +16,7 @@
16
16
  import NavigationModal from "../../modules/modals/general-settings/NavigationModal.svelte";
17
17
  import UniversalOverlay from "../../modules/universal-overlay/UniversalOverlay.svelte";
18
18
  import { getEnableDialogOverlayContext } from "../../../util/context/pineappleBaseContextDefinitions.svelte";
19
- import type { Snippet } from "svelte";
19
+ import { onMount, type Snippet } from "svelte";
20
20
  import { modals } from "svelte-modals";
21
21
  import PinyaButton from "../../elements/PinyaButton/PinyaButton.svelte";
22
22
  import { appState } from "./pinyaPageLayoutRunes.svelte.js";
@@ -33,11 +33,16 @@
33
33
  appBardEndStyle?: "classic" | "functional"
34
34
  } = $props();
35
35
 
36
- let enableUniversalOverlay = getEnableDialogOverlayContext();
36
+ let enableUniversalOverlay = $derived(getEnableDialogOverlayContext().value);
37
37
 
38
38
  const onSettingsClick = () => {
39
39
  modals.open(GeneralSettingsModal);
40
40
  };
41
+
42
+ let isMounted = $state(false);
43
+ onMount(() => {
44
+ isMounted = true;
45
+ });
41
46
  </script>
42
47
 
43
48
  {#snippet header(extraClass: string)}
@@ -94,10 +99,12 @@
94
99
  >
95
100
  <ImageIcon src={SettingsLogo} aria-hidden="true" alt=""></ImageIcon>
96
101
  </PinyaButton>
102
+ <!-- todo: investigate why enableUniversalOverlay is false here -->
97
103
  <PinyaButton
98
104
  title="Toggle conversation"
99
105
  buttonVariant={ButtonVariant.Image}
100
- colorScheme={enableUniversalOverlay.value ? ColorScheme.Secondary : undefined}
106
+ disabled={appState.allowDialog === false}
107
+ colorScheme={isMounted && enableUniversalOverlay && appState.allowDialog !== false ? ColorScheme.Secondary : undefined}
101
108
  onclick={()=>{dialogManager.toggleDialogOverlay();}}
102
109
  >
103
110
  <ImageIcon src={DialogIcon} aria-hidden="true" alt=""></ImageIcon>
@@ -126,24 +133,28 @@
126
133
 
127
134
 
128
135
  <style>
129
- :global {
136
+ :global {
137
+ .hidden {
138
+ opacity: 0;
139
+ }
140
+
130
141
  #header-action-wrapper {
131
- max-height: 2rem;
142
+ max-height: 2rem;
132
143
  display: flex;
133
144
  flex-direction: row-reverse;
134
145
  gap: 0.5rem;
135
146
 
136
- &> * {
147
+ & > * {
137
148
  padding: 0;
138
- aspect-ratio: 1 / 1;
139
- height: 100%;
140
-
141
- &> img {
142
- padding: 0.3rem;
143
- height: 95%;
144
- aspect-ratio: 1 / 1;
145
- object-fit: contain;
146
- }
149
+ aspect-ratio: 1 / 1;
150
+ height: 100%;
151
+
152
+ & > img {
153
+ padding: 0.3rem;
154
+ height: 95%;
155
+ aspect-ratio: 1 / 1;
156
+ object-fit: contain;
157
+ }
147
158
  }
148
159
 
149
160
  .pinya-button {
@@ -151,10 +162,10 @@
151
162
  }
152
163
  }
153
164
 
154
- :root {
155
- --default-page-container-margin: 4rem 1rem 0 1rem;
156
- }
157
- }
165
+ :root {
166
+ --default-page-container-margin: 4rem 1rem 0 1rem;
167
+ }
168
+ }
158
169
 
159
170
  header {
160
171
  top: 0;
@@ -1,4 +1,4 @@
1
- import type { Snippet } from "svelte";
1
+ import { type Snippet } from "svelte";
2
2
  type $$ComponentProps = {
3
3
  children: Snippet;
4
4
  appBarLead?: Snippet;
@@ -1 +1 @@
1
- {"version":3,"file":"PinyaPageLayout.svelte.d.ts","sourceRoot":"","sources":["../../../../src/lib/ui/templates/PinyaPageLayout/PinyaPageLayout.svelte.ts"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAKrC,KAAK,gBAAgB,GAAI;IACxB,QAAQ,EAAE,OAAO,CAAA;IACjB,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,eAAe,CAAC,EAAE,SAAS,GAAG,YAAY,CAAA;CAC1C,CAAC;AAyGH,QAAA,MAAM,eAAe,gEAAwC,CAAC;AAC9D,KAAK,eAAe,GAAG,UAAU,CAAC,OAAO,eAAe,CAAC,CAAC;AAC1D,eAAe,eAAe,CAAC"}
1
+ {"version":3,"file":"PinyaPageLayout.svelte.d.ts","sourceRoot":"","sources":["../../../../src/lib/ui/templates/PinyaPageLayout/PinyaPageLayout.svelte.ts"],"names":[],"mappings":"AAkBA,OAAO,EAAW,KAAK,OAAO,EAAE,MAAM,QAAQ,CAAC;AAK9C,KAAK,gBAAgB,GAAI;IACxB,QAAQ,EAAE,OAAO,CAAA;IACjB,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,eAAe,CAAC,EAAE,SAAS,GAAG,YAAY,CAAA;CAC1C,CAAC;AA+GH,QAAA,MAAM,eAAe,gEAAwC,CAAC;AAC9D,KAAK,eAAe,GAAG,UAAU,CAAC,OAAO,eAAe,CAAC,CAAC;AAC1D,eAAe,eAAe,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"pinyaPageLayoutRunes.svelte.d.ts","sourceRoot":"","sources":["../../../../src/lib/ui/templates/PinyaPageLayout/pinyaPageLayoutRunes.svelte.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAEtC,UAAU,QAAQ;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,yBAAyB,EAAE,OAAO,CAAC;IACnC,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAClC,SAAS,EAAE,MAAM,CAAC;CAClB;AAED,eAAO,MAAM,QAAQ,UAInB,CAAC"}
1
+ {"version":3,"file":"pinyaPageLayoutRunes.svelte.d.ts","sourceRoot":"","sources":["../../../../src/lib/ui/templates/PinyaPageLayout/pinyaPageLayoutRunes.svelte.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAEtC,UAAU,QAAQ;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,yBAAyB,EAAE,OAAO,CAAC;IAInC,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAClC,SAAS,EAAE,MAAM,CAAC;CAClB;AAED,eAAO,MAAM,QAAQ,UAInB,CAAC"}
@@ -1,42 +1,161 @@
1
1
  <!-- TODO: Documentation: consider documentation showcase -->
2
2
 
3
3
  <script lang="ts">
4
+ import SortDropdown from "../../components/SortDropdown.svelte";
5
+ import TagFilter from "../../components/TagFilter.svelte";
4
6
  import { PinyaCard } from "../../elements/PinyaCard";
5
7
  import type { ProjectGroup, SnippetMeta } from "./";
8
+ import { SectionType } from "./props";
6
9
 
7
10
  let {
8
11
  title,
9
12
  entryList,
10
- projectComponentProps
13
+ projectComponentProps,
14
+ // New props for Seaweed 3
15
+ sectionType = SectionType.Projects,
16
+ showFilter = false,
17
+ showSort = false,
18
+ showMoreLimit = 0
11
19
  }: ProjectGroup = $props();
12
20
 
13
- const isSpecial = $derived(entryList.length % 3 === 1);
21
+ // State
22
+ let selectedTags = $state<string[]>([]);
23
+ let sortBy = $state<string[]>(["default"]);
24
+ let isExpanded = $state(false);
14
25
 
15
- let normalUiList: SnippetMeta[] = $derived(isSpecial
16
- ? [...entryList.slice(0, -4)]
17
- : [...entryList]);
18
- let overflowUiList: SnippetMeta[] = $derived(isSpecial
19
- ? [...entryList.slice(-4)]
20
- : []);
26
+ // Derived values
27
+ const allTags = $derived([...new Set(entryList.flatMap(e => e.tags ?? []))]);
28
+
29
+ const filteredList = $derived(
30
+ selectedTags.length === 0
31
+ ? entryList
32
+ : entryList.filter(e => e.tags?.some(t => selectedTags.includes(t)))
33
+ );
34
+
35
+ function sortEntries(list: SnippetMeta[], sort: string): SnippetMeta[] {
36
+ const sorted = [...list];
37
+ switch (sort) {
38
+ case "date-desc":
39
+ return sorted.sort((a, b) => {
40
+ // Entries without dateFinished go to the bottom
41
+ if (!a.dateFinished) return 1;
42
+ if (!b.dateFinished) return -1;
43
+ return new Date(b.dateFinished).getTime() - new Date(a.dateFinished).getTime();
44
+ });
45
+ case "date-asc":
46
+ return sorted.sort((a, b) => {
47
+ // Entries without dateFinished go to the bottom
48
+ if (!a.dateFinished) return 1;
49
+ if (!b.dateFinished) return -1;
50
+ return new Date(a.dateFinished).getTime() - new Date(b.dateFinished).getTime();
51
+ });
52
+ case "duration-desc":
53
+ return sorted.sort((a, b) => {
54
+ const durationA = getDuration(a);
55
+ const durationB = getDuration(b);
56
+ // Entries without valid dates go to the bottom
57
+ if (durationA === 0) return 1;
58
+ if (durationB === 0) return -1;
59
+ return durationB - durationA;
60
+ });
61
+ case "duration-asc":
62
+ return sorted.sort((a, b) => {
63
+ const durationA = getDuration(a);
64
+ const durationB = getDuration(b);
65
+ // Entries without valid dates go to the bottom
66
+ if (durationA === 0) return 1;
67
+ if (durationB === 0) return -1;
68
+ return durationA - durationB;
69
+ });
70
+ default:
71
+ return sorted;
72
+ }
73
+ }
74
+
75
+ function getDuration(entry: SnippetMeta): number {
76
+ if (!entry.dateStarted) return 0;
77
+
78
+ if (!entry.dateFinished) {
79
+ return new Date().getTime() - new Date(entry.dateStarted).getTime();
80
+ }
81
+
82
+ return new Date(entry.dateFinished).getTime() - new Date(entry.dateStarted).getTime();
83
+ }
84
+
85
+ const sortedList = $derived(sortEntries(filteredList, sortBy.length > 0 ? sortBy[0] : "default"));
86
+
87
+ const visibleList = $derived(
88
+ showMoreLimit > 0 && !isExpanded
89
+ ? sortedList.slice(0, showMoreLimit)
90
+ : sortedList
91
+ );
92
+
93
+ const hasMore = $derived(showMoreLimit > 0 && sortedList.length > showMoreLimit);
21
94
  </script>
22
95
 
23
- <div class="mt-8 flex flex-col items-center">
96
+ <div class="flex flex-col items-center entry-group-wrapper">
24
97
  <PinyaCard class="group-header">
25
- <h2 class="m-auto">{title}</h2>
98
+ <div class="header-content">
99
+ <h2>{title}</h2>
100
+ <div class="header-controls">
101
+ {#if showFilter && allTags.length > 0}
102
+ <TagFilter bind:selectedTags {allTags} />
103
+ {/if}
104
+ {#if showSort}
105
+ <SortDropdown bind:sortBy={sortBy} {sectionType} />
106
+ {/if}
107
+ </div>
108
+ </div>
26
109
  </PinyaCard>
27
- <div class="normal-project-container">
28
- {#each normalUiList as ui (ui.key)}
29
- {@render ui.component(projectComponentProps ?? {})}
30
- {/each}
31
- </div>
32
- <div class="overflow-project-container">
33
- {#each overflowUiList as ui (ui.key)}
34
- {@render ui.component(projectComponentProps ?? {})}
35
- {/each}
36
- </div>
110
+
111
+ {#if sortedList.length === 0}
112
+ <div class="no-results">
113
+ <p>No items match your filter</p>
114
+ </div>
115
+ {:else}
116
+ <div class="normal-project-container">
117
+ {#each visibleList as ui (ui.key)}
118
+ {@render ui.component(projectComponentProps ?? {})}
119
+ {/each}
120
+ </div>
121
+
122
+ {#if hasMore}
123
+ <button class="show-more-btn" onclick={() => isExpanded = !isExpanded}>
124
+ {isExpanded ? "Show less" : `Click to see ${sortedList.length - visibleList.length} more...`}
125
+ </button>
126
+ {/if}
127
+ {/if}
37
128
  </div>
38
129
 
39
130
  <style>
131
+ .header-content {
132
+ display: flex;
133
+ flex-direction: column;
134
+ gap: 1rem;
135
+ width: 100%;
136
+ }
137
+
138
+ @media (min-width: 768px) {
139
+ .header-content {
140
+ flex-direction: row;
141
+ justify-content: space-between;
142
+ align-items: center;
143
+ }
144
+ }
145
+
146
+ .header-controls {
147
+ display: flex;
148
+ flex-direction: column;
149
+ gap: 0.5rem;
150
+ }
151
+
152
+ @media (min-width: 768px) {
153
+ .header-controls {
154
+ flex-direction: row;
155
+ gap: 1rem;
156
+ }
157
+ }
158
+
40
159
  .normal-project-container {
41
160
  display: flex;
42
161
  flex-wrap: wrap;
@@ -49,21 +168,50 @@
49
168
  align-items: start;
50
169
  }
51
170
 
52
- .overflow-project-container {
53
- display: flex;
54
- flex-wrap: wrap;
55
- gap: 2rem;
56
- margin: auto;
57
- /* 2 containers + 1 gap + extra rem */
58
- max-width: calc((28rem * 2) + 3rem);
59
- justify-content: center;
60
- align-items: start;
171
+ :global {
172
+ .upper-section-style .normal-project-container > .pinya-four-part-card {
173
+ max-width: revert;
174
+ flex-grow: revert;
175
+ flex-basis: revert;
176
+ }
177
+
178
+ .normal-project-container > .pinya-four-part-card {
179
+ max-width: 30em;
180
+ flex-grow: 1;
181
+ flex-basis: 25em;
182
+ }
183
+ }
184
+
185
+ .show-more-btn {
186
+ margin-bottom: 1.5lh;
187
+ padding: 0.5rem 1rem;
188
+ border-radius: var(--radius-lg);
189
+ border: 2px solid var(--color-primary-500);
190
+ background: transparent;
191
+ cursor: pointer;
192
+ transition: background-color 0.2s;
193
+ }
194
+
195
+ .show-more-btn:hover {
196
+ background: var(--color-primary-100);
197
+ }
198
+
199
+ .no-results {
200
+ padding: 2rem;
201
+ text-align: center;
202
+ color: var(--color-text-secondary);
61
203
  }
62
204
 
63
205
  :global {
64
206
  .group-header.pinya-card {
65
207
  margin-bottom: calc(var(--spacing) * 8);
66
208
  max-width: unset;
209
+ width: 100%;
67
210
  }
68
211
  }
212
+
213
+ .entry-group-wrapper {
214
+ max-width: calc((28rem * 3) + 5rem);
215
+ width: 100%;
216
+ }
69
217
  </style>
@@ -1 +1 @@
1
- {"version":3,"file":"EntryGroup.svelte.d.ts","sourceRoot":"","sources":["../../../../src/lib/ui/templates/SeaweedLayout/EntryGroup.svelte.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,YAAY,EAAe,MAAM,iCAAiC,CAAC;AA4CjF,QAAA,MAAM,UAAU,kDAAwC,CAAC;AACzD,KAAK,UAAU,GAAG,UAAU,CAAC,OAAO,UAAU,CAAC,CAAC;AAChD,eAAe,UAAU,CAAC"}
1
+ {"version":3,"file":"EntryGroup.svelte.d.ts","sourceRoot":"","sources":["../../../../src/lib/ui/templates/SeaweedLayout/EntryGroup.svelte.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,YAAY,EAAe,MAAM,iCAAiC,CAAC;AAwIjF,QAAA,MAAM,UAAU,kDAAwC,CAAC;AACzD,KAAK,UAAU,GAAG,UAAU,CAAC,OAAO,UAAU,CAAC,CAAC;AAChD,eAAe,UAAU,CAAC"}
@@ -102,7 +102,7 @@
102
102
  };
103
103
  });
104
104
 
105
- let comboboxValue = $state(comboboxData[0].value);
105
+ let comboboxValue = $state([comboboxData[0].value]);
106
106
 
107
107
  const addEntry = () => {
108
108
  const c = allEntries.find(e => e.key === comboboxValue[0]);
@@ -205,11 +205,9 @@
205
205
  <PinyaCombobox
206
206
  class="project-group-config"
207
207
  data={comboboxData}
208
- defaultValue={comboboxValue}
209
208
  bind:value={comboboxValue}
210
209
  label="New entry"
211
210
  placeholder="Add new entry"
212
- contentZIndex="10"
213
211
  />
214
212
  </td>
215
213
  </tr>