facades 0.1.0 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +1 -0
- data/.rbenv-gemsets +1 -0
- data/.rvmrc +1 -0
- data/.travis.yml +6 -0
- data/Gemfile +12 -0
- data/Guardfile +19 -0
- data/README.md +115 -101
- data/Rakefile +8 -0
- data/app/assets/javascripts/facades/debug/grid.js +0 -0
- data/app/helpers/facades_helper.rb +1 -0
- data/config.ru +7 -0
- data/facades.gemspec +9 -2
- data/lib/facades/helpers/layout.rb +36 -73
- data/lib/facades/helpers/navigation.rb +182 -110
- data/lib/facades/helpers/{elements.rb → notifications.rb} +9 -36
- data/lib/facades/helpers.rb +6 -17
- data/lib/facades/patterns/tabs.rb +75 -0
- data/lib/facades/patterns.rb +7 -0
- data/lib/facades/{sass_ext → sass_extensions}/color.rb +5 -13
- data/lib/facades/sass_extensions/conversions.rb +27 -0
- data/lib/facades/sass_extensions/functions.rb +84 -0
- data/lib/facades/sass_extensions/icons.rb +66 -0
- data/lib/facades/sass_extensions.rb +21 -0
- data/lib/facades/support/compass/project/MIT-LICENSE.txt +20 -0
- data/lib/facades/support/compass/project/humans.txt +8 -0
- data/lib/facades/support/compass/project/index.html +45 -0
- data/lib/facades/support/compass/project/manifest.rb +18 -0
- data/lib/facades/support/compass/project/robots.txt +4 -0
- data/lib/facades/support/compass.rb +9 -0
- data/lib/facades/support/rails.rb +12 -15
- data/lib/facades/support/simple_form.rb +32 -0
- data/lib/facades/version.rb +1 -1
- data/lib/facades.rb +21 -44
- data/spec/internal/app/helpers/application_helper.rb +3 -0
- data/spec/internal/app/views/navigation/_multi_list.html.erb +11 -0
- data/spec/internal/app/views/navigation/_multi_option_list.html.erb +14 -0
- data/spec/internal/app/views/navigation/_single_list.html.erb +9 -0
- data/spec/internal/config/database.yml +3 -0
- data/spec/internal/config/routes.rb +3 -0
- data/spec/internal/db/schema.rb +3 -0
- data/spec/internal/log/.gitignore +1 -0
- data/spec/internal/public/favicon.ico +0 -0
- data/spec/spec_helper.rb +16 -6
- data/spec/unit/helpers/layout_spec.rb +4 -0
- data/spec/unit/helpers/navigation_spec.rb +384 -0
- data/spec/unit/helpers/notifications_spec.rb +4 -0
- data/spec/unit/patterns/tabs_spec.rb +58 -0
- data/src/icons/facades.yml +105 -0
- data/src/icons/font-awesome.yml +210 -0
- data/src/scss/facades/_buttons.scss +10 -0
- data/src/scss/facades/_config.scss +99 -0
- data/src/scss/facades/_debug.scss +8 -0
- data/src/scss/facades/_forms.scss +228 -0
- data/src/scss/facades/_global.scss +104 -0
- data/src/scss/facades/_icons.scss +61 -0
- data/src/scss/facades/_mixins.scss +115 -0
- data/src/scss/facades/_mobile.scss +3 -0
- data/src/scss/facades/_setup.scss +191 -0
- data/src/scss/facades/_typography.scss +220 -0
- data/src/scss/facades/buttons/_glossy.scss +29 -0
- data/src/scss/facades/buttons/_gradient.scss +36 -0
- data/src/scss/facades/buttons/_shared.scss +33 -0
- data/src/scss/facades/buttons/_simple.scss +28 -0
- data/src/scss/facades/icons/_classes.scss +37 -0
- data/src/scss/facades/icons/_legacy.scss +27 -0
- data/src/scss/facades/layout/_lists.scss +43 -0
- data/src/scss/facades/mixins/_gradients.scss +30 -0
- data/src/scss/facades/mixins/_rhythm.scss +37 -0
- data/src/scss/facades/mobile/_buttons.scss +97 -0
- data/src/scss/facades/mobile/_config.scss +30 -0
- data/src/scss/facades/mobile/_global.scss +81 -0
- data/src/scss/facades/mobile/_mixins.scss +49 -0
- data/src/scss/facades/mobile/_setup.scss +50 -0
- data/src/scss/facades/mobile/patterns/_navbar.scss +21 -0
- data/src/scss/facades/mobile/patterns/_panel.scss +37 -0
- data/src/scss/facades/mobile/patterns/_stage.scss +20 -0
- data/src/scss/facades/mobile/patterns/_toolbar.scss +25 -0
- data/src/scss/facades/mobile/themes/_apple.scss +17 -0
- data/src/scss/facades/patterns/_labels.scss +50 -0
- data/src/scss/facades/patterns/_navbar.scss +4 -0
- data/src/scss/facades/patterns/_notifications.scss +82 -0
- data/src/scss/facades/patterns/_pagination.scss +4 -0
- data/src/scss/facades/patterns/_pills.scss +50 -0
- data/src/scss/facades/patterns/_tabs.scss +83 -0
- data/src/scss/facades/patterns/_twipsy.scss +84 -0
- data/src/scss/facades/typography/_tables.scss +95 -0
- metadata +201 -58
- data/app/views/facades/_pagination.html.erb +0 -20
- data/lib/facades/builders/form/base.rb +0 -212
- data/lib/facades/builders/form/elements.rb +0 -112
- data/lib/facades/builders/form/helper.rb +0 -29
- data/lib/facades/builders/form.rb +0 -22
- data/lib/facades/builders/sprite.rb +0 -50
- data/lib/facades/builders/table.rb +0 -76
- data/lib/facades/debug/html.rb +0 -6
- data/lib/facades/helpers/builders.rb +0 -24
- data/lib/facades/helpers/mobile.rb +0 -57
- data/lib/facades/helpers/pagination.rb +0 -83
- data/lib/facades/helpers/utility.rb +0 -31
- data/lib/facades/sass_ext/form_elements.rb +0 -52
- data/lib/facades/sass_ext/funcs.rb +0 -33
- data/lib/facades/sass_ext.rb +0 -14
- data/lib/facades/stylesheets/facades/_common.scss +0 -7
- data/lib/facades/stylesheets/facades/_css3.scss +0 -93
- data/lib/facades/stylesheets/facades/_layout.scss +0 -5
- data/lib/facades/stylesheets/facades/_normalize.scss +0 -5
- data/lib/facades/stylesheets/facades/_setup.scss +0 -104
- data/lib/facades/stylesheets/facades/_typography.scss +0 -2
- data/lib/facades/stylesheets/facades/_ui.scss +0 -3
- data/lib/facades/stylesheets/facades/_utilities.scss +0 -32
- data/lib/facades/stylesheets/facades/layout/_dropdown-list.scss +0 -7
- data/lib/facades/stylesheets/facades/layout/_forms.scss +0 -53
- data/lib/facades/stylesheets/facades/layout/_grid.scss +0 -49
- data/lib/facades/stylesheets/facades/layout/_responsive_grid.scss +0 -164
- data/lib/facades/stylesheets/facades/setup/_forms.scss +0 -284
- data/lib/facades/stylesheets/facades/setup/_ie.scss +0 -12
- data/lib/facades/stylesheets/facades/setup/_reset.scss +0 -255
- data/lib/facades/stylesheets/facades/typography/_baseline.scss +0 -91
- data/lib/facades/stylesheets/facades/typography/_lists.scss +0 -34
- data/lib/facades/stylesheets/facades/typography/_shadow.scss +0 -8
- data/lib/facades/stylesheets/facades/ui/_buttons.scss +0 -34
- data/lib/facades/stylesheets/facades/ui/_flash-messages.scss +0 -29
- data/lib/facades/stylesheets/facades/ui/_tabbed.scss +0 -5
- data/lib/facades/stylesheets/facades/ui/_tool-tip.scss +0 -44
- data/lib/facades/stylesheets/facades/utilities/_clearfix.scss +0 -20
- data/lib/facades/stylesheets/facades/utilities/_color.scss +0 -7
- data/lib/facades/stylesheets/facades/utilities/_cursors.scss +0 -4
- data/lib/facades/support/serve.rb +0 -17
- data/lib/facades/support/tipsy.rb +0 -17
- data/spec/facades/helpers/elements_spec.rb +0 -86
- data/spec/facades/helpers/layout_helpers_spec.rb +0 -5
- data/spec/facades/helpers/navigation_spec.rb +0 -107
@@ -1,136 +1,208 @@
|
|
1
1
|
module Facades
|
2
2
|
module Helpers
|
3
|
-
##
|
4
|
-
#
|
5
|
-
# Convenience helpers for building navigation lists, and defining 'on' states.
|
6
|
-
#
|
7
3
|
module Navigation
|
8
4
|
|
9
5
|
##
|
6
|
+
# Constructs a navigation list containing
|
7
|
+
# a variable number of list items and links.
|
10
8
|
#
|
11
|
-
|
12
|
-
|
13
|
-
# @param [String] text The text used within the link
|
14
|
-
# @param [String] path The url used as the link's +href+ attribute
|
15
|
-
# @param [Hash] attrs Hash of attributes to be applied to the link. This format is the same as Rail's +link_to+ helper
|
16
|
-
# @option attrs [String] :active_class The class to use if this link is 'active'. Defaults to "on"
|
17
|
-
# @option attrs [Proc] :proc A callback which, when called, determines the active state of the link
|
18
|
-
# @option attrs [Regex] :matcher A regular expression to be matched against +path+
|
19
|
-
# @param [Symbol] wrapper The html tag to be used as the wrapper. Defaults to +:li+
|
20
|
-
#
|
21
|
-
# @example Create a list item link to any page
|
22
|
-
# nav_link('Home Page', '/home') #=> <li><a href="/home">Home Page</a>
|
23
|
-
#
|
24
|
-
# @example 'Active state' functionality for the current page
|
25
|
-
# nav_link('Current Page', '/current_url') #=> <li class="on"><a href="/current_url" class="on">Current Page</a></li>
|
26
|
-
#
|
27
|
-
def nav_link(text, path, attrs = {}, wrapper = :li, &block)
|
28
|
-
|
29
|
-
if block_given?
|
30
|
-
return sub_nav_link(text, path, attrs, wrapper, :ol, &block)
|
31
|
-
end
|
32
|
-
|
33
|
-
link_attrs = update_link_attrs(path, attrs)
|
34
|
-
wrapper_attrs = link_attrs.delete(:wrapper)
|
35
|
-
child_link = link_to(text, path, link_attrs)
|
36
|
-
built = (wrapper === false ? child_link : content_tag(wrapper, child_link, wrapper_attrs))
|
37
|
-
built = built.html_safe if built.respond_to?(:html_safe)
|
38
|
-
built
|
9
|
+
def nav(options = {}, &block)
|
10
|
+
Navigator.new(self, options).render(&block)
|
39
11
|
end
|
40
|
-
alias :nav_link_to :nav_link
|
41
12
|
|
42
|
-
|
43
|
-
wrapper_attrs = attrs.delete(:wrapper)
|
44
|
-
link_attrs = update_link_attrs(path, attrs.merge(:wrapper => (attrs.delete(:item) || {}) ))
|
45
|
-
parent_link = nav_link_to(text, path, attrs, false)
|
46
|
-
child_links = content_tag(container, capture(&block), wrapper_attrs)
|
47
|
-
content_tag(wrapper, (parent_link << child_links), wrapper_attrs)
|
48
|
-
end
|
49
|
-
private :sub_nav_link
|
13
|
+
alias :navigation :nav
|
50
14
|
|
51
15
|
##
|
16
|
+
# Similar to link_to, but adds the class 'active' if the link's href is in an active state.
|
17
|
+
# If the options :proc, or :matcher is passed, they are used to determine active state. If not the current
|
18
|
+
# request.path is used.
|
52
19
|
#
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
# <ol>
|
70
|
-
# <li><a href="/home">Home Page</a>
|
71
|
-
# <ol>
|
72
|
-
# <li><a href="/about">Sub Page</a></li>
|
73
|
-
# </ol>
|
74
|
-
# </li>
|
75
|
-
# </ol>
|
76
|
-
#
|
77
|
-
def nav(container = :ol, html_attrs = {}, heading = nil, &block)
|
78
|
-
|
79
|
-
wrapper_attrs = html_attrs.delete(:wrapper) || {}
|
80
|
-
|
81
|
-
built = if Facades.enable_html5
|
82
|
-
inner = content_tag(container, capture(&block), wrapper_attrs)
|
83
|
-
inner = (content_tag(:h3, heading) << inner) unless heading.nil?
|
84
|
-
content_tag(:nav, html_attrs) do
|
85
|
-
inner
|
86
|
-
end
|
87
|
-
else
|
88
|
-
content_tag(container, capture(&block), html_attrs)
|
20
|
+
def nav_link(text, href, options = {})
|
21
|
+
options.merge!(:path => request.path)
|
22
|
+
wrapper = options.delete(:wrapper)
|
23
|
+
link = NavigationLink.new(text, href, options)
|
24
|
+
current = link.active?
|
25
|
+
link.options = Navigator.merge_html_classes('active', link.options) if current
|
26
|
+
|
27
|
+
if wrapper
|
28
|
+
if wrapper.is_a?(Hash)
|
29
|
+
wrap_attrs = wrapper
|
30
|
+
wrapper = wrap_attrs.delete(:tag) || :li
|
31
|
+
else
|
32
|
+
wrap_attrs = {}
|
33
|
+
end
|
34
|
+
wrap_attrs = Navigator.merge_html_classes('active', wrap_attrs) if current
|
35
|
+
return content_tag(wrapper, link_to(link.text, link.href, link.options), wrap_attrs)
|
89
36
|
end
|
90
|
-
built = built.html_safe if built.respond_to?(:html_safe)
|
91
|
-
built
|
92
37
|
|
38
|
+
link_to(link.text, link.href, link.options)
|
93
39
|
end
|
94
40
|
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
def update_link_attrs(path, attrs)
|
41
|
+
class Navigator
|
42
|
+
attr_reader :view, :path
|
43
|
+
attr_accessor :options, :nested, :links
|
99
44
|
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
wrapper_attrs = attrs.delete(:wrapper) || {}
|
105
|
-
wklasses = wrapper_attrs[:class].try(:split, ' ')
|
45
|
+
def initialize(tpl, options = {}, nested = false)
|
46
|
+
@view, @options, @nested, @links = tpl, options, nested, []
|
47
|
+
@path = view.request.path
|
48
|
+
end
|
106
49
|
|
107
|
-
|
108
|
-
wklasses ||= []
|
50
|
+
delegate :content_tag, :concat, :link_to, :to => :view
|
109
51
|
|
110
|
-
|
111
|
-
|
112
|
-
|
52
|
+
##
|
53
|
+
# Renders the resulting html list, wrapped in a <nav> tag.
|
54
|
+
#
|
55
|
+
def render(&block)
|
56
|
+
wrap_attrs = options.delete(:wrapper) || :ul
|
57
|
+
heading = options.delete(:heading)
|
58
|
+
|
59
|
+
unless wrap_attrs.is_a?(Hash)
|
60
|
+
wrapper = wrap_attrs
|
61
|
+
wrap_attrs = {}
|
62
|
+
else
|
63
|
+
wrapper = wrap_attrs.delete(:tag) || :ul
|
64
|
+
end
|
65
|
+
|
66
|
+
@wrapper_attrs = wrap_attrs
|
67
|
+
@wrapper = wrapper
|
68
|
+
|
69
|
+
output = content_tag(wrapper, view.capture(self, &block), options)
|
70
|
+
return output if nested?
|
71
|
+
|
72
|
+
if heading
|
73
|
+
heading = generate_heading(heading)
|
74
|
+
output = heading << output
|
75
|
+
end
|
76
|
+
content_tag(:nav, output, wrap_attrs)
|
77
|
+
|
78
|
+
end
|
113
79
|
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
80
|
+
##
|
81
|
+
# Constructs a link wrapped in a list item for use
|
82
|
+
# within a navigation list.
|
83
|
+
#
|
84
|
+
def link(text, href, link_opts = {}, &block)
|
85
|
+
|
86
|
+
wrap_attrs = link_opts.delete(:wrapper) || {}
|
87
|
+
link_opts.merge!(:path => path)
|
88
|
+
link = NavigationLink.new(text, href, link_opts)
|
89
|
+
links << link
|
90
|
+
|
91
|
+
if link.active?
|
92
|
+
wrap_attrs = merge_html_classes("active", wrap_attrs)
|
93
|
+
link.options = merge_html_classes("active", link.options)
|
94
|
+
end
|
95
|
+
|
96
|
+
if block_given?
|
97
|
+
subnav = Navigator.new(view, wrap_attrs, true)
|
98
|
+
inner = subnav.render(&block)
|
99
|
+
unless subnav.links.empty?
|
100
|
+
output = link_to(link.text, link.href, link.options) << inner
|
101
|
+
content_tag(:li, output, wrap_attrs)
|
102
|
+
else
|
103
|
+
content_tag(:li, link_to(link.text, link.href, link.options), wrap_attrs)
|
104
|
+
end
|
105
|
+
else
|
106
|
+
content_tag(:li, link_to(link.text, link.href, link.options), wrap_attrs)
|
107
|
+
end
|
119
108
|
end
|
120
109
|
|
121
|
-
|
122
|
-
|
123
|
-
|
110
|
+
class << self
|
111
|
+
|
112
|
+
##
|
113
|
+
# Takes an options array and adds any additional
|
114
|
+
# classes passed to args. If a :class key exists, it
|
115
|
+
# is updated. If not, it is added unless the result is
|
116
|
+
# an empty string.
|
117
|
+
#
|
118
|
+
def merge_html_classes(*args)
|
119
|
+
opts = args.extract_options!
|
120
|
+
klasses = (opts.delete(:class) || "").split(" ")
|
121
|
+
klasses = [klasses, args].flatten.compact.reject{ |c| c.to_s.blank? }.join(" ")
|
122
|
+
(klasses.blank? ? opts : opts.merge(:class => klasses))
|
123
|
+
end
|
124
|
+
|
124
125
|
end
|
126
|
+
|
127
|
+
private
|
125
128
|
|
126
|
-
|
127
|
-
|
129
|
+
##
|
130
|
+
# To be valid, a <nav> should have a heading of some sort.
|
131
|
+
# When passed via options, this generates the proper tag
|
132
|
+
#
|
133
|
+
def generate_heading(opts)
|
134
|
+
if opts.is_a?(Hash)
|
135
|
+
heading_tag = opts.delete(:tag)
|
136
|
+
heading_text = opts.delete(:text)
|
137
|
+
else
|
138
|
+
heading_text = opts
|
139
|
+
end
|
140
|
+
heading_tag ||= :h3
|
141
|
+
content_tag(heading_tag, heading_text)
|
142
|
+
end
|
143
|
+
|
144
|
+
def merge_html_classes(*args) #:nodoc:
|
145
|
+
Navigator.merge_html_classes(*args)
|
146
|
+
end
|
147
|
+
|
148
|
+
##
|
149
|
+
# Determines if the current navigation set
|
150
|
+
# is nested within another.
|
151
|
+
#
|
152
|
+
def nested?
|
153
|
+
@nested == true
|
154
|
+
end
|
128
155
|
|
129
|
-
attrs.merge!(:wrapper => wrapper_attrs)
|
130
|
-
attrs
|
131
156
|
end
|
132
|
-
|
133
|
-
|
157
|
+
|
158
|
+
class NavigationLink
|
159
|
+
attr_accessor :href, :text, :options
|
160
|
+
attr_reader :matcher
|
161
|
+
|
162
|
+
def initialize(text, href, options)
|
163
|
+
@href, @text, @options = href, text, options
|
164
|
+
@matcher = (options.delete(:proc) || options.delete(:matcher))
|
165
|
+
curr_path = options.delete(:path)
|
166
|
+
@matcher ||= curr_path
|
167
|
+
end
|
168
|
+
|
169
|
+
##
|
170
|
+
# Checks the link's href against either a proc,
|
171
|
+
# regexp, or current request.path depending on
|
172
|
+
# the options provided. Returns true if there is
|
173
|
+
# a match, false if not.
|
174
|
+
#
|
175
|
+
def active?
|
176
|
+
return matcher.call(href) if matcher.is_a?(Proc)
|
177
|
+
return ( (href =~ matcher).to_i >= 1 ) if matcher.is_a?(Regexp)
|
178
|
+
|
179
|
+
match_path = normalize_path(matcher)
|
180
|
+
href_path = normalize_path(href)
|
181
|
+
|
182
|
+
return false if href_path.blank? && !match_path.blank?
|
183
|
+
|
184
|
+
if key = options.delete(:match)
|
185
|
+
path_matcher = case key.to_s
|
186
|
+
when 'exact' then match_path.match(%r{^/?#{href_path}/?$}i)
|
187
|
+
when 'after' then match_path.match(%r{/?#{href_path}/?(.*)$}i)
|
188
|
+
when 'before' then match_path.match(%r{#{href_path}/?$}i)
|
189
|
+
end
|
190
|
+
else
|
191
|
+
path_matcher = match_path.match(/#{href_path}\/.*/i)
|
192
|
+
end
|
193
|
+
!!(match_path == href_path || path_matcher)
|
194
|
+
end
|
195
|
+
|
196
|
+
private
|
197
|
+
|
198
|
+
def normalize_path(path)
|
199
|
+
path.split("/").reject{ |part| part.blank? }.compact.join("/")
|
200
|
+
end
|
201
|
+
|
202
|
+
end
|
203
|
+
|
204
|
+
end # Navigation
|
134
205
|
|
135
|
-
end
|
136
|
-
|
206
|
+
end # Helpers
|
207
|
+
|
208
|
+
end # Facades
|
@@ -1,34 +1,6 @@
|
|
1
1
|
module Facades
|
2
2
|
module Helpers
|
3
|
-
|
4
|
-
#
|
5
|
-
# Generates misc html elements that aren't included in Rails core, or are custom.
|
6
|
-
#
|
7
|
-
module Elements
|
8
|
-
|
9
|
-
##
|
10
|
-
# Generates a "button" link tag. Simply a convenience method to skip adding 'class="button"' and also adds an +icon+ option
|
11
|
-
# @see Motr::Forms::Builder#button For form related buttons
|
12
|
-
#
|
13
|
-
# @param [String] txt The link text
|
14
|
-
# @param [String] path The link href
|
15
|
-
# @param [Types] Name Description
|
16
|
-
#
|
17
|
-
# @example Create a plain link.button
|
18
|
-
# button_link('Blog', '/blog') #=> <a href="/blog" class="button">Blog</a>
|
19
|
-
# @example Create a link.button with icon
|
20
|
-
# button_link('Blog', '/blog', :icon => 'blog_image.png') #=> <a href="/blog" class="button"><img src="/images/blog_image.png" alt="Blog" /> Blog</a>
|
21
|
-
|
22
|
-
def button_link(txt, path, attrs = {}, incl_span = false)
|
23
|
-
image = attrs.delete(:icon)
|
24
|
-
klasses = (attrs.delete(:class) || "").split(" ")
|
25
|
-
klasses << 'button'
|
26
|
-
klasses = klasses.uniq.compact
|
27
|
-
content = ""
|
28
|
-
content << image_tag(image) unless image.nil?
|
29
|
-
content << (incl_span ? "<span>#{txt}</span>" : txt)
|
30
|
-
link_to content.html_safe, path, attrs.merge(:class => klasses.join(" "))
|
31
|
-
end
|
3
|
+
module Notifications
|
32
4
|
|
33
5
|
##
|
34
6
|
#
|
@@ -50,29 +22,30 @@ module Facades
|
|
50
22
|
#
|
51
23
|
#
|
52
24
|
def flash_messages(attrs = {})
|
53
|
-
|
25
|
+
|
54
26
|
return if flash.nil? or flash.empty?
|
55
|
-
|
27
|
+
|
56
28
|
wrapper = attrs.delete(:wrapper) || :div
|
57
29
|
closer = attrs.delete(:closer)
|
58
30
|
unless closer === false
|
59
|
-
closer ||= "<span>
|
31
|
+
closer ||= "<span class='close'>x</span>"
|
60
32
|
end
|
61
33
|
klasses = (attrs.delete(:class) || "").split(" ")
|
62
34
|
klasses << "flash-message"
|
63
35
|
content = ""
|
64
|
-
|
36
|
+
|
65
37
|
flash.each do |key, value|
|
38
|
+
next if value === true or value.to_s == 'true' # fix awkward devise message
|
39
|
+
klasses << "notification"
|
66
40
|
klasses << "flash-message-#{key.to_s.underscore}"
|
67
41
|
msg_attrs = attrs.merge(:class => [key.to_s, klasses].flatten.join(' '))
|
68
42
|
content.concat content_tag(wrapper, "#{value} #{closer}".html_safe, msg_attrs).html_safe
|
69
43
|
end
|
70
|
-
|
44
|
+
|
71
45
|
content.html_safe
|
72
|
-
|
46
|
+
|
73
47
|
end
|
74
48
|
|
75
49
|
end
|
76
|
-
|
77
50
|
end
|
78
51
|
end
|
data/lib/facades/helpers.rb
CHANGED
@@ -1,23 +1,12 @@
|
|
1
|
+
require 'action_view'
|
1
2
|
require 'facades/helpers/layout'
|
2
3
|
require 'facades/helpers/navigation'
|
3
|
-
require 'facades/helpers/
|
4
|
-
require 'facades/helpers/pagination'
|
5
|
-
require 'facades/helpers/utility'
|
6
|
-
require 'facades/helpers/builders'
|
7
|
-
require 'facades/helpers/mobile'
|
4
|
+
require 'facades/helpers/notifications'
|
8
5
|
|
9
6
|
module Facades
|
10
|
-
module Helpers
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
include Facades::Helpers::Layout
|
15
|
-
include Facades::Helpers::Navigation
|
16
|
-
include Facades::Helpers::Elements
|
17
|
-
include Facades::Helpers::Utility
|
18
|
-
include Facades::Helpers::Builders
|
19
|
-
include Facades::Helpers::Mobile
|
20
|
-
end
|
21
|
-
|
7
|
+
module Helpers
|
8
|
+
include Facades::Helpers::Layout
|
9
|
+
include Facades::Helpers::Navigation
|
10
|
+
include Facades::Helpers::Notifications
|
22
11
|
end
|
23
12
|
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
module Facades
|
2
|
+
module Patterns
|
3
|
+
##
|
4
|
+
# Generates a tabbed container including
|
5
|
+
# a navigation as well as the tab's "panes"
|
6
|
+
#
|
7
|
+
module Tabs
|
8
|
+
|
9
|
+
def tabbed(options = {}, &block)
|
10
|
+
TabBuilder.new(self, options).render(&block)
|
11
|
+
end
|
12
|
+
|
13
|
+
class TabBuilder
|
14
|
+
attr_reader :view
|
15
|
+
attr_accessor :options, :tabs
|
16
|
+
|
17
|
+
def initialize(tpl, options = {})
|
18
|
+
@view, @options, @tabs = tpl, options, []
|
19
|
+
end
|
20
|
+
|
21
|
+
delegate :content_tag, :concat, :link_to, :capture, :to => :view
|
22
|
+
|
23
|
+
##
|
24
|
+
# Renders the resulting tab area
|
25
|
+
# including a list navigation.
|
26
|
+
#
|
27
|
+
def render(&block)
|
28
|
+
klasses = options.delete(:class) || ""
|
29
|
+
options.merge!(:class => klasses.split(" ").push("tabbed").join(" "))
|
30
|
+
rendered = view.capture(self, &block)
|
31
|
+
output = content_tag(:ul, { :class =>'tab-navigation' }) do
|
32
|
+
tabs.each_with_index do |tab, ind|
|
33
|
+
link_opts = ( ind == 0 ? { :class => 'active' } : {} )
|
34
|
+
concat content_tag(:li, link_to(tab.title, "##{tab.tab_id}"), link_opts)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
output << rendered
|
38
|
+
concat content_tag(:div, output, options)
|
39
|
+
end
|
40
|
+
|
41
|
+
##
|
42
|
+
# Adds a new panel to the tabbed area.
|
43
|
+
# @param [String] title The text to be used in the navigation link.
|
44
|
+
# @param [Hash] options A hash of html attributes to be added to the tab panel.
|
45
|
+
#
|
46
|
+
def panel(title, options = {}, &block)
|
47
|
+
panel = TabPanel.new(title, options)
|
48
|
+
tabs << panel
|
49
|
+
concat content_tag(:section, capture(&block), panel.options)
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
|
54
|
+
class TabPanel
|
55
|
+
attr_accessor :options, :title
|
56
|
+
|
57
|
+
def initialize(title, options = {})
|
58
|
+
@title, @options = title, options
|
59
|
+
@options.merge!(:id => tab_id)
|
60
|
+
klasses = @options.delete(:class) || ""
|
61
|
+
@options.merge!(:class => klasses.split(" ").push("tab").join(" "))
|
62
|
+
end
|
63
|
+
|
64
|
+
def tab_id
|
65
|
+
return options[:id] if options[:id]
|
66
|
+
value = title.mb_chars.normalize(:kd).gsub(/[^\x00-\x7F]/n, '').to_s
|
67
|
+
value.gsub(/[']+/, '').gsub(/\W+/, ' ').strip.downcase.gsub(" ", "_")
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
71
|
+
|
72
|
+
|
73
|
+
end # Tabs
|
74
|
+
end # Patterns
|
75
|
+
end # Facades
|
@@ -1,5 +1,5 @@
|
|
1
1
|
module Facades
|
2
|
-
module
|
2
|
+
module SassExtensions
|
3
3
|
module Color
|
4
4
|
|
5
5
|
# Check the luminance of color. This differs from lightness as it returns the actual values as 'light' and 'dark'
|
@@ -8,7 +8,7 @@ module Facades
|
|
8
8
|
result = ((color.red * 299) + (color.green * 587) + (color.blue * 114) / 1000)
|
9
9
|
Sass::Script::String.new( result >= 160 ? 'light' : 'dark')
|
10
10
|
end
|
11
|
-
|
11
|
+
|
12
12
|
# Tint a color by mixing it with white
|
13
13
|
def tint(color, dilution = Sass::Script::Number.new(50))
|
14
14
|
assert_type color, :Color
|
@@ -25,14 +25,6 @@ module Facades
|
|
25
25
|
mix(color, black, Sass::Script::Number.new(100 - dilution.value))
|
26
26
|
end
|
27
27
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
alpha = (color.alpha * 255).round
|
32
|
-
alphastr = alpha.to_s(16).rjust(2, '0')
|
33
|
-
Sass::Script::String.new("##{alphastr}#{color.send(:hex_str)[1..-1]}".upcase)
|
34
|
-
end
|
35
|
-
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
28
|
+
end # Color
|
29
|
+
end # SassExtensions
|
30
|
+
end # Facades
|
@@ -0,0 +1,27 @@
|
|
1
|
+
##
|
2
|
+
# Extensions to sass's unit conversion and manipulation
|
3
|
+
# functionality.
|
4
|
+
#
|
5
|
+
module Facades
|
6
|
+
module SassExtensions
|
7
|
+
module Conversions
|
8
|
+
|
9
|
+
##
|
10
|
+
# Removes any unit values (px/em/rem etc)
|
11
|
+
# from a number leaving just the numeric
|
12
|
+
# representation.
|
13
|
+
#
|
14
|
+
# @example Use unitless line heights
|
15
|
+
# line-height:numeric(1em) #=> line-height:1
|
16
|
+
#
|
17
|
+
def numeric(value)
|
18
|
+
assert_type value, :Number
|
19
|
+
return value if value.unitless?
|
20
|
+
value = value.to_s.gsub(value.unit_str, '')
|
21
|
+
value = value.to_f.denominator > 1 ? value.to_f : value.to_i
|
22
|
+
Sass::Script::Number.new(value)
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
##
|
2
|
+
# Misc functions to assist development.
|
3
|
+
#
|
4
|
+
module Facades
|
5
|
+
module SassExtensions
|
6
|
+
module Functions
|
7
|
+
|
8
|
+
##
|
9
|
+
# Compact via compass
|
10
|
+
# Compacts a sass list removing any nil or empty items.
|
11
|
+
# @see http://compass-style.org
|
12
|
+
#
|
13
|
+
def compact(*args)
|
14
|
+
sep = :comma
|
15
|
+
if args.size == 1 && args.first.is_a?(Sass::Script::List)
|
16
|
+
list = args.first
|
17
|
+
args = list.value
|
18
|
+
sep = list.separator
|
19
|
+
end
|
20
|
+
Sass::Script::List.new(args.reject{|a| !a.to_bool}, sep)
|
21
|
+
end
|
22
|
+
|
23
|
+
|
24
|
+
##
|
25
|
+
# Creates a selector including all
|
26
|
+
# fields of a particular type. Helpful to
|
27
|
+
# target text-like inputs etc.
|
28
|
+
#
|
29
|
+
def input_types(*args)
|
30
|
+
Sass::Script::String.new(args.collect do |type|
|
31
|
+
send(:"#{type}_input_types")
|
32
|
+
end.flatten.compact.join(", "))
|
33
|
+
end
|
34
|
+
|
35
|
+
##
|
36
|
+
# Takes a value or values and prepends them to an existing list.
|
37
|
+
#
|
38
|
+
def prepend(*args)
|
39
|
+
existing = args.first
|
40
|
+
unless args.first.is_a?(Sass::Script::List)
|
41
|
+
raise Sass::SyntaxError, "The first argument to 'unshift' must be a list"
|
42
|
+
end
|
43
|
+
existing = existing.value
|
44
|
+
args.each{ |arg| existing.unshift(arg) }
|
45
|
+
Sass::Script::List.new(args, :comma)
|
46
|
+
end
|
47
|
+
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
##
|
52
|
+
# Returns all input types
|
53
|
+
#
|
54
|
+
def all_input_types
|
55
|
+
[boolean_input_types, button_input_types, text_input_types].flatten
|
56
|
+
end
|
57
|
+
|
58
|
+
##
|
59
|
+
# Returns an array of boolean input types (radio/checkbox)
|
60
|
+
#
|
61
|
+
def boolean_input_types
|
62
|
+
["input[type=radio]", "input[type=checkbox]"]
|
63
|
+
end
|
64
|
+
|
65
|
+
##
|
66
|
+
# Returns an array of button style input types
|
67
|
+
#
|
68
|
+
def button_input_types
|
69
|
+
["button", "input[type=button]", "input[type=submit]", "input[type=reset]"]
|
70
|
+
end
|
71
|
+
|
72
|
+
##
|
73
|
+
# Returns an array of text style input types
|
74
|
+
#
|
75
|
+
def text_input_types
|
76
|
+
%w{email password text number search tel time url datetime date datetime-local week month}.collect do |type|
|
77
|
+
"input[type=#{type}]"
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
end
|
82
|
+
|
83
|
+
end
|
84
|
+
end
|