facades 0.1.0 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|