854 lines
31 KiB
CSS
854 lines
31 KiB
CSS
/**
|
||
* =============================================================================
|
||
* NHance — custom.css (listing tables / DataTables)
|
||
* =============================================================================
|
||
* Purpose:
|
||
* Shared look for DataTables-based listing pages: toolbar, footer, sort
|
||
* arrows, last-column spacing, card-style rows (.app-table-card +
|
||
* tbody.app-table-body), and
|
||
* safer row action dropdowns.
|
||
*
|
||
* Load order:
|
||
* Include this file in the layout <head> after app-creative and DataTables
|
||
* Bootstrap CSS so these rules can override theme defaults.
|
||
*
|
||
* Related layout:
|
||
* app/Views/layout/header.php — <link> to this file
|
||
*
|
||
* Behaviour notes (why some issues happened):
|
||
* - Toolbar: pages that used position:absolute on .dataTables_filter broke the
|
||
* flex row; we keep the filter in normal flow (see rules below).
|
||
* - Sort icons: theme used fixed vertical offsets; we use stacked triangles
|
||
* with top:50% for alignment with header text.
|
||
* - Action dropdowns: DataTables scrollX wraps the table in .dataTables_scrollBody
|
||
* with overflow:auto. Bootstrap’s dropdown (Popper) then uses a scroll
|
||
* boundary that can mis-place menus (often worse on the last row). Global
|
||
* JS in layout/footer.php sets Popper boundary and temporarily relaxes
|
||
* overflow while the menu is open — see comments there.
|
||
* =============================================================================
|
||
*/
|
||
|
||
/* -----------------------------------------------------------------------------
|
||
* SECTION: DataTables toolbar (first row inside .dataTables_wrapper)
|
||
* Search/filter left, export/buttons right, vertically centered.
|
||
* ----------------------------------------------------------------------------- */
|
||
div.dataTables_wrapper > div.row:first-of-type {
|
||
display: flex !important;
|
||
flex-wrap: wrap;
|
||
align-items: center !important;
|
||
justify-content: space-between !important;
|
||
gap: 0.15rem 0.25rem;
|
||
/* margin-left: 0 !important; */
|
||
/* margin-right: 0 !important; */
|
||
/* margin-bottom: 0.25rem !important; */
|
||
}
|
||
|
||
/* Match horizontal padding with Bootstrap columns */
|
||
div.dataTables_wrapper > div.row:first-of-type > [class*="col-"] {
|
||
padding-left: 4px;
|
||
padding-right: 4px;
|
||
}
|
||
|
||
/* Keep filter in document flow (overrides stray position:absolute in old views) */
|
||
div.dataTables_wrapper div.dataTables_filter {
|
||
position: relative !important;
|
||
float: none !important;
|
||
text-align: left !important;
|
||
margin-bottom: 0.35rem;
|
||
}
|
||
|
||
div.dataTables_wrapper .dt-buttons {
|
||
text-align: right !important;
|
||
float: none !important;
|
||
margin-bottom: 0.35rem;
|
||
}
|
||
|
||
div.dataTables_wrapper .datatable-search,
|
||
div.dataTables_wrapper .datatable-buttons {
|
||
flex: 0 1 auto;
|
||
}
|
||
|
||
/* Keep top controls on one line for desktop/tablet list pages */
|
||
@media (min-width: 768px) {
|
||
div.dataTables_wrapper > div.row:first-of-type {
|
||
flex-wrap: nowrap !important;
|
||
}
|
||
|
||
/* Legacy view-level CSS sets .dt-buttons.btn-group to grid; normalize */
|
||
div.dataTables_wrapper .dt-buttons.btn-group,
|
||
div.dataTables_wrapper .datatable-buttons.dt-buttons {
|
||
display: inline-flex !important;
|
||
flex-wrap: wrap;
|
||
align-items: center;
|
||
justify-content: flex-end;
|
||
gap: 0.4rem;
|
||
}
|
||
|
||
/* Prevent search area from consuming full row width */
|
||
div.dataTables_wrapper div.dataTables_filter {
|
||
margin-bottom: 0 !important;
|
||
}
|
||
|
||
div.dataTables_wrapper div.dataTables_filter label {
|
||
display: inline-flex !important;
|
||
align-items: center !important;
|
||
margin-bottom: 0 !important;
|
||
white-space: nowrap;
|
||
}
|
||
|
||
div.dataTables_wrapper .datatable-search-wrapper {
|
||
width: min(320px, 100%) !important;
|
||
}
|
||
}
|
||
|
||
/* Custom dom: d-flex justify-content-between (e.g. client_list, tpa_list) */
|
||
div.dataTables_wrapper .row .d-flex.justify-content-between {
|
||
width: 100%;
|
||
align-items: center !important;
|
||
}
|
||
|
||
/* -----------------------------------------------------------------------------
|
||
* SECTION: DataTables footer (last row — info, length, pagination)
|
||
* “Showing X to Y” left; “Show n entries” + pager right.
|
||
* ----------------------------------------------------------------------------- */
|
||
div.dataTables_wrapper > div.row:last-of-type {
|
||
display: flex !important;
|
||
flex-wrap: wrap;
|
||
align-items: center !important;
|
||
justify-content: space-between !important;
|
||
margin-top: 0.35rem !important;
|
||
margin-left: 0 !important;
|
||
margin-right: 0 !important;
|
||
}
|
||
|
||
/*
|
||
* Default Bootstrap/DataTables bottom row often puts length + paginate in the last
|
||
* grid column using floats; wide pagination then overlaps the word “entries”.
|
||
* Flex + gap keeps both visible on all listing pages.
|
||
*/
|
||
div.dataTables_wrapper > div.row:last-of-type > div[class*="col-"]:last-child:has(.dataTables_paginate),
|
||
div.dataTables_wrapper > div.row:last-child > div[class*="col-"]:last-child:has(.dataTables_paginate) {
|
||
display: flex !important;
|
||
flex-wrap: wrap;
|
||
align-items: center !important;
|
||
justify-content: flex-end !important;
|
||
gap: 0.5rem;
|
||
}
|
||
|
||
div.dataTables_wrapper div.dataTables_info {
|
||
padding-top: 0.5rem !important;
|
||
color: #333 !important;
|
||
font-weight: 500 !important;
|
||
}
|
||
|
||
div.dataTables_wrapper div.dataTables_length {
|
||
padding-top: 0 !important;
|
||
/* Keep “Show … entries” fully visible when pagination is wide (flex row must not shrink this) */
|
||
flex-shrink: 0 !important;
|
||
margin-right: 0.65rem !important;
|
||
overflow: visible !important;
|
||
}
|
||
|
||
div.dataTables_wrapper div.dataTables_length label {
|
||
display: inline-flex !important;
|
||
align-items: center !important;
|
||
gap: 0.35rem;
|
||
margin-bottom: 0 !important;
|
||
overflow: visible !important;
|
||
/* Views set height: 21px which can clip label text */
|
||
height: auto !important;
|
||
min-height: 0 !important;
|
||
}
|
||
|
||
/* Length “entries” dropdown — light panel */
|
||
div.dataTables_wrapper div.dataTables_length select {
|
||
/* background-color: #e0f7fa !important; */
|
||
border: 1px solid #b2ebf2 !important;
|
||
border-radius: 8px !important;
|
||
padding: 0.2rem 1.75rem 0.2rem 0.5rem !important;
|
||
font-weight: 500 !important;
|
||
color: #333 !important;
|
||
}
|
||
|
||
div.dataTables_wrapper div.dataTables_paginate {
|
||
text-align: right !important;
|
||
padding-top: 0 !important;
|
||
flex-shrink: 1 !important;
|
||
min-width: 0 !important;
|
||
}
|
||
|
||
div.dataTables_wrapper .dataTables_paginate ul.pagination {
|
||
justify-content: flex-end !important;
|
||
align-items: center !important;
|
||
flex-wrap: wrap;
|
||
margin-bottom: 0 !important;
|
||
}
|
||
|
||
/* Extra gap between “entries” and pager when both sit in a flex row (custom dom: …<'me-2'l>p…) */
|
||
div.dataTables_wrapper > div.row:last-of-type .d-flex.align-items-center,
|
||
div.dataTables_wrapper > div.row:last-child .d-flex.align-items-center {
|
||
gap: 0.5rem;
|
||
flex-wrap: wrap;
|
||
}
|
||
|
||
/* Length is often wrapped in .me-2 — that wrapper was shrinking and clipping “entries” */
|
||
div.dataTables_wrapper > div.row:last-of-type .d-flex > .me-2,
|
||
div.dataTables_wrapper > div.row:last-child .d-flex > .me-2 {
|
||
flex-shrink: 0 !important;
|
||
}
|
||
|
||
|
||
/* Inactive numbered links */
|
||
div.dataTables_wrapper .dataTables_paginate .page-item:not(.active):not(.previous):not(.next) .page-link {
|
||
background: transparent !important;
|
||
border: none !important;
|
||
color: #333 !important;
|
||
}
|
||
|
||
/* Previous / Next — shared box; arrows centered via ::before (absolute + translate) */
|
||
div.dataTables_wrapper .dataTables_paginate .page-item.previous,
|
||
div.dataTables_wrapper .dataTables_paginate .page-item.next {
|
||
display: inline-flex !important;
|
||
align-items: center !important;
|
||
align-self: center !important;
|
||
}
|
||
|
||
div.dataTables_wrapper .dataTables_paginate .page-item.previous .page-link,
|
||
div.dataTables_wrapper .dataTables_paginate .page-item.next .page-link {
|
||
border-radius: 13px !important;
|
||
border: none !important;
|
||
box-shadow: none !important;
|
||
outline: none !important;
|
||
position: relative !important;
|
||
/* Hide DataTables “Previous/Next” text; icon is ::before only */
|
||
font-size: 0 !important;
|
||
line-height: 0 !important;
|
||
color: transparent !important;
|
||
overflow: hidden !important;
|
||
min-width: 32px !important;
|
||
width: 32px !important;
|
||
min-height: 2.25rem !important;
|
||
padding: 0 !important;
|
||
display: inline-flex !important;
|
||
align-items: center !important;
|
||
justify-content: center !important;
|
||
}
|
||
|
||
div.dataTables_wrapper .dataTables_paginate .page-item.previous:not(.disabled) .page-link,
|
||
div.dataTables_wrapper .dataTables_paginate .page-item.next:not(.disabled) .page-link {
|
||
background-color: #ffffff !important;
|
||
cursor: pointer !important;
|
||
pointer-events: auto !important;
|
||
}
|
||
|
||
/* First page / last page / single page: Bootstrap + DataTables add .disabled on the <li> */
|
||
div.dataTables_wrapper .dataTables_paginate .page-item.previous.disabled .page-link,
|
||
div.dataTables_wrapper .dataTables_paginate .page-item.next.disabled .page-link {
|
||
background-color: #ffffff !important;
|
||
cursor: not-allowed !important;
|
||
pointer-events: none !important;
|
||
opacity: 1 !important;
|
||
}
|
||
|
||
div.dataTables_wrapper .dataTables_paginate .page-item.previous .page-link::before,
|
||
div.dataTables_wrapper .dataTables_paginate .page-item.next .page-link::before {
|
||
content: "";
|
||
position: absolute !important;
|
||
left: 50% !important;
|
||
top: 50% !important;
|
||
transform: translate(-50%, -50%) !important;
|
||
text-indent: 0 !important;
|
||
line-height: 1 !important;
|
||
font-size: 12px !important;
|
||
font-family: inherit !important;
|
||
display: block !important;
|
||
margin: 0 !important;
|
||
}
|
||
|
||
div.dataTables_wrapper .dataTables_paginate .page-item.previous:not(.disabled) .page-link::before {
|
||
content: "◄";
|
||
color: #333333;
|
||
}
|
||
|
||
div.dataTables_wrapper .dataTables_paginate .page-item.next:not(.disabled) .page-link::before {
|
||
content: "►";
|
||
color: #333333;
|
||
}
|
||
|
||
div.dataTables_wrapper .dataTables_paginate .page-item.previous.disabled .page-link::before {
|
||
content: "◄";
|
||
color: #adb5bd !important;
|
||
}
|
||
|
||
div.dataTables_wrapper .dataTables_paginate .page-item.next.disabled .page-link::before {
|
||
content: "►";
|
||
color: #adb5bd !important;
|
||
}
|
||
|
||
/* DataTables markup variant without .page-item/.page-link */
|
||
div.dataTables_wrapper .dataTables_paginate .paginate_button.previous,
|
||
div.dataTables_wrapper .dataTables_paginate .paginate_button.next {
|
||
border-radius: 13px !important;
|
||
background-color: #F5FFFF !important;
|
||
border: none !important;
|
||
box-shadow: none !important;
|
||
outline: none !important;
|
||
font-size: 0 !important;
|
||
line-height: 0 !important;
|
||
color: transparent !important;
|
||
position: relative !important;
|
||
overflow: hidden !important;
|
||
min-width: 32px !important;
|
||
width: 32px !important;
|
||
min-height: 2.25rem !important;
|
||
padding: 0 !important;
|
||
display: inline-flex !important;
|
||
align-items: center !important;
|
||
justify-content: center !important;
|
||
}
|
||
|
||
div.dataTables_wrapper .dataTables_paginate .paginate_button.previous:not(.disabled),
|
||
div.dataTables_wrapper .dataTables_paginate .paginate_button.next:not(.disabled) {
|
||
background-color: #ffffff !important;
|
||
cursor: pointer !important;
|
||
}
|
||
|
||
div.dataTables_wrapper .dataTables_paginate .paginate_button.previous.disabled,
|
||
div.dataTables_wrapper .dataTables_paginate .paginate_button.next.disabled {
|
||
background-color: #ffffff !important;
|
||
cursor: not-allowed !important;
|
||
pointer-events: none !important;
|
||
opacity: 1 !important;
|
||
}
|
||
|
||
div.dataTables_wrapper .dataTables_paginate .paginate_button.previous::before,
|
||
div.dataTables_wrapper .dataTables_paginate .paginate_button.next::before {
|
||
position: absolute !important;
|
||
left: 50% !important;
|
||
top: 50% !important;
|
||
transform: translate(-50%, -50%) !important;
|
||
line-height: 1 !important;
|
||
font-size: 12px !important;
|
||
display: block !important;
|
||
margin: 0 !important;
|
||
}
|
||
|
||
div.dataTables_wrapper .dataTables_paginate .paginate_button.previous:not(.disabled)::before {
|
||
content: "◄";
|
||
color: #333333;
|
||
}
|
||
|
||
div.dataTables_wrapper .dataTables_paginate .paginate_button.next:not(.disabled)::before {
|
||
content: "►";
|
||
color: #333333;
|
||
}
|
||
|
||
div.dataTables_wrapper .dataTables_paginate .paginate_button.previous.disabled::before {
|
||
content: "◄";
|
||
color: #adb5bd !important;
|
||
}
|
||
|
||
div.dataTables_wrapper .dataTables_paginate .paginate_button.next.disabled::before {
|
||
content: "►";
|
||
color: #adb5bd !important;
|
||
}
|
||
|
||
/* Bootstrap nested markup: show arrow only on .page-link (avoid duplicate icon) */
|
||
div.dataTables_wrapper .dataTables_paginate li.paginate_button.previous::before,
|
||
div.dataTables_wrapper .dataTables_paginate li.paginate_button.next::before {
|
||
content: none !important;
|
||
}
|
||
|
||
/* -----------------------------------------------------------------------------
|
||
* SECTION: Header cells — vertical alignment for label + sort icons
|
||
* ----------------------------------------------------------------------------- */
|
||
table.dataTable thead > tr > th {
|
||
vertical-align: middle !important;
|
||
}
|
||
|
||
/* Optional wrapper used in some views — keep label from colliding with sort */
|
||
table.dataTable thead th .column-header {
|
||
display: inline-block;
|
||
vertical-align: middle;
|
||
margin-right: 0;
|
||
max-width: calc(100% - 40px);
|
||
}
|
||
|
||
/* -----------------------------------------------------------------------------
|
||
* SECTION: Last column — extra right inset (header sort + row actions)
|
||
* Rounded teal header and “…” buttons were flush to the edge; this adds
|
||
* breathing room on all listing tables using .dataTable.
|
||
* ----------------------------------------------------------------------------- */
|
||
table.dataTable thead > tr > th:last-child,
|
||
table.dataTable tbody > tr > td:last-child {
|
||
padding-right: 1.35rem !important;
|
||
}
|
||
|
||
table.dataTable thead > tr > th:last-child {
|
||
text-align: left;
|
||
}
|
||
|
||
/*
|
||
* Action cells: only when the last column contains a Bootstrap dropdown (avoids
|
||
* affecting numeric/text-only last columns that are not row actions).
|
||
*/
|
||
table.dataTable tbody > tr > td:last-child:has(.dropdown) {
|
||
position: relative;
|
||
text-align: left;
|
||
}
|
||
|
||
table.dataTable tbody > tr > td:last-child:has(.dropdown) .btn-group.dropdown {
|
||
display: inline-flex;
|
||
justify-content: flex-start;
|
||
}
|
||
|
||
/* -----------------------------------------------------------------------------
|
||
* Action column — left-aligned “…” / dropdown (footer.js adds .table-action-cell)
|
||
* ----------------------------------------------------------------------------- */
|
||
table.dataTable tbody > tr > td.table-action-cell {
|
||
text-align: left !important;
|
||
vertical-align: middle !important;
|
||
}
|
||
|
||
table.dataTable tbody > tr > td.table-action-cell .btn-group.dropdown {
|
||
display: inline-flex !important;
|
||
justify-content: flex-start !important;
|
||
float: none !important;
|
||
margin-right: 0 !important; /* Prevent global dropdown margin shifting anchor */
|
||
}
|
||
|
||
table.dataTable tbody > tr > td:last-child.table-action-cell:has(.dropdown),
|
||
table.dataTable tbody > tr > td.table-action-cell:has(.dropdown) {
|
||
text-align: left !important;
|
||
}
|
||
|
||
table.dataTable tbody > tr > td:last-child.table-action-cell:has(.dropdown) .btn-group.dropdown {
|
||
justify-content: flex-start !important;
|
||
}
|
||
|
||
/* Dropdown menu stacks above row borders / scroll quirks */
|
||
div.dataTables_wrapper .dropdown-menu {
|
||
z-index: 1050;
|
||
}
|
||
|
||
/* Tbody row actions: static + optional .dropup from footer.js — menu stays inside .btn-group */
|
||
div.dataTables_wrapper table.dataTable tbody .btn-group.dropdown {
|
||
position: relative !important;
|
||
}
|
||
|
||
div.dataTables_wrapper table.dataTable tbody .btn-group.dropdown .dropdown-menu {
|
||
z-index: 1060;
|
||
}
|
||
|
||
/* If global boundary=window ever added .position-static to a row dropdown parent, the menu
|
||
loses its anchor; tbody row toggles use data-boundary="scrollParent" — this is a safety net. */
|
||
div.dataTables_wrapper table.dataTable tbody .btn-group.dropdown.position-static {
|
||
position: relative !important;
|
||
}
|
||
|
||
/* -----------------------------------------------------------------------------
|
||
* SECTION: Sort arrows — stacked triangles (neutral / asc / desc)
|
||
* ----------------------------------------------------------------------------- */
|
||
table.dataTable thead > tr > th.sorting,
|
||
table.dataTable thead > tr > th.sorting_asc,
|
||
table.dataTable thead > tr > th.sorting_desc,
|
||
table.dataTable thead > tr > th.sorting_asc_disabled,
|
||
table.dataTable thead > tr > th.sorting_desc_disabled {
|
||
position: relative !important;
|
||
/* Room for stacked sort triangles + gap before cell edge */
|
||
padding-right: 2.35rem !important;
|
||
}
|
||
|
||
/* Reset theme font icons to CSS triangles */
|
||
table.dataTable thead .sorting:before,
|
||
table.dataTable thead .sorting_asc:before,
|
||
table.dataTable thead .sorting_desc:before,
|
||
table.dataTable thead .sorting_asc_disabled:before,
|
||
table.dataTable thead .sorting_desc_disabled:before,
|
||
table.dataTable thead .sorting:after,
|
||
table.dataTable thead .sorting_asc:after,
|
||
table.dataTable thead .sorting_desc:after,
|
||
table.dataTable thead .sorting_asc_disabled:after,
|
||
table.dataTable thead .sorting_desc_disabled:after {
|
||
font-family: inherit !important;
|
||
font-size: 0 !important;
|
||
line-height: 0 !important;
|
||
width: 0 !important;
|
||
height: 0 !important;
|
||
border: none !important;
|
||
bottom: auto !important;
|
||
opacity: 1 !important;
|
||
}
|
||
|
||
/* Up triangle */
|
||
table.dataTable thead .sorting:before,
|
||
table.dataTable thead .sorting_asc:before,
|
||
table.dataTable thead .sorting_desc:before,
|
||
table.dataTable thead .sorting_asc_disabled:before,
|
||
table.dataTable thead .sorting_desc_disabled:before {
|
||
content: "" !important;
|
||
position: absolute;
|
||
right: 0.85rem !important;
|
||
left: auto !important;
|
||
top: 50% !important;
|
||
margin-top: -7px !important;
|
||
border-left: 4px solid transparent !important;
|
||
border-right: 4px solid transparent !important;
|
||
border-bottom: 5px solid rgba(178, 235, 242, 0.95) !important;
|
||
}
|
||
|
||
/* Down triangle */
|
||
table.dataTable thead .sorting:after,
|
||
table.dataTable thead .sorting_asc:after,
|
||
table.dataTable thead .sorting_desc:after,
|
||
table.dataTable thead .sorting_asc_disabled:after,
|
||
table.dataTable thead .sorting_desc_disabled:after {
|
||
content: "" !important;
|
||
position: absolute;
|
||
right: 0.85rem !important;
|
||
left: auto !important;
|
||
top: 50% !important;
|
||
margin-top: 0 !important;
|
||
border-left: 4px solid transparent !important;
|
||
border-right: 4px solid transparent !important;
|
||
border-top: 5px solid rgba(178, 235, 242, 0.95) !important;
|
||
}
|
||
|
||
/* Active: ascending — strong up arrow */
|
||
table.dataTable thead .sorting_asc:before {
|
||
border-bottom-color: #ffffff !important;
|
||
}
|
||
table.dataTable thead .sorting_asc:after {
|
||
border-top-color: rgba(255, 255, 255, 0.35) !important;
|
||
}
|
||
|
||
/* Active: descending — strong down arrow */
|
||
table.dataTable thead .sorting_desc:before {
|
||
border-bottom-color: rgba(255, 255, 255, 0.35) !important;
|
||
}
|
||
table.dataTable thead .sorting_desc:after {
|
||
border-top-color: #ffffff !important;
|
||
}
|
||
|
||
/* Sortable but not active */
|
||
table.dataTable thead .sorting:before,
|
||
table.dataTable thead .sorting:after {
|
||
border-bottom-color: rgba(178, 235, 242, 0.95) !important;
|
||
border-top-color: rgba(178, 235, 242, 0.95) !important;
|
||
}
|
||
|
||
/* Compact table variant */
|
||
table.dataTable.table-sm > thead > tr > th.sorting:before,
|
||
table.dataTable.table-sm > thead > tr > th.sorting_asc:before,
|
||
table.dataTable.table-sm > thead > tr > th.sorting_desc:before {
|
||
margin-top: -7px !important;
|
||
}
|
||
|
||
table.dataTable.table-sm > thead > tr > th.sorting:after,
|
||
table.dataTable.table-sm > thead > tr > th.sorting_asc:after,
|
||
table.dataTable.table-sm > thead > tr > th.sorting_desc:after {
|
||
margin-top: 0 !important;
|
||
}
|
||
|
||
/*
|
||
* Last header column only: sort triangles sit 2px from the inner right edge of
|
||
* the <th> (all listing pages). Matches product ask: fixed 2px gap vs. rounded edge.
|
||
*/
|
||
table.dataTable thead > tr > th:last-child.sorting:before,
|
||
table.dataTable thead > tr > th:last-child.sorting_asc:before,
|
||
table.dataTable thead > tr > th:last-child.sorting_desc:before,
|
||
table.dataTable thead > tr > th:last-child.sorting_asc_disabled:before,
|
||
table.dataTable thead > tr > th:last-child.sorting_desc_disabled:before,
|
||
table.dataTable thead > tr > th:last-child.sorting:after,
|
||
table.dataTable thead > tr > th:last-child.sorting_asc:after,
|
||
table.dataTable thead > tr > th:last-child.sorting_desc:after,
|
||
table.dataTable thead > tr > th:last-child.sorting_asc_disabled:after,
|
||
table.dataTable thead > tr > th:last-child.sorting_desc_disabled:after {
|
||
right: 0.65rem !important;
|
||
}
|
||
|
||
/* -----------------------------------------------------------------------------
|
||
* SECTION: Compact spacing mode for all listing tables
|
||
* Reduce extra white space around search/buttons/header/rows.
|
||
* ----------------------------------------------------------------------------- */
|
||
|
||
/* Search input compact height */
|
||
div.dataTables_wrapper .dataTables_filter input[type="search"] {
|
||
height: 34px !important;
|
||
min-height: 34px !important;
|
||
padding-top: 0.28rem !important;
|
||
padding-bottom: 0.28rem !important;
|
||
}
|
||
|
||
/* DataTables buttons compact */
|
||
div.dataTables_wrapper .dt-buttons .btn {
|
||
padding-top: 0.34rem !important;
|
||
padding-bottom: 0.34rem !important;
|
||
}
|
||
|
||
/* -----------------------------------------------------------------------------
|
||
* SECTION: Card-style listing rows
|
||
* Markup: <table class="app-table-card" data-custom-table-css="table">
|
||
* <tbody class="app-table-body">…</tbody>
|
||
*
|
||
* Why .app-table-card (not :has()):
|
||
* - :has() is unsupported in some environments; when invalid, the whole rule
|
||
* is dropped, so row gaps never apply.
|
||
* - dataTables.bootstrap4 sets table.dataTable { border-spacing: 0 }; we need
|
||
* a selector at least as specific as table.table.dataTable with !important.
|
||
* ----------------------------------------------------------------------------- */
|
||
table[data-custom-table-css="table"].app-table-card.table.dataTable,
|
||
table[data-custom-table-css="table"].app-table-card.table,
|
||
table[data-custom-table-css="second-table"].app-table-card.table.dataTable,
|
||
table[data-custom-table-css="second-table"].app-table-card.table {
|
||
border-collapse: separate !important;
|
||
border-spacing: 0 6px !important;
|
||
}
|
||
|
||
table[data-custom-table-css="table"].app-table-card thead tr th:first-child,
|
||
table[data-custom-table-css="second-table"].app-table-card thead tr th:first-child {
|
||
border-top-left-radius: 12px !important;
|
||
border-bottom-left-radius: 12px !important;
|
||
}
|
||
|
||
table[data-custom-table-css="table"].app-table-card thead tr th:last-child,
|
||
table[data-custom-table-css="second-table"].app-table-card thead tr th:last-child {
|
||
border-top-right-radius: 12px !important;
|
||
border-bottom-right-radius: 12px !important;
|
||
}
|
||
|
||
table[data-custom-table-css="table"].app-table-card tbody.app-table-body > tr > td,
|
||
table[data-custom-table-css="second-table"].app-table-card tbody.app-table-body > tr > td {
|
||
background-color: #ffffff !important;
|
||
border-style: solid !important;
|
||
border-color: #e8ecef !important;
|
||
border-width: 1px 0 !important;
|
||
vertical-align: middle !important;
|
||
transition: background-color 0.2s ease, border-color 0.2s ease;
|
||
}
|
||
|
||
table[data-custom-table-css="table"].app-table-card tbody.app-table-body > tr > td:first-child,
|
||
table[data-custom-table-css="second-table"].app-table-card tbody.app-table-body > tr > td:first-child {
|
||
border-left-width: 1px !important;
|
||
border-top-left-radius: 12px !important;
|
||
border-bottom-left-radius: 12px !important;
|
||
}
|
||
|
||
table[data-custom-table-css="table"].app-table-card tbody.app-table-body > tr > td:last-child,
|
||
table[data-custom-table-css="second-table"].app-table-card tbody.app-table-body > tr > td:last-child {
|
||
border-right-width: 1px !important;
|
||
border-top-right-radius: 12px !important;
|
||
border-bottom-right-radius: 12px !important;
|
||
}
|
||
|
||
table[data-custom-table-css="table"].app-table-card tbody.app-table-body > tr:hover > td,
|
||
table[data-custom-table-css="second-table"].app-table-card tbody.app-table-body > tr:hover > td {
|
||
background-color: #f0fafb !important;
|
||
border-color: #c5e6e8 !important;
|
||
}
|
||
|
||
/* Reduce header/body padding globally for listing tables */
|
||
/* table[data-custom-table-css="table"].dataTable thead th,
|
||
table[data-custom-table-css="second-table"].dataTable thead th {
|
||
padding-top: 10px !important;
|
||
padding-bottom: 10px !important; */
|
||
/* Match body cell horizontal inset so header labels line up with td text */
|
||
/* padding-left: 0.75rem !important;
|
||
padding-right: 0.75rem !important;
|
||
} */
|
||
|
||
table[data-custom-table-css="table"] tbody td,
|
||
table[data-custom-table-css="second-table"] tbody td {
|
||
padding-top: 8px !important;
|
||
padding-bottom: 8px !important;
|
||
padding-left: 0.75rem !important;
|
||
padding-right: 0.75rem !important;
|
||
}
|
||
|
||
/* Keep listing text in single line (requested no-wrap). */
|
||
div.dataTables_wrapper table.dataTable th,
|
||
div.dataTables_wrapper table.dataTable td {
|
||
white-space: nowrap !important;
|
||
}
|
||
|
||
/* Keep horizontal + vertical scrolling behavior consistent across list pages. */
|
||
div.dataTables_wrapper .dataTables_scrollHead,
|
||
div.dataTables_wrapper .dataTables_scrollBody {
|
||
width: 100% !important;
|
||
}
|
||
|
||
div.dataTables_wrapper .dataTables_scrollBody {
|
||
overflow-x: auto !important;
|
||
overflow-y: auto !important;
|
||
}
|
||
|
||
/*
|
||
* Bootstrap `.table-responsive` uses overflow-x: auto. Listing pages wrap the whole
|
||
* `.dataTables_wrapper` (toolbar + scrollX area + pagination) in it, so the same div
|
||
* gets a second horizontal scrollbar under the footer. Only `.dataTables_scrollBody`
|
||
* should scroll horizontally — turn off outer overflow when a DT wrapper is inside.
|
||
* Class is set from layout/footer.php on `init.dt`; `:has()` covers edge cases without JS.
|
||
*/
|
||
.table-responsive.nh-dt-no-outer-scroll,
|
||
.table-responsive:has(.dataTables_wrapper) {
|
||
overflow-x: visible !important;
|
||
-webkit-overflow-scrolling: auto;
|
||
}
|
||
|
||
div.dataTables_wrapper {
|
||
overflow-x: visible !important;
|
||
max-width: 100%;
|
||
}
|
||
|
||
/*
|
||
* DataTables — consistent minimum height on main app pages (≈10" laptops → large monitors).
|
||
* vmin tracks the smaller viewport edge; caps limit empty space on very large displays.
|
||
* Scroll split: min height on .dataTables_scroll / .dataTables_scrollBody.
|
||
* No scroll split: min height on wrapper only (avoids stacking min-heights with scroll region).
|
||
*/
|
||
.content-page div.dataTables_wrapper:not(:has(.dataTables_scroll)) {
|
||
min-height: clamp(18rem, 36vmin, 40rem);
|
||
}
|
||
|
||
.content-page div.dataTables_wrapper .dataTables_scroll {
|
||
min-height: clamp(16rem, 32vmin, 34rem);
|
||
}
|
||
|
||
.content-page div.dataTables_wrapper .dataTables_scrollBody {
|
||
min-height: clamp(14rem, 28vmin, 30rem);
|
||
}
|
||
|
||
/* Modals / overlays: do not reserve main-page list height */
|
||
.modal div.dataTables_wrapper,
|
||
.modal div.dataTables_wrapper .dataTables_scroll,
|
||
.modal div.dataTables_wrapper .dataTables_scrollBody,
|
||
#tpa_variation_modal div.dataTables_wrapper,
|
||
#tpa_variation_modal div.dataTables_wrapper .dataTables_scroll,
|
||
#tpa_variation_modal div.dataTables_wrapper .dataTables_scrollBody {
|
||
min-height: 0 !important;
|
||
}
|
||
|
||
/* Let the middle row shrink inside flex layouts so the wrapper doesn’t widen the page */
|
||
div.dataTables_wrapper > .row .dataTables_scroll {
|
||
max-width: 100%;
|
||
min-width: 0;
|
||
}
|
||
|
||
/* Reusable listing-table dropdown + footer spacing helpers */
|
||
div.dataTables_wrapper .dataTables_scroll {
|
||
margin-bottom: 10px;
|
||
}
|
||
|
||
div.dataTables_wrapper > .row:last-child {
|
||
clear: both;
|
||
position: relative;
|
||
}
|
||
|
||
div.dataTables_wrapper table.dataTable tbody tr.nh-force-dropup td.table-action-cell .btn-group.dropdown .dropdown-menu {
|
||
top: auto !important;
|
||
bottom: 100% !important;
|
||
margin-top: 0 !important;
|
||
margin-bottom: 0.15rem !important;
|
||
}
|
||
|
||
div.dataTables_wrapper table.dataTable tbody td.table-action-cell .dropdown-menu {
|
||
background-color: #ffffff !important;
|
||
opacity: 1 !important;
|
||
border: 1px solid rgba(0, 0, 0, 0.12) !important;
|
||
box-shadow: 0 8px 16px rgba(0, 0, 0, 0.12) !important;
|
||
z-index: 1080 !important;
|
||
max-height: none !important;
|
||
overflow-y: visible !important;
|
||
overflow-x: visible !important;
|
||
}
|
||
|
||
div.dataTables_wrapper table.dataTable tbody td.table-action-cell .dropdown-menu .dropdown-item {
|
||
background-color: #ffffff !important;
|
||
}
|
||
|
||
div.dataTables_wrapper table.dataTable tbody td.table-action-cell .dropdown-menu .dropdown-item:hover {
|
||
background-color: #f8f9fa !important;
|
||
}
|
||
|
||
/* Row action menu: reusable click-to-open menu for list pages */
|
||
table.nh-row-action-table tbody td.table-action-cell .action-menu-toggle {
|
||
border: none !important;
|
||
background: transparent !important;
|
||
padding: 2px 8px !important;
|
||
color: #7a7a7a !important;
|
||
box-shadow: none !important;
|
||
}
|
||
|
||
table.nh-row-action-table tbody td.table-action-cell .action-menu-toggle:hover,
|
||
table.nh-row-action-table tbody td.table-action-cell .action-menu-toggle:focus {
|
||
background: #f3f6f9 !important;
|
||
color: #495057 !important;
|
||
}
|
||
|
||
table.nh-row-action-table tbody td.table-action-cell .action-menu-toggle i {
|
||
font-size: 18px;
|
||
line-height: 1;
|
||
}
|
||
|
||
table.nh-row-action-table tbody .nh-row-action-menu {
|
||
position: fixed !important;
|
||
min-width: 190px;
|
||
display: none;
|
||
z-index: 1085 !important;
|
||
transform: none !important;
|
||
}
|
||
|
||
table.nh-row-action-table tbody .nh-row-action-menu.show {
|
||
display: block !important;
|
||
bottom: auto !important;
|
||
}
|
||
|
||
/* Force downward opening for custom row-action menu, even if legacy dropup classes exist */
|
||
div.dataTables_wrapper table.nh-row-action-table tbody tr.nh-force-dropup td.table-action-cell .btn-group.dropdown .nh-row-action-menu,
|
||
div.dataTables_wrapper table.nh-row-action-table tbody td.table-action-cell .btn-group.dropdown.dropup .nh-row-action-menu,
|
||
div.dataTables_wrapper table.nh-row-action-table tbody td.table-action-cell .dropup .nh-row-action-menu {
|
||
bottom: auto !important;
|
||
margin-bottom: 0 !important;
|
||
}
|
||
|
||
|
||
|
||
/* -----------------------------------------------------------------------------
|
||
* SECTION: Small screens — stack/center DataTables controls
|
||
* ----------------------------------------------------------------------------- */
|
||
@media (max-width: 767.98px) {
|
||
div.dataTables_wrapper div.dataTables_filter,
|
||
div.dataTables_wrapper div.dataTables_length,
|
||
div.dataTables_wrapper div.dataTables_info,
|
||
div.dataTables_wrapper div.dataTables_paginate {
|
||
text-align: center !important;
|
||
}
|
||
div.dataTables_wrapper .dataTables_paginate ul.pagination {
|
||
justify-content: center !important;
|
||
}
|
||
}
|
||
|
||
/* ============================================================================
|
||
* Last column sort: enough right padding so triangles are not flush to edge
|
||
* (still respects th:last-child extra inset from “last column” section above).
|
||
* ============================================================================ */
|
||
table.dataTable thead > tr > th.sorting:last-child,
|
||
table.dataTable thead > tr > th.sorting_asc:last-child,
|
||
table.dataTable thead > tr > th.sorting_desc:last-child,
|
||
table.dataTable thead > tr > th.sorting_asc_disabled:last-child,
|
||
table.dataTable thead > tr > th.sorting_desc_disabled:last-child {
|
||
padding-right: 2.35rem !important;
|
||
}
|
||
|
||
table.dataTable thead > tr > th.sorting:last-child:before,
|
||
table.dataTable thead > tr > th.sorting_asc:last-child:before,
|
||
table.dataTable thead > tr > th.sorting_desc:last-child:before,
|
||
table.dataTable thead > tr > th.sorting_asc_disabled:last-child:before,
|
||
table.dataTable thead > tr > th.sorting_desc_disabled:last-child:before,
|
||
table.dataTable thead > tr > th.sorting:last-child:after,
|
||
table.dataTable thead > tr > th.sorting_asc:last-child:after,
|
||
table.dataTable thead > tr > th.sorting_desc:last-child:after,
|
||
table.dataTable thead > tr > th.sorting_asc_disabled:last-child:after,
|
||
table.dataTable thead > tr > th.sorting_desc_disabled:last-child:after {
|
||
right: 0.65rem !important;
|
||
} |