| import * as _$react_jsx_runtime0 from "react/jsx-runtime"; | ||
| //#region src/Midcut.d.ts | ||
| declare function Midcut({ | ||
| align, | ||
| ellipsis, | ||
| min, | ||
| prefix, | ||
| value | ||
| }: Midcut.Props): string | _$react_jsx_runtime0.JSX.Element; | ||
| declare namespace Midcut { | ||
| interface Props { | ||
| align?: "start" | "end"; | ||
| ellipsis?: string; | ||
| min?: number; | ||
| prefix?: string; | ||
| value?: string; | ||
| } | ||
| } | ||
| //#endregion | ||
| export { Midcut }; |
| import { useId } from "react"; | ||
| import { jsx, jsxs } from "react/jsx-runtime"; | ||
| //#region src/Midcut.tsx | ||
| function Midcut({ align = "start", ellipsis = "…", min = 1, prefix = "", value = "" }) { | ||
| const id = useId(); | ||
| const body = value.slice(value.startsWith(prefix) ? prefix.length : 0); | ||
| if (body.length < 2) return prefix + ellipsis; | ||
| const cutAt = 1 + Math.ceil((body.length - 1) / 2); | ||
| const [start, end] = [body.slice(1, cutAt), body.slice(cutAt, -1)]; | ||
| const minWidth = prefix.length + min * 2 + 1; | ||
| return /* @__PURE__ */ jsxs("span", { | ||
| id, | ||
| title: value, | ||
| style: { | ||
| display: "inline-flex", | ||
| justifyContent: align === "end" ? "flex-end" : void 0, | ||
| width: "100%", | ||
| minWidth: `${minWidth}ch`, | ||
| textDecoration: "inherit", | ||
| containerType: "inline-size", | ||
| containerName: id | ||
| }, | ||
| children: [ | ||
| /* @__PURE__ */ jsx("style", { children: ` | ||
| .${id}-ellipsis { display: none } | ||
| @container ${id} (max-width: ${value.length + 1}ch) { | ||
| .${id}-ellipsis { display: flex } | ||
| .${id}-part { | ||
| overflow: hidden; | ||
| width: calc((100cqw - ${prefix.length + 3}ch) / 2); | ||
| } | ||
| } | ||
| ` }), | ||
| /* @__PURE__ */ jsxs("span", { | ||
| style: { | ||
| display: "inline-flex", | ||
| maxWidth: `${value.length - 1}ch`, | ||
| width: "round(down, calc(100% - 1ch), 2ch)", | ||
| whiteSpace: "nowrap" | ||
| }, | ||
| children: [ | ||
| prefix, | ||
| body.at(0), | ||
| /* @__PURE__ */ jsx("span", { | ||
| className: `${id}-part`, | ||
| children: start | ||
| }), | ||
| /* @__PURE__ */ jsx("span", { | ||
| className: `${id}-ellipsis`, | ||
| children: ellipsis | ||
| }), | ||
| /* @__PURE__ */ jsx("span", { | ||
| className: `${id}-part`, | ||
| style: { | ||
| display: "flex", | ||
| justifyContent: "flex-end" | ||
| }, | ||
| children: end | ||
| }) | ||
| ] | ||
| }), | ||
| body.at(-1) | ||
| ] | ||
| }); | ||
| } | ||
| //#endregion | ||
| export { Midcut }; |
+51
| # midcut | ||
| A <1kb React component that accurately middle-truncates monospaced text. Uses CSS `round()` and container queries (no JS measurement). | ||
| ## Install | ||
| ```bash | ||
| npm i -S midcut | ||
| pnpm add midcut | ||
| bun add midcut | ||
| ``` | ||
| ## Usage | ||
| ```tsx | ||
| import { Midcut } from "midcut"; | ||
| function App() { | ||
| return <Midcut prefix="0x" value="0x1234567890abcdef1234567890abcdef12345678" />; | ||
| } | ||
| ``` | ||
| **Important:** only use with a monospace font. | ||
| ## Props | ||
| | Prop | Type | Default | Description | | ||
| | ---------- | ------------------ | --------- | ------------------------------------------------------- | | ||
| | `value` | `string` | `""` | The string to truncate | | ||
| | `prefix` | `string` | `""` | A prefix that is always visible (e.g. `"0x"`) | | ||
| | `min` | `number` | `1` | Minimum characters visible on each side of the ellipsis | | ||
| | `ellipsis` | `string` | `"…"` | The ellipsis character(s) | | ||
| | `align` | `"start" \| "end"` | `"start"` | Alignment of the truncated string within its container | | ||
| ## How it works | ||
| 1. The string is split into two halves displayed as inline flex items | ||
| 2. A CSS container query activates truncation when the container is narrower than the full string | ||
| 3. `round(down, ..., 2ch)` snaps the truncatable width to character boundaries so characters are never partially clipped | ||
| 4. The end half uses `justify-content: flex-end` to truncate from the start | ||
| ## Development | ||
| ```bash | ||
| bun install | ||
| bun dev | ||
| ``` | ||
| ## License | ||
| MIT |
| import { useId } from "react"; | ||
| export function Midcut({ | ||
| align = "start", | ||
| ellipsis = "…", | ||
| min = 1, | ||
| prefix = "", | ||
| value = "", | ||
| }: Midcut.Props) { | ||
| const id = useId(); | ||
| const body = value.slice(value.startsWith(prefix) ? prefix.length : 0); | ||
| if (body.length < 2) return prefix + ellipsis; | ||
| const cutAt = 1 + Math.ceil((body.length - 1) / 2); | ||
| const [start, end] = [body.slice(1, cutAt), body.slice(cutAt, -1)]; | ||
| const minWidth = prefix.length + min * 2 + 1; | ||
| return ( | ||
| <span | ||
| id={id} | ||
| title={value} | ||
| style={{ | ||
| display: "inline-flex", | ||
| justifyContent: align === "end" ? "flex-end" : undefined, | ||
| width: "100%", | ||
| minWidth: `${minWidth}ch`, | ||
| textDecoration: "inherit", | ||
| containerType: "inline-size", | ||
| containerName: id, | ||
| }} | ||
| > | ||
| <style> | ||
| {` | ||
| .${id}-ellipsis { display: none } | ||
| @container ${id} (max-width: ${value.length + 1}ch) { | ||
| .${id}-ellipsis { display: flex } | ||
| .${id}-part { | ||
| overflow: hidden; | ||
| width: calc((100cqw - ${prefix.length + 3}ch) / 2); | ||
| } | ||
| } | ||
| `} | ||
| </style> | ||
| <span | ||
| style={{ | ||
| display: "inline-flex", | ||
| maxWidth: `${value.length - 1}ch`, | ||
| width: "round(down, calc(100% - 1ch), 2ch)", | ||
| whiteSpace: "nowrap", | ||
| }} | ||
| > | ||
| {prefix} | ||
| {body.at(0)} | ||
| <span className={`${id}-part`}>{start}</span> | ||
| <span className={`${id}-ellipsis`}>{ellipsis}</span> | ||
| <span | ||
| className={`${id}-part`} | ||
| style={{ | ||
| display: "flex", | ||
| justifyContent: "flex-end", | ||
| }} | ||
| > | ||
| {end} | ||
| </span> | ||
| </span> | ||
| {body.at(-1)} | ||
| </span> | ||
| ); | ||
| } | ||
| export namespace Midcut { | ||
| export interface Props { | ||
| align?: "start" | "end"; | ||
| ellipsis?: string; | ||
| min?: number; | ||
| prefix?: string; | ||
| value?: string; | ||
| } | ||
| } |
+54
-3
| { | ||
| "name": "midcut", | ||
| "version": "0.0.1", | ||
| "license": "MIT" | ||
| } | ||
| "version": "0.1.0", | ||
| "description": "A <1kb React component that accurately middle-truncates monospaced text", | ||
| "keywords": [ | ||
| "css", | ||
| "ellipsis", | ||
| "middle", | ||
| "monospace", | ||
| "react", | ||
| "truncate" | ||
| ], | ||
| "license": "MIT", | ||
| "repository": "tempoxyz/midcut", | ||
| "files": [ | ||
| "dist", | ||
| "src/Midcut.tsx" | ||
| ], | ||
| "type": "module", | ||
| "main": "dist/Midcut.mjs", | ||
| "module": "dist/Midcut.mjs", | ||
| "types": "dist/Midcut.d.mts", | ||
| "exports": { | ||
| ".": { | ||
| "types": "./dist/Midcut.d.mts", | ||
| "import": "./dist/Midcut.mjs" | ||
| } | ||
| }, | ||
| "scripts": { | ||
| "dev": "vp dev", | ||
| "build": "vp pack src/Midcut.tsx --dts --tsconfig tsconfig.app.json", | ||
| "build:demo": "vp build --outDir dist/client && vp build --outDir dist/server --ssr entry-server.tsx && bun scripts/prerender.ts", | ||
| "lint": "vp lint .", | ||
| "preview": "vp preview", | ||
| "prepublishOnly": "bun run build", | ||
| "prepare": "vp config" | ||
| }, | ||
| "devDependencies": { | ||
| "@types/react": "^19.2.5", | ||
| "@types/react-dom": "^19.2.3", | ||
| "@vitejs/plugin-react": "^5.1.1", | ||
| "react": "^19.2.0", | ||
| "react-dom": "^19.2.0", | ||
| "typescript": "~5.9.3", | ||
| "vite": "npm:@voidzero-dev/vite-plus-core@latest", | ||
| "vite-plus": "latest" | ||
| }, | ||
| "peerDependencies": { | ||
| "react": ">=18" | ||
| }, | ||
| "overrides": { | ||
| "vite": "npm:@voidzero-dev/vite-plus-core@latest", | ||
| "vitest": "npm:@voidzero-dev/vite-plus-test@latest" | ||
| }, | ||
| "packageManager": "bun@1.3.11" | ||
| } |
Empty package
Supply chain riskPackage does not contain any code. It may be removed, is name squatting, or the result of a faulty package publish.
Found 1 instance in 1 package
No README
QualityPackage does not have a README. This may indicate a failed publish or a low quality package.
Found 1 instance in 1 package
No repository
Supply chain riskPackage does not have a linked source code repository. Without this field, a package will have no reference to the location of the source code use to generate the package.
Found 1 instance in 1 package
7355
11392.19%5
400%142
Infinity%0
-100%52
Infinity%0
-100%Yes
NaN1
Infinity%8
Infinity%