Skip to content

Commit

Permalink
docs(next): Refactor PM comps to use package-manager-detector (#1491)
Browse files Browse the repository at this point in the history
fixes #1474
  • Loading branch information
ieedan authored Nov 18, 2024
1 parent 03c4e3d commit 103f7d5
Show file tree
Hide file tree
Showing 10 changed files with 60 additions and 136 deletions.
19 changes: 11 additions & 8 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions sites/docs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
"magic-string": "^0.30.12",
"mdsx": "^0.0.6",
"mode-watcher": "^0.3.1",
"package-manager-detector": "^0.2.2",
"paneforge": "1.0.0-next.1",
"postcss": "^8.4.39",
"postcss-load-config": "^6.0.1",
Expand Down
13 changes: 5 additions & 8 deletions sites/docs/src/lib/components/docs/block-toolbar.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -5,25 +5,22 @@
import Smartphone from "lucide-svelte/icons/smartphone";
import Tablet from "lucide-svelte/icons/tablet";
import Terminal from "lucide-svelte/icons/terminal";
import { getPackageManagerScriptCmd } from "$lib/utils.js";
import { Button } from "$lib/registry/new-york/ui/button/index.js";
import { Separator } from "$lib/registry/new-york/ui/separator/index.js";
import * as ToggleGroup from "$lib/registry/new-york/ui/toggle-group/index.js";
import type { Block } from "$lib/registry/schema.js";
import type { ResizablePane } from "$lib/registry/new-york/ui/resizable/index.js";
import { CopyToClipboard } from "$lib/utils/copy-to-clipboard.svelte.js";
import { getPackageManager } from "$lib/stores/package-manager.js";
import { getCommand, getPackageManager } from "$lib/stores/package-manager.js";
let { block, resizablePaneRef }: { block: Block; resizablePaneRef: ResizablePane } = $props();
const copier = new CopyToClipboard();
const selectedPackageManager = getPackageManager();
const addCommand = $derived.by(() => {
const start = getPackageManagerScriptCmd($selectedPackageManager);
const end = `shadcn-svelte@next add ${block.name}`;
return start + " " + end;
});
const addCommand = $derived(
getCommand($selectedPackageManager, "execute", `shadcn-svelte@next add ${block.name}`)
);
const blockSource = $derived(
`https://github.com/huntabyte/shadcn-svelte/tree/next/sites/docs/src/lib/registry/new-york/block/${block.name}`
Expand All @@ -40,7 +37,7 @@
class="bg-muted h-7 rounded-md border shadow-none"
size="sm"
onclick={() => {
copier.copyToClipboard(addCommand);
copier.copyToClipboard(addCommand.command + " " + addCommand.args.join(" "));
}}
>
{#if copier.isCopied}
Expand Down
5 changes: 3 additions & 2 deletions sites/docs/src/lib/components/docs/copy-button.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@
import ChevronsUpDown from "lucide-svelte/icons/chevrons-up-down";
import { tick } from "svelte";
import { cn } from "$lib/utils.js";
import { getPackageManager, packageManagers } from "$lib/stores/package-manager.js";
import { getPackageManager } from "$lib/stores/package-manager.js";
import { Button, type ButtonProps } from "$lib/registry/new-york/ui/button/index.js";
import * as DropdownMenu from "$lib/registry/new-york/ui/dropdown-menu/index.js";
import type { Agent } from "package-manager-detector";
type Props = Omit<ButtonProps, "children"> & {
isPackageManagerBlock?: boolean;
Expand Down Expand Up @@ -51,7 +52,7 @@
</DropdownMenu.Trigger>

<DropdownMenu.Content align="end" preventScroll={false}>
{#each packageManagers as pm (pm)}
{#each ["pnpm", "bun", "yarn", "npm"] satisfies Agent[] as pm (pm)}
<DropdownMenu.Item
onclick={() => {
selectedPackageManager.set(pm);
Expand Down
1 change: 1 addition & 0 deletions sites/docs/src/lib/components/docs/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export { default as PMAddComp } from "./pm-add-comp.svelte";
export { default as PMCreate } from "./pm-create.svelte";
export { default as PMInstall } from "./pm-install.svelte";
export { default as PMRemove } from "./pm-remove.svelte";
export { default as PMRun } from "./pm-run.svelte";
export { default as InstallTabs } from "./install-tabs.svelte";

export * from "./page-header/index.js";
Expand Down
59 changes: 10 additions & 49 deletions sites/docs/src/lib/components/docs/pm-block.svelte
Original file line number Diff line number Diff line change
@@ -1,65 +1,26 @@
<script lang="ts">
import Pre from "./markdown/pre.svelte";
import {
type PackageManager,
getPackageManager,
getPackageManagerInstallCmd,
getPackageManagerScriptCmd,
getPackageManagerUninstallCmd,
} from "$lib/stores/package-manager.js";
import { getCommand, getPackageManager } from "$lib/stores/package-manager.js";
import type { Command } from "package-manager-detector";
type PMBlockType = "execute" | "create" | "install" | "remove";
type Props = {
type: Command | "create";
command: string | string[];
};
export let type: PMBlockType;
export let command: string = "";
const { type, command }: Props = $props();
const selectedPackageManager = getPackageManager();
function getCmd(type: PMBlockType, pm: PackageManager) {
if (type === "execute") return getPackageManagerScriptCmd(pm);
return pm;
}
function getInstallCommand() {
if (command === "") return "install";
return getPackageManagerInstallCmd($selectedPackageManager);
}
function getUninstallCommand() {
if (command === "") return "install";
return getPackageManagerUninstallCmd($selectedPackageManager);
}
let cmdStart = getCmd(type, $selectedPackageManager);
$: cmdStart = getCmd(type, $selectedPackageManager);
let resolvedCommand = $derived(getCommand($selectedPackageManager, type, command));
</script>

<figure data-rehype-pretty-code-figure>
<Pre isPackageManagerBlock={true} tabindex={0} data-language="bash" data-theme="github-dark">
<code data-language="bash" data-theme="github-dark" style="display: grid;">
<span data-line>
<span style="color:#B392F0;font-weight:bold">{`${cmdStart}`}</span>
{#if type === "install" || type === "create" || type == "remove"}
<span style="color:#9ECBFF">
{#if type === "install"}
{`${getInstallCommand()} `}
{:else if type == "create"}
{"create "}
{:else if type == "remove"}
{`${getUninstallCommand()} `}
{/if}
</span>
{/if}
{#if command !== ""}
{#each command.split(" ") as word, i}
{#if i === 0}
<span style="color:#9ECBFF; margin-left:-8px">{`${word}`}</span>
{:else}
<span style="color:#9ECBFF">{` ${word}`}</span>
{/if}
{/each}
{/if}
<span style="color:#B392F0;font-weight:bold">{resolvedCommand.command}</span>
<span style="color:#9ECBFF">{resolvedCommand.args.join(" ")}</span>
</span>
</code>
</Pre>
Expand Down
2 changes: 1 addition & 1 deletion sites/docs/src/lib/components/docs/pm-remove.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@
export let command: string;
</script>

<PMBlock type="remove" {command} />
<PMBlock type="uninstall" {command} />
6 changes: 6 additions & 0 deletions sites/docs/src/lib/components/docs/pm-run.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<script lang="ts">
import PMBlock from "./pm-block.svelte";
export let command: string;
</script>

<PMBlock type="run" {command} />
58 changes: 22 additions & 36 deletions sites/docs/src/lib/stores/package-manager.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import { getContext, setContext } from "svelte";
import { persisted } from "svelte-persisted-store";
import type { Agent, Command, ResolvedCommand } from "package-manager-detector";
import { resolveCommand } from "package-manager-detector/commands";

const PACKAGE_MANAGER = Symbol("packageManager");

export function setPackageManager(initialValue: PackageManager = "npm") {
export function setPackageManager(initialValue: Agent = "npm") {
const packageManager = createPackageManagerStore("packageManager", initialValue);
setContext(PACKAGE_MANAGER, packageManager);
return packageManager;
Expand All @@ -13,48 +15,32 @@ export function getPackageManager(): ReturnType<typeof setPackageManager> {
return getContext(PACKAGE_MANAGER);
}

function createPackageManagerStore(key: string, initialValue: PackageManager) {
function createPackageManagerStore(key: string, initialValue: Agent) {
const store = persisted(key, initialValue);
return store;
}

export const packageManagers = ["pnpm", "bun", "yarn", "npm"] as const;
export type PackageManager = (typeof packageManagers)[number];
export type PackageManagerCommand = Command | "create";

const packageManagerToScriptCmd: Record<PackageManager, string> = {
npm: "npx",
yarn: "yarn dlx",
pnpm: "pnpm dlx",
bun: "bunx",
};
export function getCommand(
pm: Agent,
type: PackageManagerCommand,
command: string | string[]
): ResolvedCommand {
let args = [];
if (typeof command === "string") {
args = command.split(" ");
} else {
args = command;
}

export function getPackageManagerScriptCmd(pm: PackageManager): string {
return packageManagerToScriptCmd[pm];
}

const packageManagerToInstallCmd: Record<PackageManager, string> = {
npm: "install",
yarn: "add",
pnpm: "add",
bun: "add",
};
// special handling for create
if (type === "create") return { command: pm, args: ["create", ...args] };

export function getPackageManagerInstallCmd(pm: PackageManager): string {
return packageManagerToInstallCmd[pm];
}
const cmd = resolveCommand(pm, type, args);

const packageManagerToUninstallCmd: Record<PackageManager, string> = {
npm: "uninstall",
yarn: "remove",
pnpm: "remove",
bun: "remove",
};

export function getPackageManagerUninstallCmd(pm: PackageManager): string {
return packageManagerToUninstallCmd[pm];
}
// since docs are static any unresolved command is a code error
if (cmd === null) throw new Error("Could not resolve command!");

// eslint-disable-next-line @typescript-eslint/no-explicit-any
export function isPackageManager(value: any): value is PackageManager {
return packageManagers.includes(value);
return cmd;
}
32 changes: 0 additions & 32 deletions sites/docs/src/lib/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -260,38 +260,6 @@ export function getLiftMode(name: string) {
};
}

export const packageManagers = ["pnpm", "bun", "yarn", "npm"] as const;
export type PackageManager = (typeof packageManagers)[number];

export const selectedPackageManager = persisted<PackageManager>("package-manager", "npm");

const packageManagerToScriptCmd: Record<PackageManager, string> = {
npm: "npx",
yarn: "yarn dlx",
pnpm: "pnpm dlx",
bun: "bunx",
};

export function getPackageManagerScriptCmd(pm: PackageManager): string {
return packageManagerToScriptCmd[pm];
}

const packageManagerToInstallCmd: Record<PackageManager, string> = {
npm: "install",
yarn: "add",
pnpm: "add",
bun: "add",
};

export function getPackageManagerInstallCmd(pm: PackageManager): string {
return packageManagerToInstallCmd[pm];
}

// eslint-disable-next-line @typescript-eslint/no-explicit-any
export function isPackageManager(value: any): value is PackageManager {
return packageManagers.includes(value);
}

// Wrappers around svelte's `HTMLAttributes` types to add a `ref` prop can be bound to
// to get a reference to the underlying DOM element the component is rendering.
export type PrimitiveDivAttributes = WithElementRef<HTMLAttributes<HTMLDivElement>>;
Expand Down

0 comments on commit 103f7d5

Please sign in to comment.