@publier/shell 3.1.5

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 (140) hide show
  1. package/README.md +1 -0
  2. package/dist/build-integration.d.mts +7 -0
  3. package/dist/build-integration.mjs +1 -0
  4. package/dist/image-zoom-runtime-Cr8vBrXH.mjs +1 -0
  5. package/dist/index-Bc-beOEe.d.mts +1033 -0
  6. package/dist/index.d.mts +33 -0
  7. package/dist/index.mjs +1 -0
  8. package/dist/integration-6L__3wwu.mjs +102 -0
  9. package/dist/integration-DKTmdCWN.d.mts +203 -0
  10. package/dist/integration.d.mts +2 -0
  11. package/dist/integration.mjs +1 -0
  12. package/dist/loaders/index.d.mts +54 -0
  13. package/dist/loaders/index.mjs +1 -0
  14. package/dist/plugins/remark-asides.d.mts +8 -0
  15. package/dist/plugins/remark-asides.mjs +2 -0
  16. package/dist/plugins/remark-snippets.d.mts +11 -0
  17. package/dist/plugins/remark-snippets.mjs +1 -0
  18. package/dist/plugins/remark-structure.d.mts +13 -0
  19. package/dist/plugins/remark-structure.mjs +1 -0
  20. package/dist/plugins/remark-vars.d.mts +7 -0
  21. package/dist/plugins/remark-vars.mjs +1 -0
  22. package/dist/presets-DL0qjtya.mjs +1 -0
  23. package/dist/presets-RGpZ_X1B.d.mts +16 -0
  24. package/dist/runtime/code-group-sync.d.mts +30 -0
  25. package/dist/runtime/code-group-sync.mjs +103 -0
  26. package/dist/runtime/lazy-upgrade-registry.d.mts +41 -0
  27. package/dist/runtime/lazy-upgrade-registry.mjs +1 -0
  28. package/dist/runtime/tabs-sync.d.mts +25 -0
  29. package/dist/runtime/tabs-sync.mjs +106 -0
  30. package/dist/search/index.d.mts +92 -0
  31. package/dist/search/index.mjs +1 -0
  32. package/dist/tailwind/css-plugin.d.mts +16 -0
  33. package/dist/tailwind/css-plugin.mjs +1 -0
  34. package/dist/tailwind/index.d.mts +6 -0
  35. package/dist/tailwind/index.mjs +1 -0
  36. package/dist/tailwind/loader.d.mts +94 -0
  37. package/dist/tailwind/loader.mjs +2 -0
  38. package/dist/theme-toggle-element-DzFjxwpS.mjs +1 -0
  39. package/dist/themes/almond.css +115 -0
  40. package/dist/themes/aspen.css +95 -0
  41. package/dist/themes/catppuccin.css +98 -0
  42. package/dist/themes/dark.css +98 -0
  43. package/dist/themes/dusk.css +98 -0
  44. package/dist/themes/emerald.css +95 -0
  45. package/dist/themes/light.css +95 -0
  46. package/dist/themes/maple.css +119 -0
  47. package/dist/themes/neutral.css +73 -0
  48. package/dist/themes/ocean.css +98 -0
  49. package/dist/themes/purple.css +95 -0
  50. package/dist/themes/ruby.css +95 -0
  51. package/dist/themes/solar.css +98 -0
  52. package/dist/themes/vitepress.css +95 -0
  53. package/package.json +178 -0
  54. package/src/astro-modules.d.ts +20 -0
  55. package/src/components/LastModified.astro +25 -0
  56. package/src/components/announcement-banner.astro +25 -0
  57. package/src/components/aside.astro +17 -0
  58. package/src/components/ask-ai.tsx +146 -0
  59. package/src/components/badge.astro +18 -0
  60. package/src/components/breadcrumbs.astro +23 -0
  61. package/src/components/callouts/caution.astro +13 -0
  62. package/src/components/callouts/check.astro +13 -0
  63. package/src/components/callouts/danger.astro +13 -0
  64. package/src/components/callouts/info.astro +13 -0
  65. package/src/components/callouts/note.astro +13 -0
  66. package/src/components/callouts/tip.astro +13 -0
  67. package/src/components/callouts/warning.astro +13 -0
  68. package/src/components/card-grid.astro +14 -0
  69. package/src/components/card.astro +18 -0
  70. package/src/components/code-group.astro +55 -0
  71. package/src/components/columns.astro +18 -0
  72. package/src/components/docs-layout.astro +25 -0
  73. package/src/components/file-tree-node.astro +13 -0
  74. package/src/components/file-tree.astro +9 -0
  75. package/src/components/icon.astro +18 -0
  76. package/src/components/index.ts +154 -0
  77. package/src/components/link-button.astro +21 -0
  78. package/src/components/link-card.astro +21 -0
  79. package/src/components/open-in-ai.astro +13 -0
  80. package/src/components/package-install.astro +17 -0
  81. package/src/components/panels.astro +16 -0
  82. package/src/components/search-button.astro +21 -0
  83. package/src/components/sidebar.astro +12 -0
  84. package/src/components/skip-link.astro +12 -0
  85. package/src/components/steps.astro +13 -0
  86. package/src/components/table-of-contents.astro +22 -0
  87. package/src/components/tabs.astro +17 -0
  88. package/src/components/theme-storage.ts +5 -0
  89. package/src/components/theme-toggle-element.ts +85 -0
  90. package/src/components/theme-toggle.astro +25 -0
  91. package/src/components/tile-grid.astro +13 -0
  92. package/src/components/tile.astro +17 -0
  93. package/src/components/top-nav-mobile.astro +11 -0
  94. package/src/components/top-nav.astro +20 -0
  95. package/src/components/types.ts +522 -0
  96. package/src/components/ui/blur-image.astro +60 -0
  97. package/src/components/ui/changelog-entry.astro +56 -0
  98. package/src/components/ui/cta-band.astro +30 -0
  99. package/src/components/ui/feature-grid.astro +38 -0
  100. package/src/components/ui/feature-section.astro +85 -0
  101. package/src/components/ui/frame.astro +52 -0
  102. package/src/components/ui/hero.astro +47 -0
  103. package/src/components/ui/jobs-list.astro +53 -0
  104. package/src/components/ui/logo-cloud.astro +68 -0
  105. package/src/components/ui/press-gallery.astro +52 -0
  106. package/src/components/ui/pricing-comparison-table.astro +73 -0
  107. package/src/components/ui/pricing-section.astro +113 -0
  108. package/src/components/ui/pricing-table.astro +54 -0
  109. package/src/components/ui/status-indicator.astro +38 -0
  110. package/src/components/ui/team-grid.astro +63 -0
  111. package/src/components/ui/testimonial-card.astro +42 -0
  112. package/src/components/ui/types.ts +323 -0
  113. package/src/components/update-badge.astro +15 -0
  114. package/src/components/version-switcher.astro +20 -0
  115. package/src/icons/index.tsx +195 -0
  116. package/src/layouts/base-layout.astro +65 -0
  117. package/src/qwik.ts +3 -0
  118. package/src/routes/blog-index.astro +20 -0
  119. package/src/routes/blog-rss.xml.ts +40 -0
  120. package/src/routes/blog-slug.astro +32 -0
  121. package/src/routes/changelog-index.astro +25 -0
  122. package/src/routes/changelog-rss.xml.ts +47 -0
  123. package/src/routes/docs-slug.astro +31 -0
  124. package/src/routes/not-found.astro +14 -0
  125. package/src/runtime/banner-init.ts +9 -0
  126. package/src/runtime/lazy-upgrade-init.ts +5 -0
  127. package/src/runtime/sidebar-scroll-init.ts +3 -0
  128. package/src/runtime/theme-init.ts +16 -0
  129. package/src/schemas/blog.ts +38 -0
  130. package/src/schemas/changelog.ts +29 -0
  131. package/src/schemas/common.ts +88 -0
  132. package/src/schemas/docs.ts +104 -0
  133. package/src/schemas/index.ts +14 -0
  134. package/src/schemas/pages.ts +23 -0
  135. package/src/styles/base.css +627 -0
  136. package/src/styles/expressive-code.css +41 -0
  137. package/src/styles/rules.css +66 -0
  138. package/src/styles/tailwind-sources.css +17 -0
  139. package/src/tailwind/preset.css +193 -0
  140. package/src/virtual-modules.d.ts +164 -0
package/package.json ADDED
@@ -0,0 +1,178 @@
1
+ {
2
+ "name": "@publier/shell",
3
+ "version": "3.1.5",
4
+ "license": "UNLICENSED",
5
+ "description": "Qwik + Astro docs layout for Publier sites.",
6
+ "_filesRationale": "mixed: dist for build-time TS + source globs for shipped .astro components",
7
+ "type": "module",
8
+ "files": [
9
+ "dist",
10
+ "src/**/*.astro",
11
+ "src/**/*.css",
12
+ "!src/tailwind/themes/**",
13
+ "src/routes/**/*.xml.ts",
14
+ "src/schemas/**/*.ts",
15
+ "src/components/index.ts",
16
+ "src/components/types.ts",
17
+ "src/components/ui/types.ts",
18
+ "src/components/ask-ai.tsx",
19
+ "src/components/theme-storage.ts",
20
+ "src/components/theme-toggle-element.ts",
21
+ "src/runtime/banner-init.ts",
22
+ "src/runtime/lazy-upgrade-init.ts",
23
+ "src/runtime/sidebar-scroll-init.ts",
24
+ "src/runtime/theme-init.ts",
25
+ "src/icons/index.tsx",
26
+ "src/qwik.ts",
27
+ "src/astro-modules.d.ts",
28
+ "src/virtual-modules.d.ts",
29
+ "!src/**/__tests__/**",
30
+ "!src/**/*.test.ts",
31
+ "!src/**/*.test.tsx",
32
+ "!src/**/*.tsbuildinfo"
33
+ ],
34
+ "exports": {
35
+ ".": {
36
+ "types": "./dist/index.d.mts",
37
+ "import": "./dist/index.mjs"
38
+ },
39
+ "./qwik": "./src/qwik.ts",
40
+ "./build": {
41
+ "types": "./dist/build-integration.d.mts",
42
+ "import": "./dist/build-integration.mjs"
43
+ },
44
+ "./schemas": "./src/schemas/index.ts",
45
+ "./loaders": {
46
+ "types": "./dist/loaders/index.d.mts",
47
+ "import": "./dist/loaders/index.mjs"
48
+ },
49
+ "./components": "./src/components/index.ts",
50
+ "./layouts/base-layout.astro": "./src/layouts/base-layout.astro",
51
+ "./routes/*.astro": "./src/routes/*.astro",
52
+ "./routes/*.xml.ts": "./src/routes/*.xml.ts",
53
+ "./search": {
54
+ "types": "./dist/search/index.d.mts",
55
+ "import": "./dist/search/index.mjs"
56
+ },
57
+ "./styles/base.css": "./src/styles/base.css",
58
+ "./styles/expressive-code.css": "./src/styles/expressive-code.css",
59
+ "./styles/tailwind-sources.css": "./src/styles/tailwind-sources.css",
60
+ "./plugins/remark-structure": {
61
+ "types": "./dist/plugins/remark-structure.d.mts",
62
+ "import": "./dist/plugins/remark-structure.mjs"
63
+ },
64
+ "./plugins/remark-asides": {
65
+ "types": "./dist/plugins/remark-asides.d.mts",
66
+ "import": "./dist/plugins/remark-asides.mjs"
67
+ },
68
+ "./plugins/remark-snippets": {
69
+ "types": "./dist/plugins/remark-snippets.d.mts",
70
+ "import": "./dist/plugins/remark-snippets.mjs"
71
+ },
72
+ "./plugins/remark-vars": {
73
+ "types": "./dist/plugins/remark-vars.d.mts",
74
+ "import": "./dist/plugins/remark-vars.mjs"
75
+ },
76
+ "./integration": {
77
+ "types": "./dist/integration.d.mts",
78
+ "import": "./dist/integration.mjs"
79
+ },
80
+ "./runtime/code-group-sync": {
81
+ "types": "./dist/runtime/code-group-sync.d.mts",
82
+ "import": "./dist/runtime/code-group-sync.mjs"
83
+ },
84
+ "./runtime/lazy-upgrade-registry": {
85
+ "types": "./dist/runtime/lazy-upgrade-registry.d.mts",
86
+ "import": "./dist/runtime/lazy-upgrade-registry.mjs"
87
+ },
88
+ "./runtime/tabs-sync": {
89
+ "types": "./dist/runtime/tabs-sync.d.mts",
90
+ "import": "./dist/runtime/tabs-sync.mjs"
91
+ },
92
+ "./tailwind": {
93
+ "types": "./dist/tailwind/index.d.mts",
94
+ "import": "./dist/tailwind/index.mjs"
95
+ },
96
+ "./tailwind/css-plugin": {
97
+ "types": "./dist/tailwind/css-plugin.d.mts",
98
+ "import": "./dist/tailwind/css-plugin.mjs"
99
+ },
100
+ "./tailwind/loader": {
101
+ "types": "./dist/tailwind/loader.d.mts",
102
+ "import": "./dist/tailwind/loader.mjs"
103
+ },
104
+ "./tailwind/preset.css": "./src/tailwind/preset.css",
105
+ "./tailwind/themes/*": "./dist/themes/*"
106
+ },
107
+ "publishConfig": {
108
+ "access": "public"
109
+ },
110
+ "dependencies": {
111
+ "@astrojs/rss": "^4.0.18",
112
+ "@astrojs/sitemap": "^3.7.2",
113
+ "@fontsource-variable/inter": "^5.2.8",
114
+ "@fontsource-variable/jetbrains-mono": "^5.2.8",
115
+ "@github/clipboard-copy-element": "^1.3.0",
116
+ "@github/relative-time-element": "^5.0.0",
117
+ "@github/tab-container-element": "^4.8.2",
118
+ "@tailwindcss/typography": "^0.5.19",
119
+ "astro-pagefind": "^1.8.6",
120
+ "daisyui": "^5.5.19",
121
+ "hastscript": "^9.0.1",
122
+ "katex": "^0.16.45",
123
+ "mdast-util-directive": "^3.1.0",
124
+ "mdast-util-from-markdown": "^2.0.3",
125
+ "mdast-util-to-markdown": "^2.1.2",
126
+ "mdast-util-to-string": "^4.0.0",
127
+ "medium-zoom": "^1.1.0",
128
+ "rehype-autolink-headings": "^7.1.0",
129
+ "rehype-external-links": "^3.0.0",
130
+ "rehype-katex": "^7.0.1",
131
+ "remark-directive": "^4.0.0",
132
+ "remark-gfm": "^4.0.1",
133
+ "remark-math": "^6.0.0",
134
+ "unist-util-visit": "^5.1.0",
135
+ "yaml": "^2.9.0",
136
+ "@publier/native": "1.1.3"
137
+ },
138
+ "peerDependencies": {
139
+ "@astrojs/markdown-remark": ">=7.0.0",
140
+ "@qwik.dev/astro": ">=1.0.0",
141
+ "@qwik.dev/core": ">=2.0.0-beta",
142
+ "@tailwindcss/vite": "^4",
143
+ "astro": "^6.0.0 || >=7.0.0-alpha.0",
144
+ "astro-expressive-code": ">=0.35.0",
145
+ "tailwindcss": "^4",
146
+ "vite": ">=8"
147
+ },
148
+ "peerDependenciesMeta": {
149
+ "astro-expressive-code": {
150
+ "optional": true
151
+ }
152
+ },
153
+ "devDependencies": {
154
+ "@astrojs/mdx": "^7.0.0",
155
+ "@qwik.dev/core": "2.0.0-beta.34",
156
+ "@types/mdast": "^4.0.4",
157
+ "astro": "7.0.0",
158
+ "rehype-stringify": "^10.0.1",
159
+ "remark-parse": "^11.0.0",
160
+ "remark-rehype": "^11.1.2",
161
+ "tsdown": "^0.22.0",
162
+ "typescript": "^6.0.3",
163
+ "unified": "^11.0.5",
164
+ "vfile": "^6.0.3",
165
+ "vite": "^8.0.12"
166
+ },
167
+ "repository": {
168
+ "type": "git",
169
+ "url": "https://github.com/Publier/publier.git",
170
+ "directory": "packages/shell"
171
+ },
172
+ "scripts": {
173
+ "build": "tsdown && node --experimental-strip-types --no-warnings ../../tools/css-theme-precompile/precompile.ts .",
174
+ "dev": "tsdown --watch",
175
+ "check-types": "tsc --noEmit",
176
+ "test": "echo \"@publier/shell: covered by root vitest workspace\" && exit 0"
177
+ }
178
+ }
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Ambient type for `.astro` component imports.
3
+ *
4
+ * Astro files are normally typed via `astro sync` in a consumer project,
5
+ * but `@publier/shell` type-checks its own source via `tsc --noEmit` outside
6
+ * of Astro's build pipeline. This declaration lets `index.ts` re-export the
7
+ * default export of sibling `.astro` files without TypeScript erroring.
8
+ *
9
+ * At runtime, the consumer's Astro build (via Vite's astro plugin) provides
10
+ * the real implementation — the `.astro` default export is an Astro
11
+ * `ComponentFactory` that Astro's SSR renderer knows how to emit.
12
+ */
13
+ declare module '*.astro' {
14
+ // Props are validated in each `.astro` file's own frontmatter via an
15
+ // exported `Props` interface; we use `any` at the boundary to avoid
16
+ // forcing a generic type import everywhere.
17
+ // biome-ignore lint/suspicious/noExplicitAny: library-boundary escape hatch, see docblock above.
18
+ const Component: (_props: any) => any;
19
+ export default Component;
20
+ }
@@ -0,0 +1,25 @@
1
+ ---
2
+ import { shellRenderLastModified } from '@publier/native';
3
+
4
+ interface Props {
5
+ date: Date | string | null | undefined;
6
+ format?: 'relative' | 'absolute';
7
+ }
8
+
9
+ const { date, format = 'relative' } = Astro.props;
10
+
11
+ const parsed: Date | null = date
12
+ ? date instanceof Date
13
+ ? Number.isNaN(date.getTime())
14
+ ? null
15
+ : date
16
+ : (() => {
17
+ const d = new Date(date);
18
+ return Number.isNaN(d.getTime()) ? null : d;
19
+ })()
20
+ : null;
21
+
22
+ const html = shellRenderLastModified(parsed ? parsed.getTime() : null, Date.now(), format);
23
+ ---
24
+
25
+ <Fragment set:html={html} />
@@ -0,0 +1,25 @@
1
+ ---
2
+ import { shellRenderAnnouncementBanner } from '@publier/native';
3
+
4
+ export type AnnouncementBannerVariant = 'info' | 'warning' | 'success';
5
+
6
+ interface Props {
7
+ message: string;
8
+ href?: string;
9
+ variant?: AnnouncementBannerVariant;
10
+ dismissible?: boolean;
11
+ storageKey?: string;
12
+ }
13
+
14
+ const {
15
+ message,
16
+ href,
17
+ variant = 'info',
18
+ dismissible = true,
19
+ storageKey = 'publier-banner-dismissed',
20
+ } = Astro.props;
21
+
22
+ const html = shellRenderAnnouncementBanner(message, href ?? null, variant, dismissible, storageKey);
23
+ ---
24
+
25
+ <Fragment set:html={html} />
@@ -0,0 +1,17 @@
1
+ ---
2
+ import { shellRenderAside } from '@publier/native';
3
+
4
+ export type AsideType = 'note' | 'tip' | 'caution' | 'danger';
5
+
6
+ interface Props {
7
+ type?: AsideType;
8
+ title?: string;
9
+ }
10
+
11
+ const { type = 'note', title } = Astro.props;
12
+ const titleId = `publier-aside-${Math.random().toString(36).slice(2, 10)}`;
13
+ const slotHtml = await Astro.slots.render('default');
14
+ const html = shellRenderAside(type, title ?? null, slotHtml, titleId);
15
+ ---
16
+
17
+ <Fragment set:html={html} />
@@ -0,0 +1,146 @@
1
+ import { $, component$, useOnDocument, useSignal, useVisibleTask$ } from '@qwik.dev/core';
2
+ import { MessageCircle, Send, Sparkles, X } from '../icons/index';
3
+
4
+ export const AskAi = component$(() => {
5
+ const open = useSignal(false);
6
+ const input = useSignal('');
7
+ const textareaRef = useSignal<HTMLTextAreaElement>();
8
+
9
+
10
+ useOnDocument(
11
+ 'keydown',
12
+ $((e: Event) => {
13
+ const ke = e as KeyboardEvent;
14
+ if ((ke.metaKey || ke.ctrlKey) && ke.key === '/') {
15
+ ke.preventDefault();
16
+ open.value = !open.value;
17
+ }
18
+ if (ke.key === 'Escape' && open.value) {
19
+ open.value = false;
20
+ }
21
+ }),
22
+ );
23
+
24
+
25
+ useOnDocument(
26
+ 'publier:ai-toggle',
27
+ $(() => {
28
+ open.value = !open.value;
29
+ }),
30
+ );
31
+
32
+
33
+
34
+ // biome-ignore lint/correctness/noQwikUseVisibleTask: focusing a dialog input after it mounts requires DOM access.
35
+ useVisibleTask$(({ track }) => {
36
+ track(() => open.value);
37
+ if (open.value) {
38
+ textareaRef.value?.focus();
39
+ }
40
+ });
41
+
42
+ return (
43
+ <>
44
+ {}
45
+ <button
46
+ type="button"
47
+ class={[
48
+ 'fixed bottom-4 right-4 z-50 inline-flex items-center gap-2 rounded-full border border-border bg-background px-4 py-2.5 text-sm font-medium text-foreground shadow-lg transition-all hover:bg-accent',
49
+ open.value ? 'translate-y-10 opacity-0 pointer-events-none' : '',
50
+ ].join(' ')}
51
+ onClick$={() => {
52
+ open.value = true;
53
+ }}
54
+ aria-label="Ask AI"
55
+ >
56
+ <MessageCircle width={16} height={16} />
57
+ <span>Ask AI</span>
58
+ </button>
59
+
60
+ {}
61
+ {open.value && (
62
+ <>
63
+ {}
64
+ <div
65
+ class="fixed inset-0 z-50 bg-background/80 backdrop-blur-sm lg:hidden"
66
+ onClick$={() => {
67
+ open.value = false;
68
+ }}
69
+ />
70
+
71
+ {}
72
+ <div
73
+ role="dialog"
74
+ aria-modal="true"
75
+ aria-label="Ask AI"
76
+ class="fixed inset-x-2 top-4 z-50 flex flex-col rounded-2xl border border-border bg-background shadow-2xl lg:inset-x-auto lg:inset-y-2 lg:right-2 lg:w-[460px] lg:rounded-xl"
77
+ >
78
+ {}
79
+ <div class="flex items-center justify-between border-b border-border px-4 py-3">
80
+ <div class="flex items-center gap-2">
81
+ <Sparkles width={16} height={16} class="text-primary" />
82
+ <span class="text-sm font-medium">Ask AI</span>
83
+ </div>
84
+ <button
85
+ type="button"
86
+ class="rounded-md p-1 text-muted-foreground transition-colors hover:bg-accent hover:text-foreground"
87
+ onClick$={() => {
88
+ open.value = false;
89
+ }}
90
+ aria-label="Close"
91
+ >
92
+ <X width={16} height={16} />
93
+ </button>
94
+ </div>
95
+
96
+ {}
97
+ <div class="flex-1 overflow-y-auto px-4 py-6">
98
+ <div class="flex flex-col items-center justify-center gap-3 text-center text-muted-foreground">
99
+ <div class="flex size-12 items-center justify-center rounded-full bg-accent">
100
+ <Sparkles width={24} height={24} class="text-primary" />
101
+ </div>
102
+ <p class="text-sm font-medium text-foreground">How can I help you?</p>
103
+ <p class="text-xs">Ask a question about the documentation.</p>
104
+ <p class="mt-4 text-xs">AI integration coming soon.</p>
105
+ </div>
106
+ </div>
107
+
108
+ {}
109
+ <div class="border-t border-border p-3">
110
+ <div class="flex items-end gap-2">
111
+ <textarea
112
+ ref={textareaRef}
113
+ class="max-h-32 min-h-[40px] flex-1 resize-none rounded-lg border border-border bg-muted/40 px-3 py-2 text-sm text-foreground placeholder:text-muted-foreground focus:border-primary focus:outline-none"
114
+ placeholder="Ask a question..."
115
+ rows={1}
116
+ value={input.value}
117
+ onInput$={(_, el) => {
118
+ input.value = el.value;
119
+ }}
120
+ />
121
+ <button
122
+ type="button"
123
+ class="flex size-9 shrink-0 items-center justify-center rounded-lg bg-primary text-primary-foreground transition-colors hover:bg-primary/90 disabled:opacity-50"
124
+ disabled={!input.value.trim()}
125
+ aria-label="Send"
126
+ >
127
+ <Send width={16} height={16} />
128
+ </button>
129
+ </div>
130
+ <div class="mt-2 flex items-center justify-between text-[10px] text-muted-foreground">
131
+ <span>
132
+ Press{' '}
133
+ <kbd class="rounded border border-border bg-background px-1 py-0.5 font-mono">
134
+ ⌘/
135
+ </kbd>{' '}
136
+ to toggle
137
+ </span>
138
+ <span>Powered by Publier AI</span>
139
+ </div>
140
+ </div>
141
+ </div>
142
+ </>
143
+ )}
144
+ </>
145
+ );
146
+ });
@@ -0,0 +1,18 @@
1
+ ---
2
+ import { shellRenderBadge } from '@publier/native';
3
+
4
+ export type BadgeVariant = 'default' | 'note' | 'tip' | 'caution' | 'danger' | 'success';
5
+ export type BadgeSize = 'small' | 'medium' | 'large';
6
+
7
+ interface Props {
8
+ text: string;
9
+ variant?: BadgeVariant;
10
+ size?: BadgeSize;
11
+ class?: string;
12
+ }
13
+
14
+ const { text, variant = 'default', size = 'medium', class: customClass } = Astro.props;
15
+ const html = shellRenderBadge(text, variant, size, customClass ?? null);
16
+ ---
17
+
18
+ <Fragment set:html={html} />
@@ -0,0 +1,23 @@
1
+ ---
2
+ import { shellRenderBreadcrumbs } from '@publier/native';
3
+
4
+ export interface BreadcrumbItem {
5
+ label: string;
6
+ href?: string;
7
+ }
8
+
9
+ interface Props {
10
+ items: BreadcrumbItem[];
11
+ label?: string;
12
+ class?: string;
13
+ }
14
+
15
+ const { items, label, class: customClass } = Astro.props;
16
+ const html = shellRenderBreadcrumbs(
17
+ JSON.stringify(Array.isArray(items) ? items : []),
18
+ label ?? null,
19
+ customClass ?? null,
20
+ );
21
+ ---
22
+
23
+ <Fragment set:html={html} />
@@ -0,0 +1,13 @@
1
+ ---
2
+ import Aside from '../aside.astro';
3
+
4
+ interface Props {
5
+ title?: string;
6
+ }
7
+
8
+ const { title } = Astro.props;
9
+ ---
10
+
11
+ <Aside type="caution" title={title}>
12
+ <slot />
13
+ </Aside>
@@ -0,0 +1,13 @@
1
+ ---
2
+ import Aside from '../aside.astro';
3
+
4
+ interface Props {
5
+ title?: string;
6
+ }
7
+
8
+ const { title } = Astro.props;
9
+ ---
10
+
11
+ <Aside type="tip" title={title ?? 'Check'}>
12
+ <slot />
13
+ </Aside>
@@ -0,0 +1,13 @@
1
+ ---
2
+ import Aside from '../aside.astro';
3
+
4
+ interface Props {
5
+ title?: string;
6
+ }
7
+
8
+ const { title } = Astro.props;
9
+ ---
10
+
11
+ <Aside type="danger" title={title}>
12
+ <slot />
13
+ </Aside>
@@ -0,0 +1,13 @@
1
+ ---
2
+ import Aside from '../aside.astro';
3
+
4
+ interface Props {
5
+ title?: string;
6
+ }
7
+
8
+ const { title } = Astro.props;
9
+ ---
10
+
11
+ <Aside type="note" title={title ?? 'Info'}>
12
+ <slot />
13
+ </Aside>
@@ -0,0 +1,13 @@
1
+ ---
2
+ import Aside from '../aside.astro';
3
+
4
+ interface Props {
5
+ title?: string;
6
+ }
7
+
8
+ const { title } = Astro.props;
9
+ ---
10
+
11
+ <Aside type="note" title={title}>
12
+ <slot />
13
+ </Aside>
@@ -0,0 +1,13 @@
1
+ ---
2
+ import Aside from '../aside.astro';
3
+
4
+ interface Props {
5
+ title?: string;
6
+ }
7
+
8
+ const { title } = Astro.props;
9
+ ---
10
+
11
+ <Aside type="tip" title={title}>
12
+ <slot />
13
+ </Aside>
@@ -0,0 +1,13 @@
1
+ ---
2
+ import Aside from '../aside.astro';
3
+
4
+ interface Props {
5
+ title?: string;
6
+ }
7
+
8
+ const { title } = Astro.props;
9
+ ---
10
+
11
+ <Aside type="caution" title={title ?? 'Warning'}>
12
+ <slot />
13
+ </Aside>
@@ -0,0 +1,14 @@
1
+ ---
2
+ import { shellRenderCardGrid } from '@publier/native';
3
+
4
+ interface Props {
5
+ minColumnWidth?: string;
6
+ class?: string;
7
+ }
8
+
9
+ const { minColumnWidth = '15rem', class: customClass } = Astro.props;
10
+ const slotHtml = await Astro.slots.render('default');
11
+ const html = shellRenderCardGrid(minColumnWidth, customClass ?? null, slotHtml);
12
+ ---
13
+
14
+ <Fragment set:html={html} />
@@ -0,0 +1,18 @@
1
+ ---
2
+ import { shellRenderCard } from '@publier/native';
3
+
4
+ export type CardVariant = 'default' | 'note' | 'tip' | 'danger' | 'success';
5
+
6
+ interface Props {
7
+ title: string;
8
+ variant?: CardVariant;
9
+ class?: string;
10
+ }
11
+
12
+ const { title, variant = 'default', class: customClass } = Astro.props;
13
+ const iconSlot = Astro.slots.has('icon') ? await Astro.slots.render('icon') : null;
14
+ const slotHtml = await Astro.slots.render('default');
15
+ const html = shellRenderCard(title, variant, customClass ?? null, iconSlot, slotHtml);
16
+ ---
17
+
18
+ <Fragment set:html={html} />
@@ -0,0 +1,55 @@
1
+ ---
2
+ import { Code } from 'astro-expressive-code/components';
3
+
4
+ export interface CodeGroupItem {
5
+ label: string;
6
+ code: string;
7
+ lang?: string;
8
+ filename?: string;
9
+ }
10
+
11
+ interface Props {
12
+ items: CodeGroupItem[];
13
+ syncKey?: string;
14
+ }
15
+
16
+ const { items, syncKey } = Astro.props;
17
+ const id = `publier-cg-${Math.random().toString(36).slice(2, 10)}`;
18
+ ---
19
+
20
+ <tab-container
21
+ class="not-prose my-4 rounded-box overflow-hidden border border-base-300 bg-base-200"
22
+ data-publier-cg
23
+ data-sync-key={syncKey}
24
+ >
25
+ <div role="tablist" class="tabs tabs-border px-2">
26
+ {items.map((item, i) => (
27
+ <button
28
+ type="button"
29
+ role="tab"
30
+ id={`${id}-tab-${i}`}
31
+ aria-controls={`${id}-panel-${i}`}
32
+ aria-selected={i === 0 ? 'true' : 'false'}
33
+ tabindex={i === 0 ? 0 : -1}
34
+ class="tab font-mono"
35
+ data-tab-label={item.label}
36
+ >
37
+ {item.label}
38
+ </button>
39
+ ))}
40
+ </div>
41
+ {items.map((item, i) => (
42
+ <div
43
+ id={`${id}-panel-${i}`}
44
+ role="tabpanel"
45
+ aria-labelledby={`${id}-tab-${i}`}
46
+ hidden={i !== 0}
47
+ >
48
+ <Code
49
+ code={item.code}
50
+ lang={item.lang ?? 'plaintext'}
51
+ title={item.filename}
52
+ />
53
+ </div>
54
+ ))}
55
+ </tab-container>
@@ -0,0 +1,18 @@
1
+ ---
2
+ import { shellRenderColumns } from '@publier/native';
3
+
4
+ export type ColumnCount = 2 | 3 | 4;
5
+ export type ColumnGap = 'sm' | 'md' | 'lg';
6
+
7
+ interface Props {
8
+ cols?: ColumnCount;
9
+ gap?: ColumnGap;
10
+ class?: string;
11
+ }
12
+
13
+ const { cols = 2, gap = 'md', class: customClass } = Astro.props;
14
+ const slotHtml = await Astro.slots.render('default');
15
+ const html = shellRenderColumns(cols, gap, customClass ?? null, slotHtml);
16
+ ---
17
+
18
+ <Fragment set:html={html} />