@rimelight/ui 0.0.13 → 0.0.14

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": "@rimelight/ui",
3
- "version": "0.0.13",
3
+ "version": "0.0.14",
4
4
  "private": false,
5
5
  "description": "Rimelight Entertainment UI Library.",
6
6
  "homepage": "https://rimelight.com/docs",
package/src/env.d.ts CHANGED
@@ -12,6 +12,29 @@ declare module "virtual:rimelight-ui" {
12
12
  export function getUIConfig(): DefaultUIConfig
13
13
  }
14
14
 
15
+ interface StarlightAddonsConfig {
16
+ copy?: boolean
17
+ share?: boolean
18
+ }
19
+
20
+ declare module "virtual:rimelight-starlight-addons-config" {
21
+ const config: StarlightAddonsConfig
22
+ export default config
23
+ }
24
+
25
+ declare module "turndown" {
26
+ class TurndownService {
27
+ constructor(options?: Record<string, unknown>)
28
+ turndown(html: Node | string): string
29
+ use(plugin: () => void): void
30
+ }
31
+ export default TurndownService
32
+ }
33
+
34
+ declare module "turndown-plugin-gfm" {
35
+ export function gfm(): void
36
+ }
37
+
15
38
  declare namespace App {
16
39
  interface Locals {
17
40
  cfContext?: Record<string, unknown>
@@ -0,0 +1,45 @@
1
+ ---
2
+ import { Tabs, TabItem } from "@astrojs/starlight/components"
3
+ import { Code as AstroCode } from "astro:components"
4
+
5
+ interface Props {
6
+ pkg: string
7
+ type?: "add" | "create" | "install" | "remove" | "run"
8
+ dev?: boolean
9
+ }
10
+
11
+ const { pkg, type = "add", dev = false } = Astro.props
12
+
13
+ const commands: Record<string, Record<string, string>> = {
14
+ npm: { add: "npm i", create: "npm create", install: "npm install", remove: "npm uninstall", run: "npm run", devOption: "-D" },
15
+ yarn: { add: "yarn add", create: "yarn create", install: "yarn install", remove: "yarn remove", run: "yarn run", devOption: "-D" },
16
+ pnpm: { add: "pnpm add", create: "pnpm create", install: "pnpm install", remove: "pnpm remove", run: "pnpm run", devOption: "-D" },
17
+ bun: { add: "bun add", create: "bun create", install: "bun install", remove: "bun remove", run: "bun run", devOption: "-d" },
18
+ }
19
+
20
+ function getCommand(manager: string, cmdType: string, pkgName: string, devFlag: boolean): string {
21
+ const mgrCmds = commands[manager]
22
+ if (!mgrCmds) return ""
23
+ let cmd = mgrCmds[cmdType]
24
+ if (!cmd) return ""
25
+ if (cmdType === "add" && devFlag && mgrCmds.devOption) cmd += " " + mgrCmds.devOption
26
+ if (pkgName && cmdType !== "install") cmd += " " + pkgName
27
+ return cmd
28
+ }
29
+
30
+ const managers = ["npm", "pnpm", "yarn", "bun"] as const
31
+ const singleManager = managers[0] as string
32
+ const command = getCommand(singleManager, type, pkg, dev)
33
+ ---
34
+
35
+ {(managers.length as number) === 1 ? (
36
+ <AstroCode code={command} lang="sh" />
37
+ ) : (
38
+ <Tabs syncKey="package-managers">
39
+ {managers.map((manager) => (
40
+ <TabItem label={manager}>
41
+ <AstroCode code={getCommand(manager, type, pkg, dev)} lang="sh" />
42
+ </TabItem>
43
+ ))}
44
+ </Tabs>
45
+ )}
@@ -1,114 +1,113 @@
1
- ---
2
- import DefaultPageTitle from "@astrojs/starlight/components/PageTitle.astro";
3
- import config from "virtual:rimelight-starlight-addons-config";
4
-
5
- const { copy = true, share = true } = config ?? {};
6
-
7
- const currentUrl = Astro.url.href;
8
- const currentTitle = (Astro.locals as any).starlightRoute?.entry?.data?.title || "";
9
- ---
10
-
11
- <DefaultPageTitle />
12
- {(copy || share) && (
13
- <div class="rl-addons">
14
- {copy && (
15
- <button class="rl-addon-btn" id="rl-copy-markdown" title="Copy Markdown">
16
- <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect width="14" height="14" x="8" y="8" rx="2" ry="2"/><path d="M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2"/></svg>
17
- </button>
18
- )}
19
- {share && (
20
- <button class="rl-addon-btn" id="rl-share" title="Share">
21
- <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="18" cy="5" r="3"/><circle cx="6" cy="12" r="3"/><circle cx="18" cy="19" r="3"/><line x1="8.59" x2="15.42" y1="13.51" y2="17.49"/><line x1="15.41" x2="8.59" y1="6.51" y2="10.49"/></svg>
22
- </button>
23
- )}
24
- </div>
25
- )}
26
-
27
- <style>
28
- .rl-addons {
29
- display: flex;
30
- gap: 0.5rem;
31
- align-items: center;
32
- }
33
-
34
- .rl-addon-btn {
35
- background-color: var(--sl-color-gray-6);
36
- color: var(--sl-color-white);
37
- border: 1px solid var(--sl-color-gray-5);
38
- padding: 0.5rem;
39
- border-radius: 0.25rem;
40
- cursor: pointer;
41
- display: flex;
42
- align-items: center;
43
- justify-content: center;
44
- transition: background-color 0.2s ease;
45
- height: 2rem;
46
- width: 2rem;
47
- }
48
-
49
- .rl-addon-btn:hover {
50
- background-color: var(--sl-color-gray-5);
51
- }
52
-
53
- .rl-addon-btn:disabled {
54
- opacity: 0.7;
55
- cursor: not-allowed;
56
- }
57
- </style>
58
-
59
- <script>
60
- import TurndownService from "turndown";
61
- import { gfm } from "turndown-plugin-gfm";
62
-
63
- const turndown = new TurndownService({
64
- headingStyle: "atx",
65
- codeBlockStyle: "fenced",
66
- bulletListMarker: "-",
67
- });
68
- turndown.use(gfm);
69
-
70
- const copyBtn = document.getElementById("rl-copy-markdown");
71
- const shareBtn = document.getElementById("rl-share");
72
-
73
- if (copyBtn) {
74
- copyBtn.addEventListener("click", async () => {
75
- try {
76
- copyBtn.disabled = true;
77
- const contentEl = document.querySelector("main .sl-markdown-content");
78
- if (!contentEl) {
79
- throw new Error("Content not found");
80
- }
81
- const clone = contentEl.cloneNode(true);
82
- clone.querySelectorAll("script, style, noscript, .sl-anchor-link, [data-pagefind-ignore]").forEach(el => el.remove());
83
- const markdown = turndown.turndown(clone as HTMLElement);
84
- await navigator.clipboard.writeText(markdown);
85
- copyBtn.classList.add("copied");
86
- setTimeout(() => copyBtn.classList.remove("copied"), 2000);
87
- } catch (err) {
88
- console.error("Failed to copy:", err);
89
- } finally {
90
- copyBtn.disabled = false;
91
- }
92
- });
93
- }
94
-
95
- if (shareBtn) {
96
- shareBtn.addEventListener("click", async () => {
97
- if (navigator.share) {
98
- try {
99
- await navigator.share({ title: document.title, url: window.location.href });
100
- } catch (err) {
101
- if (err.name !== "AbortError") {
102
- console.error("Share failed:", err);
103
- }
104
- }
105
- } else {
106
- try {
107
- await navigator.clipboard.writeText(window.location.href);
108
- } catch (err) {
109
- console.error("Failed to copy link:", err);
110
- }
111
- }
112
- });
113
- }
1
+ ---
2
+ import DefaultPageTitle from "@astrojs/starlight/components/PageTitle.astro";
3
+ import config from "virtual:rimelight-starlight-addons-config";
4
+
5
+ const { copy = true, share = true } = config ?? {};
6
+ ---
7
+
8
+ <DefaultPageTitle />
9
+ {(copy || share) && (
10
+ <div class="rl-addons">
11
+ {copy && (
12
+ <button class="rl-addon-btn" id="rl-copy-markdown" title="Copy Markdown">
13
+ <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect width="14" height="14" x="8" y="8" rx="2" ry="2"/><path d="M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2"/></svg>
14
+ </button>
15
+ )}
16
+ {share && (
17
+ <button class="rl-addon-btn" id="rl-share" title="Share">
18
+ <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="18" cy="5" r="3"/><circle cx="6" cy="12" r="3"/><circle cx="18" cy="19" r="3"/><line x1="8.59" x2="15.42" y1="13.51" y2="17.49"/><line x1="15.41" x2="8.59" y1="6.51" y2="10.49"/></svg>
19
+ </button>
20
+ )}
21
+ </div>
22
+ )}
23
+
24
+ <style>
25
+ .rl-addons {
26
+ display: flex;
27
+ gap: 0.5rem;
28
+ align-items: center;
29
+ }
30
+
31
+ .rl-addon-btn {
32
+ background-color: var(--sl-color-gray-6);
33
+ color: var(--sl-color-white);
34
+ border: 1px solid var(--sl-color-gray-5);
35
+ padding: 0.5rem;
36
+ border-radius: 0.25rem;
37
+ cursor: pointer;
38
+ display: flex;
39
+ align-items: center;
40
+ justify-content: center;
41
+ transition: background-color 0.2s ease;
42
+ height: 2rem;
43
+ width: 2rem;
44
+ }
45
+
46
+ .rl-addon-btn:hover {
47
+ background-color: var(--sl-color-gray-5);
48
+ }
49
+
50
+ .rl-addon-btn:disabled {
51
+ opacity: 0.7;
52
+ cursor: not-allowed;
53
+ }
54
+ </style>
55
+
56
+ <script>
57
+ import TurndownService from "turndown";
58
+ import { gfm } from "turndown-plugin-gfm";
59
+
60
+ const turndown = new TurndownService({
61
+ headingStyle: "atx",
62
+ codeBlockStyle: "fenced",
63
+ bulletListMarker: "-",
64
+ });
65
+ turndown.use(gfm);
66
+
67
+ const copyBtn = document.getElementById("rl-copy-markdown") as HTMLButtonElement | null;
68
+ const shareBtn = document.getElementById("rl-share");
69
+
70
+ if (copyBtn) {
71
+ copyBtn.addEventListener("click", async () => {
72
+ try {
73
+ copyBtn.disabled = true;
74
+ const contentEl = document.querySelector("main .sl-markdown-content");
75
+ if (!contentEl) {
76
+ throw new Error("Content not found");
77
+ }
78
+ const clone = contentEl.cloneNode(true) as Element;
79
+ clone.querySelectorAll("script, style, noscript, .sl-anchor-link, [data-pagefind-ignore]").forEach((el: Element) => el.remove());
80
+ const markdown = turndown.turndown(clone as HTMLElement);
81
+ await navigator.clipboard.writeText(markdown);
82
+ copyBtn.classList.add("copied");
83
+ setTimeout(() => copyBtn.classList.remove("copied"), 2000);
84
+ } catch (err) {
85
+ console.error("Failed to copy:", err);
86
+ } finally {
87
+ copyBtn.disabled = false;
88
+ }
89
+ });
90
+ }
91
+
92
+ const typedShareBtn = shareBtn as HTMLButtonElement | null;
93
+ if (typedShareBtn) {
94
+ typedShareBtn.addEventListener("click", async () => {
95
+ if (navigator.share) {
96
+ try {
97
+ await navigator.share({ title: document.title, url: window.location.href });
98
+ } catch (err) {
99
+ const error = err as { name?: string };
100
+ if (error.name !== "AbortError") {
101
+ console.error("Share failed:", err);
102
+ }
103
+ }
104
+ } else {
105
+ try {
106
+ await navigator.clipboard.writeText(window.location.href);
107
+ } catch (err) {
108
+ console.error("Failed to copy link:", err);
109
+ }
110
+ }
111
+ });
112
+ }
114
113
  </script>
@@ -8,12 +8,14 @@ const __dirname = path.dirname(fileURLToPath(import.meta.url))
8
8
  export interface StarlightAddonsConfig {
9
9
  copy?: boolean
10
10
  share?: boolean
11
+ packageManagers?: string[]
11
12
  }
12
13
 
13
14
  export default function starlightAddons(userConfig?: StarlightAddonsConfig): StarlightPlugin {
14
15
  const defaultConfig: StarlightAddonsConfig = {
15
16
  copy: true,
16
- share: true
17
+ share: true,
18
+ packageManagers: ["npm"]
17
19
  }
18
20
 
19
21
  const config: StarlightAddonsConfig = {
@@ -25,7 +27,11 @@ export default function starlightAddons(userConfig?: StarlightAddonsConfig): Sta
25
27
  name: "rimelight-ui-starlight-addons",
26
28
  hooks: {
27
29
  "config:setup"({ addIntegration, updateConfig, logger }) {
28
- if (!config.copy && !config.share) {
30
+ if (
31
+ !config.copy &&
32
+ !config.share &&
33
+ (!config.packageManagers || config.packageManagers.length === 0)
34
+ ) {
29
35
  logger.warn("StarlightAddons: Nothing enabled.")
30
36
  }
31
37
 
package/src/preset.ts CHANGED
@@ -61,48 +61,33 @@ export default definePreset(() => {
61
61
  ],
62
62
  [
63
63
  /^([hw])-(6xs|5xs|4xs|3xs|2xs|xs|sm|md|lg|xl|2xl|3xl|4xl|5xl|6xl)$/,
64
- ([, prop, s], { theme }) => {
65
- if (!s) return
66
- const val = (theme as { spacing?: Record<string, string> }).spacing?.[s]
67
- if (!val) return
64
+ ([, prop, s]) => {
65
+ if (!s) return false
66
+ const spacing: Record<string, string> = {
67
+ "6xs": "0.125rem",
68
+ "5xs": "0.25rem",
69
+ "4xs": "0.375rem",
70
+ "3xs": "0.5rem",
71
+ "2xs": "0.625rem",
72
+ "xs": "0.75rem",
73
+ "sm": "0.875rem",
74
+ "md": "1rem",
75
+ "lg": "1.25rem",
76
+ "xl": "1.5rem",
77
+ "2xl": "2rem",
78
+ "3xl": "3rem",
79
+ "4xl": "4rem",
80
+ "5xl": "6rem",
81
+ "6xl": "8rem"
82
+ }
83
+ const val = spacing[s]
84
+ if (!val) return false
68
85
  return prop === "h" ? { height: val } : { width: val }
69
86
  }
70
87
  ]
71
88
  ],
72
89
 
73
90
  theme: {
74
- spacing: {
75
- // 2px
76
- "6xs": "0.125rem",
77
- // 4px
78
- "5xs": "0.25rem",
79
- // 6px
80
- "4xs": "0.375rem",
81
- // 8px
82
- "3xs": "0.5rem",
83
- // 10px
84
- "2xs": "0.625rem",
85
- // 12px
86
- "xs": "0.75rem",
87
- // 14px
88
- "sm": "0.875rem",
89
- // 16px
90
- "md": "1rem",
91
- // 20px
92
- "lg": "1.25rem",
93
- // 24px
94
- "xl": "1.5rem",
95
- // 32px
96
- "2xl": "2rem",
97
- // 48px
98
- "3xl": "3rem",
99
- // 64px
100
- "4xl": "4rem",
101
- // 96px
102
- "5xl": "6rem",
103
- // 128px
104
- "6xl": "8rem"
105
- },
106
91
  colors: {
107
92
  "background": "var(--background)",
108
93
  "foreground": "var(--foreground)",