🎩 You're Invited:Meet the Socket team at Black Hat in Las Vegas, August 3-6.RSVP
Sign In

@nixopus/ui

Package Overview
Dependencies
Maintainers
1
Versions
34
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@nixopus/ui - npm Package Compare versions

Comparing version
0.1.29
to
0.1.30
+85
src/components/info-line.tsx
import * as React from 'react';
import { Check, Copy } from 'lucide-react';
import { cn } from '../lib/utils';
export interface InfoLineProps {
/** Icon component to display */
icon: React.ComponentType<{ className?: string }>;
/** Label text (displayed as uppercase) */
label: string;
/** Actual value to display */
value: string;
/** Optional display value (if different from value) */
displayValue?: string;
/** Optional sublabel text */
sublabel?: string;
/** Whether to use monospace font */
mono?: boolean;
/** Whether to show copy button */
copyable?: boolean;
/** Optional className for the container */
className?: string;
}
/**
* InfoLine - A component for displaying key-value pairs with icons
*
* Useful for displaying metadata, configuration values, or any labeled information.
* Supports copy functionality and optional sublabels.
*
* @example
* ```tsx
* <InfoLine
* icon={Globe}
* label="Domain"
* value="example.com"
* copyable
* />
* ```
*/
export function InfoLine({
icon: Icon,
label,
value,
displayValue,
sublabel,
mono,
copyable,
className
}: InfoLineProps) {
const [copied, setCopied] = React.useState(false);
const handleCopy = () => {
navigator.clipboard.writeText(value);
setCopied(true);
setTimeout(() => setCopied(false), 2000);
};
return (
<div className={cn('flex items-start gap-3 py-2', className)}>
<Icon className="h-4 w-4 mt-1 text-muted-foreground flex-shrink-0" />
<div className="flex-1 min-w-0">
<p className="text-xs text-muted-foreground uppercase tracking-wide mb-0.5">{label}</p>
<div className="flex items-center gap-2">
<span className={cn('text-sm truncate', mono && 'font-mono')} title={value}>
{displayValue || value}
</span>
{copyable && (
<button
onClick={handleCopy}
className="text-muted-foreground hover:text-foreground transition-colors flex-shrink-0"
aria-label="Copy to clipboard"
>
{copied ? (
<Check className="h-3 w-3 text-emerald-500" />
) : (
<Copy className="h-3 w-3" />
)}
</button>
)}
</div>
{sublabel && <p className="text-xs text-muted-foreground/60 mt-0.5">{sublabel}</p>}
</div>
</div>
);
}
import * as React from 'react';
import { cn } from '../lib/utils';
export interface SectionLabelProps {
/** Content to display as section label */
children: React.ReactNode;
/** Optional className */
className?: string;
}
/**
* SectionLabel - A styled label component for section headers
*
* Displays text in uppercase with tracking and muted color.
* Useful for grouping related content sections.
*
* @example
* ```tsx
* <SectionLabel>Deployment Details</SectionLabel>
* ```
*/
export function SectionLabel({ children, className }: SectionLabelProps) {
return (
<h3 className={cn('text-xs font-semibold uppercase tracking-wider text-muted-foreground', className)}>
{children}
</h3>
);
}
import * as React from 'react';
import { cn } from '../lib/utils';
export interface StatBlockProps {
/** Value to display (number or string) */
value: string | number;
/** Label text */
label: string;
/** Optional sublabel text */
sublabel?: string;
/** Color variant */
color?: 'emerald' | 'red' | 'amber' | 'blue' | 'purple';
/** Whether to show pulse animation */
pulse?: boolean;
/** Optional className */
className?: string;
}
const colorClasses = {
emerald: 'text-emerald-500',
red: 'text-red-500',
amber: 'text-amber-500',
blue: 'text-blue-500',
purple: 'text-purple-500'
};
/**
* StatBlock - A component for displaying statistics with optional color coding and pulse animation
*
* Useful for displaying metrics, counts, or key performance indicators.
* Supports color variants and pulse animation for active/important stats.
*
* @example
* ```tsx
* <StatBlock
* value={42}
* label="Total Deployments"
* color="emerald"
* pulse
* />
* ```
*/
export function StatBlock({ value, label, sublabel, color, pulse, className }: StatBlockProps) {
return (
<div className={cn('relative', className)}>
<div className="space-y-1">
<div className="flex items-center gap-2">
{pulse && (
<span className="relative flex h-2 w-2">
<span className="animate-ping absolute inline-flex h-full w-full rounded-full bg-emerald-400 opacity-75" />
<span className="relative inline-flex rounded-full h-2 w-2 bg-emerald-500" />
</span>
)}
<span
className={cn(
'text-2xl font-bold tracking-tight capitalize',
color && colorClasses[color]
)}
>
{value}
</span>
</div>
<p className="text-sm text-muted-foreground">{label}</p>
{sublabel && <p className="text-xs text-muted-foreground/60">{sublabel}</p>}
</div>
</div>
);
}
import * as React from 'react';
import { cn } from '../lib/utils';
export interface StatusConfig {
/** Text color class */
color: string;
/** Background color class */
bgColor: string;
/** Label text */
label: string;
/** Whether to show pulse animation */
pulse?: boolean;
}
export interface StatusIndicatorProps {
/** Status configuration object */
statusConfig?: StatusConfig;
/** Status value (string) - used with statusConfigMap if provided */
status?: string;
/** Map of status values to configs (for convenience) */
statusConfigMap?: Record<string, StatusConfig>;
/** Default config when status is not found */
defaultConfig?: StatusConfig;
/** Size of the indicator dot */
size?: 'sm' | 'md' | 'lg';
/** Whether to show label */
showLabel?: boolean;
/** Custom label for no status state */
noStatusLabel?: string;
/** Optional className */
className?: string;
}
const defaultStatusConfig: StatusConfig = {
color: 'text-zinc-500',
bgColor: 'bg-zinc-500',
label: 'Unknown',
pulse: false
};
const sizeClasses = {
sm: 'h-1.5 w-1.5',
md: 'h-2 w-2',
lg: 'h-3 w-3'
};
/**
* StatusIndicator - A component for displaying status with colored dot and optional label
*
* Displays a colored dot (with optional pulse animation) and label to indicate status.
* Can be used with a direct statusConfig or with a statusConfigMap for convenience.
*
* @example
* ```tsx
* // Direct config
* <StatusIndicator
* statusConfig={{
* color: 'text-emerald-500',
* bgColor: 'bg-emerald-500',
* label: 'Running',
* pulse: true
* }}
* />
*
* // With status map
* <StatusIndicator
* status="running"
* statusConfigMap={{
* running: { color: 'text-emerald-500', bgColor: 'bg-emerald-500', label: 'Running', pulse: true },
* stopped: { color: 'text-zinc-500', bgColor: 'bg-zinc-500', label: 'Stopped', pulse: false }
* }}
* />
* ```
*/
export function StatusIndicator({
statusConfig,
status,
statusConfigMap,
defaultConfig = defaultStatusConfig,
size = 'md',
showLabel = true,
noStatusLabel = 'No status',
className
}: StatusIndicatorProps) {
const config = React.useMemo(() => {
if (statusConfig) {
return statusConfig;
}
if (status && statusConfigMap) {
return statusConfigMap[status] || defaultConfig;
}
return defaultConfig;
}, [statusConfig, status, statusConfigMap, defaultConfig]);
const sizeClass = React.useMemo(() => sizeClasses[size], [size]);
const hasStatus = !!statusConfig || !!status;
const indicatorDot = React.useMemo(
() => (
<span className={cn('relative flex', sizeClass)}>
{config.pulse && (
<span
className={cn(
'animate-ping absolute inline-flex h-full w-full rounded-full opacity-75',
config.bgColor
)}
/>
)}
<span className={cn('relative inline-flex rounded-full', sizeClass, config.bgColor)} />
</span>
),
[config, sizeClass]
);
const label = React.useMemo(
() =>
showLabel ? (
<span className={cn('text-sm font-medium capitalize', config.color)}>{config.label}</span>
) : null,
[showLabel, config]
);
const noStatusIndicatorDot = React.useMemo(
() => (
<span className={cn('relative flex', sizeClass)}>
<span className={cn('relative inline-flex rounded-full bg-zinc-400', sizeClass)} />
</span>
),
[sizeClass]
);
const noStatusLabelElement = React.useMemo(
() => (showLabel ? <span className="text-sm text-muted-foreground">{noStatusLabel}</span> : null),
[showLabel, noStatusLabel]
);
if (!hasStatus) {
return (
<div className={cn('flex items-center gap-2', className)}>
{noStatusIndicatorDot}
{noStatusLabelElement}
</div>
);
}
return (
<div className={cn('flex items-center gap-2', className)}>
{indicatorDot}
{label}
</div>
);
}
+1
-1
{
"name": "@nixopus/ui",
"version": "0.1.29",
"version": "0.1.30",
"description": "Nixopus UI component library - Pure React components for building Nixopus applications",

@@ -5,0 +5,0 @@ "main": "./dist/index.js",

@@ -28,2 +28,3 @@ // Core UI Components (Pure Components)

export * from './components/input';
export * from './components/info-line';
export * from './components/label';

@@ -40,2 +41,3 @@ export * from './components/loading';

export * from './components/select';
export * from './components/section-label';
export * from './components/separator';

@@ -45,2 +47,4 @@ export * from './components/sheet';

export * from './components/sonner';
export * from './components/stat-block';
export * from './components/status-indicator';
export * from './components/stepper';

@@ -47,0 +51,0 @@ export * from './components/sub-page-header';

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display