diff options
Diffstat (limited to 'packages/ui/src/components/code.tsx')
| -rw-r--r-- | packages/ui/src/components/code.tsx | 52 |
1 files changed, 52 insertions, 0 deletions
diff --git a/packages/ui/src/components/code.tsx b/packages/ui/src/components/code.tsx new file mode 100644 index 000000000..f1c7efada --- /dev/null +++ b/packages/ui/src/components/code.tsx @@ -0,0 +1,52 @@ +import { type FileContents, File, FileOptions, LineAnnotation } from "@pierre/precision-diffs" +import { ComponentProps, createEffect, splitProps } from "solid-js" + +export type CodeProps<T = {}> = FileOptions<T> & { + file: FileContents + annotations?: LineAnnotation<T>[] + class?: string + classList?: ComponentProps<"div">["classList"] +} + +export function Code<T>(props: CodeProps<T>) { + let container!: HTMLDivElement + const [local, others] = splitProps(props, ["file", "class", "classList", "annotations"]) + const file = () => local.file + + createEffect(() => { + const instance = new File<T>({ + theme: { dark: "oc-1-dark", light: "oc-1-light" }, // or any Shiki theme + overflow: "wrap", // or 'scroll' + themeType: "system", // 'system', 'light', or 'dark' + disableLineNumbers: false, // optional + // lang: 'typescript', // optional - auto-detected from filename if not provided + ...others, + }) + + instance.render({ + file: file(), + lineAnnotations: local.annotations, + containerWrapper: container, + }) + }) + + return ( + <div + data-component="code" + style={{ + "--pjs-font-family": "var(--font-family-mono)", + "--pjs-font-size": "var(--font-size-small)", + "--pjs-line-height": "24px", + "--pjs-tab-size": 2, + "--pjs-font-features": "var(--font-family-mono--font-feature-settings)", + "--pjs-header-font-family": "var(--font-family-sans)", + "--pjs-gap-block": 0, + }} + classList={{ + ...(local.classList || {}), + [local.class ?? ""]: !!local.class, + }} + ref={container} + /> + ) +} |
