Skip to content

Commit

Permalink
Add a compact nested element style
Browse files Browse the repository at this point in the history
This compact element is great for single content elements (like pictures in a gallery). It uses the half width of the normal element and has an overall densed style to safe space in elements with lots of nested elements.

Define a compact element by adding `compact: true` to its element definition.
  • Loading branch information
tvdeyen committed Feb 28, 2018
1 parent fdd9875 commit ec90ee2
Show file tree
Hide file tree
Showing 6 changed files with 146 additions and 10 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

## 4.1.0 (unreleased)

* Add a compact nested element style [#1357](https://github.com/AlchemyCMS/alchemy_cms/pull/1357) by [tvdeyen](https://github.com/tvdeyen)
* Replaces PNG icons with FontAwesome icon font [#1342](https://github.com/AlchemyCMS/alchemy_cms/pull/1342) by [tvdeyen](https://github.com/tvdeyen)
* Remove pleaseWait overlay from links with GET requests [#1343](https://github.com/AlchemyCMS/alchemy_cms/pull/1343) by [tvdeyen](https://github.com/tvdeyen)
* Removed fixed table headers from admin resource tables [#1339](https://github.com/AlchemyCMS/alchemy_cms/pull/1339) by [tvdeyen](https://github.com/tvdeyen)
Expand Down
7 changes: 6 additions & 1 deletion app/assets/javascripts/alchemy/alchemy.dragndrop.js.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ $.extend Alchemy,
opacity: 0.5
cursor: "move"
containment: $('#element_area')
tolerance: "intersect"
tolerance: "pointer"
update: (event, ui) ->
# This callback is called twice for both elements, the source and the receiving
# but, we only want to call ajax callback once on the receiving element.
Expand Down Expand Up @@ -63,13 +63,18 @@ $.extend Alchemy,
$this.sortable('option', 'connectWith', $dropzone)
$this.sortable('refresh')
$dropzone.css('minHeight', 36)
ui.item.addClass('dragged')
if ui.item.hasClass('compact')
ui.placeholder.addClass('compact').css
height: ui.item.outerHeight()
Alchemy.Tinymce.remove(ids)
return
stop: (event, ui) ->
ids = getTinymceIDs(ui)
name = ui.item.data('element-name')
$dropzone = $("[data-droppable-elements~='#{name}']")
$dropzone.css('minHeight', '')
ui.item.removeClass('dragged')
Alchemy.Tinymce.init(ids)
return

Expand Down
114 changes: 106 additions & 8 deletions app/assets/stylesheets/alchemy/elements.scss
Original file line number Diff line number Diff line change
Expand Up @@ -165,9 +165,12 @@

&.dragged {
border-style: dotted;
height: 36px;
overflow: hidden;

* { display: none }
&:not(.compact) {
height: 36px !important;
transition: height 0.2s;
}
}

&.with-contents, &.without-contents.not-nestable {
Expand Down Expand Up @@ -711,26 +714,121 @@ textarea.has_tinymce {
background-color: $medium-gray;

.expanded.element-editor > & {
padding: 16px 8px 8px;
padding: 8px 4px 4px;
}

.add-nestable-element-button {
width: calc(50% - 8px);
margin: 4px;
text-align: center;
}
}

.nested-elements {
display: flex;
flex-wrap: wrap;

.element-editor,
.droppable_element_placeholder {
width: calc(100% - 8px);
margin: 4px;

&.compact {
width: calc(50% - 8px);
}
}

.element-editor {
position: relative;

&.compact {
padding-bottom: 16px;
overflow: hidden;

.element-toolbar {
visibility: hidden;
position: absolute;
height: 35px;
padding: 2px 0;
opacity: 0;
z-index: 1;
border-bottom: 1px solid $medium-gray;
transition: all 0.2s;
}

.element-header:hover + .element-toolbar,
.element-toolbar:hover {
visibility: visible;
opacity: 1;
}

.element-footer {
position: absolute;
bottom: 0;
width: 100%;
margin-top: 0;
background-color: $light-gray;
transform: translate3d(0, 28px, 0);
transition: transform 0.2s;

&:hover {
transform: translate3d(0, 0, 0);
}

.button {
padding: 4px 8px;
}
}

.element-title {
max-width: 80%;
}

&:not(.folded) .ajax-folder,
.picture_tool {
display: none;
}

.element_tools {
display: flex;
width: 100%;
justify-content: space-between;
margin-left: 0;
}

.element-content {
padding: 4px 8px;
}

.button_with_label {
margin: 0 4px;
}

.content_editor,
.picture_thumbnail {
width: 100%;
}

.picture_thumbnail {
margin: 0;
}

.thumbnail_background {
height: 115px;
}
}
}

.element-header {
background-color: transparent;
}

.element-toolbar {
background-color: transparent;
width: 100%;
border-top: 1px solid $medium-gray;
}
}

.add-nestable-element-button {
margin-top: 0;
}

.essence_date--label {
position: absolute;
right: 5px;
Expand Down
1 change: 1 addition & 0 deletions app/helpers/alchemy/admin/elements_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ def element_editor_classes(element, local_assigns)
element.nestable_elements.any? ? 'nestable' : 'not-nestable',
element.taggable? ? 'taggable' : 'not-taggable',
element.folded ? 'folded' : 'expanded',
element.compact? ? 'compact' : nil,
local_assigns[:draggable] == false ? 'not-draggable' : 'draggable'
].join(' ')
end
Expand Down
8 changes: 7 additions & 1 deletion app/models/alchemy/element.rb
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ class Element < BaseRecord
"contents",
"hint",
"picture_gallery",
"taggable"
"taggable",
"compact"
].freeze

SKIPPED_ATTRIBUTES_ON_COPY = [
Expand Down Expand Up @@ -258,6 +259,11 @@ def expanded?
!folded?
end

# Defined as compact element?
def compact?
definition['compact'] == true
end

# The element's view partial is dependent from its name
#
# == Define elements
Expand Down
25 changes: 25 additions & 0 deletions spec/models/alchemy/element_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -701,6 +701,31 @@ module Alchemy
end
end

describe '#compact?' do
subject { element.compact? }

let(:element) { build(:alchemy_element) }

before do
expect(element).to receive(:definition) { definition }
end

context "definition has 'compact' key with true value" do
let(:definition) { {'compact' => true} }
it { is_expected.to be(true) }
end

context "definition has 'compact' key with foo value" do
let(:definition) { {'compact' => 'foo'} }
it { is_expected.to be(false) }
end

context "definition has no 'compact' key" do
let(:definition) { {'name' => 'article'} }
it { is_expected.to be(false) }
end
end

describe '#trash!' do
let(:element) { create(:alchemy_element) }

Expand Down

0 comments on commit ec90ee2

Please sign in to comment.