Position download button in corner + better Arabic font

- Move export button outside header-actions to enable absolute positioning
- Button now positioned at top-right (LTR) / top-left (RTL)
- Switch from Tajawal to IBM Plex Sans Arabic (slicker, more technical)
- Add RTL-specific font-family in CSS
This commit is contained in:
fahed
2026-02-03 15:49:31 +03:00
parent 12f548fc78
commit 60eda25fe3
3 changed files with 44 additions and 18 deletions

View File

@@ -17,7 +17,7 @@
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" /> <link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
<link rel="preconnect" href="https://fonts.googleapis.com"> <link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=DM+Sans:wght@400;500;600&family=Tajawal:wght@400;500;700&display=swap" rel="stylesheet"> <link href="https://fonts.googleapis.com/css2?family=DM+Sans:wght@400;500;600&family=IBM+Plex+Sans+Arabic:wght@400;500;600;700&display=swap" rel="stylesheet">
<!-- <!--
Notice the use of %PUBLIC_URL% in the tags above. Notice the use of %PUBLIC_URL% in the tags above.
It will be replaced with the URL of the `public` folder during the build. It will be replaced with the URL of the `public` folder during the build.

View File

@@ -38,6 +38,12 @@ body {
-moz-osx-font-smoothing: grayscale; -moz-osx-font-smoothing: grayscale;
} }
/* RTL Arabic font */
html[dir="rtl"] body,
html[dir="rtl"] {
font-family: 'IBM Plex Sans Arabic', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
}
/* Loading & Error */ /* Loading & Error */
.loading-container, .loading-container,
.error-container { .error-container {
@@ -1861,6 +1867,7 @@ table tbody tr:hover {
/* Chart Export Button & Header */ /* Chart Export Button & Header */
.exportable-chart-wrapper { .exportable-chart-wrapper {
position: relative;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
height: 100%; height: 100%;
@@ -1872,7 +1879,12 @@ table tbody tr:hover {
justify-content: space-between; justify-content: space-between;
gap: 16px; gap: 16px;
margin-bottom: 16px; margin-bottom: 16px;
flex-wrap: wrap; padding-right: 44px; /* Space for absolute download button */
}
html[dir="rtl"] .chart-header-with-export {
padding-right: 0;
padding-left: 44px;
} }
.chart-header-with-export h2 { .chart-header-with-export h2 {
@@ -1881,6 +1893,7 @@ table tbody tr:hover {
font-weight: 600; font-weight: 600;
color: var(--text-primary); color: var(--text-primary);
line-height: 1.4; line-height: 1.4;
flex-shrink: 0;
} }
.chart-header-actions { .chart-header-actions {
@@ -1896,7 +1909,14 @@ table tbody tr:hover {
min-height: 0; min-height: 0;
} }
.chart-export-btn { /* Download button - always top corner, outside normal flow */
.chart-export-btn,
.chart-export-btn.visible {
position: absolute !important;
top: 0 !important;
right: 0 !important;
left: auto !important;
z-index: 10;
width: 32px; width: 32px;
height: 32px; height: 32px;
min-width: 32px; min-width: 32px;
@@ -1909,10 +1929,17 @@ table tbody tr:hover {
justify-content: center; justify-content: center;
color: var(--text-muted); color: var(--text-muted);
transition: background 0.15s ease, color 0.15s ease; transition: background 0.15s ease, color 0.15s ease;
flex-shrink: 0;
}
html[dir="rtl"] .chart-export-btn,
html[dir="rtl"] .chart-export-btn.visible {
right: auto !important;
left: 0 !important;
} }
.chart-export-btn:hover { .chart-export-btn:hover {
background: var(--bg-tertiary); background: var(--border);
color: var(--text-primary); color: var(--text-primary);
} }

View File

@@ -46,23 +46,22 @@ export function ExportableChart({ children, filename = 'chart', title = '', clas
return ( return (
<div className="exportable-chart-wrapper"> <div className="exportable-chart-wrapper">
{/* Download button - positioned absolutely in corner */}
<button
className="chart-export-btn visible"
onClick={exportAsPNG}
title="Download as PNG"
>
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
<path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/>
<polyline points="7 10 12 15 17 10"/>
<line x1="12" y1="15" x2="12" y2="3"/>
</svg>
</button>
{title && ( {title && (
<div className="chart-header-with-export"> <div className="chart-header-with-export">
<h2>{title}</h2> <h2>{title}</h2>
<div className="chart-header-actions"> {controls && <div className="chart-header-actions">{controls}</div>}
{controls}
<button
className="chart-export-btn visible"
onClick={exportAsPNG}
title="Download as PNG"
>
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
<path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/>
<polyline points="7 10 12 15 17 10"/>
<line x1="12" y1="15" x2="12" y2="3"/>
</svg>
</button>
</div>
</div> </div>
)} )}
{!title && controls && <div className="chart-controls">{controls}</div>} {!title && controls && <div className="chart-controls">{controls}</div>}