@flanksource/clicky-ui 0.2.7 → 0.2.9
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/dist/components/Combobox.cjs +89 -49
- package/dist/components/Combobox.cjs.map +1 -1
- package/dist/components/Combobox.d.ts +3 -0
- package/dist/components/Combobox.d.ts.map +1 -1
- package/dist/components/Combobox.js +91 -51
- package/dist/components/Combobox.js.map +1 -1
- package/dist/components/FilterBar.cjs +42 -44
- package/dist/components/FilterBar.cjs.map +1 -1
- package/dist/components/FilterBar.d.ts +19 -0
- package/dist/components/FilterBar.d.ts.map +1 -1
- package/dist/components/FilterBar.js +43 -45
- package/dist/components/FilterBar.js.map +1 -1
- package/dist/components/JsonSchemaForm.cjs +35 -0
- package/dist/components/JsonSchemaForm.cjs.map +1 -0
- package/dist/components/JsonSchemaForm.d.ts +3 -0
- package/dist/components/JsonSchemaForm.d.ts.map +1 -0
- package/dist/components/JsonSchemaForm.js +35 -0
- package/dist/components/JsonSchemaForm.js.map +1 -0
- package/dist/components/json-schema-form-array.cjs +169 -0
- package/dist/components/json-schema-form-array.cjs.map +1 -0
- package/dist/components/json-schema-form-array.d.ts +8 -0
- package/dist/components/json-schema-form-array.d.ts.map +1 -0
- package/dist/components/json-schema-form-array.js +169 -0
- package/dist/components/json-schema-form-array.js.map +1 -0
- package/dist/components/json-schema-form-fields.cjs +365 -0
- package/dist/components/json-schema-form-fields.cjs.map +1 -0
- package/dist/components/json-schema-form-fields.d.ts +19 -0
- package/dist/components/json-schema-form-fields.d.ts.map +1 -0
- package/dist/components/json-schema-form-fields.js +365 -0
- package/dist/components/json-schema-form-fields.js.map +1 -0
- package/dist/components/json-schema-form-render.cjs +154 -0
- package/dist/components/json-schema-form-render.cjs.map +1 -0
- package/dist/components/json-schema-form-render.d.ts +40 -0
- package/dist/components/json-schema-form-render.d.ts.map +1 -0
- package/dist/components/json-schema-form-render.js +154 -0
- package/dist/components/json-schema-form-render.js.map +1 -0
- package/dist/components/json-schema-form-resolve.cjs +121 -0
- package/dist/components/json-schema-form-resolve.cjs.map +1 -0
- package/dist/components/json-schema-form-resolve.d.ts +19 -0
- package/dist/components/json-schema-form-resolve.d.ts.map +1 -0
- package/dist/components/json-schema-form-resolve.js +121 -0
- package/dist/components/json-schema-form-resolve.js.map +1 -0
- package/dist/components/json-schema-form-types.d.ts +108 -0
- package/dist/components/json-schema-form-types.d.ts.map +1 -0
- package/dist/components.cjs +7 -0
- package/dist/components.cjs.map +1 -1
- package/dist/components.d.ts +3 -0
- package/dist/components.d.ts.map +1 -1
- package/dist/components.js +8 -1
- package/dist/components.js.map +1 -1
- package/dist/data/Clicky.cjs +1 -1
- package/dist/data/Clicky.cjs.map +1 -1
- package/dist/data/Clicky.js +1 -1
- package/dist/data/Clicky.js.map +1 -1
- package/dist/data/DataTable.cjs +16 -15
- package/dist/data/DataTable.cjs.map +1 -1
- package/dist/data/DataTable.d.ts +2 -1
- package/dist/data/DataTable.d.ts.map +1 -1
- package/dist/data/DataTable.js +16 -15
- package/dist/data/DataTable.js.map +1 -1
- package/dist/data/Icon.cjs +11 -0
- package/dist/data/Icon.cjs.map +1 -1
- package/dist/data/Icon.d.ts +12 -1
- package/dist/data/Icon.d.ts.map +1 -1
- package/dist/data/Icon.js +12 -1
- package/dist/data/Icon.js.map +1 -1
- package/dist/data/LogDetails.cjs +277 -0
- package/dist/data/LogDetails.cjs.map +1 -0
- package/dist/data/LogDetails.d.ts +5 -0
- package/dist/data/LogDetails.d.ts.map +1 -0
- package/dist/data/LogDetails.js +277 -0
- package/dist/data/LogDetails.js.map +1 -0
- package/dist/data/LogsTable.cjs +6 -202
- package/dist/data/LogsTable.cjs.map +1 -1
- package/dist/data/LogsTable.d.ts.map +1 -1
- package/dist/data/LogsTable.js +4 -200
- package/dist/data/LogsTable.js.map +1 -1
- package/dist/data/MatrixTable.cjs +17 -9
- package/dist/data/MatrixTable.cjs.map +1 -1
- package/dist/data/MatrixTable.d.ts +3 -1
- package/dist/data/MatrixTable.d.ts.map +1 -1
- package/dist/data/MatrixTable.js +17 -9
- package/dist/data/MatrixTable.js.map +1 -1
- package/dist/data/Properties.cjs +2 -2
- package/dist/data/Properties.cjs.map +1 -1
- package/dist/data/Properties.js +2 -2
- package/dist/data/Properties.js.map +1 -1
- package/dist/data/cells/TagList.cjs +19 -3
- package/dist/data/cells/TagList.cjs.map +1 -1
- package/dist/data/cells/TagList.d.ts +11 -1
- package/dist/data/cells/TagList.d.ts.map +1 -1
- package/dist/data/cells/TagList.js +19 -3
- package/dist/data/cells/TagList.js.map +1 -1
- package/dist/data/cells/Timestamp.cjs +17 -2
- package/dist/data/cells/Timestamp.cjs.map +1 -1
- package/dist/data/cells/Timestamp.d.ts +2 -0
- package/dist/data/cells/Timestamp.d.ts.map +1 -1
- package/dist/data/cells/Timestamp.js +17 -2
- package/dist/data/cells/Timestamp.js.map +1 -1
- package/dist/data/log-utils.cjs +7 -0
- package/dist/data/log-utils.cjs.map +1 -0
- package/dist/data/log-utils.d.ts +2 -0
- package/dist/data/log-utils.d.ts.map +1 -0
- package/dist/data/log-utils.js +7 -0
- package/dist/data/log-utils.js.map +1 -0
- package/dist/data.cjs +3 -0
- package/dist/data.cjs.map +1 -1
- package/dist/data.d.ts +2 -2
- package/dist/data.d.ts.map +1 -1
- package/dist/data.js +5 -2
- package/dist/index.cjs +13 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +15 -2
- package/dist/index.js.map +1 -1
- package/dist/rpc/EntityExplorerApp.cjs +3 -2
- package/dist/rpc/EntityExplorerApp.cjs.map +1 -1
- package/dist/rpc/EntityExplorerApp.js +3 -2
- package/dist/rpc/EntityExplorerApp.js.map +1 -1
- package/dist/rpc/OperationActionDialog.cjs +1 -1
- package/dist/rpc/OperationActionDialog.cjs.map +1 -1
- package/dist/rpc/OperationActionDialog.js +1 -1
- package/dist/rpc/OperationActionDialog.js.map +1 -1
- package/dist/rpc/OperationCommandPage.cjs +21 -14
- package/dist/rpc/OperationCommandPage.cjs.map +1 -1
- package/dist/rpc/OperationCommandPage.d.ts.map +1 -1
- package/dist/rpc/OperationCommandPage.js +21 -14
- package/dist/rpc/OperationCommandPage.js.map +1 -1
- package/dist/rpc/apiClient.cjs +316 -0
- package/dist/rpc/apiClient.cjs.map +1 -0
- package/dist/rpc/apiClient.d.ts +44 -0
- package/dist/rpc/apiClient.d.ts.map +1 -0
- package/dist/rpc/apiClient.js +316 -0
- package/dist/rpc/apiClient.js.map +1 -0
- package/dist/rpc/useOperations.cjs.map +1 -1
- package/dist/rpc/useOperations.d.ts +2 -1
- package/dist/rpc/useOperations.d.ts.map +1 -1
- package/dist/rpc/useOperations.js.map +1 -1
- package/dist/rpc.cjs +3 -0
- package/dist/rpc.cjs.map +1 -1
- package/dist/rpc.d.ts +1 -0
- package/dist/rpc.d.ts.map +1 -1
- package/dist/rpc.js +3 -0
- package/dist/rpc.js.map +1 -1
- package/dist/styles.css +1 -1
- package/package.json +1 -1
package/dist/data/Icon.cjs
CHANGED
|
@@ -124,6 +124,17 @@ function Icon({
|
|
|
124
124
|
}
|
|
125
125
|
);
|
|
126
126
|
}
|
|
127
|
+
function LabelIcon({
|
|
128
|
+
icon,
|
|
129
|
+
className
|
|
130
|
+
}) {
|
|
131
|
+
if (icon == null || icon === "" || icon === false) return null;
|
|
132
|
+
if (typeof icon === "string") {
|
|
133
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: icon, className: utils.cn("shrink-0", className) });
|
|
134
|
+
}
|
|
135
|
+
return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: icon });
|
|
136
|
+
}
|
|
127
137
|
exports.Icon = Icon;
|
|
138
|
+
exports.LabelIcon = LabelIcon;
|
|
128
139
|
exports.setFallbackIconProvider = setFallbackIconProvider;
|
|
129
140
|
//# sourceMappingURL=Icon.cjs.map
|
package/dist/data/Icon.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Icon.cjs","sources":["../../src/data/Icon.tsx"],"sourcesContent":["import type { CSSProperties, ComponentType, ElementType } from \"react\";\nimport { cn } from \"../lib/utils\";\nimport { resolveSize, type SizeToken } from \"../lib/size\";\nimport { useDensityValue } from \"../hooks/use-density\";\n\nexport type IconStyle = \"plain\" | \"badge\";\n\nexport type IconTone = \"emerald\" | \"amber\" | \"rose\" | \"slate\" | \"sky\" | \"violet\" | \"neutral\";\n\nexport type StaticIconComponent = ElementType;\n\ntype CommonIconProps = {\n /** Classes applied to the glyph or badge wrapper. */\n className?: string;\n /** Explicit glyph width. */\n width?: string | number;\n /** Explicit glyph height. */\n height?: string | number;\n /** CSS rotate value or degrees. */\n rotate?: string | number;\n /** Flip direction for imported glyphs. */\n flip?: string;\n /** Forward inline rendering semantics to imported glyphs. */\n inline?: boolean;\n /** Accessible title for the glyph. */\n title?: string;\n /**\n * Presentation style. `plain` (default) renders the icon inline.\n * `badge` wraps the icon in a circular chip (white background, ring, shadow)\n * sized by `size` — use in stage/approval cells so the chip scales with a\n * neighbouring avatar.\n */\n style?: IconStyle;\n /**\n * Named size token (xxs..xxl). Drives the badge diameter and glyph. The\n * glyph is always ~50% of the badge diameter so it scales consistently\n * across sizes. For `style=\"plain\"` it sets width/height when neither is\n * provided.\n */\n size?: SizeToken;\n /** Semantic color for `style=\"badge\"`. Ignored for plain icons. */\n tone?: IconTone;\n};\n\nexport type IconProps = CommonIconProps &\n (\n | {\n /** Imported static icon component. */\n icon: StaticIconComponent;\n name?: never;\n }\n | {\n /** Runtime icon name resolved by the fallback provider. */\n name: string;\n icon?: never;\n }\n );\n\nconst TONE_CLASSES: Record<IconTone, string> = {\n emerald: \"text-emerald-700 ring-emerald-200/80\",\n amber: \"text-amber-700 ring-amber-200/80\",\n rose: \"text-rose-700 ring-rose-200/80\",\n slate: \"text-slate-700 ring-slate-200/80\",\n sky: \"text-sky-700 ring-sky-200/80\",\n violet: \"text-violet-700 ring-violet-200/80\",\n neutral: \"text-foreground ring-border\",\n};\n\nconst DEFAULT_PLAIN_ICON_SIZE = \"1em\";\n\n/**\n * Optional secondary icon provider for user-supplied runtime names.\n * Built-in/default icons should pass an imported component via `icon`.\n */\nexport type FallbackIconProps = {\n /** Runtime icon name to resolve. */\n name?: string;\n /** Classes applied by Icon. */\n className?: string;\n /** Requested glyph size. */\n size?: string | number;\n /** Accessible label. */\n alt?: string;\n};\n\ntype FallbackIconComponent = ComponentType<FallbackIconProps>;\n\nlet fallbackIcon: FallbackIconComponent | null = null;\n\n/**\n * Register a secondary glyph provider. Pass the flanksource Icon/ResourceIcon\n * (or any compatible component) to resolve user-supplied runtime names.\n */\nexport function setFallbackIconProvider(component: FallbackIconComponent | null): void {\n fallbackIcon = component;\n}\n\nfunction renderImportedGlyph(\n ImportedIcon: StaticIconComponent,\n glyphWidth: number | string | undefined,\n glyphHeight: number | string | undefined,\n rotate: string | number | undefined,\n flip: string | undefined,\n inline: boolean | undefined,\n glyphClassName: string | undefined,\n title: string | undefined,\n): JSX.Element {\n const transform = [\n typeof rotate === \"number\" ? `rotate(${rotate}deg)` : typeof rotate === \"string\" ? rotate : \"\",\n flip === \"horizontal\" || flip === \"both\" ? \"scaleX(-1)\" : \"\",\n flip === \"vertical\" || flip === \"both\" ? \"scaleY(-1)\" : \"\",\n ]\n .filter(Boolean)\n .join(\" \");\n\n return (\n <ImportedIcon\n {...(glyphClassName ? { className: glyphClassName } : {})}\n {...(glyphWidth != null ? { width: glyphWidth } : {})}\n {...(glyphHeight != null ? { height: glyphHeight } : {})}\n {...(inline != null ? { \"aria-hidden\": !title } : {})}\n {...(title ? { title, role: \"img\" } : { \"aria-hidden\": true })}\n {...(transform ? { style: { transform } } : {})}\n />\n );\n}\n\nfunction renderRuntimeGlyph(\n name: string,\n glyphWidth: number | string | undefined,\n glyphHeight: number | string | undefined,\n glyphClassName: string | undefined,\n title: string | undefined,\n): JSX.Element {\n if (fallbackIcon) {\n const Fallback = fallbackIcon;\n const glyphSize = typeof glyphWidth === \"number\" ? glyphWidth : glyphHeight;\n return (\n <Fallback\n name={name}\n {...(glyphClassName ? { className: glyphClassName } : {})}\n {...(glyphSize != null ? { size: glyphSize } : {})}\n {...(title ? { alt: title } : {})}\n />\n );\n }\n\n return (\n <span\n className={cn(\n \"inline-flex shrink-0 items-center justify-center rounded-sm border border-dashed border-muted-foreground/50 text-[0.65em] leading-none text-muted-foreground\",\n glyphClassName,\n )}\n title={title ?? name}\n role={title ? \"img\" : undefined}\n aria-label={title}\n aria-hidden={title ? undefined : true}\n style={{\n width: glyphWidth,\n height: glyphHeight,\n }}\n >\n ?\n </span>\n );\n}\n\nexport function Icon({\n icon: ImportedIcon,\n name,\n className,\n width,\n height,\n rotate,\n flip,\n inline,\n title,\n style = \"plain\",\n size,\n tone = \"neutral\",\n}: IconProps) {\n const density = useDensityValue();\n const pxSize = size != null ? resolveSize(size, density) : undefined;\n const glyphSize = pxSize != null ? Math.max(8, Math.round(pxSize * 0.5)) : undefined;\n const defaultGlyphSize = style === \"badge\" ? glyphSize : (pxSize ?? DEFAULT_PLAIN_ICON_SIZE);\n const resolvedWidth = width ?? height ?? defaultGlyphSize;\n const resolvedHeight = height ?? resolvedWidth;\n\n const glyphClassName = cn(\n \"inline-block shrink-0 align-[-0.125em]\",\n style === \"plain\" ? className : undefined,\n );\n const glyphTitle = style === \"plain\" ? title : undefined;\n\n const renderedIcon = ImportedIcon\n ? renderImportedGlyph(\n ImportedIcon,\n resolvedWidth,\n resolvedHeight,\n rotate,\n flip,\n inline,\n glyphClassName,\n glyphTitle,\n )\n : renderRuntimeGlyph(name, resolvedWidth, resolvedHeight, glyphClassName, glyphTitle);\n\n if (style === \"plain\") {\n return renderedIcon;\n }\n\n const badgeStyle: CSSProperties | undefined =\n pxSize != null ? { width: pxSize, height: pxSize } : undefined;\n\n return (\n <span\n title={title}\n aria-label={title}\n role={title ? \"img\" : undefined}\n className={cn(\n \"inline-flex items-center justify-center rounded-full bg-white shadow-sm ring-1 ring-inset\",\n TONE_CLASSES[tone],\n className,\n )}\n style={badgeStyle}\n >\n {renderedIcon}\n </span>\n );\n}\n"],"names":["jsx","cn","size","useDensityValue","resolveSize"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Icon.cjs","sources":["../../src/data/Icon.tsx"],"sourcesContent":["import type { CSSProperties, ComponentType, ElementType, ReactNode } from \"react\";\nimport { cn } from \"../lib/utils\";\nimport { resolveSize, type SizeToken } from \"../lib/size\";\nimport { useDensityValue } from \"../hooks/use-density\";\n\n// LabelIconSpec is the icon a label may carry: an iconify/runtime name (resolved\n// via the fallback provider) or a fully-rendered node the caller supplies.\nexport type LabelIconSpec = string | ReactNode;\n\nexport type IconStyle = \"plain\" | \"badge\";\n\nexport type IconTone = \"emerald\" | \"amber\" | \"rose\" | \"slate\" | \"sky\" | \"violet\" | \"neutral\";\n\nexport type StaticIconComponent = ElementType;\n\ntype CommonIconProps = {\n /** Classes applied to the glyph or badge wrapper. */\n className?: string;\n /** Explicit glyph width. */\n width?: string | number;\n /** Explicit glyph height. */\n height?: string | number;\n /** CSS rotate value or degrees. */\n rotate?: string | number;\n /** Flip direction for imported glyphs. */\n flip?: string;\n /** Forward inline rendering semantics to imported glyphs. */\n inline?: boolean;\n /** Accessible title for the glyph. */\n title?: string;\n /**\n * Presentation style. `plain` (default) renders the icon inline.\n * `badge` wraps the icon in a circular chip (white background, ring, shadow)\n * sized by `size` — use in stage/approval cells so the chip scales with a\n * neighbouring avatar.\n */\n style?: IconStyle;\n /**\n * Named size token (xxs..xxl). Drives the badge diameter and glyph. The\n * glyph is always ~50% of the badge diameter so it scales consistently\n * across sizes. For `style=\"plain\"` it sets width/height when neither is\n * provided.\n */\n size?: SizeToken;\n /** Semantic color for `style=\"badge\"`. Ignored for plain icons. */\n tone?: IconTone;\n};\n\nexport type IconProps = CommonIconProps &\n (\n | {\n /** Imported static icon component. */\n icon: StaticIconComponent;\n name?: never;\n }\n | {\n /** Runtime icon name resolved by the fallback provider. */\n name: string;\n icon?: never;\n }\n );\n\nconst TONE_CLASSES: Record<IconTone, string> = {\n emerald: \"text-emerald-700 ring-emerald-200/80\",\n amber: \"text-amber-700 ring-amber-200/80\",\n rose: \"text-rose-700 ring-rose-200/80\",\n slate: \"text-slate-700 ring-slate-200/80\",\n sky: \"text-sky-700 ring-sky-200/80\",\n violet: \"text-violet-700 ring-violet-200/80\",\n neutral: \"text-foreground ring-border\",\n};\n\nconst DEFAULT_PLAIN_ICON_SIZE = \"1em\";\n\n/**\n * Optional secondary icon provider for user-supplied runtime names.\n * Built-in/default icons should pass an imported component via `icon`.\n */\nexport type FallbackIconProps = {\n /** Runtime icon name to resolve. */\n name?: string;\n /** Classes applied by Icon. */\n className?: string;\n /** Requested glyph size. */\n size?: string | number;\n /** Accessible label. */\n alt?: string;\n};\n\ntype FallbackIconComponent = ComponentType<FallbackIconProps>;\n\nlet fallbackIcon: FallbackIconComponent | null = null;\n\n/**\n * Register a secondary glyph provider. Pass the flanksource Icon/ResourceIcon\n * (or any compatible component) to resolve user-supplied runtime names.\n */\nexport function setFallbackIconProvider(component: FallbackIconComponent | null): void {\n fallbackIcon = component;\n}\n\nfunction renderImportedGlyph(\n ImportedIcon: StaticIconComponent,\n glyphWidth: number | string | undefined,\n glyphHeight: number | string | undefined,\n rotate: string | number | undefined,\n flip: string | undefined,\n inline: boolean | undefined,\n glyphClassName: string | undefined,\n title: string | undefined,\n): JSX.Element {\n const transform = [\n typeof rotate === \"number\" ? `rotate(${rotate}deg)` : typeof rotate === \"string\" ? rotate : \"\",\n flip === \"horizontal\" || flip === \"both\" ? \"scaleX(-1)\" : \"\",\n flip === \"vertical\" || flip === \"both\" ? \"scaleY(-1)\" : \"\",\n ]\n .filter(Boolean)\n .join(\" \");\n\n return (\n <ImportedIcon\n {...(glyphClassName ? { className: glyphClassName } : {})}\n {...(glyphWidth != null ? { width: glyphWidth } : {})}\n {...(glyphHeight != null ? { height: glyphHeight } : {})}\n {...(inline != null ? { \"aria-hidden\": !title } : {})}\n {...(title ? { title, role: \"img\" } : { \"aria-hidden\": true })}\n {...(transform ? { style: { transform } } : {})}\n />\n );\n}\n\nfunction renderRuntimeGlyph(\n name: string,\n glyphWidth: number | string | undefined,\n glyphHeight: number | string | undefined,\n glyphClassName: string | undefined,\n title: string | undefined,\n): JSX.Element {\n if (fallbackIcon) {\n const Fallback = fallbackIcon;\n const glyphSize = typeof glyphWidth === \"number\" ? glyphWidth : glyphHeight;\n return (\n <Fallback\n name={name}\n {...(glyphClassName ? { className: glyphClassName } : {})}\n {...(glyphSize != null ? { size: glyphSize } : {})}\n {...(title ? { alt: title } : {})}\n />\n );\n }\n\n return (\n <span\n className={cn(\n \"inline-flex shrink-0 items-center justify-center rounded-sm border border-dashed border-muted-foreground/50 text-[0.65em] leading-none text-muted-foreground\",\n glyphClassName,\n )}\n title={title ?? name}\n role={title ? \"img\" : undefined}\n aria-label={title}\n aria-hidden={title ? undefined : true}\n style={{\n width: glyphWidth,\n height: glyphHeight,\n }}\n >\n ?\n </span>\n );\n}\n\nexport function Icon({\n icon: ImportedIcon,\n name,\n className,\n width,\n height,\n rotate,\n flip,\n inline,\n title,\n style = \"plain\",\n size,\n tone = \"neutral\",\n}: IconProps) {\n const density = useDensityValue();\n const pxSize = size != null ? resolveSize(size, density) : undefined;\n const glyphSize = pxSize != null ? Math.max(8, Math.round(pxSize * 0.5)) : undefined;\n const defaultGlyphSize = style === \"badge\" ? glyphSize : (pxSize ?? DEFAULT_PLAIN_ICON_SIZE);\n const resolvedWidth = width ?? height ?? defaultGlyphSize;\n const resolvedHeight = height ?? resolvedWidth;\n\n const glyphClassName = cn(\n \"inline-block shrink-0 align-[-0.125em]\",\n style === \"plain\" ? className : undefined,\n );\n const glyphTitle = style === \"plain\" ? title : undefined;\n\n const renderedIcon = ImportedIcon\n ? renderImportedGlyph(\n ImportedIcon,\n resolvedWidth,\n resolvedHeight,\n rotate,\n flip,\n inline,\n glyphClassName,\n glyphTitle,\n )\n : renderRuntimeGlyph(name, resolvedWidth, resolvedHeight, glyphClassName, glyphTitle);\n\n if (style === \"plain\") {\n return renderedIcon;\n }\n\n const badgeStyle: CSSProperties | undefined =\n pxSize != null ? { width: pxSize, height: pxSize } : undefined;\n\n return (\n <span\n title={title}\n aria-label={title}\n role={title ? \"img\" : undefined}\n className={cn(\n \"inline-flex items-center justify-center rounded-full bg-white shadow-sm ring-1 ring-inset\",\n TONE_CLASSES[tone],\n className,\n )}\n style={badgeStyle}\n >\n {renderedIcon}\n </span>\n );\n}\n\n/**\n * LabelIcon renders a label's leading glyph from a {@link LabelIconSpec}: a\n * string is treated as a runtime icon name (resolved by the registered fallback\n * provider), any other ReactNode is rendered as-is. Returns null for an absent\n * or empty spec so callers can spread it unconditionally before a label.\n */\nexport function LabelIcon({\n icon,\n className,\n}: {\n icon?: LabelIconSpec;\n className?: string;\n}): JSX.Element | null {\n if (icon == null || icon === \"\" || icon === false) return null;\n if (typeof icon === \"string\") {\n return <Icon name={icon} className={cn(\"shrink-0\", className)} />;\n }\n return <>{icon}</>;\n}\n"],"names":["jsx","cn","size","useDensityValue","resolveSize"],"mappings":"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"}
|
package/dist/data/Icon.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { ComponentType, ElementType } from 'react';
|
|
1
|
+
import { ComponentType, ElementType, ReactNode } from 'react';
|
|
2
2
|
import { SizeToken } from '../lib/size';
|
|
3
|
+
export type LabelIconSpec = string | ReactNode;
|
|
3
4
|
export type IconStyle = "plain" | "badge";
|
|
4
5
|
export type IconTone = "emerald" | "amber" | "rose" | "slate" | "sky" | "violet" | "neutral";
|
|
5
6
|
export type StaticIconComponent = ElementType;
|
|
@@ -65,5 +66,15 @@ type FallbackIconComponent = ComponentType<FallbackIconProps>;
|
|
|
65
66
|
*/
|
|
66
67
|
export declare function setFallbackIconProvider(component: FallbackIconComponent | null): void;
|
|
67
68
|
export declare function Icon({ icon: ImportedIcon, name, className, width, height, rotate, flip, inline, title, style, size, tone, }: IconProps): import("react/jsx-runtime").JSX.Element;
|
|
69
|
+
/**
|
|
70
|
+
* LabelIcon renders a label's leading glyph from a {@link LabelIconSpec}: a
|
|
71
|
+
* string is treated as a runtime icon name (resolved by the registered fallback
|
|
72
|
+
* provider), any other ReactNode is rendered as-is. Returns null for an absent
|
|
73
|
+
* or empty spec so callers can spread it unconditionally before a label.
|
|
74
|
+
*/
|
|
75
|
+
export declare function LabelIcon({ icon, className, }: {
|
|
76
|
+
icon?: LabelIconSpec;
|
|
77
|
+
className?: string;
|
|
78
|
+
}): JSX.Element | null;
|
|
68
79
|
export {};
|
|
69
80
|
//# sourceMappingURL=Icon.d.ts.map
|
package/dist/data/Icon.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Icon.d.ts","sourceRoot":"","sources":["../../src/data/Icon.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAiB,aAAa,EAAE,WAAW,EAAE,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"Icon.d.ts","sourceRoot":"","sources":["../../src/data/Icon.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAiB,aAAa,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAElF,OAAO,EAAe,KAAK,SAAS,EAAE,MAAM,aAAa,CAAC;AAK1D,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,SAAS,CAAC;AAE/C,MAAM,MAAM,SAAS,GAAG,OAAO,GAAG,OAAO,CAAC;AAE1C,MAAM,MAAM,QAAQ,GAAG,SAAS,GAAG,OAAO,GAAG,MAAM,GAAG,OAAO,GAAG,KAAK,GAAG,QAAQ,GAAG,SAAS,CAAC;AAE7F,MAAM,MAAM,mBAAmB,GAAG,WAAW,CAAC;AAE9C,KAAK,eAAe,GAAG;IACrB,qDAAqD;IACrD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,4BAA4B;IAC5B,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACxB,6BAA6B;IAC7B,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACzB,mCAAmC;IACnC,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACzB,0CAA0C;IAC1C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,6DAA6D;IAC7D,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,sCAAsC;IACtC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;;;OAKG;IACH,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB;;;;;OAKG;IACH,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,mEAAmE;IACnE,IAAI,CAAC,EAAE,QAAQ,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,SAAS,GAAG,eAAe,GACrC,CACI;IACE,sCAAsC;IACtC,IAAI,EAAE,mBAAmB,CAAC;IAC1B,IAAI,CAAC,EAAE,KAAK,CAAC;CACd,GACD;IACE,2DAA2D;IAC3D,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,KAAK,CAAC;CACd,CACJ,CAAC;AAcJ;;;GAGG;AACH,MAAM,MAAM,iBAAiB,GAAG;IAC9B,oCAAoC;IACpC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,+BAA+B;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,4BAA4B;IAC5B,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACvB,wBAAwB;IACxB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,KAAK,qBAAqB,GAAG,aAAa,CAAC,iBAAiB,CAAC,CAAC;AAI9D;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,SAAS,EAAE,qBAAqB,GAAG,IAAI,GAAG,IAAI,CAErF;AAwED,wBAAgB,IAAI,CAAC,EACnB,IAAI,EAAE,YAAY,EAClB,IAAI,EACJ,SAAS,EACT,KAAK,EACL,MAAM,EACN,MAAM,EACN,IAAI,EACJ,MAAM,EACN,KAAK,EACL,KAAe,EACf,IAAI,EACJ,IAAgB,GACjB,EAAE,SAAS,2CAiDX;AAED;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,EACxB,IAAI,EACJ,SAAS,GACV,EAAE;IACD,IAAI,CAAC,EAAE,aAAa,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,GAAG,GAAG,CAAC,OAAO,GAAG,IAAI,CAMrB"}
|
package/dist/data/Icon.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { jsx } from "react/jsx-runtime";
|
|
1
|
+
import { jsx, Fragment } from "react/jsx-runtime";
|
|
2
2
|
import { cn } from "../lib/utils.js";
|
|
3
3
|
import { resolveSize } from "../lib/size.js";
|
|
4
4
|
import { useDensityValue } from "../hooks/use-density.js";
|
|
@@ -122,8 +122,19 @@ function Icon({
|
|
|
122
122
|
}
|
|
123
123
|
);
|
|
124
124
|
}
|
|
125
|
+
function LabelIcon({
|
|
126
|
+
icon,
|
|
127
|
+
className
|
|
128
|
+
}) {
|
|
129
|
+
if (icon == null || icon === "" || icon === false) return null;
|
|
130
|
+
if (typeof icon === "string") {
|
|
131
|
+
return /* @__PURE__ */ jsx(Icon, { name: icon, className: cn("shrink-0", className) });
|
|
132
|
+
}
|
|
133
|
+
return /* @__PURE__ */ jsx(Fragment, { children: icon });
|
|
134
|
+
}
|
|
125
135
|
export {
|
|
126
136
|
Icon,
|
|
137
|
+
LabelIcon,
|
|
127
138
|
setFallbackIconProvider
|
|
128
139
|
};
|
|
129
140
|
//# sourceMappingURL=Icon.js.map
|
package/dist/data/Icon.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Icon.js","sources":["../../src/data/Icon.tsx"],"sourcesContent":["import type { CSSProperties, ComponentType, ElementType } from \"react\";\nimport { cn } from \"../lib/utils\";\nimport { resolveSize, type SizeToken } from \"../lib/size\";\nimport { useDensityValue } from \"../hooks/use-density\";\n\nexport type IconStyle = \"plain\" | \"badge\";\n\nexport type IconTone = \"emerald\" | \"amber\" | \"rose\" | \"slate\" | \"sky\" | \"violet\" | \"neutral\";\n\nexport type StaticIconComponent = ElementType;\n\ntype CommonIconProps = {\n /** Classes applied to the glyph or badge wrapper. */\n className?: string;\n /** Explicit glyph width. */\n width?: string | number;\n /** Explicit glyph height. */\n height?: string | number;\n /** CSS rotate value or degrees. */\n rotate?: string | number;\n /** Flip direction for imported glyphs. */\n flip?: string;\n /** Forward inline rendering semantics to imported glyphs. */\n inline?: boolean;\n /** Accessible title for the glyph. */\n title?: string;\n /**\n * Presentation style. `plain` (default) renders the icon inline.\n * `badge` wraps the icon in a circular chip (white background, ring, shadow)\n * sized by `size` — use in stage/approval cells so the chip scales with a\n * neighbouring avatar.\n */\n style?: IconStyle;\n /**\n * Named size token (xxs..xxl). Drives the badge diameter and glyph. The\n * glyph is always ~50% of the badge diameter so it scales consistently\n * across sizes. For `style=\"plain\"` it sets width/height when neither is\n * provided.\n */\n size?: SizeToken;\n /** Semantic color for `style=\"badge\"`. Ignored for plain icons. */\n tone?: IconTone;\n};\n\nexport type IconProps = CommonIconProps &\n (\n | {\n /** Imported static icon component. */\n icon: StaticIconComponent;\n name?: never;\n }\n | {\n /** Runtime icon name resolved by the fallback provider. */\n name: string;\n icon?: never;\n }\n );\n\nconst TONE_CLASSES: Record<IconTone, string> = {\n emerald: \"text-emerald-700 ring-emerald-200/80\",\n amber: \"text-amber-700 ring-amber-200/80\",\n rose: \"text-rose-700 ring-rose-200/80\",\n slate: \"text-slate-700 ring-slate-200/80\",\n sky: \"text-sky-700 ring-sky-200/80\",\n violet: \"text-violet-700 ring-violet-200/80\",\n neutral: \"text-foreground ring-border\",\n};\n\nconst DEFAULT_PLAIN_ICON_SIZE = \"1em\";\n\n/**\n * Optional secondary icon provider for user-supplied runtime names.\n * Built-in/default icons should pass an imported component via `icon`.\n */\nexport type FallbackIconProps = {\n /** Runtime icon name to resolve. */\n name?: string;\n /** Classes applied by Icon. */\n className?: string;\n /** Requested glyph size. */\n size?: string | number;\n /** Accessible label. */\n alt?: string;\n};\n\ntype FallbackIconComponent = ComponentType<FallbackIconProps>;\n\nlet fallbackIcon: FallbackIconComponent | null = null;\n\n/**\n * Register a secondary glyph provider. Pass the flanksource Icon/ResourceIcon\n * (or any compatible component) to resolve user-supplied runtime names.\n */\nexport function setFallbackIconProvider(component: FallbackIconComponent | null): void {\n fallbackIcon = component;\n}\n\nfunction renderImportedGlyph(\n ImportedIcon: StaticIconComponent,\n glyphWidth: number | string | undefined,\n glyphHeight: number | string | undefined,\n rotate: string | number | undefined,\n flip: string | undefined,\n inline: boolean | undefined,\n glyphClassName: string | undefined,\n title: string | undefined,\n): JSX.Element {\n const transform = [\n typeof rotate === \"number\" ? `rotate(${rotate}deg)` : typeof rotate === \"string\" ? rotate : \"\",\n flip === \"horizontal\" || flip === \"both\" ? \"scaleX(-1)\" : \"\",\n flip === \"vertical\" || flip === \"both\" ? \"scaleY(-1)\" : \"\",\n ]\n .filter(Boolean)\n .join(\" \");\n\n return (\n <ImportedIcon\n {...(glyphClassName ? { className: glyphClassName } : {})}\n {...(glyphWidth != null ? { width: glyphWidth } : {})}\n {...(glyphHeight != null ? { height: glyphHeight } : {})}\n {...(inline != null ? { \"aria-hidden\": !title } : {})}\n {...(title ? { title, role: \"img\" } : { \"aria-hidden\": true })}\n {...(transform ? { style: { transform } } : {})}\n />\n );\n}\n\nfunction renderRuntimeGlyph(\n name: string,\n glyphWidth: number | string | undefined,\n glyphHeight: number | string | undefined,\n glyphClassName: string | undefined,\n title: string | undefined,\n): JSX.Element {\n if (fallbackIcon) {\n const Fallback = fallbackIcon;\n const glyphSize = typeof glyphWidth === \"number\" ? glyphWidth : glyphHeight;\n return (\n <Fallback\n name={name}\n {...(glyphClassName ? { className: glyphClassName } : {})}\n {...(glyphSize != null ? { size: glyphSize } : {})}\n {...(title ? { alt: title } : {})}\n />\n );\n }\n\n return (\n <span\n className={cn(\n \"inline-flex shrink-0 items-center justify-center rounded-sm border border-dashed border-muted-foreground/50 text-[0.65em] leading-none text-muted-foreground\",\n glyphClassName,\n )}\n title={title ?? name}\n role={title ? \"img\" : undefined}\n aria-label={title}\n aria-hidden={title ? undefined : true}\n style={{\n width: glyphWidth,\n height: glyphHeight,\n }}\n >\n ?\n </span>\n );\n}\n\nexport function Icon({\n icon: ImportedIcon,\n name,\n className,\n width,\n height,\n rotate,\n flip,\n inline,\n title,\n style = \"plain\",\n size,\n tone = \"neutral\",\n}: IconProps) {\n const density = useDensityValue();\n const pxSize = size != null ? resolveSize(size, density) : undefined;\n const glyphSize = pxSize != null ? Math.max(8, Math.round(pxSize * 0.5)) : undefined;\n const defaultGlyphSize = style === \"badge\" ? glyphSize : (pxSize ?? DEFAULT_PLAIN_ICON_SIZE);\n const resolvedWidth = width ?? height ?? defaultGlyphSize;\n const resolvedHeight = height ?? resolvedWidth;\n\n const glyphClassName = cn(\n \"inline-block shrink-0 align-[-0.125em]\",\n style === \"plain\" ? className : undefined,\n );\n const glyphTitle = style === \"plain\" ? title : undefined;\n\n const renderedIcon = ImportedIcon\n ? renderImportedGlyph(\n ImportedIcon,\n resolvedWidth,\n resolvedHeight,\n rotate,\n flip,\n inline,\n glyphClassName,\n glyphTitle,\n )\n : renderRuntimeGlyph(name, resolvedWidth, resolvedHeight, glyphClassName, glyphTitle);\n\n if (style === \"plain\") {\n return renderedIcon;\n }\n\n const badgeStyle: CSSProperties | undefined =\n pxSize != null ? { width: pxSize, height: pxSize } : undefined;\n\n return (\n <span\n title={title}\n aria-label={title}\n role={title ? \"img\" : undefined}\n className={cn(\n \"inline-flex items-center justify-center rounded-full bg-white shadow-sm ring-1 ring-inset\",\n TONE_CLASSES[tone],\n className,\n )}\n style={badgeStyle}\n >\n {renderedIcon}\n </span>\n );\n}\n"],"names":[],"mappings":";;;;AA0DA,MAAM,eAAyC;AAAA,EAC7C,SAAS;AAAA,EACT,OAAO;AAAA,EACP,MAAM;AAAA,EACN,OAAO;AAAA,EACP,KAAK;AAAA,EACL,QAAQ;AAAA,EACR,SAAS;AACX;AAEA,MAAM,0BAA0B;AAmBhC,IAAI,eAA6C;AAM1C,SAAS,wBAAwB,WAA+C;AACrF,iBAAe;AACjB;AAEA,SAAS,oBACP,cACA,YACA,aACA,QACA,MACA,QACA,gBACA,OACa;AACb,QAAM,YAAY;AAAA,IAChB,OAAO,WAAW,WAAW,UAAU,MAAM,SAAS,OAAO,WAAW,WAAW,SAAS;AAAA,IAC5F,SAAS,gBAAgB,SAAS,SAAS,eAAe;AAAA,IAC1D,SAAS,cAAc,SAAS,SAAS,eAAe;AAAA,EAAA,EAEvD,OAAO,OAAO,EACd,KAAK,GAAG;AAEX,SACE;AAAA,IAAC;AAAA,IAAA;AAAA,MACE,GAAI,iBAAiB,EAAE,WAAW,eAAA,IAAmB,CAAA;AAAA,MACrD,GAAI,cAAc,OAAO,EAAE,OAAO,WAAA,IAAe,CAAA;AAAA,MACjD,GAAI,eAAe,OAAO,EAAE,QAAQ,YAAA,IAAgB,CAAA;AAAA,MACpD,GAAI,UAAU,OAAO,EAAE,eAAe,CAAC,MAAA,IAAU,CAAA;AAAA,MACjD,GAAI,QAAQ,EAAE,OAAO,MAAM,UAAU,EAAE,eAAe,KAAA;AAAA,MACtD,GAAI,YAAY,EAAE,OAAO,EAAE,UAAA,EAAU,IAAM,CAAA;AAAA,IAAC;AAAA,EAAA;AAGnD;AAEA,SAAS,mBACP,MACA,YACA,aACA,gBACA,OACa;AACb,MAAI,cAAc;AAChB,UAAM,WAAW;AACjB,UAAM,YAAY,OAAO,eAAe,WAAW,aAAa;AAChE,WACE;AAAA,MAAC;AAAA,MAAA;AAAA,QACC;AAAA,QACC,GAAI,iBAAiB,EAAE,WAAW,eAAA,IAAmB,CAAA;AAAA,QACrD,GAAI,aAAa,OAAO,EAAE,MAAM,UAAA,IAAc,CAAA;AAAA,QAC9C,GAAI,QAAQ,EAAE,KAAK,UAAU,CAAA;AAAA,MAAC;AAAA,IAAA;AAAA,EAGrC;AAEA,SACE;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,WAAW;AAAA,QACT;AAAA,QACA;AAAA,MAAA;AAAA,MAEF,OAAO,SAAS;AAAA,MAChB,MAAM,QAAQ,QAAQ;AAAA,MACtB,cAAY;AAAA,MACZ,eAAa,QAAQ,SAAY;AAAA,MACjC,OAAO;AAAA,QACL,OAAO;AAAA,QACP,QAAQ;AAAA,MAAA;AAAA,MAEX,UAAA;AAAA,IAAA;AAAA,EAAA;AAIL;AAEO,SAAS,KAAK;AAAA,EACnB,MAAM;AAAA,EACN;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,QAAQ;AAAA,EACR;AAAA,EACA,OAAO;AACT,GAAc;AACZ,QAAM,UAAU,gBAAA;AAChB,QAAM,SAAS,QAAQ,OAAO,YAAY,MAAM,OAAO,IAAI;AAC3D,QAAM,YAAY,UAAU,OAAO,KAAK,IAAI,GAAG,KAAK,MAAM,SAAS,GAAG,CAAC,IAAI;AAC3E,QAAM,mBAAmB,UAAU,UAAU,YAAa,UAAU;AACpE,QAAM,gBAAgB,SAAS,UAAU;AACzC,QAAM,iBAAiB,UAAU;AAEjC,QAAM,iBAAiB;AAAA,IACrB;AAAA,IACA,UAAU,UAAU,YAAY;AAAA,EAAA;AAElC,QAAM,aAAa,UAAU,UAAU,QAAQ;AAE/C,QAAM,eAAe,eACjB;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EAAA,IAEF,mBAAmB,MAAM,eAAe,gBAAgB,gBAAgB,UAAU;AAEtF,MAAI,UAAU,SAAS;AACrB,WAAO;AAAA,EACT;AAEA,QAAM,aACJ,UAAU,OAAO,EAAE,OAAO,QAAQ,QAAQ,WAAW;AAEvD,SACE;AAAA,IAAC;AAAA,IAAA;AAAA,MACC;AAAA,MACA,cAAY;AAAA,MACZ,MAAM,QAAQ,QAAQ;AAAA,MACtB,WAAW;AAAA,QACT;AAAA,QACA,aAAa,IAAI;AAAA,QACjB;AAAA,MAAA;AAAA,MAEF,OAAO;AAAA,MAEN,UAAA;AAAA,IAAA;AAAA,EAAA;AAGP;"}
|
|
1
|
+
{"version":3,"file":"Icon.js","sources":["../../src/data/Icon.tsx"],"sourcesContent":["import type { CSSProperties, ComponentType, ElementType, ReactNode } from \"react\";\nimport { cn } from \"../lib/utils\";\nimport { resolveSize, type SizeToken } from \"../lib/size\";\nimport { useDensityValue } from \"../hooks/use-density\";\n\n// LabelIconSpec is the icon a label may carry: an iconify/runtime name (resolved\n// via the fallback provider) or a fully-rendered node the caller supplies.\nexport type LabelIconSpec = string | ReactNode;\n\nexport type IconStyle = \"plain\" | \"badge\";\n\nexport type IconTone = \"emerald\" | \"amber\" | \"rose\" | \"slate\" | \"sky\" | \"violet\" | \"neutral\";\n\nexport type StaticIconComponent = ElementType;\n\ntype CommonIconProps = {\n /** Classes applied to the glyph or badge wrapper. */\n className?: string;\n /** Explicit glyph width. */\n width?: string | number;\n /** Explicit glyph height. */\n height?: string | number;\n /** CSS rotate value or degrees. */\n rotate?: string | number;\n /** Flip direction for imported glyphs. */\n flip?: string;\n /** Forward inline rendering semantics to imported glyphs. */\n inline?: boolean;\n /** Accessible title for the glyph. */\n title?: string;\n /**\n * Presentation style. `plain` (default) renders the icon inline.\n * `badge` wraps the icon in a circular chip (white background, ring, shadow)\n * sized by `size` — use in stage/approval cells so the chip scales with a\n * neighbouring avatar.\n */\n style?: IconStyle;\n /**\n * Named size token (xxs..xxl). Drives the badge diameter and glyph. The\n * glyph is always ~50% of the badge diameter so it scales consistently\n * across sizes. For `style=\"plain\"` it sets width/height when neither is\n * provided.\n */\n size?: SizeToken;\n /** Semantic color for `style=\"badge\"`. Ignored for plain icons. */\n tone?: IconTone;\n};\n\nexport type IconProps = CommonIconProps &\n (\n | {\n /** Imported static icon component. */\n icon: StaticIconComponent;\n name?: never;\n }\n | {\n /** Runtime icon name resolved by the fallback provider. */\n name: string;\n icon?: never;\n }\n );\n\nconst TONE_CLASSES: Record<IconTone, string> = {\n emerald: \"text-emerald-700 ring-emerald-200/80\",\n amber: \"text-amber-700 ring-amber-200/80\",\n rose: \"text-rose-700 ring-rose-200/80\",\n slate: \"text-slate-700 ring-slate-200/80\",\n sky: \"text-sky-700 ring-sky-200/80\",\n violet: \"text-violet-700 ring-violet-200/80\",\n neutral: \"text-foreground ring-border\",\n};\n\nconst DEFAULT_PLAIN_ICON_SIZE = \"1em\";\n\n/**\n * Optional secondary icon provider for user-supplied runtime names.\n * Built-in/default icons should pass an imported component via `icon`.\n */\nexport type FallbackIconProps = {\n /** Runtime icon name to resolve. */\n name?: string;\n /** Classes applied by Icon. */\n className?: string;\n /** Requested glyph size. */\n size?: string | number;\n /** Accessible label. */\n alt?: string;\n};\n\ntype FallbackIconComponent = ComponentType<FallbackIconProps>;\n\nlet fallbackIcon: FallbackIconComponent | null = null;\n\n/**\n * Register a secondary glyph provider. Pass the flanksource Icon/ResourceIcon\n * (or any compatible component) to resolve user-supplied runtime names.\n */\nexport function setFallbackIconProvider(component: FallbackIconComponent | null): void {\n fallbackIcon = component;\n}\n\nfunction renderImportedGlyph(\n ImportedIcon: StaticIconComponent,\n glyphWidth: number | string | undefined,\n glyphHeight: number | string | undefined,\n rotate: string | number | undefined,\n flip: string | undefined,\n inline: boolean | undefined,\n glyphClassName: string | undefined,\n title: string | undefined,\n): JSX.Element {\n const transform = [\n typeof rotate === \"number\" ? `rotate(${rotate}deg)` : typeof rotate === \"string\" ? rotate : \"\",\n flip === \"horizontal\" || flip === \"both\" ? \"scaleX(-1)\" : \"\",\n flip === \"vertical\" || flip === \"both\" ? \"scaleY(-1)\" : \"\",\n ]\n .filter(Boolean)\n .join(\" \");\n\n return (\n <ImportedIcon\n {...(glyphClassName ? { className: glyphClassName } : {})}\n {...(glyphWidth != null ? { width: glyphWidth } : {})}\n {...(glyphHeight != null ? { height: glyphHeight } : {})}\n {...(inline != null ? { \"aria-hidden\": !title } : {})}\n {...(title ? { title, role: \"img\" } : { \"aria-hidden\": true })}\n {...(transform ? { style: { transform } } : {})}\n />\n );\n}\n\nfunction renderRuntimeGlyph(\n name: string,\n glyphWidth: number | string | undefined,\n glyphHeight: number | string | undefined,\n glyphClassName: string | undefined,\n title: string | undefined,\n): JSX.Element {\n if (fallbackIcon) {\n const Fallback = fallbackIcon;\n const glyphSize = typeof glyphWidth === \"number\" ? glyphWidth : glyphHeight;\n return (\n <Fallback\n name={name}\n {...(glyphClassName ? { className: glyphClassName } : {})}\n {...(glyphSize != null ? { size: glyphSize } : {})}\n {...(title ? { alt: title } : {})}\n />\n );\n }\n\n return (\n <span\n className={cn(\n \"inline-flex shrink-0 items-center justify-center rounded-sm border border-dashed border-muted-foreground/50 text-[0.65em] leading-none text-muted-foreground\",\n glyphClassName,\n )}\n title={title ?? name}\n role={title ? \"img\" : undefined}\n aria-label={title}\n aria-hidden={title ? undefined : true}\n style={{\n width: glyphWidth,\n height: glyphHeight,\n }}\n >\n ?\n </span>\n );\n}\n\nexport function Icon({\n icon: ImportedIcon,\n name,\n className,\n width,\n height,\n rotate,\n flip,\n inline,\n title,\n style = \"plain\",\n size,\n tone = \"neutral\",\n}: IconProps) {\n const density = useDensityValue();\n const pxSize = size != null ? resolveSize(size, density) : undefined;\n const glyphSize = pxSize != null ? Math.max(8, Math.round(pxSize * 0.5)) : undefined;\n const defaultGlyphSize = style === \"badge\" ? glyphSize : (pxSize ?? DEFAULT_PLAIN_ICON_SIZE);\n const resolvedWidth = width ?? height ?? defaultGlyphSize;\n const resolvedHeight = height ?? resolvedWidth;\n\n const glyphClassName = cn(\n \"inline-block shrink-0 align-[-0.125em]\",\n style === \"plain\" ? className : undefined,\n );\n const glyphTitle = style === \"plain\" ? title : undefined;\n\n const renderedIcon = ImportedIcon\n ? renderImportedGlyph(\n ImportedIcon,\n resolvedWidth,\n resolvedHeight,\n rotate,\n flip,\n inline,\n glyphClassName,\n glyphTitle,\n )\n : renderRuntimeGlyph(name, resolvedWidth, resolvedHeight, glyphClassName, glyphTitle);\n\n if (style === \"plain\") {\n return renderedIcon;\n }\n\n const badgeStyle: CSSProperties | undefined =\n pxSize != null ? { width: pxSize, height: pxSize } : undefined;\n\n return (\n <span\n title={title}\n aria-label={title}\n role={title ? \"img\" : undefined}\n className={cn(\n \"inline-flex items-center justify-center rounded-full bg-white shadow-sm ring-1 ring-inset\",\n TONE_CLASSES[tone],\n className,\n )}\n style={badgeStyle}\n >\n {renderedIcon}\n </span>\n );\n}\n\n/**\n * LabelIcon renders a label's leading glyph from a {@link LabelIconSpec}: a\n * string is treated as a runtime icon name (resolved by the registered fallback\n * provider), any other ReactNode is rendered as-is. Returns null for an absent\n * or empty spec so callers can spread it unconditionally before a label.\n */\nexport function LabelIcon({\n icon,\n className,\n}: {\n icon?: LabelIconSpec;\n className?: string;\n}): JSX.Element | null {\n if (icon == null || icon === \"\" || icon === false) return null;\n if (typeof icon === \"string\") {\n return <Icon name={icon} className={cn(\"shrink-0\", className)} />;\n }\n return <>{icon}</>;\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,277 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
const jsxRuntime = require("react/jsx-runtime");
|
|
4
|
+
const react = require("react");
|
|
5
|
+
const DataTable = require("./DataTable.cjs");
|
|
6
|
+
const Properties = require("./Properties.cjs");
|
|
7
|
+
const TagList = require("./cells/TagList.cjs");
|
|
8
|
+
const propertiesUtils = require("./properties-utils.cjs");
|
|
9
|
+
const logUtils = require("./log-utils.cjs");
|
|
10
|
+
const UiCopy = require("../icons/components/UiCopy.cjs");
|
|
11
|
+
const UiZoomIn = require("../icons/components/UiZoomIn.cjs");
|
|
12
|
+
const UiZoomOut = require("../icons/components/UiZoomOut.cjs");
|
|
13
|
+
const TAGS_PATH = "details.tags";
|
|
14
|
+
const DETAIL_ROW_CLASS = "grid-cols-[fit-content(30ch)_minmax(0,1fr)]";
|
|
15
|
+
function renderLogDetails(row, context) {
|
|
16
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
17
|
+
LogDetails,
|
|
18
|
+
{
|
|
19
|
+
row,
|
|
20
|
+
filterActions: context.filterActionsByColumn,
|
|
21
|
+
columns: context.columns
|
|
22
|
+
}
|
|
23
|
+
);
|
|
24
|
+
}
|
|
25
|
+
function fieldColumnKey(path) {
|
|
26
|
+
if (!path.startsWith("details.") || path === TAGS_PATH) return void 0;
|
|
27
|
+
const rest = path.slice("details.".length);
|
|
28
|
+
return rest && !rest.includes(".") ? rest : void 0;
|
|
29
|
+
}
|
|
30
|
+
function LogDetails({
|
|
31
|
+
row,
|
|
32
|
+
filterActions,
|
|
33
|
+
columns
|
|
34
|
+
}) {
|
|
35
|
+
const [openPaths, setOpenPaths] = react.useState({});
|
|
36
|
+
const setPathOpen = (path, open) => {
|
|
37
|
+
setOpenPaths((current) => ({ ...current, [path]: open }));
|
|
38
|
+
};
|
|
39
|
+
const details = react.useMemo(() => buildProcessedLogDetails(row), [row]);
|
|
40
|
+
const labelForPath = (path) => propertiesUtils.formatPropertyLabel(path.split(".").pop() ?? path);
|
|
41
|
+
const columnByKey = react.useMemo(
|
|
42
|
+
() => new Map(columns.map((column) => [column.key, column])),
|
|
43
|
+
[columns]
|
|
44
|
+
);
|
|
45
|
+
const fieldFilter = (path) => {
|
|
46
|
+
const key = fieldColumnKey(path);
|
|
47
|
+
if (!key) return void 0;
|
|
48
|
+
const actions = filterActions[key];
|
|
49
|
+
const column = columnByKey.get(key);
|
|
50
|
+
if (!actions || !column) return void 0;
|
|
51
|
+
const token = DataTable.getFilterTokens(row, column)[0];
|
|
52
|
+
return token ? { actions, token } : void 0;
|
|
53
|
+
};
|
|
54
|
+
const prefixActions = [
|
|
55
|
+
{
|
|
56
|
+
id: "expand",
|
|
57
|
+
icon: UiZoomIn.UiZoomIn,
|
|
58
|
+
label: (key) => `Expand ${labelForPath(key)}`,
|
|
59
|
+
visible: (_k, _v, item) => !!item.expandable,
|
|
60
|
+
disabled: (_k, _v, item) => !!item.expanded,
|
|
61
|
+
onClick: (_k, _v, item) => {
|
|
62
|
+
var _a;
|
|
63
|
+
return (_a = item.onToggle) == null ? void 0 : _a.call(item, true);
|
|
64
|
+
}
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
id: "collapse",
|
|
68
|
+
icon: UiZoomOut.UiZoomOut,
|
|
69
|
+
label: (key) => `Collapse ${labelForPath(key)}`,
|
|
70
|
+
visible: (_k, _v, item) => !!item.expandable,
|
|
71
|
+
disabled: (_k, _v, item) => !item.expanded,
|
|
72
|
+
onClick: (_k, _v, item) => {
|
|
73
|
+
var _a;
|
|
74
|
+
return (_a = item.onToggle) == null ? void 0 : _a.call(item, false);
|
|
75
|
+
}
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
id: "include",
|
|
79
|
+
icon: UiZoomIn.UiZoomIn,
|
|
80
|
+
label: (key) => `Include ${labelForPath(key)}`,
|
|
81
|
+
visible: (key) => !!fieldFilter(key),
|
|
82
|
+
onClick: (key) => {
|
|
83
|
+
const filter = fieldFilter(key);
|
|
84
|
+
filter == null ? void 0 : filter.actions.toggleInclude(filter.token);
|
|
85
|
+
}
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
id: "exclude",
|
|
89
|
+
icon: UiZoomOut.UiZoomOut,
|
|
90
|
+
label: (key) => `Exclude ${labelForPath(key)}`,
|
|
91
|
+
visible: (key) => !!fieldFilter(key),
|
|
92
|
+
onClick: (key) => {
|
|
93
|
+
const filter = fieldFilter(key);
|
|
94
|
+
filter == null ? void 0 : filter.actions.toggleExclude(filter.token);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
];
|
|
98
|
+
const suffixActions = [
|
|
99
|
+
{
|
|
100
|
+
id: "copy",
|
|
101
|
+
icon: UiCopy.UiCopy,
|
|
102
|
+
label: (key) => `Copy ${labelForPath(key)}`,
|
|
103
|
+
visible: (key) => key !== TAGS_PATH,
|
|
104
|
+
onClick: (_k, value) => copyLogDetailsValue(value)
|
|
105
|
+
}
|
|
106
|
+
];
|
|
107
|
+
const renderLabel = (key) => labelForPath(key);
|
|
108
|
+
const renderValue = (key, value, item) => {
|
|
109
|
+
if (key === TAGS_PATH) {
|
|
110
|
+
const count = Array.isArray(value) ? value.length : 0;
|
|
111
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "font-mono text-muted-foreground", children: [
|
|
112
|
+
"[",
|
|
113
|
+
count,
|
|
114
|
+
" tags]"
|
|
115
|
+
] });
|
|
116
|
+
}
|
|
117
|
+
return item.expandable ? /* @__PURE__ */ jsxRuntime.jsx(LogValueSummary, { value }) : /* @__PURE__ */ jsxRuntime.jsx(LogScalarValue, { value });
|
|
118
|
+
};
|
|
119
|
+
const toItems = (value, path, depth) => getValueEntries(value).map(([key, entryValue]) => {
|
|
120
|
+
const entryPath = `${path}.${String(key)}`;
|
|
121
|
+
const isTags = entryPath === TAGS_PATH;
|
|
122
|
+
const expandable = isTags || isExpandableValue(entryValue);
|
|
123
|
+
const open = openPaths[entryPath] ?? depth < 1;
|
|
124
|
+
return {
|
|
125
|
+
key: entryPath,
|
|
126
|
+
value: entryValue,
|
|
127
|
+
expandable,
|
|
128
|
+
expanded: open,
|
|
129
|
+
onToggle: (next) => setPathOpen(entryPath, next),
|
|
130
|
+
renderChildren: () => isTags ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
131
|
+
TagList.TagPropertiesList,
|
|
132
|
+
{
|
|
133
|
+
tags: TagList.normalizeTags(entryValue),
|
|
134
|
+
rowClassName: DETAIL_ROW_CLASS
|
|
135
|
+
}
|
|
136
|
+
) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
137
|
+
Properties.Properties,
|
|
138
|
+
{
|
|
139
|
+
density: "compact",
|
|
140
|
+
items: toItems(entryValue, entryPath, depth + 1),
|
|
141
|
+
renderLabel,
|
|
142
|
+
renderValue,
|
|
143
|
+
prefixActions,
|
|
144
|
+
suffixActions,
|
|
145
|
+
rowClassName: DETAIL_ROW_CLASS,
|
|
146
|
+
className: "mt-density-1"
|
|
147
|
+
}
|
|
148
|
+
)
|
|
149
|
+
};
|
|
150
|
+
});
|
|
151
|
+
const properties = /* @__PURE__ */ jsxRuntime.jsx(
|
|
152
|
+
Properties.Properties,
|
|
153
|
+
{
|
|
154
|
+
density: "compact",
|
|
155
|
+
items: toItems(details, "details", 0),
|
|
156
|
+
renderLabel,
|
|
157
|
+
renderValue,
|
|
158
|
+
prefixActions,
|
|
159
|
+
suffixActions,
|
|
160
|
+
rowClassName: DETAIL_ROW_CLASS
|
|
161
|
+
}
|
|
162
|
+
);
|
|
163
|
+
const tagActions = filterActions["tags"];
|
|
164
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-density-3 text-xs", children: tagActions ? /* @__PURE__ */ jsxRuntime.jsx(TagList.TagActionsProvider, { value: tagActions, children: properties }) : properties });
|
|
165
|
+
}
|
|
166
|
+
function LogValueSummary({ value }) {
|
|
167
|
+
if (Array.isArray(value)) {
|
|
168
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "font-mono text-muted-foreground", children: [
|
|
169
|
+
"[",
|
|
170
|
+
value.length,
|
|
171
|
+
" items]"
|
|
172
|
+
] });
|
|
173
|
+
}
|
|
174
|
+
const record = logUtils.asRecord(value);
|
|
175
|
+
if (record) {
|
|
176
|
+
const count = Object.keys(record).length;
|
|
177
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "font-mono text-muted-foreground", children: [
|
|
178
|
+
"{ ",
|
|
179
|
+
count,
|
|
180
|
+
" properties",
|
|
181
|
+
" }"
|
|
182
|
+
] });
|
|
183
|
+
}
|
|
184
|
+
return /* @__PURE__ */ jsxRuntime.jsx(LogScalarValue, { value });
|
|
185
|
+
}
|
|
186
|
+
function LogScalarValue({ value }) {
|
|
187
|
+
if (value === null || value === void 0) {
|
|
188
|
+
return /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-mono italic text-muted-foreground", children: "null" });
|
|
189
|
+
}
|
|
190
|
+
if (typeof value === "string") {
|
|
191
|
+
return /* @__PURE__ */ jsxRuntime.jsx("pre", { className: "max-h-48 overflow-auto whitespace-pre-wrap break-words font-mono text-[11px] leading-relaxed text-foreground", children: value });
|
|
192
|
+
}
|
|
193
|
+
if (typeof value === "number" || typeof value === "boolean") {
|
|
194
|
+
return /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-mono text-blue-700 dark:text-blue-400", children: String(value) });
|
|
195
|
+
}
|
|
196
|
+
return /* @__PURE__ */ jsxRuntime.jsx("pre", { className: "max-h-48 overflow-auto whitespace-pre-wrap break-words font-mono text-[11px] leading-relaxed text-foreground", children: stablePrettyString(value) });
|
|
197
|
+
}
|
|
198
|
+
function getValueEntries(value) {
|
|
199
|
+
if (Array.isArray(value)) {
|
|
200
|
+
return value.map((entry, index) => [index, entry]);
|
|
201
|
+
}
|
|
202
|
+
return Object.entries(logUtils.asRecord(value) ?? {});
|
|
203
|
+
}
|
|
204
|
+
function isExpandableValue(value) {
|
|
205
|
+
return getValueEntries(value).length > 0;
|
|
206
|
+
}
|
|
207
|
+
function stablePrettyString(value) {
|
|
208
|
+
if (typeof value === "string") return value;
|
|
209
|
+
try {
|
|
210
|
+
return JSON.stringify(value, null, 2);
|
|
211
|
+
} catch {
|
|
212
|
+
return String(value);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
function copyLogDetailsValue(value) {
|
|
216
|
+
var _a;
|
|
217
|
+
if (typeof navigator !== "undefined" && ((_a = navigator.clipboard) == null ? void 0 : _a.writeText)) {
|
|
218
|
+
Promise.resolve(navigator.clipboard.writeText(stablePrettyString(value))).catch(
|
|
219
|
+
() => void 0
|
|
220
|
+
);
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
function buildProcessedLogDetails(row) {
|
|
224
|
+
const attributes = buildProcessedLogAttributes(row);
|
|
225
|
+
return stripEmptyProperties({
|
|
226
|
+
timestamp: row.timestamp,
|
|
227
|
+
level: row.level,
|
|
228
|
+
pod: row.pod,
|
|
229
|
+
logger: row.logger,
|
|
230
|
+
thread: row.thread,
|
|
231
|
+
message: row.message,
|
|
232
|
+
tags: row.tags,
|
|
233
|
+
...Object.keys(attributes).length > 0 ? { attributes } : {}
|
|
234
|
+
});
|
|
235
|
+
}
|
|
236
|
+
function buildProcessedLogAttributes(row) {
|
|
237
|
+
const attributes = {
|
|
238
|
+
...logUtils.asRecord(row.raw),
|
|
239
|
+
...logUtils.asRecord(row.parsedLine)
|
|
240
|
+
};
|
|
241
|
+
const hiddenKeys = /* @__PURE__ */ new Set([
|
|
242
|
+
"@timestamp",
|
|
243
|
+
"container",
|
|
244
|
+
"event.dataset",
|
|
245
|
+
"labels",
|
|
246
|
+
"level",
|
|
247
|
+
"line",
|
|
248
|
+
"log.level",
|
|
249
|
+
"log.logger",
|
|
250
|
+
"logger",
|
|
251
|
+
"message",
|
|
252
|
+
"msg",
|
|
253
|
+
"pod",
|
|
254
|
+
"process.thread.name",
|
|
255
|
+
"service",
|
|
256
|
+
"service.name",
|
|
257
|
+
"severity",
|
|
258
|
+
"thread",
|
|
259
|
+
"time",
|
|
260
|
+
"timestamp"
|
|
261
|
+
]);
|
|
262
|
+
return stripEmptyProperties(
|
|
263
|
+
Object.fromEntries(Object.entries(attributes).filter(([key]) => !hiddenKeys.has(key)))
|
|
264
|
+
);
|
|
265
|
+
}
|
|
266
|
+
function stripEmptyProperties(record) {
|
|
267
|
+
return Object.fromEntries(
|
|
268
|
+
Object.entries(record).filter(([, value]) => {
|
|
269
|
+
if (value == null) return false;
|
|
270
|
+
if (typeof value === "string") return value.trim().length > 0;
|
|
271
|
+
if (Array.isArray(value)) return value.length > 0;
|
|
272
|
+
return true;
|
|
273
|
+
})
|
|
274
|
+
);
|
|
275
|
+
}
|
|
276
|
+
exports.renderLogDetails = renderLogDetails;
|
|
277
|
+
//# sourceMappingURL=LogDetails.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LogDetails.cjs","sources":["../../src/data/LogDetails.tsx"],"sourcesContent":["import { useMemo, useState, type ReactNode } from \"react\";\nimport {\n getFilterTokens,\n type DataTableColumn,\n type DataTableRowDetailContext,\n} from \"./DataTable\";\nimport { Properties, type PropertiesAction, type PropertiesItem } from \"./Properties\";\nimport {\n TagActionsProvider,\n TagPropertiesList,\n type TagActionsContextValue,\n normalizeTags,\n} from \"./cells/TagList\";\nimport { formatPropertyLabel } from \"./properties-utils\";\nimport type { LogsTableRow } from \"./LogsTable\";\nimport { asRecord } from \"./log-utils\";\nimport { UiCopy, UiZoomIn, UiZoomOut } from \"../icons\";\n\nconst TAGS_PATH = \"details.tags\";\n\n// Key column shrinks to its content (no min/fixed width), never wider than 30ch.\nconst DETAIL_ROW_CLASS = \"grid-cols-[fit-content(30ch)_minmax(0,1fr)]\";\n\nexport function renderLogDetails(\n row: LogsTableRow,\n context: DataTableRowDetailContext<LogsTableRow>,\n): ReactNode {\n return (\n <LogDetails\n row={row}\n filterActions={context.filterActionsByColumn}\n columns={context.columns}\n />\n );\n}\n\n/**\n * Maps a top-level detail field path (`details.<columnKey>`) to its column key.\n * Returns undefined for nested paths and the tags array, which have their own\n * filter affordances.\n */\nfunction fieldColumnKey(path: string): string | undefined {\n if (!path.startsWith(\"details.\") || path === TAGS_PATH) return undefined;\n const rest = path.slice(\"details.\".length);\n return rest && !rest.includes(\".\") ? rest : undefined;\n}\n\nfunction LogDetails({\n row,\n filterActions,\n columns,\n}: {\n row: LogsTableRow;\n filterActions: Record<string, TagActionsContextValue>;\n columns: DataTableColumn<LogsTableRow>[];\n}) {\n const [openPaths, setOpenPaths] = useState<Record<string, boolean>>({});\n const setPathOpen = (path: string, open: boolean) => {\n setOpenPaths((current) => ({ ...current, [path]: open }));\n };\n const details = useMemo(() => buildProcessedLogDetails(row), [row]);\n\n const labelForPath = (path: string) => formatPropertyLabel(path.split(\".\").pop() ?? path);\n\n const columnByKey = useMemo(\n () => new Map(columns.map((column) => [column.key, column])),\n [columns],\n );\n\n // Include/exclude is wired only for fields whose column is a multi/nested-multi\n // (tristate) filter; other columns (high-cardinality text, number, timestamp)\n // don't honor multiFilters, so they get no filter actions. The toggle token\n // must match the column's filter token (e.g. a status column maps \"INFO\" to a\n // normalized status), so it is derived via getFilterTokens rather than the\n // displayed value.\n const fieldFilter = (\n path: string,\n ): { actions: TagActionsContextValue; token: string } | undefined => {\n const key = fieldColumnKey(path);\n if (!key) return undefined;\n const actions = filterActions[key];\n const column = columnByKey.get(key);\n if (!actions || !column) return undefined;\n const token = getFilterTokens(row, column)[0];\n return token ? { actions, token } : undefined;\n };\n\n const prefixActions: PropertiesAction<unknown>[] = [\n {\n id: \"expand\",\n icon: UiZoomIn,\n label: (key) => `Expand ${labelForPath(key)}`,\n visible: (_k, _v, item) => !!item.expandable,\n disabled: (_k, _v, item) => !!item.expanded,\n onClick: (_k, _v, item) => item.onToggle?.(true),\n },\n {\n id: \"collapse\",\n icon: UiZoomOut,\n label: (key) => `Collapse ${labelForPath(key)}`,\n visible: (_k, _v, item) => !!item.expandable,\n disabled: (_k, _v, item) => !item.expanded,\n onClick: (_k, _v, item) => item.onToggle?.(false),\n },\n {\n id: \"include\",\n icon: UiZoomIn,\n label: (key) => `Include ${labelForPath(key)}`,\n visible: (key) => !!fieldFilter(key),\n onClick: (key) => {\n const filter = fieldFilter(key);\n filter?.actions.toggleInclude(filter.token);\n },\n },\n {\n id: \"exclude\",\n icon: UiZoomOut,\n label: (key) => `Exclude ${labelForPath(key)}`,\n visible: (key) => !!fieldFilter(key),\n onClick: (key) => {\n const filter = fieldFilter(key);\n filter?.actions.toggleExclude(filter.token);\n },\n },\n ];\n\n // Copy sits immediately after the value (suffix), separate from the leading\n // expand/collapse/include/exclude controls.\n const suffixActions: PropertiesAction<unknown>[] = [\n {\n id: \"copy\",\n icon: UiCopy,\n label: (key) => `Copy ${labelForPath(key)}`,\n visible: (key) => key !== TAGS_PATH,\n onClick: (_k, value) => copyLogDetailsValue(value),\n },\n ];\n\n const renderLabel = (key: string) => labelForPath(key);\n const renderValue = (key: string, value: unknown, item: PropertiesItem<unknown>) => {\n if (key === TAGS_PATH) {\n const count = Array.isArray(value) ? value.length : 0;\n return <span className=\"font-mono text-muted-foreground\">[{count} tags]</span>;\n }\n return item.expandable ? <LogValueSummary value={value} /> : <LogScalarValue value={value} />;\n };\n\n const toItems = (value: unknown, path: string, depth: number): PropertiesItem<unknown>[] =>\n getValueEntries(value).map(([key, entryValue]) => {\n const entryPath = `${path}.${String(key)}`;\n const isTags = entryPath === TAGS_PATH;\n const expandable = isTags || isExpandableValue(entryValue);\n const open = openPaths[entryPath] ?? depth < 1;\n return {\n key: entryPath,\n value: entryValue,\n expandable,\n expanded: open,\n onToggle: (next) => setPathOpen(entryPath, next),\n renderChildren: () =>\n isTags ? (\n <TagPropertiesList\n tags={normalizeTags(entryValue as string[])}\n rowClassName={DETAIL_ROW_CLASS}\n />\n ) : (\n <Properties\n density=\"compact\"\n items={toItems(entryValue, entryPath, depth + 1)}\n renderLabel={renderLabel}\n renderValue={renderValue}\n prefixActions={prefixActions}\n suffixActions={suffixActions}\n rowClassName={DETAIL_ROW_CLASS}\n className=\"mt-density-1\"\n />\n ),\n };\n });\n\n const properties = (\n <Properties\n density=\"compact\"\n items={toItems(details, \"details\", 0)}\n renderLabel={renderLabel}\n renderValue={renderValue}\n prefixActions={prefixActions}\n suffixActions={suffixActions}\n rowClassName={DETAIL_ROW_CLASS}\n />\n );\n\n const tagActions = filterActions[\"tags\"];\n return (\n <div className=\"space-y-density-3 text-xs\">\n {tagActions ? (\n <TagActionsProvider value={tagActions}>{properties}</TagActionsProvider>\n ) : (\n properties\n )}\n </div>\n );\n}\n\nfunction LogValueSummary({ value }: { value: unknown }) {\n if (Array.isArray(value)) {\n return <span className=\"font-mono text-muted-foreground\">[{value.length} items]</span>;\n }\n const record = asRecord(value);\n if (record) {\n const count = Object.keys(record).length;\n return (\n <span className=\"font-mono text-muted-foreground\">\n {\"{ \"}\n {count} properties{\" }\"}\n </span>\n );\n }\n return <LogScalarValue value={value} />;\n}\n\nfunction LogScalarValue({ value }: { value: unknown }) {\n if (value === null || value === undefined) {\n return <span className=\"font-mono italic text-muted-foreground\">null</span>;\n }\n\n if (typeof value === \"string\") {\n return (\n <pre className=\"max-h-48 overflow-auto whitespace-pre-wrap break-words font-mono text-[11px] leading-relaxed text-foreground\">\n {value}\n </pre>\n );\n }\n\n if (typeof value === \"number\" || typeof value === \"boolean\") {\n return <span className=\"font-mono text-blue-700 dark:text-blue-400\">{String(value)}</span>;\n }\n\n return (\n <pre className=\"max-h-48 overflow-auto whitespace-pre-wrap break-words font-mono text-[11px] leading-relaxed text-foreground\">\n {stablePrettyString(value)}\n </pre>\n );\n}\n\nfunction getValueEntries(value: unknown): Array<[string | number, unknown]> {\n if (Array.isArray(value)) {\n return value.map((entry, index) => [index, entry]);\n }\n return Object.entries(asRecord(value) ?? {});\n}\n\nfunction isExpandableValue(value: unknown) {\n return getValueEntries(value).length > 0;\n}\n\nfunction stablePrettyString(value: unknown): string {\n if (typeof value === \"string\") return value;\n try {\n return JSON.stringify(value, null, 2);\n } catch {\n return String(value);\n }\n}\n\nfunction copyLogDetailsValue(value: unknown) {\n if (typeof navigator !== \"undefined\" && navigator.clipboard?.writeText) {\n Promise.resolve(navigator.clipboard.writeText(stablePrettyString(value))).catch(\n () => undefined,\n );\n }\n}\n\nfunction buildProcessedLogDetails(row: LogsTableRow): Record<string, unknown> {\n const attributes = buildProcessedLogAttributes(row);\n return stripEmptyProperties({\n timestamp: row.timestamp,\n level: row.level,\n pod: row.pod,\n logger: row.logger,\n thread: row.thread,\n message: row.message,\n tags: row.tags,\n ...(Object.keys(attributes).length > 0 ? { attributes } : {}),\n });\n}\n\nfunction buildProcessedLogAttributes(row: LogsTableRow): Record<string, unknown> {\n const attributes = {\n ...asRecord(row.raw),\n ...asRecord(row.parsedLine),\n };\n const hiddenKeys = new Set([\n \"@timestamp\",\n \"container\",\n \"event.dataset\",\n \"labels\",\n \"level\",\n \"line\",\n \"log.level\",\n \"log.logger\",\n \"logger\",\n \"message\",\n \"msg\",\n \"pod\",\n \"process.thread.name\",\n \"service\",\n \"service.name\",\n \"severity\",\n \"thread\",\n \"time\",\n \"timestamp\",\n ]);\n\n return stripEmptyProperties(\n Object.fromEntries(Object.entries(attributes).filter(([key]) => !hiddenKeys.has(key))),\n );\n}\n\nfunction stripEmptyProperties(record: Record<string, unknown>): Record<string, unknown> {\n return Object.fromEntries(\n Object.entries(record).filter(([, value]) => {\n if (value == null) return false;\n if (typeof value === \"string\") return value.trim().length > 0;\n if (Array.isArray(value)) return value.length > 0;\n return true;\n }),\n );\n}\n"],"names":["jsx","useState","useMemo","formatPropertyLabel","getFilterTokens","UiZoomIn","UiZoomOut","UiCopy","jsxs","TagPropertiesList","normalizeTags","Properties","TagActionsProvider","asRecord"],"mappings":"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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
import { DataTableRowDetailContext } from './DataTable';
|
|
3
|
+
import { LogsTableRow } from './LogsTable';
|
|
4
|
+
export declare function renderLogDetails(row: LogsTableRow, context: DataTableRowDetailContext<LogsTableRow>): ReactNode;
|
|
5
|
+
//# sourceMappingURL=LogDetails.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LogDetails.d.ts","sourceRoot":"","sources":["../../src/data/LogDetails.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAqB,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAC1D,OAAO,EAGL,KAAK,yBAAyB,EAC/B,MAAM,aAAa,CAAC;AASrB,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAShD,wBAAgB,gBAAgB,CAC9B,GAAG,EAAE,YAAY,EACjB,OAAO,EAAE,yBAAyB,CAAC,YAAY,CAAC,GAC/C,SAAS,CAQX"}
|