Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
134 changes: 99 additions & 35 deletions app/assets/stylesheets/wigu/active_admin_theme.scss
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,50 @@ $skinBorderRadius: 4px!default;
$skinBorderWindowColor: #e6e9ee!default;
$skinTablePadding: 10px!default;

// Header menu colors. Defaults follow $skinMainSecondColor, so a project that
// overrides it still gets the menu following that accent. Every colour here has
// a matching text colour, otherwise a light value would be unreadable.
$skinMenuPillColor: $skinMainSecondColor!default; // top-level current/hover pill
$skinMenuTextColor: #ffffff!default; // dropdown item text, hover/current included
// Follows the dropdown text rather than defaulting to white on its own: a
// project that light-themes the menu sets one variable, not two.
$skinMenuPillTextColor: $skinMenuTextColor!default; // text on that pill
$skinMenuPanelColor: $skinMainSecondColor!default; // dropdown panel bg + hover "bridge" border
$skinMenuItemHoverColor: transparent!default; // dropdown item hover/current bg

// Header / menu sizing. NOTE: not a no-op refactor — dropdown item height and
// dropdown width change for every project, configured or not. Header padding
// keeps its previous asymmetric values, so the header itself does not move.
$skinMenuFontSize: 1em!default; // top-level tab text size (does not cascade into dropdowns)
$skinMenuItemPaddingY: 8px!default; // dropdown item top/bottom padding (was 6px/4px + a 7px border)
$skinMenuItemLineHeight: 1.5!default; // dropdown item line-height
$skinMenuPanelMaxWidth: 260px!default; // dropdown panel ceiling; longer labels wrap instead of leaving the viewport
$skinHeaderPaddingTop: 5px!default; // header top padding (base value, kept so the header does not shift)
$skinHeaderPaddingBottom: 9px!default; // header bottom padding
$skinHeaderLogoMaxHeight: none!default; // cap the site_title logo image height

// Title bar
$skinTitleBarColor: lighten($skinMainFirstColor, 8%)!default;
$skinTitleBarBorderColor: $skinMainSecondColor!default;
$skinTitleBarBorderWidth: 3px!default;
$skinTitleBarButtonPaddingY: 10px!default; // action button vertical padding
$skinTitleBarButtonPaddingX: 20px!default; // action button horizontal padding

// A wrong-typed override is legal SassScript, so it compiles without a word and
// emits CSS the browser drops — `border-bottom: none solid #5ea3d3`,
// `padding: 10 12px`. The rule silently vanishes and ActiveAdmin's own value
// reappears. Fail the build with a readable message instead.
@each $name, $value in (
skinBorderRadius: $skinBorderRadius,
skinTablePadding: $skinTablePadding
skinTablePadding: $skinTablePadding,
skinMenuFontSize: $skinMenuFontSize,
skinMenuItemPaddingY: $skinMenuItemPaddingY,
skinMenuPanelMaxWidth: $skinMenuPanelMaxWidth,
skinHeaderPaddingTop: $skinHeaderPaddingTop,
skinHeaderPaddingBottom: $skinHeaderPaddingBottom,
skinTitleBarBorderWidth: $skinTitleBarBorderWidth,
skinTitleBarButtonPaddingY: $skinTitleBarButtonPaddingY,
skinTitleBarButtonPaddingX: $skinTitleBarButtonPaddingX
) {
@if type-of($value) != number or (unitless($value) and $value != 0) {
@error "$#{$name} must be a length with a unit (e.g. 10px), got `#{$value}`.";
Expand All @@ -21,7 +58,14 @@ $skinTablePadding: 10px!default;
@each $name, $value in (
skinMainFirstColor: $skinMainFirstColor,
skinMainSecondColor: $skinMainSecondColor,
skinBorderWindowColor: $skinBorderWindowColor
skinBorderWindowColor: $skinBorderWindowColor,
skinMenuPillColor: $skinMenuPillColor,
skinMenuPillTextColor: $skinMenuPillTextColor,
skinMenuPanelColor: $skinMenuPanelColor,
skinMenuItemHoverColor: $skinMenuItemHoverColor,
skinMenuTextColor: $skinMenuTextColor,
skinTitleBarColor: $skinTitleBarColor,
skinTitleBarBorderColor: $skinTitleBarBorderColor
) {
@if type-of($value) != color {
@error "$#{$name} must be a color (use `transparent`, not `none`), got `#{$value}`.";
Expand Down Expand Up @@ -80,52 +124,87 @@ body.active_admin {
#header {
background-color: $skinMainFirstColor;
border-bottom: 1px solid lighten( $skinMainFirstColor, 15% )!important;
padding-bottom: 9px;
padding-top: $skinHeaderPaddingTop;
padding-bottom: $skinHeaderPaddingBottom;
border: none;
text-shadow: none;
background-image: none;
h1.site_title {
color: $skinMainSecondColor;
font-size: 16px;
img {
max-height: $skinHeaderLogoMaxHeight;
}
}
a, a:link {
color: #ffffff;
}
ul.tabs > li > a {
color: #ffffff;
// On the anchor, not the li, so the dropdown subtree does not inherit it.
font-size: $skinMenuFontSize;
@include rounded($skinBorderRadius);
padding: 6px 10px 6px 10px;
}
ul.tabs > li.current > a, ul.tabs > li:hover > a {
background-color: $skinMainSecondColor;
background-color: $skinMenuPillColor;
color: $skinMenuPillTextColor;
}
ul.tabs {
li.has_nested {
a {
// `> a` only: leaf items need no room for the submenu arrow.
> a {
padding-right: 20px;
}
ul {
background-color: $skinMainSecondColor;
@include rounded($skinBorderRadius);
background-color: $skinMenuPanelColor;
@include rounded-all(0, $skinBorderRadius, $skinBorderRadius, $skinBorderRadius);
// Size to content instead of the base's max-width: calc(100% + 20px),
// which wraps long labels onto a second line — but keep a ceiling, or
// a long label pushes the panel out of the viewport where the :hover
// chain cannot follow it. Past the ceiling, labels wrap as before.
// Known limit: a depth-2 flyout under a right-edge tab can still leave
// a 1280px viewport — it sits at left:100% of an already-offset panel,
// and CSS cannot see the distance to the viewport edge. ActiveAdmin's
// own 175px panels already land within 5px of the edge there, so any
// widening inherits this. A full fix needs JS that flips the flyout to
// `right:100%`, or CSS anchor positioning once it is baseline.
width: max-content;
max-width: $skinMenuPanelMaxWidth;
overflow-wrap: break-word;
li > a {
padding-left: 15px;
color: $skinMenuTextColor;
line-height: $skinMenuItemLineHeight;
padding-top: $skinMenuItemPaddingY;
padding-bottom: $skinMenuItemPaddingY;
}
li.current > a::before, li:hover > a::before {
li:hover > a, li.current > a, li > a:focus {
background-color: $skinMenuItemHoverColor;
}
li.current > a::before, li:hover > a::before, li > a:focus::before {
content: '';
display: block;
width: 7px;
height: 4px;
position: absolute;
top: 12px;
top: 50%;
left: 4px;
background: transparent url($menu-arrow-dark-icon-url) no-repeat 0 0;
transform: rotate(-90deg);
// currentColor, so the marker follows $skinMenuTextColor instead of
// a fixed-palette PNG that only reads against the default panel.
border: 3px solid transparent;
border-left-color: currentColor;
margin-top: -3px;
}
}
}
li.has_nested:hover {
a {
border-bottom: 7px solid $skinMainSecondColor;
// `> li.has_nested` + `> a` so the "bridge" border is added only to a
// hovered TOP-LEVEL menu item (bridging its pill to the dropdown). Without
// the `>`, nested has_nested items (e.g. System > Components) also got the
// border, which pushed the next dropdown item down when their submenu
// opened. 5px to match the base's `ul { margin-top: 5px }` gap, and square
// off the corners that face the panel so the header does not show through.
> li.has_nested:hover {
> a {
@include rounded-top($skinBorderRadius);
border-bottom: 5px solid $skinMenuPanelColor;
}
}
}
Expand All @@ -134,9 +213,9 @@ body.active_admin {
background-image: none;
border: none;
box-shadow: none;
background-color: lighten( $skinMainFirstColor, 8% );
background-color: $skinTitleBarColor;
border: none;
border-bottom: 3px solid $skinMainSecondColor;
border-bottom: $skinTitleBarBorderWidth solid $skinTitleBarBorderColor;
#titlebar_left {
span.breadcrumb {
font-size: 12px;
Expand All @@ -160,7 +239,7 @@ body.active_admin {
@include rounded($skinBorderRadius);
background-color: $skinMainSecondColor;
border: none;
padding: 10px 20px;
padding: $skinTitleBarButtonPaddingY $skinTitleBarButtonPaddingX;
color: #ffffff;
font-weight: 600;
&:hover {
Expand Down Expand Up @@ -193,21 +272,6 @@ body.active_admin {
}
}
}
div.batch_actions_selector {
a {
background-image: none;
border: none;
box-shadow: none;
background-color: $skinMainSecondColor;
@include rounded($skinBorderRadius);
border: none;
padding: 10px 20px;
color: #ffffff;
&:hover {
background-color: lighten( $skinMainSecondColor, 5% );
}
}
}
}
}
.flashes {
Expand Down
23 changes: 20 additions & 3 deletions test/css_check.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,23 @@ module CssCheck
"dark chrome" => '$skinMainFirstColor: #111418; $skinBorderWindowColor: #b8babe;',
"square + wide" => '$skinBorderRadius: 0; $skinTablePadding: 14px;',
"rem radius" => '$skinBorderRadius: 0.25rem;',
"light menu" => '$skinMenuPanelColor: #ffffff; $skinMenuTextColor: #333333;
$skinMenuPillColor: #f0f0f0; $skinMenuPillTextColor: #222222;',
"dark menu" => '$skinMenuPanelColor: #222222; $skinMenuItemHoverColor: #3a3a3a;',
"roomy menu" => '$skinMenuFontSize: 1.6em; $skinMenuItemPaddingY: 12px;',
}.freeze

# Wrong-typed overrides. All of these are legal SassScript, so without the
# guards in the theme they compile silently and emit declarations the browser
# drops — the rule simply vanishes and ActiveAdmin's own value reappears, with
# nothing in the build output to say why.
BAD = {
"$skinBorderRadius without a unit" => '$skinBorderRadius: 4;',
"$skinTablePadding: none" => '$skinTablePadding: none;',
"$skinBorderWindowColor: none" => '$skinBorderWindowColor: none;',
"$skinBorderRadius without a unit" => '$skinBorderRadius: 4;',
"$skinTablePadding: none" => '$skinTablePadding: none;',
"$skinBorderWindowColor: none" => '$skinBorderWindowColor: none;',
"$skinMenuItemPaddingY without a unit" => '$skinMenuItemPaddingY: 8;',
"$skinMenuItemHoverColor: none" => '$skinMenuItemHoverColor: none;',
"$skinTitleBarBorderWidth: none" => '$skinTitleBarBorderWidth: none;',
}.freeze

def self.load_paths
Expand Down Expand Up @@ -61,6 +68,16 @@ def self.run
# expected — the theme's type guards caught it
end

# The header menu's text colours must follow the variables. A hard-coded
# white that out-specifies $skinMenuTextColor is invisible on a light panel,
# which is the whole point of being able to set the panel colour.
menu = compile(GOOD["light menu"]).scan(/^[^{}]*#wrapper #header ul\.tabs[^{}]*\{[^}]*\}/m).join("\n")
whites = menu.scan(/^\s*color:\s*(?:#f{3,6}|white)\s*;/i)
unless whites.empty?
failures << "light menu: #{whites.size} hard-coded white colour(s) left in the header menu; " \
"they out-specify $skinMenuTextColor and render invisible on a light panel"
end

if failures.empty?
puts "css_check: #{GOOD.size} overrides compile clean, #{BAD.size} bad ones rejected"
else
Expand Down
Loading