import { ComputedRef, Ref, computed, onMounted, ref } from 'vue'; import type { Settings, Table } from '../stores/main/models'; function isHexColor(val: string | undefined): boolean { return /^#[0-9A-Fa-f]{3,8}$/.test(val ?? ''); } function colorClass(val: string | undefined, prefix: 'bg' | 'text'): string { return val && !isHexColor(val) ? `${prefix}-${val}` : ''; } function colorStyle( val: string | undefined, cssProp: string ): Record { return val && isHexColor(val) ? { [cssProp]: val } : {}; } interface Params { selectedTable: Ref; settings: ComputedRef; tableMaximized: Ref; } /** * Classes and inline styles from the Style, Dimensions and Header settings. * Colors hold either a Quasar palette name ("blue-5", as a class) or a hex * value ("#2196F3", as an inline style). */ export function useTableStyles({ selectedTable, settings, tableMaximized, }: Params) { const adminBarPresent = ref(!!document.querySelector('#wpadminbar')); onMounted(() => { adminBarPresent.value = !!document.querySelector('#wpadminbar'); }); const tableCssClasses = computed(() => { return [ 'vtable', `vtable-${selectedTable.value?.id}`, { 'sticky-header-table': settings.value.top.stickyHeader }, { 'admin-bar-presented-on-fullscreen': tableMaximized.value && adminBarPresent.value, }, ]; }); const tableStyle = computed(() => ({ height: settings.value.dimensions.tableHeight ? settings.value.dimensions.tableHeight + 'px' : '100%', })); const cardClasses = computed(() => [ colorClass(settings.value.general.backgroundColor, 'bg'), colorClass(settings.value.general.textColor, 'text'), ]); const cardColorStyle = computed(() => ({ ...colorStyle(settings.value.general.backgroundColor, 'background-color'), ...colorStyle(settings.value.general.textColor, 'color'), })); const cardStyle = computed(() => ({ maxWidth: settings.value.dimensions.tableMaxWidth ? settings.value.dimensions.tableMaxWidth + 'px' : '100%', })); const topClasses = computed(() => [ colorClass(settings.value.top.topBackgroundColor, 'bg'), colorClass(settings.value.top.textColor, 'text'), ]); const topColorStyle = computed(() => ({ ...colorStyle(settings.value.top.topBackgroundColor, 'background-color'), ...colorStyle(settings.value.top.textColor, 'color'), })); // Column-scoped only: the `tr-` class is added in the body slot, // where the row is in scope and this result is already memoized per column. function tableTdClasses(index: string | number) { return [ 'vtable__td', `td-${index}`, colorClass(settings.value.general.textColor, 'text'), ]; } function tableTdStyle(): Record { return colorStyle(settings.value.general.textColor, 'color'); } function headerTextColor(): string | undefined { const { top, general } = settings.value; return top.headerTextColor || top.textColor || general.textColor; } function headerBgColor(): string | undefined { const { top } = settings.value; return top.headerBackgroundColor || top.topBackgroundColor; } function tableThClasses(index: string | number) { return [ 'vtable__th', `th-${index}`, colorClass(headerTextColor(), 'text'), colorClass(headerBgColor(), 'bg'), ]; } function tableThStyle(): Record { return { ...colorStyle(headerTextColor(), 'color'), ...colorStyle(headerBgColor(), 'background-color'), }; } return { tableCssClasses, tableStyle, cardClasses, cardStyle, cardColorStyle, topClasses, topColorStyle, tableTdClasses, tableTdStyle, tableThClasses, tableThStyle, }; }