refactor: update color classes to use CSS variables for consistency
This commit is contained in:
@@ -57,7 +57,7 @@ export default function ImageCropModal({ src, fileName, onCancel, onConfirm }: I
|
|||||||
<span className="text-xs text-[var(--text-2)] shrink-0">بزرگنمایی</span>
|
<span className="text-xs text-[var(--text-2)] shrink-0">بزرگنمایی</span>
|
||||||
<input type="range" min={1} max={3} step={0.01} value={zoom}
|
<input type="range" min={1} max={3} step={0.01} value={zoom}
|
||||||
onChange={e => setZoom(Number(e.target.value))}
|
onChange={e => setZoom(Number(e.target.value))}
|
||||||
className="w-full accent-indigo-600" />
|
className="w-full accent-[var(--primary)]" />
|
||||||
</div>
|
</div>
|
||||||
<div className="flex items-center justify-end gap-3">
|
<div className="flex items-center justify-end gap-3">
|
||||||
<button onClick={onCancel} disabled={processing}
|
<button onClick={onCancel} disabled={processing}
|
||||||
|
|||||||
@@ -100,7 +100,7 @@ export default function PaymentDetailPage() {
|
|||||||
label="نوبت مرتبط"
|
label="نوبت مرتبط"
|
||||||
value={
|
value={
|
||||||
<a href={`/admin/appointments/${payment.appointment_uuid}`}
|
<a href={`/admin/appointments/${payment.appointment_uuid}`}
|
||||||
className="text-primary-600 hover:underline text-xs font-mono">
|
className="text-[var(--primary)] hover:underline text-xs font-mono">
|
||||||
مشاهده نوبت
|
مشاهده نوبت
|
||||||
</a>
|
</a>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,13 @@ const INTENTIONAL = [
|
|||||||
'lib/avatarColors.ts', // گرادیان تزئینی آواتار، در هر دو تم یکسان
|
'lib/avatarColors.ts', // گرادیان تزئینی آواتار، در هر دو تم یکسان
|
||||||
];
|
];
|
||||||
|
|
||||||
|
/** پالت پیشفرض Tailwind v4 — هر خانوادهٔ دیگری باید در `@theme` تعریف شده باشد. */
|
||||||
|
const TAILWIND_FAMILIES = new Set([
|
||||||
|
'slate', 'gray', 'zinc', 'neutral', 'stone', 'red', 'orange', 'amber', 'yellow',
|
||||||
|
'lime', 'green', 'emerald', 'teal', 'cyan', 'sky', 'blue', 'indigo', 'violet',
|
||||||
|
'purple', 'fuchsia', 'pink', 'rose',
|
||||||
|
]);
|
||||||
|
|
||||||
const HEX = /#[0-9a-fA-F]{3,8}\b/;
|
const HEX = /#[0-9a-fA-F]{3,8}\b/;
|
||||||
const PALETTE_UTIL =
|
const PALETTE_UTIL =
|
||||||
/(?:^|[\s"'`{])(?:dark:|hover:|focus:|active:|group-hover:|md:|lg:|sm:)*(?:bg|text|border|divide|ring|fill|stroke)-(?:white|black|gray|slate|zinc|neutral|stone|red|green|emerald|blue|sky|amber|yellow|orange|purple|indigo|violet|pink|rose|teal|cyan)(?:-\d{2,3})?\b/;
|
/(?:^|[\s"'`{])(?:dark:|hover:|focus:|active:|group-hover:|md:|lg:|sm:)*(?:bg|text|border|divide|ring|fill|stroke)-(?:white|black|gray|slate|zinc|neutral|stone|red|green|emerald|blue|sky|amber|yellow|orange|purple|indigo|violet|pink|rose|teal|cyan)(?:-\d{2,3})?\b/;
|
||||||
@@ -77,4 +84,27 @@ describe('theme tokens', () => {
|
|||||||
.filter((f) => PALETTE_UTIL.test(strip(readFileSync(join(ROOT, f), 'utf8'))));
|
.filter((f) => PALETTE_UTIL.test(strip(readFileSync(join(ROOT, f), 'utf8'))));
|
||||||
expect(offenders).toEqual([]);
|
expect(offenders).toEqual([]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* `text-primary-600` و امثالش هیچ رنگی تولید نمیکنند: نه در پالت پیشفرض Tailwind
|
||||||
|
* هستند و نه در `@theme` تعریف شدهاند — یعنی کلاسِ مرده در هر دو تم.
|
||||||
|
*/
|
||||||
|
it('کلاس رنگی با مقیاس تعریفنشده ندارد', () => {
|
||||||
|
const theme = readFileSync(join(ROOT, 'styles.css'), 'utf8');
|
||||||
|
const declared = new Set(
|
||||||
|
[...theme.matchAll(/--color-([a-z]+)-\d{2,3}\s*:/g)].map((m) => m[1]),
|
||||||
|
);
|
||||||
|
const utilities = new RegExp(
|
||||||
|
String.raw`\b(?:bg|text|border|ring|divide|from|to|via|outline|accent|caret|fill|stroke|placeholder|shadow)-([a-z]+)-\d{2,3}\b`,
|
||||||
|
'g',
|
||||||
|
);
|
||||||
|
const offenders: string[] = [];
|
||||||
|
for (const f of files) {
|
||||||
|
const src = strip(readFileSync(join(ROOT, f), 'utf8'));
|
||||||
|
for (const m of src.matchAll(utilities)) {
|
||||||
|
if (!TAILWIND_FAMILIES.has(m[1]) && !declared.has(m[1])) offenders.push(`${f}: ${m[0]}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect(offenders).toEqual([]);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user