= 1024 && $unitIndex < count($units) - 1) { $value /= 1024; $unitIndex += 1; } $decimals = $disk ? ($unitIndex >= 4 ? 2 : ($unitIndex >= 1 ? 1 : 0)) : ($unitIndex === 0 ? 0 : 1); return number_format($value, $decimals) . ' ' . $units[$unitIndex]; } } if (!function_exists('sortable_table_format_value')) { function sortable_table_format_value($value, $row, $column) { $format = $column['format'] ?? null; if (is_callable($format)) { return [$format($value, $row, $column), $value]; } switch ($format) { case 'number': return [number_format((float)$value), (float)$value]; case 'bytes': return [sortable_table_format_bytes($value, false), (float)$value]; case 'disk-bytes': return [sortable_table_format_bytes($value, true), (float)$value]; case 'percent': return [number_format((float)$value, 1) . '%', (float)$value]; case 'duration-ms': $number = (float)$value; if ($number >= 1000) { return [number_format($number / 1000, $number >= 10000 ? 0 : 1) . ' s', $number]; } return [number_format($number, $number >= 100 ? 0 : 1) . ' ms', $number]; case 'bool': return [$value ? 'Yes' : 'No', $value ? 1 : 0]; default: if (is_bool($value)) { return [$value ? 'Yes' : 'No', $value ? 1 : 0]; } return [(string)$value, is_scalar($value) ? $value : '']; } } } return [ 'render' => function($prop) { include_js('js/u-format.js'); include_js('js/u-sortable-table.js'); $tableId = (string)($prop['id'] ?? ('sortable-table-' . uniqid())); $title = (string)($prop['title'] ?? ''); $subtitle = (string)($prop['subtitle'] ?? ''); $columns = is_array($prop['columns'] ?? null) ? $prop['columns'] : []; $rows = is_array($prop['rows'] ?? null) ? $prop['rows'] : []; $emptyLabel = (string)($prop['empty_label'] ?? 'No data available'); $storageKey = (string)($prop['storage_key'] ?? ('starter.sort.' . $tableId)); $sort = is_array($prop['sort'] ?? null) ? $prop['sort'] : []; $initOptions = ['storageKey' => $storageKey]; if (isset($sort['column'])) { $initOptions['initialSort'] = [ 'column' => (int)$sort['column'], 'direction' => (($sort['direction'] ?? 'asc') === 'desc') ? 'desc' : 'asc', ]; } $jsonFlags = JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS | JSON_HEX_QUOT; ob_start(); ?>

>
'Lightweight sortable HTML table with remembered sort state and human-readable data formatting', ];