@lapis-notes/workspace 0.3.2 → 0.3.4

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/CHANGELOG.md CHANGED
@@ -1,5 +1,35 @@
1
1
  # @lapis-notes/workspace
2
2
 
3
+ ## 0.3.4
4
+
5
+ ### Patch Changes
6
+
7
+ - [#70](https://github.com/lapismd/lapis-notes/pull/70)
8
+ [`df60318`](https://github.com/lapismd/lapis-notes/commit/df603187df2680d46720ee2af0a226c6fbb25a22)
9
+ Thanks [@stevejuma](https://github.com/stevejuma)! - Show representative
10
+ skeletons while the plugin registry catalog and details load, preserving
11
+ existing empty/error states, verified metadata, and App-owned actions.
12
+ - Updated dependencies
13
+ [[`5bd58d8`](https://github.com/lapismd/lapis-notes/commit/5bd58d8033062923f09549fa341d84f22b143452),
14
+ [`8a7ec3c`](https://github.com/lapismd/lapis-notes/commit/8a7ec3c3d1d1610e8be0e3b29aab4b2f4188a0c5),
15
+ [`5292b52`](https://github.com/lapismd/lapis-notes/commit/5292b52ebc37318fcfad7971e4e309cf3afaff18)]:
16
+ - @lapis-notes/api@0.2.6
17
+
18
+ ## 0.3.3
19
+
20
+ ### Patch Changes
21
+
22
+ - [#66](https://github.com/lapismd/lapis-notes/pull/66)
23
+ [`6086980`](https://github.com/lapismd/lapis-notes/commit/6086980be8a0d9cf6e697a689b0c17f409afdc3f)
24
+ Thanks [@stevejuma](https://github.com/stevejuma)! - Consume published Design
25
+ Core 0.10.1 so browser hosts can reserve leading and trailing native controls
26
+ and title-bar height, with a continuous divider when sidebars collapse. Keep
27
+ portable registry ranges and existing compatibility.
28
+ - Updated dependencies
29
+ [[`6086980`](https://github.com/lapismd/lapis-notes/commit/6086980be8a0d9cf6e697a689b0c17f409afdc3f)]:
30
+ - @lapis-notes/api@0.2.5
31
+ - @lapis-notes/ui@0.1.7
32
+
3
33
  ## 0.3.2
4
34
 
5
35
  ### Patch Changes
@@ -26,6 +26,7 @@
26
26
  import PluginBrowserLanding from "./PluginBrowserLanding.svelte";
27
27
  import PluginBrowserDirectory from "./PluginBrowserDirectory.svelte";
28
28
  import PluginRegistryContentState from "./PluginRegistryContentState.svelte";
29
+ import PluginRegistrySkeleton from "./PluginRegistrySkeleton.svelte";
29
30
  import PluginBrowserDetail from "./PluginBrowserDetail.svelte";
30
31
  import "./community-presentation/community-typography.css";
31
32
  export interface PluginBrowserNavigation {
@@ -409,10 +410,9 @@
409
410
  label="Registry content"
410
411
  >
411
412
  <div class="registry-browser">
412
- {#if registry.initialLoading}<PluginRegistryContentState
413
- kind="loading"
414
- heading="Loading plugins"
415
- description="Reading your verified registry…"
413
+ {#if registry.initialLoading}<PluginRegistrySkeleton
414
+ layout={navigation.route.page === "plugin" ? "detail" : navigation.route.page}
415
+ label="Loading plugins"
416
416
  />
417
417
  {:else if registry.lastError && !registry.catalogEntries.length}<PluginRegistryContentState
418
418
  kind="warning"
@@ -495,10 +495,9 @@
495
495
  persist();
496
496
  }}
497
497
  />
498
- {:else if selected && session.loading}<PluginRegistryContentState
499
- kind="loading"
500
- heading="Loading plugin details"
501
- description="Reading verified plugin metadata…"
498
+ {:else if selected && session.loading}<PluginRegistrySkeleton
499
+ layout="detail"
500
+ label="Loading plugin details"
502
501
  />
503
502
  {:else}<PluginRegistryContentState
504
503
  kind="empty"
@@ -5,6 +5,7 @@
5
5
  import SearchX from "@lucide/svelte/icons/search-x";
6
6
  import Sparkles from "@lucide/svelte/icons/sparkles";
7
7
  import * as Button from "@lapismd/design-core/shadcn/button";
8
+ import PluginRegistrySkeleton from "./PluginRegistrySkeleton.svelte";
8
9
 
9
10
  let {
10
11
  kind,
@@ -29,6 +30,9 @@
29
30
  } = $props();
30
31
  </script>
31
32
 
33
+ {#if kind === "loading"}
34
+ <PluginRegistrySkeleton label={heading} />
35
+ {:else}
32
36
  <div
33
37
  class="lapis-plugin-registry-state"
34
38
  data-ui-component="plugin-registry-content-state"
@@ -56,7 +60,7 @@
56
60
  <AlertTriangle />
57
61
  {:else}
58
62
  <PackageIcon />
59
- {#if kind !== "loading"}<Sparkles />{/if}
63
+ <Sparkles />
60
64
  {/if}
61
65
  </div>
62
66
  <div class="lapis-plugin-registry-state__body">
@@ -78,3 +82,4 @@
78
82
  {/if}
79
83
  </div>
80
84
  </div>
85
+ {/if}
@@ -0,0 +1,112 @@
1
+ <script lang="ts">
2
+ import { Skeleton } from "@lapismd/design-core/shadcn/skeleton";
3
+
4
+ let {
5
+ layout = "list",
6
+ label = "Loading plugins",
7
+ }: {
8
+ layout?: "landing" | "directory" | "detail" | "list";
9
+ label?: string;
10
+ } = $props();
11
+ </script>
12
+
13
+ <div
14
+ class="registry-skeleton"
15
+ data-ui-component="plugin-registry-skeleton"
16
+ data-layout={layout}
17
+ aria-busy="true"
18
+ >
19
+ <span class="sr-only" role="status">{label}</span>
20
+ <div class="registry-skeleton__layout" aria-hidden="true">
21
+ <header class="registry-skeleton__header">
22
+ {#if layout === "detail"}
23
+ <Skeleton class="registry-skeleton__avatar" />
24
+ {/if}
25
+ <div class="registry-skeleton__copy">
26
+ <Skeleton class="registry-skeleton__title" />
27
+ <Skeleton class="registry-skeleton__line" />
28
+ <Skeleton class="registry-skeleton__short" />
29
+ </div>
30
+ {#if layout === "detail" || layout === "directory"}
31
+ <Skeleton class="registry-skeleton__action" />
32
+ {/if}
33
+ </header>
34
+ {#if layout === "detail"}
35
+ <Skeleton class="registry-skeleton__banner" data-ui-part="banner" />
36
+ <div class="registry-skeleton__detail">
37
+ <div class="registry-skeleton__copy" data-ui-part="overview">
38
+ <Skeleton class="registry-skeleton__title" />
39
+ {#each Array(5) as _}<Skeleton class="registry-skeleton__line" />{/each}
40
+ </div>
41
+ <aside class="registry-skeleton__copy" data-ui-part="metadata">
42
+ <Skeleton class="registry-skeleton__short" />
43
+ {#each Array(5) as _}<Skeleton class="registry-skeleton__line" />{/each}
44
+ </aside>
45
+ </div>
46
+ {:else}
47
+ <div class="registry-skeleton__cards" data-ui-part="cards">
48
+ {#each Array(layout === "landing" ? 3 : layout === "directory" ? 6 : 4) as _}
49
+ <div class="registry-skeleton__card">
50
+ <Skeleton class="registry-skeleton__avatar" />
51
+ <div class="registry-skeleton__copy">
52
+ <Skeleton class="registry-skeleton__short" />
53
+ <Skeleton class="registry-skeleton__line" />
54
+ <Skeleton class="registry-skeleton__line" />
55
+ </div>
56
+ </div>
57
+ {/each}
58
+ </div>
59
+ {/if}
60
+ </div>
61
+ </div>
62
+
63
+ <style>
64
+ .registry-skeleton {
65
+ container-type: inline-size;
66
+ width: 100%;
67
+ min-width: 0;
68
+ padding: 1.5rem;
69
+ color: var(--ui-workspace-foreground, var(--foreground));
70
+ --ui-skeleton-background: color-mix(in srgb, var(--ui-workspace-foreground, var(--foreground)) 9%, var(--ui-workspace-view-background, var(--background)));
71
+ }
72
+ .registry-skeleton__layout,
73
+ .registry-skeleton__copy,
74
+ .registry-skeleton__cards,
75
+ .registry-skeleton__detail {
76
+ display: grid;
77
+ min-width: 0;
78
+ gap: 1rem;
79
+ }
80
+ .registry-skeleton__layout { gap: 2rem; }
81
+ .registry-skeleton__header,
82
+ .registry-skeleton__card {
83
+ display: flex;
84
+ min-width: 0;
85
+ align-items: center;
86
+ gap: 1rem;
87
+ }
88
+ .registry-skeleton__card {
89
+ border: 1px solid var(--ui-workspace-border, var(--border));
90
+ border-radius: var(--radius);
91
+ padding: 1rem;
92
+ }
93
+ .registry-skeleton__copy { flex: 1; }
94
+ .registry-skeleton :global(.registry-skeleton__avatar) {
95
+ width: 3.5rem;
96
+ height: 3.5rem;
97
+ flex-shrink: 0;
98
+ }
99
+ .registry-skeleton :global(.registry-skeleton__title) { width: min(75%, 20rem); height: 2rem; }
100
+ .registry-skeleton :global(.registry-skeleton__line) { height: 0.875rem; width: 100%; }
101
+ .registry-skeleton :global(.registry-skeleton__short) { height: 0.875rem; width: 60%; }
102
+ .registry-skeleton :global(.registry-skeleton__action) { height: 2.25rem; width: 6rem; }
103
+ .registry-skeleton :global(.registry-skeleton__banner) { width: 100%; aspect-ratio: 3 / 1; }
104
+ @container (min-width: 44rem) {
105
+ [data-layout="landing"] .registry-skeleton__cards,
106
+ [data-layout="directory"] .registry-skeleton__cards { grid-template-columns: repeat(3, minmax(0, 1fr)); }
107
+ .registry-skeleton__detail { grid-template-columns: minmax(0, 2fr) minmax(0, 1fr); gap: 2rem; }
108
+ }
109
+ @media (prefers-reduced-motion: reduce) {
110
+ .registry-skeleton :global([data-ui-component="skeleton"]) { animation: none; }
111
+ }
112
+ </style>
@@ -0,0 +1,7 @@
1
+ type $$ComponentProps = {
2
+ layout?: "landing" | "directory" | "detail" | "list";
3
+ label?: string;
4
+ };
5
+ declare const PluginRegistrySkeleton: import("svelte").Component<$$ComponentProps, {}, "">;
6
+ type PluginRegistrySkeleton = ReturnType<typeof PluginRegistrySkeleton>;
7
+ export default PluginRegistrySkeleton;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lapis-notes/workspace",
3
- "version": "0.3.2",
3
+ "version": "0.3.4",
4
4
  "description": "Lapis Notes workspace shell backed by design-core",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -38,10 +38,10 @@
38
38
  }
39
39
  },
40
40
  "dependencies": {
41
- "@lapis-notes/api": "^0.2.4",
42
- "@lapismd/design-core": "^0.8.0 || ^0.9.0",
43
- "@lucide/svelte": "^0.523.0",
44
- "@lapis-notes/ui": "^0.1.6"
41
+ "@lapis-notes/api": "^0.2.6",
42
+ "@lapis-notes/ui": "^0.1.7",
43
+ "@lapismd/design-core": "^0.8.0 || ^0.9.0 || ^0.10.0",
44
+ "@lucide/svelte": "^0.523.0"
45
45
  },
46
46
  "peerDependencies": {
47
47
  "svelte": "^5.0.0"