fix: replace flex-shrink-0 with shrink-0 for consistent styling across components

This commit is contained in:
GitHub Actions
2026-03-09 20:03:57 +00:00
parent 82a55da026
commit 542d4ff3ee
21 changed files with 2977 additions and 35 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -72,8 +72,20 @@
"@vitest/ui": "^4.0.18",
"autoprefixer": "^10.4.27",
"eslint": "^9.39.3 <10.0.0",
"eslint-import-resolver-typescript": "^4.4.4",
"eslint-plugin-import-x": "^4.16.1",
"eslint-plugin-jsx-a11y": "^6.10.2",
"eslint-plugin-no-unsanitized": "^4.1.5",
"eslint-plugin-promise": "^7.2.1",
"eslint-plugin-react-compiler": "^19.1.0-rc.2",
"eslint-plugin-react-hooks": "^7.0.1",
"eslint-plugin-react-refresh": "^0.5.2",
"eslint-plugin-security": "^4.0.0",
"eslint-plugin-sonarjs": "^4.0.1",
"eslint-plugin-testing-library": "^7.16.0",
"eslint-plugin-unicorn": "^63.0.0",
"eslint-plugin-unused-imports": "^4.4.1",
"eslint-plugin-vitest": "^0.5.4",
"jsdom": "28.1.0",
"knip": "^5.86.0",
"postcss": "^8.5.8",

View File

@@ -239,7 +239,7 @@ export function AccessListForm({ initialData, onSubmit, onCancel, onDelete, isLo
</select>
{(formData.type === 'blacklist' || formData.type === 'geo_blacklist') && (
<div className="mt-2 flex items-start gap-2 p-3 bg-blue-900/20 border border-blue-700/50 rounded-lg">
<Info className="h-4 w-4 text-blue-400 mt-0.5 flex-shrink-0" />
<Info className="h-4 w-4 text-blue-400 mt-0.5 shrink-0" />
<p className="text-xs text-blue-300">
<strong>Recommended:</strong> Block lists are safer than allow lists. They block known bad actors while allowing everyone else access, preventing lockouts.
</p>
@@ -302,7 +302,7 @@ export function AccessListForm({ initialData, onSubmit, onCancel, onDelete, isLo
</div>
{preset.warning && (
<div className="flex items-start gap-1 mt-2 text-xs text-orange-400">
<AlertTriangle className="h-3 w-3 mt-0.5 flex-shrink-0" />
<AlertTriangle className="h-3 w-3 mt-0.5 shrink-0" />
<span>{preset.warning}</span>
</div>
)}
@@ -352,7 +352,7 @@ export function AccessListForm({ initialData, onSubmit, onCancel, onDelete, isLo
</div>
{preset.warning && (
<div className="flex items-start gap-1 mt-2 text-xs text-orange-400">
<AlertTriangle className="h-3 w-3 mt-0.5 flex-shrink-0" />
<AlertTriangle className="h-3 w-3 mt-0.5 shrink-0" />
<span>{preset.warning}</span>
</div>
)}

View File

@@ -91,7 +91,7 @@ export function CrowdSecKeyWarning() {
<div className="flex flex-col gap-3">
<div className="flex items-start justify-between">
<div className="flex items-center gap-2">
<AlertTriangle className="h-5 w-5 text-warning flex-shrink-0" />
<AlertTriangle className="h-5 w-5 text-warning shrink-0" />
<h4 className="font-semibold text-content-primary">
{t('security.crowdsec.keyWarning.title')}
</h4>
@@ -122,7 +122,7 @@ export function CrowdSecKeyWarning() {
variant="ghost"
size="sm"
onClick={() => setShowKey(!showKey)}
className="flex-shrink-0"
className="shrink-0"
title={showKey ? 'Hide key' : 'Show key'}
>
{showKey ? <EyeOff className="h-4 w-4" /> : <Eye className="h-4 w-4" />}
@@ -132,7 +132,7 @@ export function CrowdSecKeyWarning() {
size="sm"
onClick={handleCopy}
disabled={copied}
className="flex-shrink-0"
className="shrink-0"
>
{copied ? (
<>

View File

@@ -296,7 +296,7 @@ export default function Layout({ children }: LayoutProps) {
})}
</nav>
<div className={`mt-2 border-t border-gray-200 dark:border-gray-800 pt-4 flex-shrink-0 ${isCollapsed ? 'hidden' : ''}`}>
<div className={`mt-2 border-t border-gray-200 dark:border-gray-800 pt-4 shrink-0 ${isCollapsed ? 'hidden' : ''}`}>
<div className="text-xs text-gray-500 dark:text-gray-500 text-center mb-2 flex flex-col gap-0.5">
<span>Version {health?.version || 'dev'}</span>
{health?.git_commit && health.git_commit !== 'unknown' && (
@@ -319,7 +319,7 @@ export default function Layout({ children }: LayoutProps) {
{/* Collapsed Logout */}
{isCollapsed && (
<div className="mt-2 border-t border-gray-200 dark:border-gray-800 pt-4 pb-4 flex-shrink-0">
<div className="mt-2 border-t border-gray-200 dark:border-gray-800 pt-4 pb-4 shrink-0">
<button
onClick={() => {
setMobileSidebarOpen(false)

View File

@@ -90,7 +90,7 @@ const NotificationCenter: FC = () => {
{/* Update Notification */}
{updateInfo?.available && (
<div className="flex items-start px-4 py-3 border-b dark:border-gray-700 bg-yellow-50 dark:bg-yellow-900/10 hover:bg-yellow-100 dark:hover:bg-yellow-900/20">
<div className="flex-shrink-0 mt-0.5">
<div className="shrink-0 mt-0.5">
<AlertCircle className="w-5 h-5 text-yellow-500" />
</div>
<div className="ml-3 w-0 flex-1">
@@ -119,7 +119,7 @@ const NotificationCenter: FC = () => {
key={notification.id}
className="flex items-start px-4 py-3 border-b dark:border-gray-700 hover:bg-gray-50 dark:hover:bg-gray-700"
>
<div className="flex-shrink-0 mt-0.5">
<div className="shrink-0 mt-0.5">
{getIcon(notification.type)}
</div>
<div className="ml-3 w-0 flex-1">
@@ -133,7 +133,7 @@ const NotificationCenter: FC = () => {
{new Date(notification.created_at).toLocaleString()}
</p>
</div>
<div className="ml-4 flex-shrink-0 flex">
<div className="ml-4 shrink-0 flex">
<button
onClick={() => markReadMutation.mutate(notification.id)}
className="bg-white dark:bg-gray-800 rounded-md inline-flex text-gray-400 hover:text-gray-500 focus:outline-none"

View File

@@ -225,7 +225,7 @@ export function PermissionsPolicyBuilder({ value, onChange }: PermissionsPolicyB
) : (
policies.map((policy) => (
<div key={policy.feature} className="flex items-center gap-3 p-3 bg-gray-50 dark:bg-gray-800 rounded-lg">
<span className="font-mono text-sm font-semibold text-gray-900 dark:text-white flex-shrink-0">
<span className="font-mono text-sm font-semibold text-gray-900 dark:text-white shrink-0">
{policy.feature}
</span>
<div className="flex-1">

View File

@@ -87,7 +87,7 @@ export function SecurityScoreDisplay({
<Card className="p-4">
<div className="flex items-start gap-4">
{/* Circular Score Display */}
<div className="flex-shrink-0">
<div className="shrink-0">
<div
className={`${sizeClasses[size]} rounded-full ${getScoreBgColor()} flex flex-col items-center justify-center font-bold ${getScoreColor()}`}
>
@@ -177,7 +177,7 @@ export function SecurityScoreDisplay({
<ul className="mt-3 space-y-2 pl-6">
{suggestions.map((suggestion, index) => (
<li key={index} className="flex items-start gap-2 text-sm text-gray-600 dark:text-gray-400">
<AlertCircle className="w-4 h-4 text-yellow-500 flex-shrink-0 mt-0.5" />
<AlertCircle className="w-4 h-4 text-yellow-500 shrink-0 mt-0.5" />
<span>{suggestion}</span>
</li>
))}

View File

@@ -33,7 +33,7 @@ export default function CertificateCleanupDialog({
>
<form onSubmit={handleSubmit}>
<div className="flex items-start gap-3 mb-4">
<div className="flex-shrink-0 w-10 h-10 rounded-full bg-orange-900/30 flex items-center justify-center">
<div className="shrink-0 w-10 h-10 rounded-full bg-orange-900/30 flex items-center justify-center">
<AlertTriangle className="h-5 w-5 text-orange-400" />
</div>
<div className="flex-1">

View File

@@ -32,7 +32,7 @@ export default function ImportSuccessModal({
<div className="relative bg-dark-card rounded-lg p-6 w-[500px] max-w-full mx-4 border border-gray-800">
{/* Header */}
<div className="flex items-center gap-3 mb-6">
<div className="flex-shrink-0 w-12 h-12 rounded-full bg-green-900/30 flex items-center justify-center">
<div className="shrink-0 w-12 h-12 rounded-full bg-green-900/30 flex items-center justify-center">
<CheckCircle className="h-6 w-6 text-green-400" />
</div>
<div>
@@ -101,7 +101,7 @@ export default function ImportSuccessModal({
{created > 0 && (
<div className="bg-blue-900/20 border border-blue-800/50 rounded-lg p-4 mb-6">
<div className="flex items-start gap-3">
<Info className="h-4 w-4 text-blue-400 mt-0.5 flex-shrink-0" />
<Info className="h-4 w-4 text-blue-400 mt-0.5 shrink-0" />
<div>
<p className="text-sm font-medium text-blue-300">Certificate Provisioning</p>
<p className="text-xs text-gray-400 mt-1">

View File

@@ -306,7 +306,7 @@ export default function ManualDNSChallenge({
size="sm"
onClick={() => handleCopy('name', challenge.fqdn)}
aria-label={t('dnsProvider.manual.copyRecordName')}
className="flex-shrink-0"
className="shrink-0"
>
{copiedField === 'name' ? (
<Check className="h-4 w-4 text-success" aria-hidden="true" />
@@ -343,7 +343,7 @@ export default function ManualDNSChallenge({
size="sm"
onClick={() => handleCopy('value', challenge.value)}
aria-label={t('dnsProvider.manual.copyRecordValue')}
className="flex-shrink-0"
className="shrink-0"
>
{copiedField === 'value' ? (
<Check className="h-4 w-4 text-success" aria-hidden="true" />
@@ -433,7 +433,7 @@ export default function ManualDNSChallenge({
>
<div className="flex items-start gap-3">
<StatusIcon
className={`h-5 w-5 flex-shrink-0 ${statusConfig.colorClass} ${
className={`h-5 w-5 shrink-0 ${statusConfig.colorClass} ${
currentStatus === 'verifying' ? 'animate-spin' : ''
}`}
aria-hidden="true"

View File

@@ -81,7 +81,7 @@ export function Alert({
className={cn(alertVariants({ variant }), className)}
{...props}
>
<IconComponent className={cn('h-5 w-5 flex-shrink-0 mt-0.5', iconColor)} />
<IconComponent className={cn('h-5 w-5 shrink-0 mt-0.5', iconColor)} />
<div className="flex-1 min-w-0">
{title && (
<h5 className="font-semibold text-sm mb-1">{title}</h5>
@@ -92,7 +92,7 @@ export function Alert({
<button
type="button"
onClick={handleDismiss}
className="flex-shrink-0 p-1 rounded-md text-content-muted hover:text-content-primary hover:bg-surface-muted transition-colors duration-fast"
className="shrink-0 p-1 rounded-md text-content-muted hover:text-content-primary hover:bg-surface-muted transition-colors duration-fast"
aria-label="Dismiss alert"
>
<X className="h-4 w-4" />

View File

@@ -35,7 +35,7 @@ const SelectTrigger = React.forwardRef<
>
{children}
<SelectPrimitive.Icon asChild>
<ChevronDown className="h-4 w-4 text-content-muted flex-shrink-0" />
<ChevronDown className="h-4 w-4 text-content-muted shrink-0" />
</SelectPrimitive.Icon>
</SelectPrimitive.Trigger>
))

View File

@@ -129,7 +129,7 @@ export function SkeletonList({
{Array.from({ length: items }).map((_, i) => (
<div key={i} className="flex items-center gap-4">
{showAvatar && (
<Skeleton variant="circular" className="h-10 w-10 flex-shrink-0" />
<Skeleton variant="circular" className="h-10 w-10 shrink-0" />
)}
<div className="flex-1 space-y-2">
<Skeleton className="h-4 w-1/3" />

View File

@@ -580,7 +580,7 @@ export default function CrowdSecConfig() {
{/* Yellow warning: Process running but LAPI initializing */}
{lapiStatusQuery.data && lapiStatusQuery.data.running && !lapiStatusQuery.data.lapi_ready && initialCheckComplete && (
<div className="flex items-start gap-3 p-4 bg-yellow-900/20 border border-yellow-700/50 rounded-lg" data-testid="lapi-warning">
<AlertTriangle className="w-5 h-5 text-yellow-400 flex-shrink-0 mt-0.5" />
<AlertTriangle className="w-5 h-5 text-yellow-400 shrink-0 mt-0.5" />
<div className="flex-1">
<p className="text-sm text-yellow-200 font-medium mb-2">
{t('crowdsecConfig.lapiInitializing')}
@@ -606,7 +606,7 @@ export default function CrowdSecConfig() {
{/* Red warning: Process not running at all */}
{lapiStatusQuery.data && !lapiStatusQuery.data.running && initialCheckComplete && (
<div className="flex items-start gap-3 p-4 bg-red-900/20 border border-red-700/50 rounded-lg" data-testid="lapi-not-running-warning">
<AlertTriangle className="w-5 h-5 text-red-400 flex-shrink-0 mt-0.5" />
<AlertTriangle className="w-5 h-5 text-red-400 shrink-0 mt-0.5" />
<div className="flex-1">
<p className="text-sm text-red-200 font-medium mb-2">
{t('crowdsecConfig.notRunning')}

View File

@@ -94,7 +94,7 @@ const Logs: FC = () => {
: 'hover:bg-surface-muted text-content-secondary'
}`}
>
<FileText className="w-4 h-4 mr-2 flex-shrink-0" />
<FileText className="w-4 h-4 mr-2 shrink-0" />
<div className="flex-1 min-w-0">
<div className="font-medium truncate">{log.name}</div>
<div className="text-xs text-content-muted">{(log.size / 1024 / 1024).toFixed(2)} MB</div>

View File

@@ -175,7 +175,7 @@ export default function Plugins() {
<div className="flex items-start justify-between">
<div className="flex-1 min-w-0">
<div className="flex items-center gap-3">
<Package className="w-5 h-5 text-content-secondary flex-shrink-0" />
<Package className="w-5 h-5 text-content-secondary shrink-0" />
<div className="flex-1 min-w-0">
<h3 className="text-base font-medium text-content-primary truncate">
{plugin.name}
@@ -228,7 +228,7 @@ export default function Plugins() {
<div className="flex items-start justify-between">
<div className="flex-1 min-w-0">
<div className="flex items-center gap-3">
<Package className="w-5 h-5 text-brand-500 flex-shrink-0" />
<Package className="w-5 h-5 text-brand-500 shrink-0" />
<div className="flex-1 min-w-0">
<h3 className="text-base font-medium text-content-primary truncate">
{plugin.name}

View File

@@ -438,7 +438,7 @@ export default function ProxyHosts() {
style={{ maxWidth: '100%' }}
>
<span className="truncate max-w-[30ch]">{d}</span>
<ExternalLink size={12} className="opacity-50 flex-shrink-0" />
<ExternalLink size={12} className="opacity-50 shrink-0" />
</a>
</div>
)
@@ -1101,7 +1101,7 @@ export default function ProxyHosts() {
<DialogContent className="max-w-lg">
<DialogHeader>
<div className="flex items-start gap-3">
<div className="flex-shrink-0 w-10 h-10 rounded-full bg-error/10 flex items-center justify-center">
<div className="shrink-0 w-10 h-10 rounded-full bg-error/10 flex items-center justify-center">
<AlertTriangle className="h-5 w-5 text-error" />
</div>
<div>

View File

@@ -90,7 +90,7 @@ export default function RateLimiting() {
{/* Info Banner */}
<div className="bg-blue-900/20 border border-blue-800/50 rounded-lg p-4">
<div className="flex items-start gap-3">
<Info className="h-5 w-5 text-blue-400 flex-shrink-0 mt-0.5" />
<Info className="h-5 w-5 text-blue-400 shrink-0 mt-0.5" />
<div>
<h3 className="text-sm font-semibold text-blue-300 mb-1">
{t('rateLimiting.aboutTitle')}

View File

@@ -452,9 +452,9 @@ export default function SystemSettings() {
/>
{publicURLValid !== null && (
publicURLValid ? (
<CheckCircle2 className="h-5 w-5 text-green-500 self-center flex-shrink-0" />
<CheckCircle2 className="h-5 w-5 text-green-500 self-center shrink-0" />
) : (
<XCircle className="h-5 w-5 text-red-500 self-center flex-shrink-0" />
<XCircle className="h-5 w-5 text-red-500 self-center shrink-0" />
)
)}
</div>

View File

@@ -371,7 +371,7 @@ export default function WafConfig() {
{/* Info Banner */}
<div className="bg-blue-900/20 border border-blue-800/50 rounded-lg p-4">
<div className="flex items-start gap-3">
<FileCode2 className="h-5 w-5 text-blue-400 flex-shrink-0 mt-0.5" />
<FileCode2 className="h-5 w-5 text-blue-400 shrink-0 mt-0.5" />
<div>
<h3 className="text-sm font-semibold text-blue-300 mb-1">
{t('wafConfig.aboutTitle')}