wip
This commit is contained in:
@@ -70,6 +70,18 @@ function parseVoltageSortKey(voltageLabel: string): number {
|
||||
function compactNumericForLocale(value: string, locale: 'en' | 'de'): string {
|
||||
const v = normalizeValue(value);
|
||||
if (!v) return '';
|
||||
|
||||
// Compact common bending-radius style: "15xD (Single core); 12xD (Multi core)" -> "15/12xD".
|
||||
// Keep semantics, reduce width. Never truncate with ellipses.
|
||||
if (/\d+xD/i.test(v)) {
|
||||
const nums = Array.from(v.matchAll(/(\d+)xD/gi)).map(m => m[1]).filter(Boolean);
|
||||
const unique: string[] = [];
|
||||
for (const n of nums) {
|
||||
if (!unique.includes(n)) unique.push(n);
|
||||
}
|
||||
if (unique.length) return `${unique.join('/') }xD`;
|
||||
}
|
||||
|
||||
const hasDigit = /\d/.test(v);
|
||||
if (!hasDigit) return v;
|
||||
const trimmed = v.replace(/\s+/g, ' ').trim();
|
||||
@@ -242,6 +254,12 @@ function denseAbbrevLabel(args: { key: string; locale: 'en' | 'de'; unit?: strin
|
||||
return args.locale === 'de' ? 'Leiter' : 'Cond.';
|
||||
case 'shape':
|
||||
return args.locale === 'de' ? 'Form' : 'Shape';
|
||||
// Electrical
|
||||
case 'cap':
|
||||
// Capacitance. Use a clear label; lowercase "cap" looks like an internal key.
|
||||
return `Cap${suffix}`;
|
||||
case 'X':
|
||||
return `X${suffix}`;
|
||||
case 'test_volt':
|
||||
return `U_test${suffix}`;
|
||||
case 'rated_volt':
|
||||
@@ -265,13 +283,14 @@ function denseAbbrevLabel(args: { key: string; locale: 'en' | 'de'; unit?: strin
|
||||
}
|
||||
}
|
||||
|
||||
function summarizeOptions(options: string[] | undefined, maxItems: number = 3): string {
|
||||
function summarizeOptions(options: string[] | undefined): string {
|
||||
const vals = (options || []).map(normalizeValue).filter(Boolean);
|
||||
if (vals.length === 0) return '';
|
||||
const uniq = Array.from(new Set(vals));
|
||||
if (uniq.length === 1) return uniq[0];
|
||||
if (uniq.length <= maxItems) return uniq.join(' / ');
|
||||
return `${uniq.slice(0, maxItems).join(' / ')} / ...`;
|
||||
// Never use ellipsis truncation in datasheets. Prefer full value list.
|
||||
// (Long values should be handled by layout; if needed we can later add wrapping rules.)
|
||||
return uniq.join(' / ');
|
||||
}
|
||||
|
||||
function parseNumericOption(value: string): number | null {
|
||||
@@ -294,10 +313,17 @@ function summarizeNumericRange(options: string[] | undefined): { ok: boolean; te
|
||||
return { ok: true, text: `${fmt(min)}–${fmt(max)}` };
|
||||
}
|
||||
|
||||
function summarizeSmartOptions(label: string, options: string[] | undefined): string {
|
||||
function summarizeSmartOptions(_label: string, options: string[] | undefined): string {
|
||||
const range = summarizeNumericRange(options);
|
||||
if (range.ok) return range.text;
|
||||
return summarizeOptions(options, 3);
|
||||
return summarizeOptions(options);
|
||||
}
|
||||
|
||||
function normalizeDesignation(value: string): string {
|
||||
return String(value || '')
|
||||
.toUpperCase()
|
||||
.replace(/-\d+$/g, '')
|
||||
.replace(/[^A-Z0-9]+/g, '');
|
||||
}
|
||||
|
||||
function buildExcelModel(args: { product: ProductData; locale: 'en' | 'de' }): BuildExcelModelResult {
|
||||
@@ -361,6 +387,14 @@ function buildExcelModel(args: { product: ProductData; locale: 'en' | 'de' }): B
|
||||
'cpr class': { header: 'CPR class', unit: '', key: 'cpr' },
|
||||
'flame retardant': { header: 'Flame retardant', unit: '', key: 'flame' },
|
||||
'self-extinguishing of single cable': { header: 'Flame retardant', unit: '', key: 'flame' },
|
||||
|
||||
// High-value electrical/screen columns
|
||||
'capacitance (approx.)': { header: 'Capacitance', unit: 'uF/km', key: 'cap' },
|
||||
'capacitance': { header: 'Capacitance', unit: 'uF/km', key: 'cap' },
|
||||
'reactance': { header: 'Reactance', unit: 'Ohm/km', key: 'X' },
|
||||
'diameter over screen': { header: 'Diameter over screen', unit: 'mm', key: 'D_screen' },
|
||||
'metallic screen mm2': { header: 'Metallic screen', unit: 'mm2', key: 'S_screen' },
|
||||
'metallic screen': { header: 'Metallic screen', unit: 'mm2', key: 'S_screen' },
|
||||
};
|
||||
|
||||
const excelKeys = Object.keys(sample).filter(k => k && k !== 'Part Number' && k !== 'Units');
|
||||
@@ -464,6 +498,10 @@ function buildExcelModel(args: { product: ProductData; locale: 'en' | 'de' }): B
|
||||
const denseTableKeyOrder = [
|
||||
'Cond',
|
||||
'shape',
|
||||
// Electrical properties (when present)
|
||||
'cap',
|
||||
'X',
|
||||
// Dimensions and ratings
|
||||
'DI',
|
||||
'RI',
|
||||
'Wi',
|
||||
@@ -473,6 +511,9 @@ function buildExcelModel(args: { product: ProductData; locale: 'en' | 'de' }): B
|
||||
'Wm',
|
||||
'Rbv',
|
||||
'Ø',
|
||||
// Screen data (when present)
|
||||
'D_screen',
|
||||
'S_screen',
|
||||
'Fzv',
|
||||
'G',
|
||||
] as const;
|
||||
@@ -510,16 +551,33 @@ function buildExcelModel(args: { product: ProductData; locale: 'en' | 'de' }): B
|
||||
if (!mappedByKey.has(c.mapping.key)) mappedByKey.set(c.mapping.key, c);
|
||||
}
|
||||
|
||||
// If conductor material is missing in Excel, derive it from designation.
|
||||
// NA... => Al, N... => Cu (common for this dataset).
|
||||
if (!mappedByKey.has('Cond')) {
|
||||
mappedByKey.set('Cond', {
|
||||
excelKey: '',
|
||||
mapping: { header: 'Cond.', unit: '', key: 'Cond' },
|
||||
});
|
||||
}
|
||||
|
||||
const orderedTableColumns = denseTableKeyOrder
|
||||
.filter(k => mappedByKey.has(k))
|
||||
.map(k => mappedByKey.get(k)!)
|
||||
.map(({ excelKey, mapping }) => {
|
||||
const unit = normalizeUnit(units[excelKey] || mapping.unit || '');
|
||||
const unit = normalizeUnit((excelKey ? units[excelKey] : '') || mapping.unit || '');
|
||||
return {
|
||||
key: mapping.key,
|
||||
label: denseAbbrevLabel({ key: mapping.key, locale: args.locale, unit }) || formatExcelHeaderLabel(excelKey, unit),
|
||||
get: (rowIndex: number) => {
|
||||
const srcRowIndex = indices[rowIndex];
|
||||
|
||||
if (mapping.key === 'Cond' && !excelKey) {
|
||||
const pn = normalizeDesignation(args.product.name || args.product.slug || args.product.sku || '');
|
||||
if (/^NA/.test(pn)) return 'Al';
|
||||
if (/^N/.test(pn)) return 'Cu';
|
||||
return '';
|
||||
}
|
||||
|
||||
const raw = excelKey ? normalizeValue(String(compatibleRows[srcRowIndex]?.[excelKey] ?? '')) : '';
|
||||
return compactCellForDenseTable(raw, unit, args.locale);
|
||||
},
|
||||
|
||||
@@ -2,6 +2,7 @@ import * as React from 'react';
|
||||
import { Document, Image, Page, Text, View } from '@react-pdf/renderer';
|
||||
|
||||
import type { DatasheetModel, DatasheetVoltageTable } from '../model/types';
|
||||
import { CONFIG } from '../model/utils';
|
||||
import { styles } from './styles';
|
||||
import { Header } from './components/Header';
|
||||
import { Footer } from './components/Footer';
|
||||
@@ -25,9 +26,9 @@ function chunk<T>(arr: T[], size: number): T[][] {
|
||||
export function DatasheetDocument(props: { model: DatasheetModel; assets: Assets }): React.ReactElement {
|
||||
const { model, assets } = props;
|
||||
const headerTitle = model.labels.datasheet;
|
||||
const footerLeft = `${model.labels.sku}: ${model.product.sku}`;
|
||||
|
||||
const firstColLabel = model.locale === 'de' ? 'Adern & Querschnitt' : 'Cores & cross-section';
|
||||
// Dense tables require compact headers (no wrapping). Use standard abbreviations.
|
||||
const firstColLabel = model.locale === 'de' ? 'Adern & QS' : 'Cores & CS';
|
||||
|
||||
const tablePages: Array<{ table: DatasheetVoltageTable; rows: DatasheetVoltageTable['rows'] }> =
|
||||
model.voltageTables.flatMap(t => {
|
||||
@@ -40,7 +41,7 @@ export function DatasheetDocument(props: { model: DatasheetModel; assets: Assets
|
||||
<Document>
|
||||
<Page size="A4" style={styles.page}>
|
||||
<Header title={headerTitle} logoDataUrl={assets.logoDataUrl} qrDataUrl={assets.qrDataUrl} />
|
||||
<Footer leftText={footerLeft} locale={model.locale} />
|
||||
<Footer locale={model.locale} siteUrl={CONFIG.siteUrl} />
|
||||
|
||||
<Text style={styles.h1}>{model.product.name}</Text>
|
||||
{model.product.categoriesLine ? <Text style={styles.subhead}>{model.product.categoriesLine}</Text> : null}
|
||||
@@ -66,19 +67,18 @@ export function DatasheetDocument(props: { model: DatasheetModel; assets: Assets
|
||||
) : null}
|
||||
</Page>
|
||||
|
||||
{tablePages.map((p, index) => (
|
||||
<Page key={`${p.table.voltageLabel}-${index}`} size="A4" style={styles.page}>
|
||||
<Header title={headerTitle} logoDataUrl={assets.logoDataUrl} qrDataUrl={assets.qrDataUrl} />
|
||||
<Footer leftText={footerLeft} locale={model.locale} />
|
||||
{tablePages.map((p, index) => (
|
||||
<Page key={`${p.table.voltageLabel}-${index}`} size="A4" style={styles.page}>
|
||||
<Header title={headerTitle} logoDataUrl={assets.logoDataUrl} qrDataUrl={assets.qrDataUrl} />
|
||||
<Footer locale={model.locale} siteUrl={CONFIG.siteUrl} />
|
||||
|
||||
<Section title={`${model.labels.crossSection} — ${p.table.voltageLabel}`}>
|
||||
{p.table.metaItems.length ? <KeyValueGrid items={p.table.metaItems} /> : null}
|
||||
</Section>
|
||||
|
||||
<DenseTable table={{ columns: p.table.columns, rows: p.rows }} firstColLabel={firstColLabel} />
|
||||
</Page>
|
||||
))}
|
||||
</Document>
|
||||
);
|
||||
</Page>
|
||||
))}
|
||||
</Document>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -15,38 +15,99 @@ export function DenseTable(props: {
|
||||
const cols = props.table.columns;
|
||||
const rows = props.table.rows;
|
||||
|
||||
const cfgPct = cols.length >= 12 ? 0.28 : 0.32;
|
||||
const dataPct = 1 - cfgPct;
|
||||
const each = cols.length ? dataPct / cols.length : dataPct;
|
||||
const cfgW = `${Math.round(cfgPct * 100)}%`;
|
||||
const dataW = `${Math.round(clamp(each, 0.03, 0.12) * 1000) / 10}%`;
|
||||
const noWrapHeader = (label: string): string => {
|
||||
const raw = String(label || '').trim();
|
||||
if (!raw) return '';
|
||||
|
||||
// Ensure the header never wraps into a second line.
|
||||
// - Remove whitespace break opportunities (NBSP)
|
||||
// NOTE: Avoid inserting zero-width joiners between letters.
|
||||
// Some PDF viewers render them with spacing/odd glyph behavior.
|
||||
// This is intentionally aggressive because broken headers destroy scanability.
|
||||
return raw.replace(/\s+/g, '\u00A0');
|
||||
};
|
||||
|
||||
// Column widths: use explicit percentages (no rounding gaps) so the table always
|
||||
// consumes the full content width.
|
||||
// Goal:
|
||||
// - keep the designation column *not too wide*
|
||||
// - guarantee enough width for data headers when there is available space
|
||||
const cfgMin = 0.18;
|
||||
const cfgMax = 0.30;
|
||||
|
||||
let cfgPct = cols.length >= 14 ? 0.22 : cols.length >= 12 ? 0.24 : cols.length >= 10 ? 0.26 : 0.30;
|
||||
cfgPct = clamp(cfgPct, cfgMin, cfgMax);
|
||||
|
||||
const minDataPct = cols.length >= 14 ? 0.045 : cols.length >= 12 ? 0.05 : cols.length >= 10 ? 0.055 : 0.06;
|
||||
// If the initial cfgPct leaves too little width per data column, reduce cfgPct.
|
||||
const cfgPctMaxForMinData = 1 - cols.length * minDataPct;
|
||||
if (Number.isFinite(cfgPctMaxForMinData)) {
|
||||
cfgPct = Math.min(cfgPct, cfgPctMaxForMinData);
|
||||
cfgPct = clamp(cfgPct, cfgMin, cfgMax);
|
||||
}
|
||||
|
||||
const cfgW = `${(cfgPct * 100).toFixed(4)}%`;
|
||||
const dataTotal = 1 - cfgPct;
|
||||
const each = cols.length ? dataTotal / cols.length : dataTotal;
|
||||
const dataWs = cols.map((_, idx) => {
|
||||
// Keep the last column as the remainder so percentages sum to exactly 100%.
|
||||
if (idx === cols.length - 1) {
|
||||
const used = each * Math.max(0, cols.length - 1);
|
||||
const remainder = Math.max(0, dataTotal - used);
|
||||
return `${(remainder * 100).toFixed(4)}%`;
|
||||
}
|
||||
return `${(each * 100).toFixed(4)}%`;
|
||||
});
|
||||
|
||||
return (
|
||||
<View style={styles.tableWrap}>
|
||||
<View style={styles.tableHeader}>
|
||||
<View style={styles.tableHeader} wrap={false}>
|
||||
<View style={{ width: cfgW }}>
|
||||
<Text style={styles.tableHeaderCell}>{props.firstColLabel}</Text>
|
||||
<Text
|
||||
style={[
|
||||
styles.tableHeaderCell,
|
||||
styles.tableHeaderCellCfg,
|
||||
cols.length ? styles.tableHeaderCellDivider : null,
|
||||
]}
|
||||
wrap={false}
|
||||
>
|
||||
{noWrapHeader(props.firstColLabel)}
|
||||
</Text>
|
||||
</View>
|
||||
{cols.map(c => (
|
||||
<View key={c.key} style={{ width: dataW }}>
|
||||
<Text style={styles.tableHeaderCell}>{c.label}</Text>
|
||||
</View>
|
||||
))}
|
||||
{cols.map((c, idx) => {
|
||||
const isLast = idx === cols.length - 1;
|
||||
return (
|
||||
<View key={c.key} style={{ width: dataWs[idx] }}>
|
||||
<Text
|
||||
style={[styles.tableHeaderCell, !isLast ? styles.tableHeaderCellDivider : null]}
|
||||
wrap={false}
|
||||
>
|
||||
{noWrapHeader(c.label)}
|
||||
</Text>
|
||||
</View>
|
||||
);
|
||||
})}
|
||||
</View>
|
||||
|
||||
{rows.map((r, ri) => (
|
||||
<View key={`${r.configuration}-${ri}`} style={[styles.tableRow, ri % 2 === 0 ? styles.tableRowAlt : null]}>
|
||||
<View
|
||||
key={`${r.configuration}-${ri}`}
|
||||
style={[styles.tableRow, ri % 2 === 0 ? styles.tableRowAlt : null]}
|
||||
wrap={false}
|
||||
>
|
||||
<View style={{ width: cfgW }}>
|
||||
<Text style={styles.tableCell}>{r.configuration}</Text>
|
||||
<Text style={[styles.tableCell, styles.tableCellCfg, cols.length ? styles.tableCellDivider : null]}>{r.configuration}</Text>
|
||||
</View>
|
||||
{r.cells.map((cell, ci) => (
|
||||
<View key={`${cols[ci]?.key || ci}`} style={{ width: dataW }}>
|
||||
<Text style={styles.tableCell}>{cell}</Text>
|
||||
</View>
|
||||
))}
|
||||
{r.cells.map((cell, ci) => {
|
||||
const isLast = ci === r.cells.length - 1;
|
||||
return (
|
||||
<View key={`${cols[ci]?.key || ci}`} style={{ width: dataWs[ci] }}>
|
||||
<Text style={[styles.tableCell, !isLast ? styles.tableCellDivider : null]}>{cell}</Text>
|
||||
</View>
|
||||
);
|
||||
})}
|
||||
</View>
|
||||
))}
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -3,19 +3,20 @@ import { Text, View } from '@react-pdf/renderer';
|
||||
|
||||
import { styles } from '../styles';
|
||||
|
||||
export function Footer(props: { leftText: string; locale: 'en' | 'de' }): React.ReactElement {
|
||||
export function Footer(props: { locale: 'en' | 'de'; siteUrl?: string }): React.ReactElement {
|
||||
const date = new Date().toLocaleDateString(props.locale === 'en' ? 'en-US' : 'de-DE', {
|
||||
year: 'numeric',
|
||||
month: 'long',
|
||||
day: 'numeric',
|
||||
});
|
||||
|
||||
const siteUrl = props.siteUrl || 'https://klz-cables.com';
|
||||
|
||||
return (
|
||||
<View style={styles.footer} fixed>
|
||||
<Text>{props.leftText}</Text>
|
||||
<Text>{siteUrl}</Text>
|
||||
<Text>{date}</Text>
|
||||
<Text render={({ pageNumber, totalPages }) => `${pageNumber}/${totalPages}`} />
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -8,18 +8,36 @@ export function KeyValueGrid(props: { items: KeyValueItem[] }): React.ReactEleme
|
||||
const items = (props.items || []).filter(i => i.label && i.value);
|
||||
if (!items.length) return null;
|
||||
|
||||
// 4-column layout: (label, value, label, value)
|
||||
const rows: Array<[KeyValueItem, KeyValueItem | null]> = [];
|
||||
for (let i = 0; i < items.length; i += 2) {
|
||||
rows.push([items[i], items[i + 1] || null]);
|
||||
}
|
||||
|
||||
return (
|
||||
<View style={styles.kvGrid}>
|
||||
{items.map((item, index) => {
|
||||
const isLast = index === items.length - 1;
|
||||
const valueText = item.unit ? `${item.value} ${item.unit}` : item.value;
|
||||
{rows.map(([left, right], rowIndex) => {
|
||||
const isLast = rowIndex === rows.length - 1;
|
||||
const leftValue = left.unit ? `${left.value} ${left.unit}` : left.value;
|
||||
const rightValue = right ? (right.unit ? `${right.value} ${right.unit}` : right.value) : '';
|
||||
|
||||
return (
|
||||
<View key={`${item.label}-${index}`} style={[styles.kvRow, isLast ? styles.kvRowLast : null]}>
|
||||
<View style={styles.kvLabel}>
|
||||
<Text style={styles.kvLabelText}>{item.label}</Text>
|
||||
<View
|
||||
key={`${left.label}-${rowIndex}`}
|
||||
style={[styles.kvRow, isLast ? styles.kvRowLast : null]}
|
||||
wrap={false}
|
||||
>
|
||||
<View style={[styles.kvCell, { width: '23%' }]}>
|
||||
<Text style={styles.kvLabelText}>{left.label}</Text>
|
||||
</View>
|
||||
<View style={styles.kvValue}>
|
||||
<Text style={styles.kvValueText}>{valueText}</Text>
|
||||
<View style={[styles.kvCell, styles.kvMidDivider, { width: '27%' }]}>
|
||||
<Text style={styles.kvValueText}>{leftValue}</Text>
|
||||
</View>
|
||||
<View style={[styles.kvCell, { width: '23%' }]}>
|
||||
<Text style={styles.kvLabelText}>{right?.label || ''}</Text>
|
||||
</View>
|
||||
<View style={[styles.kvCell, { width: '27%' }]}>
|
||||
<Text style={styles.kvValueText}>{rightValue}</Text>
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
@@ -27,4 +45,3 @@ export function KeyValueGrid(props: { items: KeyValueItem[] }): React.ReactEleme
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -3,12 +3,16 @@ import { Text, View } from '@react-pdf/renderer';
|
||||
|
||||
import { styles } from '../styles';
|
||||
|
||||
export function Section(props: { title: string; children: React.ReactNode }): React.ReactElement {
|
||||
export function Section(props: {
|
||||
title: string;
|
||||
children: React.ReactNode;
|
||||
boxed?: boolean;
|
||||
}): React.ReactElement {
|
||||
const boxed = props.boxed ?? true;
|
||||
return (
|
||||
<View style={styles.section}>
|
||||
<View style={boxed ? styles.section : styles.sectionPlain}>
|
||||
<Text style={styles.sectionTitle}>{props.title}</Text>
|
||||
{props.children}
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
import { StyleSheet } from '@react-pdf/renderer';
|
||||
import { Font, StyleSheet } from '@react-pdf/renderer';
|
||||
|
||||
// Prevent automatic word hyphenation, which can create multi-line table headers
|
||||
// even when we try to keep them single-line.
|
||||
Font.registerHyphenationCallback(word => [word]);
|
||||
|
||||
export const COLORS = {
|
||||
navy: '#0E2A47',
|
||||
@@ -76,6 +80,10 @@ export const styles = StyleSheet.create({
|
||||
padding: 14,
|
||||
marginBottom: 14,
|
||||
},
|
||||
sectionPlain: {
|
||||
paddingVertical: 2,
|
||||
marginBottom: 12,
|
||||
},
|
||||
sectionTitle: {
|
||||
fontSize: 10,
|
||||
fontWeight: 700,
|
||||
@@ -86,34 +94,56 @@ export const styles = StyleSheet.create({
|
||||
body: { fontSize: 10, lineHeight: 1.5, color: COLORS.darkGray },
|
||||
|
||||
kvGrid: {
|
||||
width: '100%',
|
||||
borderWidth: 1,
|
||||
borderColor: COLORS.lightGray,
|
||||
},
|
||||
kvRow: { flexDirection: 'row', borderBottomWidth: 1, borderBottomColor: COLORS.lightGray },
|
||||
kvRow: {
|
||||
flexDirection: 'row',
|
||||
borderBottomWidth: 1,
|
||||
borderBottomColor: COLORS.lightGray,
|
||||
},
|
||||
kvRowLast: { borderBottomWidth: 0 },
|
||||
kvLabel: {
|
||||
width: '45%',
|
||||
paddingVertical: 6,
|
||||
paddingHorizontal: 8,
|
||||
backgroundColor: COLORS.almostWhite,
|
||||
kvCell: { paddingVertical: 6, paddingHorizontal: 8 },
|
||||
// Visual separator between (label,value) pairs in the 4-col KV grid.
|
||||
// Matches the engineering-table look and improves scanability.
|
||||
kvMidDivider: {
|
||||
borderRightWidth: 1,
|
||||
borderRightColor: COLORS.lightGray,
|
||||
},
|
||||
kvValue: { width: '55%', paddingVertical: 6, paddingHorizontal: 8 },
|
||||
kvLabelText: { fontSize: 8.5, fontWeight: 700, color: COLORS.mediumGray },
|
||||
kvValueText: { fontSize: 9.5, color: COLORS.darkGray },
|
||||
|
||||
tableWrap: { borderWidth: 1, borderColor: COLORS.lightGray },
|
||||
tableHeader: { flexDirection: 'row', backgroundColor: '#6B707A' },
|
||||
tableWrap: { width: '100%', borderWidth: 1, borderColor: COLORS.lightGray },
|
||||
tableHeader: {
|
||||
width: '100%',
|
||||
flexDirection: 'row',
|
||||
backgroundColor: '#FFFFFF',
|
||||
borderBottomWidth: 1,
|
||||
borderBottomColor: COLORS.lightGray,
|
||||
},
|
||||
tableHeaderCell: {
|
||||
paddingVertical: 5,
|
||||
paddingHorizontal: 4,
|
||||
fontSize: 6.6,
|
||||
fontWeight: 700,
|
||||
color: '#FFFFFF',
|
||||
color: COLORS.navy,
|
||||
},
|
||||
tableRow: { flexDirection: 'row', borderBottomWidth: 1, borderBottomColor: COLORS.lightGray },
|
||||
tableHeaderCellCfg: {
|
||||
paddingHorizontal: 6,
|
||||
},
|
||||
tableHeaderCellDivider: {
|
||||
borderRightWidth: 1,
|
||||
borderRightColor: COLORS.lightGray,
|
||||
},
|
||||
tableRow: { width: '100%', flexDirection: 'row', borderBottomWidth: 1, borderBottomColor: COLORS.lightGray },
|
||||
tableRowAlt: { backgroundColor: COLORS.almostWhite },
|
||||
tableCell: { paddingVertical: 4, paddingHorizontal: 4, fontSize: 6.6, color: COLORS.darkGray },
|
||||
tableCellCfg: {
|
||||
paddingHorizontal: 6,
|
||||
},
|
||||
tableCellDivider: {
|
||||
borderRightWidth: 1,
|
||||
borderRightColor: COLORS.lightGray,
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user