@glossarist/concept-browser 0.2.2 → 0.2.3

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@glossarist/concept-browser",
3
- "version": "0.2.2",
3
+ "version": "0.2.3",
4
4
  "description": "Vue SPA for browsing Glossarist terminology datasets with cross-reference resolution, graph visualization, and multi-language support",
5
5
  "type": "module",
6
6
  "bin": {
@@ -6,7 +6,7 @@ const { config } = useSiteConfig();
6
6
 
7
7
  const poweredBy = computed(() => {
8
8
  const pb = config.value?.features?.poweredBy as { title?: string; url?: string } | undefined;
9
- return { title: pb?.title || 'Glossarist', url: pb?.url || 'https://glossarist.org' };
9
+ return { title: pb?.title || 'Glossarist Concept Browser', url: pb?.url || 'https://github.com/glossarist/concept-browser' };
10
10
  });
11
11
 
12
12
  const socialLinks = computed(() => {
@@ -51,7 +51,7 @@ const ownerUrl = computed(() => config.value?.branding?.ownerUrl || '/');
51
51
  >{{ link.label }}</a>
52
52
  <span class="text-ink-200">|</span>
53
53
  <span class="text-xs">
54
- Powered by <a :href="poweredBy.url" target="_blank" rel="noopener" class="concept-link">{{ poweredBy.title }}</a>
54
+ Built with the <a :href="poweredBy.url" target="_blank" rel="noopener" class="concept-link">{{ poweredBy.title }}</a>
55
55
  </span>
56
56
  </div>
57
57
  </div>
@@ -31,6 +31,7 @@ const datasetEntries = computed(() => {
31
31
  });
32
32
 
33
33
  const currentManifest = computed(() => store.manifests.get(currentDataset.value));
34
+ const showDatasetNav = computed(() => !!currentManifest.value || !!siteConfig.value?.defaultDataset);
34
35
 
35
36
  function closeMobile() { ui.sidebarOpen = false; }
36
37
 
@@ -42,7 +43,8 @@ function goToDataset(id: string) {
42
43
  function pageRoute(page: { route: string; datasetScoped?: boolean }): string {
43
44
  if (!page.route) return '/';
44
45
  if (page.datasetScoped) {
45
- return `/dataset/${currentDataset.value}/${page.route}`;
46
+ const dsId = currentDataset.value || siteConfig.value?.defaultDataset || '';
47
+ return `/dataset/${dsId}/${page.route}`;
46
48
  }
47
49
  return `/${page.route}`;
48
50
  }
@@ -84,8 +86,8 @@ function isActive(page: { route: string; datasetScoped?: boolean }): boolean {
84
86
  </nav>
85
87
 
86
88
  <!-- Dataset-level navigation (shown when viewing a dataset) -->
87
- <div v-if="currentManifest" class="mb-6">
88
- <div class="section-label">{{ currentManifest.title }}</div>
89
+ <div v-if="showDatasetNav" class="mb-6">
90
+ <div class="section-label">{{ currentManifest?.title || siteConfig?.title || 'Dataset' }}</div>
89
91
  <nav class="space-y-0.5">
90
92
  <router-link
91
93
  v-for="page in datasetPages"
@@ -126,13 +128,13 @@ function isActive(page: { route: string; datasetScoped?: boolean }): boolean {
126
128
  <!-- Powered by -->
127
129
  <div class="mt-6 pt-4 border-t border-ink-100/60">
128
130
  <div class="text-[11px] text-ink-300">
129
- Powered by
131
+ Built with the
130
132
  <a
131
133
  :href="(siteConfig?.features?.poweredBy as any)?.url || 'https://glossarist.org'"
132
134
  target="_blank"
133
135
  rel="noopener"
134
136
  class="concept-link"
135
- >{{ (siteConfig?.features?.poweredBy as any)?.title || 'Glossarist' }}</a>
137
+ >{{ (siteConfig?.features?.poweredBy as any)?.title || 'Glossarist Concept Browser' }}</a>
136
138
  </div>
137
139
  </div>
138
140
  </div>
package/src/style.css CHANGED
@@ -196,6 +196,10 @@
196
196
  .prose-news li {
197
197
  @apply mb-1;
198
198
  }
199
+ .prose-news li.list-level-2 {
200
+ @apply pl-3;
201
+ list-style-type: circle;
202
+ }
199
203
  .prose-page a,
200
204
  .prose-news a {
201
205
  @apply concept-link;
@@ -53,11 +53,14 @@ export function renderAsciiDocLite(text: string): string {
53
53
  }
54
54
 
55
55
  // Unordered list item
56
- if (trimmed.match(/^\*\s+/)) {
56
+ if (trimmed.match(/^\*+\s+/)) {
57
57
  flushParagraph(output);
58
58
  const items: string[] = [];
59
- while (i < lines.length && lines[i].trim().match(/^\*\s+/)) {
60
- items.push(`<li>${inlineFormat(lines[i].trim().replace(/^\*\s+/, ''))}</li>`);
59
+ while (i < lines.length && lines[i].trim().match(/^\*+\s+/)) {
60
+ const itemLine = lines[i].trim();
61
+ const stars = itemLine.match(/^(\*+)\s+/)?.[1].length ?? 1;
62
+ const text = itemLine.replace(/^\*+\s+/, '');
63
+ items.push(`<li class="list-level-${stars}">${inlineFormat(text)}</li>`);
61
64
  i++;
62
65
  }
63
66
  output.push(`<ul>${items.join('')}</ul>`);
@@ -64,7 +64,11 @@ function stripFrontmatter(text: string): string {
64
64
  function formatDate(dateStr: string) {
65
65
  if (!dateStr) return '';
66
66
  try {
67
- return new Date(dateStr).toLocaleDateString('en-US', {
67
+ // Handle Jekyll-style dates: "2024-06-19 00:00:00 +0800"
68
+ const normalized = dateStr
69
+ .replace(/^(\d{4}-\d{2}-\d{2})\s+(\d{2}:\d{2}:\d{2})\s+([+-]\d{2})(\d{2})$/, '$1T$2$3:$4')
70
+ .replace(/^(\d{4}-\d{2}-\d{2})\s+([+-]\d{2})(\d{2})$/, '$1T00:00:00$2:$3');
71
+ return new Date(normalized).toLocaleDateString('en-US', {
68
72
  year: 'numeric', month: 'long', day: 'numeric',
69
73
  });
70
74
  } catch {
@@ -136,7 +140,7 @@ function formatDate(dateStr: string) {
136
140
  <p v-if="activeSlug !== post.slug && post.excerpt" class="text-ink-500 text-sm mt-2 leading-relaxed">{{ post.excerpt }}</p>
137
141
  </button>
138
142
 
139
- <div v-if="activeSlug === post.slug" class="card border-t-0 rounded-t-none p-6 pt-2 -mt-1">
143
+ <div v-if="activeSlug === post.slug" class="card rounded-t-none -mt-1 p-6 pt-3 border-t border-ink-100/40">
140
144
  <div v-if="activeLoading" class="animate-pulse space-y-2">
141
145
  <div class="h-4 bg-ink-100 rounded w-full"></div>
142
146
  <div class="h-4 bg-ink-100 rounded w-5/6"></div>