UNPKG

@vue-interface/data-table

Version:
228 lines (181 loc) 7.28 kB
const Color = require('color'); const plugin = require('tailwindcss/plugin'); const colors = require('tailwindcss/colors'); const variations = require('@vue-interface/variant/tailwindcss/variations'); function opacity(color) { const matches = Color(color) .toString() .match(/^rgba\((\d+,\s?){3}(\d?.?\d+)\)$/); return matches ? parseFloat(matches[2]) : 1; } function contrast(color, light, dark) { return Color(color).luminosity() > .5 ? (dark || 'black') : (light || 'white'); } function mix(color, subject, percent) { return Color(color).mix(Color(subject), percent); } function opaque(background, foreground) { return mix(Color(foreground).alpha(1), background, opacity(foreground)); } module.exports = plugin(function({ addComponents, theme }) { const component = { // Include styles from the reboot '.table thead, .table tbody, .table tfoot, .table tr, .table td, .table th': { borderColor: 'inherit', borderStyle: 'solid', borderWidth: 0 }, // Table styles '.table': { width: '100%', marginBottom: '1rem', color: theme('table.color'), verticalAlign: theme('table.verticalAlign'), borderColor: theme('table.borderColor'), }, // Target th & td // We need the child combinator to prevent styles leaking to nested tables which doesn't have a `.table` class. // We use the universal selectors here to simplify the selector (else we would need 6 different selectors). // Another advantage is that this generates less code and makes the selector less specific making it easier to override. '.table> :not(caption) > * > *': { padding: `${theme('table.cell.paddingY')} ${theme('table.cell.paddingX')}`, backgroundColor: theme('table.backgroundColor'), backgroundImage: `linear-gradient(transparent, transparent)`, borderBottomWidth: theme('table.borderWidth'), }, '.table> tbody': { verticalAlign: 'inherit' }, '.table > thead': { verticalAlign: 'bottom' }, // Highlight border color between thead, tbody and tfoot. '.table > :not(:last-child) > :last-child > *': { borderBottomColor: theme('table.seperator.borderColor') }, // // Change placement of captions with a class // '.caption-top': { captionSide: 'top' }, // // Condensed table w/ half padding // '.table-sm > :not(caption) > * > *': { padding: `${theme('table.sm.cell.paddingY')} ${theme('table.sm.cell.paddingX')}` }, // Border versions // // Add or remove borders all around the table and between all the columns. // // When borders are added on all sides of the cells, the corners can render odd when // these borders do not have the same color or if they are semi-transparent. // Therefor we add top and border bottoms to the `tr`s and left and right borders // to the `td`s or `th`s '.table-bordered > :not(caption) > *': { borderWidth: `${theme('table.borderWidth')} 0` }, '.table-bordered > :not(caption) > * > *': { borderWidth: `0 ${theme('table.borderWidth')}` }, '.table-borderless > :not(caption) > * > *': { borderBottomWidth: 0 }, // Zebra-striping // // Default zebra-stripe styles (alternating gray and transparent backgrounds) [`.table-striped > tbody > tr:nth-of-type(${theme('table.striped.order')})`]: { color: theme('table.striped.color') }, // Active table // // The `.table-active` class can be added to highlight rows or cells '.table-active': { color: theme('table.active.color') }, // Hover effect // // Placed here since it has to come after the potential zebra striping '.table-hover > tbody > tr:hover': { color: theme('table.hover.color') }, '.table-responsive': { overflowX: 'auto', '-webkit-overflow-scrolling': 'touch' } }; // Table variants // // Table variants set the table cell backgrounds, border colors // and the colors of the striped, hovered & active tables Object.entries(theme('variations', variations)) .forEach(([state, background]) => { const color = contrast(opaque('#fff', background)); const stripedBackgroundColor = mix(color, background, .05); const stripeColor = contrast(stripedBackgroundColor); const hoverBackgroundColor = mix(color, background, .075); const hoverColor = contrast(hoverBackgroundColor); const activeBackgroundColor = mix(color, background, .1); const activeColor = contrast(activeBackgroundColor); component[`.table-${state}`] = { color, borderColor: mix(color, background, .05), striped: { color: stripeColor, backgroundColor: stripedBackgroundColor }, hover: { color: hoverColor, backgroundColor: hoverBackgroundColor }, active: { color: activeColor, backgroundColor: activeBackgroundColor } }; }); addComponents(component); }, { theme: { table: theme => ({ color: 'inherit', backgroundColor: 'transparent', borderWidth: '1px', borderColor: theme('colors.gray.200', colors.gray[200]), th: { fontWeight: 'bold' }, cell: { paddingY: '.5rem', paddingX: '.5rem', verticalAlign: 'top', }, striped: { order: 'odd', color: 'inherit', backgroundColor: `${Color(theme('colors.black', colors.black)).fade(.05)}`, }, active: { color: 'inherit', backgroundColor: `${Color(theme('colors.black', colors.black)).fade(.1)}`, }, hover: { color: 'inherit', backgroundColor: `${Color(theme('colors.black', colors.black)).fade(.075)}`, }, seperator: { borderColor: theme('colors.gray.200', colors.gray[200]) }, caption: { borderColor: theme('colors.gray.400', colors.gray[400]) }, sm: { cell: { paddingY: '.25rem', paddingX: '.25rem', } } }) } });