diff --git a/app/helpers/elements_helper.rb b/app/helpers/elements_helper.rb index 652012d4b..ade93be10 100644 --- a/app/helpers/elements_helper.rb +++ b/app/helpers/elements_helper.rb @@ -12,6 +12,19 @@ module ElementsHelper def sage_elements [ # Sage Generated Elements + { + title: "meter", + description: "A horizontal display indicating the measurement of a known (finite) quantity", + scss_design: "done", + scss_dev: "done", + scss_doc: "done", + rails_design: "doing", + rails_dev: "doing", + rails_doc: "doing", + react_design: "todo", + react_dev: "todo", + react_doc: "todo" + }, { title: "form_select", description: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.", @@ -168,19 +181,6 @@ def sage_elements react_dev: "todo", react_doc: "todo" }, - { - title: "danger_button", - description: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.", - scss_design: "todo", - scss_dev: "todo", - scss_doc: "todo", - rails_design: "todo", - rails_dev: "todo", - rails_doc: "todo", - react_design: "todo", - react_dev: "todo", - react_doc: "todo" - }, { title: "button", description: "Standard button styling with multiple display options. Can be applied on both button and link elements.", diff --git a/app/helpers/objects_helper.rb b/app/helpers/objects_helper.rb index 27c8f8309..f914affae 100644 --- a/app/helpers/objects_helper.rb +++ b/app/helpers/objects_helper.rb @@ -12,6 +12,32 @@ module ObjectsHelper def sage_objects [ # Sage Generated Objects + { + title: "input_helper", + description: "Provides an extended tooltip/popup for text inputs", + scss_design: "doing", + scss_dev: "doing", + scss_doc: "doing", + rails_design: "todo", + rails_dev: "todo", + rails_doc: "todo", + react_design: "todo", + react_dev: "todo", + react_doc: "todo" + }, + { + title: "input_group", + description: "Allows inline grouping of text inputs with buttons", + scss_design: "done", + scss_dev: "done", + scss_doc: "done", + rails_design: "doing", + rails_dev: "doing", + rails_doc: "doing", + react_design: "todo", + react_dev: "todo", + react_doc: "todo" + }, { title: "billboard", description: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.", diff --git a/app/views/application/_assistant.html.erb b/app/views/application/_assistant.html.erb index 751fd380a..21ade0323 100644 --- a/app/views/application/_assistant.html.erb +++ b/app/views/application/_assistant.html.erb @@ -5,7 +5,7 @@ Toggle main menu <%- end -%> - <%= image_pack_tag("media/images/docs/sage.svg", class: "sage-assistant__branding")%> + <%= image_pack_tag("docs/sage.svg", class: "sage-assistant__branding")%>
diff --git a/app/views/application/_meta.html.erb b/app/views/application/_meta.html.erb index 273c21a53..3a1833d66 100644 --- a/app/views/application/_meta.html.erb +++ b/app/views/application/_meta.html.erb @@ -4,9 +4,9 @@ -<%= favicon_link_tag "sage/apple-touch-icon.png", rel: "apple-touch-icon", sizes: "180x180", type: "image/png" %> -<%= favicon_link_tag "sage/favicon-32x32.png", rel: "icon", sizes: "32x32", type: "image/png" %> -<%= favicon_link_tag "sage/favicon-16x16.png", rel: "icon", sizes: "16x16", type: "image/png" %> -<%= favicon_link_tag "sage/favicon.ico", rel: "icon", type: "image/x-icon" %> + + + + <%= csrf_meta_tags %> diff --git a/app/views/application/_scripts.html.erb b/app/views/application/_scripts.html.erb index 534c5ecd2..a38f0422d 100644 --- a/app/views/application/_scripts.html.erb +++ b/app/views/application/_scripts.html.erb @@ -1,15 +1,21 @@ <%= javascript_include_tag "//cdn.jsdelivr.net/gh/google/code-prettify@master/loader/run_prettify.js", cache: true %> -<%# javascript_include_tag "sage_system", cache: true %> +<%= javascript_pack_tag "docs" %> <%= javascript_pack_tag "system" %> diff --git a/app/views/examples/elements/_element.html.erb b/app/views/examples/elements/_element.html.erb index e93358d85..d34e2ba29 100644 --- a/app/views/examples/elements/_element.html.erb +++ b/app/views/examples/elements/_element.html.erb @@ -19,7 +19,8 @@

Code

-
+ +
<%= CGI.unescapeHTML(CGI.escapeHTML render "examples/elements/#{@title}/preview") %>
diff --git a/app/views/examples/elements/button/_preview.html.erb b/app/views/examples/elements/button/_preview.html.erb index b72401048..3e169e5e4 100644 --- a/app/views/examples/elements/button/_preview.html.erb +++ b/app/views/examples/elements/button/_preview.html.erb @@ -379,7 +379,7 @@

Danger

-<%= render "sage/examples/elements/button/markup", +<%= render "examples/elements/button/markup", text: "Button", is_link_btn: false, link_url: "", @@ -394,7 +394,7 @@ %> -<%= render "sage/examples/elements/button/markup", +<%= render "examples/elements/button/markup", text: "Link", is_link_btn: true, link_url: "#", @@ -409,7 +409,7 @@ %> -<%= render "sage/examples/elements/button/markup", +<%= render "examples/elements/button/markup", text: "Button (icon-left)", is_link_btn: false, link_url: "", @@ -424,7 +424,7 @@ %> -<%= render "sage/examples/elements/button/markup", +<%= render "examples/elements/button/markup", text: "Button (icon-right)", is_link_btn: false, link_url: "", @@ -443,7 +443,7 @@

Danger (disabled)

-<%= render "sage/examples/elements/button/markup", +<%= render "examples/elements/button/markup", text: "Button", is_link_btn: false, link_url: "", @@ -458,7 +458,7 @@ %> -<%= render "sage/examples/elements/button/markup", +<%= render "examples/elements/button/markup", text: "Link", is_link_btn: true, link_url: "#", @@ -473,7 +473,7 @@ %> -<%= render "sage/examples/elements/button/markup", +<%= render "examples/elements/button/markup", text: "Link (icon-left)", is_link_btn: true, link_url: "#", @@ -492,7 +492,7 @@

Flex Align End

-<%= render "sage/examples/elements/button/markup", +<%= render "examples/elements/button/markup", text: "Add A Model", is_link_btn: false, link_url: "", @@ -507,7 +507,7 @@ %> -<%= render "sage/examples/elements/button/markup", +<%= render "examples/elements/button/markup", text: "Cancel", is_link_btn: false, link_url: "", diff --git a/app/views/examples/elements/danger_button/_preview.html.erb b/app/views/examples/elements/danger_button/_preview.html.erb deleted file mode 100644 index 62bc1de53..000000000 --- a/app/views/examples/elements/danger_button/_preview.html.erb +++ /dev/null @@ -1,11 +0,0 @@ - - - -Danger Button (link) -
- - - - -Danger (link, disabled) -
diff --git a/app/views/examples/elements/danger_button/_props.html.erb b/app/views/examples/elements/danger_button/_props.html.erb deleted file mode 100644 index e69de29bb..000000000 diff --git a/app/views/examples/elements/danger_button/_rules_do.html.erb b/app/views/examples/elements/danger_button/_rules_do.html.erb deleted file mode 100644 index e69de29bb..000000000 diff --git a/app/views/examples/elements/danger_button/_rules_dont.html.erb b/app/views/examples/elements/danger_button/_rules_dont.html.erb deleted file mode 100644 index e69de29bb..000000000 diff --git a/app/views/examples/elements/description/_preview.html.erb b/app/views/examples/elements/description/_preview.html.erb index 90ea8e745..a7b201a9d 100644 --- a/app/views/examples/elements/description/_preview.html.erb +++ b/app/views/examples/elements/description/_preview.html.erb @@ -1,4 +1,4 @@ -<%= render "sage/examples/elements/description/markup", +<%= render "examples/elements/description/markup", title: "Name", data: "John Doe" -%> \ No newline at end of file +%> diff --git a/app/views/examples/elements/form_input/_preview.html.erb b/app/views/examples/elements/form_input/_preview.html.erb index e72b3abbd..0a96ad0a0 100644 --- a/app/views/examples/elements/form_input/_preview.html.erb +++ b/app/views/examples/elements/form_input/_preview.html.erb @@ -18,7 +18,7 @@ message_text: "This is a message" %> -

Text (with error modifier)

+

Text (with error)

<%= render "examples/elements/form_input/markup", id: "form__fname2", input_type: "text", @@ -35,8 +35,28 @@ has_error: true, message_text: "This is a message" %> + +

Text (prefilled)

+ <%= render "examples/elements/form_input/markup", + id: "form__country", + input_type: "text", + label_text: "Country", + placeholder: "Country", + value: "USA", + required: true, + disabled: false, + input_mode: "", + pattern: "", + max: "", + minlength: "", + maxlength: "", + has_error: false, + message_text: "" + %> + +

Text (disabled)

<%= render "examples/elements/form_input/markup", - id: "form__lname", + id: "form__apt", input_type: "text", label_text: "PO Box", placeholder: "PO Box", diff --git a/app/views/examples/elements/form_select/_preview.html.erb b/app/views/examples/elements/form_select/_preview.html.erb index be8cd953a..870eb4e20 100644 --- a/app/views/examples/elements/form_select/_preview.html.erb +++ b/app/views/examples/elements/form_select/_preview.html.erb @@ -1,4 +1,4 @@ -<%= render "sage/examples/elements/form_select/markup", +<%= render "examples/elements/form_select/markup", name: "Characters", has_error: false, select_options: [ @@ -34,7 +34,7 @@ message: "This is a message" %> -<%= render "sage/examples/elements/form_select/markup", +<%= render "examples/elements/form_select/markup", name: "Pets", has_error: true, select_options: [ diff --git a/app/views/examples/elements/link_button/_preview.html.erb b/app/views/examples/elements/link_button/_preview.html.erb index ac2f93cc7..9b229a1d5 100644 --- a/app/views/examples/elements/link_button/_preview.html.erb +++ b/app/views/examples/elements/link_button/_preview.html.erb @@ -1 +1 @@ -<%= render "sage/examples/elements/link_button/markup" %> \ No newline at end of file +<%= render "examples/elements/link_button/markup" %> diff --git a/app/views/examples/elements/live_stream_wrapper/_preview.html.erb b/app/views/examples/elements/live_stream_wrapper/_preview.html.erb index 6e66a8234..89f3a4362 100644 --- a/app/views/examples/elements/live_stream_wrapper/_preview.html.erb +++ b/app/views/examples/elements/live_stream_wrapper/_preview.html.erb @@ -1,7 +1,7 @@ -<%= render "sage/examples/elements/live_stream_wrapper/markup", +<%= render "examples/elements/live_stream_wrapper/markup", is_awake: true %> -<%= render "sage/examples/elements/live_stream_wrapper/markup", +<%= render "examples/elements/live_stream_wrapper/markup", is_awake: false -%> \ No newline at end of file +%> diff --git a/app/views/examples/elements/meter/_preview.html.erb b/app/views/examples/elements/meter/_preview.html.erb index 6ae916c58..b42f8d2bf 100644 --- a/app/views/examples/elements/meter/_preview.html.erb +++ b/app/views/examples/elements/meter/_preview.html.erb @@ -1,5 +1,5 @@ -<%= render "sage/examples/elements/form_input/markup", +<%= render "examples/elements/form_input/markup", id: "pw-meter-example", input_type: "number", label_text: "Meter value", @@ -16,7 +16,7 @@ message_text: "" %> -<%= render "sage/examples/elements/meter/markup", +<%= render "examples/elements/meter/markup", id: "pw-hint-meter", label: "Password strength", value: 1, diff --git a/app/views/examples/elements/switch/_preview.html.erb b/app/views/examples/elements/switch/_preview.html.erb index d3def7a9e..2d878f411 100644 --- a/app/views/examples/elements/switch/_preview.html.erb +++ b/app/views/examples/elements/switch/_preview.html.erb @@ -144,29 +144,5 @@ required: false, message: "" %> - - <%= render "examples/elements/switch/markup", - type: "radio", - name: "sage-switch-11", - id: "sage-switch-11", - value: "switch-11-value", - label_text: "Switch (radio)", - has_error: false, - checked: false, - disabled: false, - required: false, - message: "Additional Info" - %> - <%= render "examples/elements/switch/markup", - type: "radio", - name: "sage-switch-12", - id: "sage-switch-12", - value: "switch-12-value", - label_text: "Switch (radio)", - has_error: true, - checked: false, - disabled: false, - required: true, - message: "Additional Info" - %>
+
diff --git a/app/views/examples/elements/table/_preview.html.erb b/app/views/examples/elements/table/_preview.html.erb index 1708cb60f..35bac9633 100644 --- a/app/views/examples/elements/table/_preview.html.erb +++ b/app/views/examples/elements/table/_preview.html.erb @@ -1,5 +1,5 @@

Responsive table

-<%= render "sage/examples/elements/table/markup", +<%= render "examples/elements/table/markup", caption: "Responsive tables require the use of two parent containers", condensed: false, responsive: true, @@ -9,7 +9,7 @@ %>

Striped table

-<%= render "sage/examples/elements/table/markup", +<%= render "examples/elements/table/markup", caption: "Striped tables display a background color on odd-numbered rows", condensed: false, responsive: true, @@ -19,7 +19,7 @@ %>

Striped table with condensed padding

-<%= render "sage/examples/elements/table/markup", +<%= render "examples/elements/table/markup", caption: "Condensed tables use decreased vertical padding in table cells", condensed: true, responsive: true, @@ -29,7 +29,7 @@ %>

Sortable table with condensed padding

-<%= render "sage/examples/elements/table/markup", +<%= render "examples/elements/table/markup", caption: "NOTE: this example is for mockup purposes only and does not implement sorting cells", condensed: true, responsive: true, diff --git a/app/views/examples/objects/_object.html.erb b/app/views/examples/objects/_object.html.erb index 9b0a2d5ec..c493e7e99 100644 --- a/app/views/examples/objects/_object.html.erb +++ b/app/views/examples/objects/_object.html.erb @@ -19,7 +19,8 @@

Code

-
+ +
<%= CGI.unescapeHTML(CGI.escapeHTML render "examples/objects/#{@title}/preview") %>
diff --git a/app/views/examples/objects/assistant/_markup.html.erb b/app/views/examples/objects/assistant/_markup.html.erb index 7b905ca85..0ef6626e5 100644 --- a/app/views/examples/objects/assistant/_markup.html.erb +++ b/app/views/examples/objects/assistant/_markup.html.erb @@ -5,7 +5,7 @@ Toggle main menu <%- end -%> - <%= image_pack_tag("media/images/docs/sage.svg", class: "sage-assistant__branding")%> + <%= image_pack_tag("docs/sage.svg", class: "sage-assistant__branding")%>
diff --git a/app/views/examples/objects/billboard/_markup.html.erb b/app/views/examples/objects/billboard/_markup.html.erb index d3ca189e6..42486e310 100644 --- a/app/views/examples/objects/billboard/_markup.html.erb +++ b/app/views/examples/objects/billboard/_markup.html.erb @@ -1,7 +1,7 @@ -
+
Billboard Title

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.

-
\ No newline at end of file +
diff --git a/app/views/examples/objects/billboard/_preview.html.erb b/app/views/examples/objects/billboard/_preview.html.erb index b423ab85b..c41a4537b 100644 --- a/app/views/examples/objects/billboard/_preview.html.erb +++ b/app/views/examples/objects/billboard/_preview.html.erb @@ -1,16 +1,16 @@
- <%= render "examples/objects/billboard/markup", img: "sage/billboard/background_1.jpg" %> + <%= render "examples/objects/billboard/markup", img: "media/images/docs/billboard/background_1.jpg" %>
- <%= render "examples/objects/billboard/markup", img: "sage/billboard/background_2.jpg" %> + <%= render "examples/objects/billboard/markup", img: "media/images/docs/billboard/background_2.jpg" %>

- <%= render "examples/objects/billboard/markup", img: "sage/billboard/background_3.jpg" %> + <%= render "examples/objects/billboard/markup", img: "media/images/docs/billboard/background_3.jpg" %>
- <%= render "examples/objects/billboard/markup", img: "sage/billboard/background_4.jpg" %> + <%= render "examples/objects/billboard/markup", img: "media/images/docs/billboard/background_4.jpg" %>
diff --git a/app/views/examples/objects/card/_markup.html.erb b/app/views/examples/objects/card/_markup.html.erb index 13fe39d6e..68eb6d4c2 100644 --- a/app/views/examples/objects/card/_markup.html.erb +++ b/app/views/examples/objects/card/_markup.html.erb @@ -1,10 +1,10 @@
<%= is_spaced ? " sage-card--spaced" : "" %>"> <% if has_img %> - <%= image_tag("#{img_path}", class: "sage-card__img", alt: "#{img_alt}") %> + <%= image_pack_tag("#{img_path}", class: "sage-card__img", alt: "#{img_alt}") %> <% end %>

<%= title %>

<%= text %>

<%= action_text %>
-
\ No newline at end of file +
diff --git a/app/views/examples/objects/card/_preview.html.erb b/app/views/examples/objects/card/_preview.html.erb index bcaf3ef37..7716dbd8a 100644 --- a/app/views/examples/objects/card/_preview.html.erb +++ b/app/views/examples/objects/card/_preview.html.erb @@ -1,6 +1,6 @@
- <%= render "sage/examples/objects/card/markup", + <%= render "examples/objects/card/markup", is_compact: false, is_spaced: false, title: "Card w/ Image", @@ -9,12 +9,12 @@ action_style_primary: true, action_style_tertiary: false, has_img: true, - img_path: "sage/card/card-placeholder-lg.png", + img_path: "docs/card/card-placeholder-lg.png", img_alt: "Alternative text for image" %>
- <%= render "sage/examples/objects/card/markup", + <%= render "examples/objects/card/markup", is_compact: false, is_spaced: false, title: "Card w/ Image", @@ -23,12 +23,12 @@ action_style_primary: false, action_style_tertiary: true, has_img: true, - img_path: "sage/card/card-placeholder-lg.png", + img_path: "docs/card/card-placeholder-lg.png", img_alt: "Alternative text for image" %>
- <%= render "sage/examples/objects/card/markup", + <%= render "examples/objects/card/markup", is_compact: true, is_spaced: false, title: "Compact Card w/ Image", @@ -37,10 +37,10 @@ action_style_primary: true, action_style_tertiary: false, has_img: true, - img_path: "sage/card/card-placeholder-sm.png", + img_path: "docs/card/card-placeholder-sm.png", img_alt: "Alternative text for image" %> - <%= render "sage/examples/objects/card/markup", + <%= render "examples/objects/card/markup", is_compact: true, is_spaced: false, title: "Compact Card w/ Image", @@ -49,12 +49,12 @@ action_style_primary: false, action_style_tertiary: true, has_img: true, - img_path: "sage/card/card-placeholder-sm.png", + img_path: "docs/card/card-placeholder-sm.png", img_alt: "Alternative text for image" %>
- <%= render "sage/examples/objects/card/markup", + <%= render "examples/objects/card/markup", is_compact: false, is_spaced: true, title: "Spaced Card w/ Image", @@ -63,12 +63,12 @@ action_style_primary: true, action_style_tertiary: false, has_img: true, - img_path: "sage/card/card-placeholder-lg.png", + img_path: "docs/card/card-placeholder-lg.png", img_alt: "Alternative text for image" %>
- <%= render "sage/examples/objects/card/markup", + <%= render "examples/objects/card/markup", is_compact: false, is_spaced: true, title: "Spaced Card w/ Image", @@ -77,12 +77,12 @@ action_style_primary: false, action_style_tertiary: true, has_img: true, - img_path: "sage/card/card-placeholder-lg.png", + img_path: "docs/card/card-placeholder-lg.png", img_alt: "Alternative text for image" %>
- <%= render "sage/examples/objects/card/markup", + <%= render "examples/objects/card/markup", is_compact: true, is_spaced: true, title: "Spaced & Compact w/ Image", @@ -91,10 +91,10 @@ action_style_primary: true, action_style_tertiary: false, has_img: true, - img_path: "sage/card/card-placeholder-sm.png", + img_path: "docs/card/card-placeholder-sm.png", img_alt: "Alternative text for image" %> - <%= render "sage/examples/objects/card/markup", + <%= render "examples/objects/card/markup", is_compact: true, is_spaced: true, title: "Spaced & Compact w/ Image", @@ -103,12 +103,12 @@ action_style_primary: false, action_style_tertiary: true, has_img: true, - img_path: "sage/card/card-placeholder-sm.png", + img_path: "docs/card/card-placeholder-sm.png", img_alt: "Alternative text for image" %>
- <%= render "sage/examples/objects/card/markup", + <%= render "examples/objects/card/markup", is_compact: false, is_spaced: false, title: "Card w/ No Image", @@ -122,7 +122,7 @@ %>
- <%= render "sage/examples/objects/card/markup", + <%= render "examples/objects/card/markup", is_compact: false, is_spaced: false, title: "Card w/ No Image", diff --git a/app/views/examples/objects/form_section/_markup.html.erb b/app/views/examples/objects/form_section/_markup.html.erb index eff3df1db..5294ffa86 100644 --- a/app/views/examples/objects/form_section/_markup.html.erb +++ b/app/views/examples/objects/form_section/_markup.html.erb @@ -6,7 +6,7 @@
- <%= render "sage/examples/objects/alert/markup", + <%= render "examples/objects/alert/markup", color: "", sage_icon_name: "sage-icon-info-circle", sage_alert_title: "Form Section Content Will Go Here", diff --git a/app/views/examples/objects/form_section/_preview.html.erb b/app/views/examples/objects/form_section/_preview.html.erb index a36532060..74a7616a0 100644 --- a/app/views/examples/objects/form_section/_preview.html.erb +++ b/app/views/examples/objects/form_section/_preview.html.erb @@ -1,4 +1,4 @@ -<%= render "sage/examples/objects/form_section/markup", +<%= render "examples/objects/form_section/markup", title: "Form Section Title", sub_title: "Helpful text that lets the customer have an idea how to work with the section." %> diff --git a/app/views/examples/objects/input_group/_markup.html.erb b/app/views/examples/objects/input_group/_markup.html.erb index a869bd6a6..a06398119 100644 --- a/app/views/examples/objects/input_group/_markup.html.erb +++ b/app/views/examples/objects/input_group/_markup.html.erb @@ -1,5 +1,5 @@
- <%= render "sage/examples/elements/form_input/markup", + <%= render "examples/elements/form_input/markup", id: "#{ group_id }", input_type: "#{ group_button_type}", label_text: "#{ group_button_label }", @@ -16,7 +16,7 @@ message_text: "" %> <%- if has_hint -%> - <%= render "sage/examples/objects/input_helper/markup", + <%= render "examples/objects/input_helper/markup", helper_id: "", helper_target: "input-group-pw-example", description: "Your password must meet the following criteria:", diff --git a/app/views/examples/objects/input_group/_preview.html.erb b/app/views/examples/objects/input_group/_preview.html.erb index 6970dc29d..d0134b937 100644 --- a/app/views/examples/objects/input_group/_preview.html.erb +++ b/app/views/examples/objects/input_group/_preview.html.erb @@ -1,6 +1,6 @@

Input group with password reveal toggle and helper

- <%= render "sage/examples/objects/input_group/markup", + <%= render "examples/objects/input_group/markup", group_id: "input-group-pw-example", has_button: true, has_hint: true, @@ -17,7 +17,7 @@ %>

Input group with primary button

- <%= render "sage/examples/objects/input_group/markup", + <%= render "examples/objects/input_group/markup", group_id: 'input-group-search-example', has_button: true, has_hint: false, diff --git a/app/views/examples/objects/input_helper/_markup.html.erb b/app/views/examples/objects/input_helper/_markup.html.erb index ea983baae..c7d7ccf88 100644 --- a/app/views/examples/objects/input_helper/_markup.html.erb +++ b/app/views/examples/objects/input_helper/_markup.html.erb @@ -9,7 +9,7 @@ <%- end -%> - <%= render "sage/examples/elements/meter/markup", + <%= render "examples/elements/meter/markup", id: "pw-hint-meter", label: "Password strength", value: 0, diff --git a/app/views/examples/objects/input_helper/_preview.html.erb b/app/views/examples/objects/input_helper/_preview.html.erb index 58e99cf3d..192a11947 100644 --- a/app/views/examples/objects/input_helper/_preview.html.erb +++ b/app/views/examples/objects/input_helper/_preview.html.erb @@ -1,6 +1,6 @@

Input helper

- <%= render "sage/examples/objects/input_helper/markup", + <%= render "examples/objects/input_helper/markup", helper_id: "", helper_target: "", description: "Your password must meet the following criteria:", diff --git a/app/views/examples/objects/live_active_mic/_preview.html.erb b/app/views/examples/objects/live_active_mic/_preview.html.erb index 7ae339ae0..9245012b1 100644 --- a/app/views/examples/objects/live_active_mic/_preview.html.erb +++ b/app/views/examples/objects/live_active_mic/_preview.html.erb @@ -1,4 +1,4 @@
- <%= render "sage/examples/objects/live_active_mic/markup" %> -
\ No newline at end of file + <%= render "examples/objects/live_active_mic/markup" %> +
diff --git a/app/views/examples/objects/live_avatar/_markup.html.erb b/app/views/examples/objects/live_avatar/_markup.html.erb index 1c7c7e65d..f418ecaf5 100644 --- a/app/views/examples/objects/live_avatar/_markup.html.erb +++ b/app/views/examples/objects/live_avatar/_markup.html.erb @@ -3,6 +3,6 @@ <%= initials %> <% if url != "" %> - <%= image_tag("#{url}", class: "sage-live-avatar__image", alt: "") %> + <%= image_pack_tag("#{url}", class: "sage-live-avatar__image", alt: "") %> <% end %> -
\ No newline at end of file +
diff --git a/app/views/examples/objects/live_avatar/_preview.html.erb b/app/views/examples/objects/live_avatar/_preview.html.erb index a4e9aab67..3db1833ee 100644 --- a/app/views/examples/objects/live_avatar/_preview.html.erb +++ b/app/views/examples/objects/live_avatar/_preview.html.erb @@ -24,7 +24,7 @@ initials: "LJ", color: "", hasRing: false, - url: "sage/avatar/jay.png", + url: "docs/avatar/jay.png", scale: false, custom_class: "" %> @@ -54,7 +54,7 @@ initials: "CJ", color: "sage", hasRing: true, - url: "sage/avatar/cj.png", + url: "docs/avatar/cj.png", scale: false, custom_class: "" %> diff --git a/app/views/examples/objects/live_profile_card/_preview.html.erb b/app/views/examples/objects/live_profile_card/_preview.html.erb index e184d318d..df80446d4 100644 --- a/app/views/examples/objects/live_profile_card/_preview.html.erb +++ b/app/views/examples/objects/live_profile_card/_preview.html.erb @@ -7,7 +7,7 @@ initials: "JC", color: "", hasRing: false, - url: "sage/avatar/jay.png", + url: "docs/avatar/jay.png", iconsActive: true %> @@ -20,7 +20,7 @@ initials: "JC", color: "sage", hasRing: false, - url: "sage/avatar/cj.png", + url: "docs/avatar/cj.png", iconsActive: false %> diff --git a/app/views/examples/objects/live_stream_video_grid/_preview.html.erb b/app/views/examples/objects/live_stream_video_grid/_preview.html.erb index 73a90482d..011c077ed 100644 --- a/app/views/examples/objects/live_stream_video_grid/_preview.html.erb +++ b/app/views/examples/objects/live_stream_video_grid/_preview.html.erb @@ -14,12 +14,12 @@ }, { initials: 'CM', - avatarURL: 'sage/avatar/court.png', + avatarURL: 'docs/avatar/court.png', color: '', }, { initials: 'PJ', - avatarURL: 'sage/avatar/phil.png', + avatarURL: 'docs/avatar/phil.png', color: 'red', }, { diff --git a/app/views/examples/objects/nav/_preview.html.erb b/app/views/examples/objects/nav/_preview.html.erb index 4a442057d..e6c7d9aec 100644 --- a/app/views/examples/objects/nav/_preview.html.erb +++ b/app/views/examples/objects/nav/_preview.html.erb @@ -1,4 +1,4 @@ -<%= render "sage/examples/objects/nav/markup", +<%= render "examples/objects/nav/markup", nav_links: [ { text: "Nav Link 1", @@ -49,4 +49,4 @@ url: "#" } ] -%> \ No newline at end of file +%> diff --git a/app/views/examples/objects/page_heading/_preview.html.erb b/app/views/examples/objects/page_heading/_preview.html.erb index 3af94cd0e..20ae003d4 100644 --- a/app/views/examples/objects/page_heading/_preview.html.erb +++ b/app/views/examples/objects/page_heading/_preview.html.erb @@ -1,6 +1,6 @@ -<%= render "sage/examples/objects/page_heading/markup", +<%= render "examples/objects/page_heading/markup", page_title: "Page Title", back_icon: "sage-icon-caret-left", back_text: "Back to Something", back_url: "#" -%> \ No newline at end of file +%> diff --git a/app/views/examples/objects/pagination/_preview.html.erb b/app/views/examples/objects/pagination/_preview.html.erb index 305297120..1b88e4fff 100644 --- a/app/views/examples/objects/pagination/_preview.html.erb +++ b/app/views/examples/objects/pagination/_preview.html.erb @@ -1,4 +1,4 @@ -<%= render "sage/examples/objects/pagination/markup", +<%= render "examples/objects/pagination/markup", total_count: "32", pagination_items: [ { @@ -95,4 +95,4 @@ is_current: false }, ] -%> \ No newline at end of file +%> diff --git a/app/views/examples/objects/panel/_preview.html.erb b/app/views/examples/objects/panel/_preview.html.erb index ffdc5b4eb..7d42fb77b 100644 --- a/app/views/examples/objects/panel/_preview.html.erb +++ b/app/views/examples/objects/panel/_preview.html.erb @@ -1,5 +1,5 @@ -<%= render "sage/examples/objects/panel/markup", +<%= render "examples/objects/panel/markup", header: "Header Content", body: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.", footer: "Footer Content" -%> \ No newline at end of file +%> diff --git a/app/views/examples/objects/sidebar/_preview.html.erb b/app/views/examples/objects/sidebar/_preview.html.erb index aa8af4220..3de6eb9c7 100644 --- a/app/views/examples/objects/sidebar/_preview.html.erb +++ b/app/views/examples/objects/sidebar/_preview.html.erb @@ -1,4 +1,4 @@ -<%= render "sage/examples/objects/sidebar/markup", - body_content: "sage/examples/objects/nav/preview", +<%= render "examples/objects/sidebar/markup", + body_content: "examples/objects/nav/preview", footer_content: "" -%> \ No newline at end of file +%> diff --git a/app/views/examples/objects/tabs/_preview.html.erb b/app/views/examples/objects/tabs/_preview.html.erb index 9492796c2..938a5b5e6 100644 --- a/app/views/examples/objects/tabs/_preview.html.erb +++ b/app/views/examples/objects/tabs/_preview.html.erb @@ -1,4 +1,4 @@ -<%= render "sage/examples/objects/tabs/markup", +<%= render "examples/objects/tabs/markup", options: [ { text: "Active", @@ -17,4 +17,4 @@ is_active: false }, ] -%> \ No newline at end of file +%> diff --git a/app/views/pages/index.html.erb b/app/views/pages/index.html.erb index 1a626006f..f358535de 100644 --- a/app/views/pages/index.html.erb +++ b/app/views/pages/index.html.erb @@ -3,11 +3,11 @@

The Sage Design System (SDS) is our single source of truth, providing everything you need to build great products for our customers. It is the culmination of designers and developers working together to give teams the ability to ship high-quality products faster.

<% end %>
- <%= image_pack_tag("media/images/docs/sage_illustration.png", class: "sage-panel__img")%> + <%= image_pack_tag("docs/sage_illustration.png", class: "sage-panel__img")%>

How it works

The UI of the Kajabi Core application is a combination of Rails Components, React Components and a custom CSS Framework called Sage that applies a uniform style to both.

We think of our approach to UI at Kajabi in this way: We default to using Rails Components and a classic Rails approach to most problems and move to React where it counts.

Rails does many things very well and gives us the ability to move quickly and solve complex problems with very simple, tried and true, code solutions. With that said, sometimes we come across a problem that we want to solve that the standard rails approach will just not be enough ( Think complex interactions with many versions of state ). In this case we move to React as our default approach to solving complex, Javascript heavy problems.

Because our system contains two different approaches to UI creation, we utilize a SCSS Design System to provide the styles to both types of components (Think Bootstrap, but customized for our products). Our Design System provides the styles for the core components that make up the UI of our product.

- <%= image_pack_tag("media/images/docs/sage_structure.png", class: "sage-panel__img", style: "width: 500px; margin: 0 auto")%> + <%= image_pack_tag("docs/sage_structure.png", class: "sage-panel__img", style: "width: 500px; margin: 0 auto")%>
diff --git a/config/webpacker.yml b/config/webpacker.yml index c5436d176..11452c784 100644 --- a/config/webpacker.yml +++ b/config/webpacker.yml @@ -17,7 +17,7 @@ default: &default cache_manifest: false # Extract and emit a css file - extract_css: false + extract_css: true static_assets_extensions: - .jpg diff --git a/lib/sage-frontend/images/docs/favicon.ico b/lib/sage-frontend/images/docs/favicon.ico deleted file mode 100644 index f0a67c47e..000000000 Binary files a/lib/sage-frontend/images/docs/favicon.ico and /dev/null differ diff --git a/lib/sage-frontend/javascript/define.js b/lib/sage-frontend/javascript/define.js index 4c37f3bf6..73574bb25 100644 --- a/lib/sage-frontend/javascript/define.js +++ b/lib/sage-frontend/javascript/define.js @@ -1 +1,2 @@ window.Sage = window.Sage || {}; +window.Sage.docs = window.Sage.docs || {}; diff --git a/lib/sage-frontend/javascript/docs/banner.js b/lib/sage-frontend/javascript/docs/banner.js new file mode 100644 index 000000000..75a5f709a --- /dev/null +++ b/lib/sage-frontend/javascript/docs/banner.js @@ -0,0 +1,16 @@ +Sage.docs.banner = (function() { + + // ================================================== + // Functions + // ================================================== + + function init() { + Sage.banner.init(); + } + + + return { + init: init + }; + +})(); diff --git a/lib/sage-frontend/javascript/docs/example.js b/lib/sage-frontend/javascript/docs/example.js new file mode 100644 index 000000000..83d741d57 --- /dev/null +++ b/lib/sage-frontend/javascript/docs/example.js @@ -0,0 +1,46 @@ +Sage.docs.example = (function() { + + var expandedText = "Collapse this code snippet"; + var collapsedText = "Expand this code snippet"; + + + // ================================================== + // Functions + // ================================================== + + + // Note: assumes we won't have multiple code snippets per page + function showHideCodeSample() { + var codeBtn = document.querySelector('.example__expand-btn'), + codeSnippet = codeBtn.closest('.sage-code-snippet'); + + codeBtn.addEventListener('click', function(e) { + updateButtonState(e.target, this); + e.target.parentElement.classList.toggle('example__code--expanded'); + e.target.nextElementSibling.focus(); + }); + } + + + // toggle code example button state + function updateButtonState(evt) { + if (evt.getAttribute('aria-expanded') === 'false') { + evt.setAttribute('aria-expanded', 'true'); + evt.innerText = expandedText; + } else { + evt.setAttribute('aria-expanded', 'false'); + evt.innerText = collapsedText; + } + } + + + function init() { + showHideCodeSample(); + } + + + return { + init: init + }; + +})(); diff --git a/lib/sage-frontend/javascript/docs/index.js b/lib/sage-frontend/javascript/docs/index.js index 8c0a92838..1b0a3aee4 100644 --- a/lib/sage-frontend/javascript/docs/index.js +++ b/lib/sage-frontend/javascript/docs/index.js @@ -1,3 +1,34 @@ -require("../define") +require('../define') -console.warn('JS DOCS!'); +require('./live-option-menu') +require('./banner') +require('./example') +require('./meter') +require('./inputhelper') +require('./example') + +// Conditional routing +// NOTE: modules must be imported above to be initialized below +if (document.querySelector('.sage-docs') !== null) { + + if (document.querySelector('.sage-live-option-menu-anchor') !== null) { + Sage.docs.liveOptionMenu.init(); + } + + if (document.getElementById('pw-meter-example') !== null) { + Sage.docs.meter.init(); + } + + if (document.querySelector('.sage-banner--active') !== null && document.querySelector('.example__preview--page') !== null) { + Sage.docs.banner.init(); + } + + if (document.querySelector('.example__code') !== null && document.querySelector('.example__expand-btn') !== null) { + Sage.docs.example.init(); + } + + if (document.querySelector('.sage-input-helper') !== null && document.querySelector('[data-js-example="input-helper"]') !== null) { + Sage.docs.inputhelper.init(); + } + +} diff --git a/lib/sage-frontend/javascript/docs/inputhelper.js b/lib/sage-frontend/javascript/docs/inputhelper.js new file mode 100644 index 000000000..ade0c53fb --- /dev/null +++ b/lib/sage-frontend/javascript/docs/inputhelper.js @@ -0,0 +1,20 @@ +Sage.docs.inputhelper = (function() { + + // ================================================== + // Functions + // ================================================== + + function init() { + var helperFieldset = document.querySelector('[data-js-example="input-helper"]'); + var helperExample = helperFieldset.querySelector('.sage-input-helper'); + + helperExample.classList.add('sage-input-helper--visible'); + helperExample.style.position = 'relative'; + } + + + return { + init: init + }; + +})(); diff --git a/lib/sage-frontend/javascript/docs/live-option-menu.js b/lib/sage-frontend/javascript/docs/live-option-menu.js new file mode 100644 index 000000000..34dfb9e3c --- /dev/null +++ b/lib/sage-frontend/javascript/docs/live-option-menu.js @@ -0,0 +1,30 @@ +Sage.docs.liveOptionMenu = (function() { + // ================================================== + // Variables + // ================================================== + var sageLiveOptionMenu = document.querySelectorAll('.sage-live-option-menu-anchor'); + + + // ================================================== + // Functions + // ================================================== + + function init() { + + // Simulate contextual menu + sageLiveOptionMenu.forEach(function(anchor) { + anchor.addEventListener('click', function(e) { + var target = e.currentTarget; + if (!target) return; + var isExpanded = target.getAttribute('aria-expanded') == 'true'; + target.setAttribute('aria-expanded', !isExpanded); + }); + }); + } + + + return { + init: init + } + +})(); diff --git a/lib/sage-frontend/javascript/docs/meter.js b/lib/sage-frontend/javascript/docs/meter.js new file mode 100644 index 000000000..d38495fb6 --- /dev/null +++ b/lib/sage-frontend/javascript/docs/meter.js @@ -0,0 +1,23 @@ +Sage.docs.meter = (function() { + + // ================================================== + // Functions + // ================================================== + + + function init() { + var meterUpdate = document.getElementById('pw-meter-example'), + meterBar = document.getElementById('pw-hint-meter'); + + meterUpdate.addEventListener('input', function(e) { + meterBar.value = e.target.value; + Sage.meter.updateMeter('[js-meter-type="password"]'); + }); + } + + + return { + init: init + }; + +})(); diff --git a/lib/sage-frontend/javascript/system/alert.js b/lib/sage-frontend/javascript/system/alert.js new file mode 100644 index 000000000..f0bcf0d1c --- /dev/null +++ b/lib/sage-frontend/javascript/system/alert.js @@ -0,0 +1,24 @@ +Sage.alert = (function () { + // ================================================== + // Variables + // ================================================== + + var alertCloseBtns = document.querySelectorAll(".sage-alert__close"); + + // ================================================== + // Functions + // ================================================== + + alertCloseBtns.forEach(function (btn) { + var alert = btn.closest(".sage-alert"); + btn.addEventListener("click", function () { + alert.style.display = "none"; + }); + }); + + function init() {} + + return { + init: init, + }; +})(); diff --git a/lib/sage-frontend/javascript/system/banner.js b/lib/sage-frontend/javascript/system/banner.js new file mode 100644 index 000000000..f9666a151 --- /dev/null +++ b/lib/sage-frontend/javascript/system/banner.js @@ -0,0 +1,46 @@ +Sage.banner = (function() { + + // ================================================== + // Variables + // ================================================== + + var activeBanner, bannerCloseBtn; + + var bodyClass = "banner-active"; + var bannerClass = ".sage-banner--active"; + + + // ================================================== + // Functions + // ================================================== + + // check to see if an active banner exists + function bannerIsEnabled() { + return document.querySelector(bannerClass) !== null; + } + + function bindEvents() { + bannerCloseBtn.addEventListener('click', function(e) { + e.target.parentElement.classList.toggle('sage-banner--active'); + document.querySelector('body').classList.toggle(bodyClass); + }); + } + + + function init() { + if (bannerIsEnabled()) { + document.body.classList.add(bodyClass); + activeBanner = document.querySelector(bannerClass); + bannerCloseBtn = activeBanner.querySelector('.sage-banner__close'); + + bindEvents(); + } + } + + + return { + init: init, + bannerIsEnabled: bannerIsEnabled + }; + +})(); diff --git a/lib/sage-frontend/javascript/system/define.js b/lib/sage-frontend/javascript/system/define.js new file mode 100644 index 000000000..f7ba27d2c --- /dev/null +++ b/lib/sage-frontend/javascript/system/define.js @@ -0,0 +1,2 @@ +var Sage = Sage || {}; +Sage.docs = Sage.docs || {}; diff --git a/lib/sage-frontend/javascript/system/example.js b/lib/sage-frontend/javascript/system/example.js new file mode 100644 index 000000000..d9b2b4496 --- /dev/null +++ b/lib/sage-frontend/javascript/system/example.js @@ -0,0 +1,38 @@ +Sage.module = (function() { + /* + This is an example template. To create a module: + 1. Duplicate or copy this structure + 2. Rename `Sage.module` above to your module name + 3. Import (require) the module in `sage_system.js` + 4. When applicable, initialize in `init.js` + */ + + // ================================================== + // Variables + // ================================================== + + + // ================================================== + // Functions + // ================================================== + + /* + Add functions here that should run when this module + is initialized in `init.js`: event handlers, etc. + */ + function init() { + + } + + + /* + Functions declared above are considered "private" and + not exposed to the global `window` object. To allow a + function to be "public" and usable in other modules, + return them below. See `util.js` for examples. + */ + return { + init: init + }; + +})(); diff --git a/lib/sage-frontend/javascript/system/index.js b/lib/sage-frontend/javascript/system/index.js index f77c456a7..af5f7464f 100644 --- a/lib/sage-frontend/javascript/system/index.js +++ b/lib/sage-frontend/javascript/system/index.js @@ -1,12 +1,17 @@ -require("../define") -// require("./util") +//= require lib/zxcvbn -// require("./tooltip") -// require("./sidebar") -// require("./overlay") -// require("./banner") -// require("./alert") +require('../define') +require('./util') -// require("./init") +require('./table') +require('./tooltip') +require('./sidebar') +require('./overlay') +require('./banner') +require('./alert') +require('./select') +require('./meter') +require('./inputgroup') +require('./inputhelper') -console.warn('JS System!'); +require('./init') diff --git a/lib/sage-frontend/javascript/system/init.js b/lib/sage-frontend/javascript/system/init.js new file mode 100644 index 000000000..235765c22 --- /dev/null +++ b/lib/sage-frontend/javascript/system/init.js @@ -0,0 +1,56 @@ +Sage.init = function(elementNamesToInit) { + var shouldInit = function(elementName, selector) { + return elementNamesToInit.includes(elementName) && document.querySelector(selector) !== null; + }; + + // Initialize Table + if ( shouldInit('table', '.sage-table') ) { + Sage.table.init(); + } + + // Initialize Tooltip + if ( shouldInit('tooltip', '[data-tooltip]') ) { + Sage.tooltip(); + } + + // Initialize Sidebar + if ( shouldInit('sidebar', '.sage-sidebar') ) { + Sage.sidebar.init(); + } + + // Initialize Overlay + if ( shouldInit('overlay', '.sage-overlay') ) { + Sage.overlay.init(); + } + + // Initialize Alert + if ( shouldInit('alert', '.sage-alert') ) { + Sage.alert.init(); + } + + // Initialize Select + if ( shouldInit('select', '.sage-select') ) { + Sage.select.init(); + } + + // Initialize Input groups + if ( shouldInit('inputgroup', '.sage-input-group') ) { + Sage.inputgroup.init(); + } + + // Initialize Input groups + if ( shouldInit('inputhelper', '.sage-input-helper') ) { + Sage.inputhelper.init(); + } + + // Initialize Meter + if ( shouldInit('meter', '.sage-meter') ) { + Sage.meter.init(); + } + + // Initialize Banner + if ( shouldInit('banner', '.sage-banner--active') && !document.querySelector('.sage-docs') ) { + Sage.banner.init(); + } + +} diff --git a/lib/sage-frontend/javascript/system/inputgroup.js b/lib/sage-frontend/javascript/system/inputgroup.js new file mode 100644 index 000000000..583b70821 --- /dev/null +++ b/lib/sage-frontend/javascript/system/inputgroup.js @@ -0,0 +1,47 @@ +Sage.inputgroup = (function() { + + // ================================================== + // Functions + // ================================================== + + function togglePasswordDisplay(evt) { + var parentEle = evt.target.parentElement, + field = parentEle.querySelector(".sage-input__field"), + activeClassName = "sage-input-group--visible"; + + if (field.type === "password") { + field.type = "text"; + parentEle.classList.add(activeClassName); + } else { + field.type = "password"; + parentEle.classList.remove(activeClassName); + } + + field.focus(); + } + + + function bindPWEvents() { + var pwShowBtn = Sage.util.nodelistToArray(document.querySelectorAll("[data-js-mask='password']")); + + // show/hide password text; assumes multiple password fields + pwShowBtn.forEach(function(btn) { + btn.addEventListener("click", function(e) { + togglePasswordDisplay(e); + }); + }); + } + + + function init() { + if (document.querySelector(".sage-input-group__toggle").length !== null) { + bindPWEvents(); + } + } + + + return { + init: init + }; + +})(); diff --git a/lib/sage-frontend/javascript/system/inputhelper.js b/lib/sage-frontend/javascript/system/inputhelper.js new file mode 100644 index 000000000..b773bf0e1 --- /dev/null +++ b/lib/sage-frontend/javascript/system/inputhelper.js @@ -0,0 +1,153 @@ +Sage.inputhelper = (function() { + + // ================================================== + // Variables + // ================================================== + var spcValues = /(?=.*[~`!@#$%^&*|(){}/=:;.,<>+-])/g; + var numValues = /(?=[0-9])/g; + var minLengthPW = 8; + + var visibleHintClass = "sage-input-helper--visible"; + var passingClass = "sage-hint__list-item--success"; + var inputErrorClass = "sage-input--error"; + var sageMeterBar = ".sage-meter__bar"; + + + // ================================================== + // Functions + // ================================================== + + // update strength level of password + function updateStrengthMeter(inputValue, meter, reqsMet) { + var trueScore, revisedScore; + + if (typeof zxcvbn !== "undefined") { + trueScore = zxcvbn(inputValue).score; + // artificially reduce score if requirements are not met + revisedScore = (reqsMet === true ? trueScore : trueScore - 1); + // update meter value + meter.value = revisedScore; + // append corresponding classes + Sage.meter.updateMeter(sageMeterBar); + } else { + // hides meter if zxcvbn library is not loaded + meter.closest(".sage-meter").style.display = "none"; + } + } + + // test value against regex string + function regexTest(str, testMatch) { + return testMatch.test(str); + } + + // check for password length + function pwLength(str) { + return str.length >= minLengthPW; + } + + function checkRequirements(ele, reqs, meter) { + var val = ele.value; + var metChar = false, + metSym = false, + metNum = false, + metAllReqs = false; + + reqs.forEach(function(item) { + if (item.type === "characters") { + metChar = updateCriteria(pwLength(val), item.id); + } else if (item.type === "symbols") { + metSym = updateCriteria(regexTest(val, spcValues), item.id); + } else if (item.type === "numbers") { + metNum = updateCriteria(regexTest(val, numValues), item.id); + } + }); + + // all requirements are met + if (metChar && metSym && metNum) { + metAllReqs = true; + ele.parentElement.classList.remove(inputErrorClass); + } + + updateStrengthMeter(val, meter, metAllReqs); + } + + // toggles item criteria + function updateCriteria(bool, itemID) { + var criteria = document.getElementById(itemID); + + if (bool === true ) { + criteria.classList.add(passingClass); + } else { + criteria.classList.remove(passingClass); + } + return bool; + } + + + // toggles visibility of helper window + function toggleHintIE(ele, className) { + if (ele.classList.contains(className)) { + ele.classList.remove(className); + } else { + ele.classList.add(className); + } + } + + + // trigger classes for active state in IE + function focusBlurIE(field) { + field.addEventListener("focus", function(e) { + toggleHintIE(helper, visibleHintClass); + }); + field.addEventListener("blur", function(e) { + toggleHintIE(helper, visibleHintClass); + }); + } + + + // bind events related to each input helper for passwords + function bindPWEvents(helper) { + var fieldID = helper.getAttribute("data-js-helper-target"), + field = document.getElementById(fieldID), + meter = helper.querySelector(".sage-meter__bar"); + + var helperList = Sage.util.nodelistToArray(helper.querySelectorAll(".sage-hint__list-item")), + helperReqItems = helperList.map(function(ele) { + return { + id: ele.id, + type: ele.getAttribute("data-js-hint-type") || null + } + }); + + if (Sage.util.isIE()) { + focusBlurIE(field); + } + + field.addEventListener("input", function(e) { + var targetField = e.target, + fieldParent = e.target.parentElement; + + // add error state + fieldParent.classList.add(inputErrorClass); + checkRequirements(targetField, helperReqItems, meter); + }); + } + + + function init() { + if (document.querySelector("[data-js-helper-target]") !== null) { + var helperTargets = Sage.util.nodelistToArray(document.querySelectorAll("[data-js-helper-target]")); + + helperTargets.forEach(function(helper) { + bindPWEvents(helper); + }); + } + } + + + return { + init: init, + updateStrengthMeter: updateStrengthMeter + }; + +})(); diff --git a/lib/sage-frontend/javascript/system/meter.js b/lib/sage-frontend/javascript/system/meter.js new file mode 100644 index 000000000..507679783 --- /dev/null +++ b/lib/sage-frontend/javascript/system/meter.js @@ -0,0 +1,60 @@ +Sage.meter = (function() { + + // ================================================== + // Functions + // ================================================== + + // builds an object from meter data + function getMeterValues(ele) { + var meter = document.querySelector(ele); + + return { + current: meter.value, + optimum: attributeValue(meter, "optimum"), + min: attributeValue(meter, "min"), + max: attributeValue(meter, "max") + }; + } + + + // appends classes to meter for styling of current state + function updateMeter(ele) { + var meter = document.querySelector(ele), + values = getMeterValues(ele), + optimumThreshold = 0.5; + + // reset any meter classes + meter.className = "sage-meter__bar"; + + // assign new class based on current value + if (values.current === values.max) { + meter.classList.add('sage-meter__bar--max'); + } else if ((values.optimum !== 0) && values.current >= values.optimum) { + meter.classList.add('sage-meter__bar--optimum'); + } else if ((values.optimum !== 0) && ((values.current / values.optimum) > optimumThreshold)) { + meter.classList.add('sage-meter__bar--med'); + } else if (values.current <= values.max) { + meter.classList.add('sage-meter__bar--low'); + } + } + + + // retrieve attribute value or default to 0 + function attributeValue(ele, attributeName) { + return ele.hasAttribute(attributeName) ? parseInt(ele.getAttribute(attributeName)) : 0; + } + + + function init() { + if (document.querySelector('[js-meter-type="password"]') !== null) { + updateMeter('[js-meter-type="password"]'); + } + } + + + return { + init: init, + updateMeter: updateMeter + }; + +})(); diff --git a/lib/sage-frontend/javascript/system/overlay.js b/lib/sage-frontend/javascript/system/overlay.js new file mode 100644 index 000000000..c895c70af --- /dev/null +++ b/lib/sage-frontend/javascript/system/overlay.js @@ -0,0 +1,40 @@ +Sage.overlay = (function() { + + // ================================================== + // Variables + // ================================================== + var sageNavOverlay = document.querySelector('.sage-overlay'); + var bodyClassName = 'sage-overlay--open'; + + + // ================================================== + // Functions + // ================================================== + + // open or close overlay + function toggleOverlay(open) { + return open === 'open' ? sageNavOverlay.classList.add(bodyClassName) : sageNavOverlay.classList.remove(bodyClassName) + } + + + function init() { + // Close overlay and sidebar menu on click + sageNavOverlay.addEventListener('click', function(e) { + if (document.querySelector('.sage-overlay--open') !== null) { + toggleOverlay('close'); + Sage.sidebar.resetSideNav(); + } + }); + + } + + + + + + return { + init: init, + toggleOverlay: toggleOverlay + }; + +})(); diff --git a/lib/sage-frontend/javascript/system/select.js b/lib/sage-frontend/javascript/system/select.js new file mode 100644 index 000000000..3c6291ad7 --- /dev/null +++ b/lib/sage-frontend/javascript/system/select.js @@ -0,0 +1,47 @@ +Sage.select = (function() { + + // ================================================== + // Variables + // ================================================== + var elSelectParentList = document.querySelectorAll('.sage-select'), + classActive = 'sage-select--value-selected', + htmlArrow = ''; + + // ================================================== + // Functions + // ================================================== + + function updateValueSelectedState(value, elSelectParent) { + var cL = elSelectParent.classList; + Sage.util.isEmptyString(value) ? cL.remove(classActive) : cL.add(classActive); + } + + function disableSelectPromptOptions(elSelect) { + [].forEach.call(elSelect.options, function(elOption) { + if (elOption.text.startsWith('--')) elOption.setAttribute('disabled', true); + }); + } + + function bindEvents(elSelect, elSelectParent) { + elSelect.addEventListener('change', function(evt) { + updateValueSelectedState(evt.target.value, elSelectParent) + }); + } + + function init() { + elSelectParentList.forEach(function(elSelectParent) { + var elSelect = elSelectParent.querySelector('select'); + + elSelectParent.insertAdjacentHTML('beforeEnd', htmlArrow); + disableSelectPromptOptions(elSelect); + updateValueSelectedState(elSelect.value, elSelectParent); + + bindEvents(elSelect, elSelectParent); + }); + } + + return { + init: init, + }; + +})(); diff --git a/lib/sage-frontend/javascript/system/sidebar.js b/lib/sage-frontend/javascript/system/sidebar.js new file mode 100644 index 000000000..5ee33a334 --- /dev/null +++ b/lib/sage-frontend/javascript/system/sidebar.js @@ -0,0 +1,76 @@ +Sage.sidebar = (function() { + + // ================================================== + // Variables + // ================================================== + var sageToggleBtns = Sage.util.nodelistToArray(document.querySelectorAll('[data-js-target-type="sidebar"]')); + + + // ================================================== + // Functions + // ================================================== + + // open or close sidenav + function toggleSidebar(ele, evt) { + var buttonTarget = document.getElementById(Sage.util.getBtnTarget(evt)); + + buttonTarget.classList.toggle('sage-sidebar--open'); + + if (buttonTarget.classList.contains('sage-sidebar--open')) { + ele.setAttribute('aria-expanded', true); + Sage.overlay.toggleOverlay('open'); + } else { + ele.setAttribute('aria-expanded', false); + Sage.overlay.toggleOverlay('closed'); + } + } + + + // reset sidenav state to closed/default + function resetSideNav() { + if (document.querySelector('.sage-sidebar--open') !== null) { + var openSidebar = document.querySelector('.sage-sidebar--open'); + + openSidebar.classList.remove('sage-sidebar--open'); + sageToggleBtns.forEach(function(btn) { + btn.setAttribute('aria-expanded', false); + }); + Sage.overlay.toggleOverlay('close'); + } + } + + + // ================================================== + // Event handlers + // ================================================== + + function init() { + + // Toggle sidebar on menu button click + sageToggleBtns.forEach(function(btn) { + if (btn.dataset.jsBtnTarget.includes('example-')) { + return; + } + + btn.addEventListener('click', function(e) { + toggleSidebar(this, e); + }); + }); + + // Close overlay and menu on esc keypress + document.addEventListener('keyup', function(e) { + var keyNum = 'which' in e ? e.which : e.keyCode; + + if (keyNum === 27 && document.querySelector('.sage-sidebar--open') !== null) { // esc key + resetSideNav(); + } + }); + } + + + return { + init: init, + resetSideNav: resetSideNav + }; + +})(); diff --git a/lib/sage-frontend/javascript/system/table.js b/lib/sage-frontend/javascript/system/table.js new file mode 100644 index 000000000..f864d201a --- /dev/null +++ b/lib/sage-frontend/javascript/system/table.js @@ -0,0 +1,47 @@ +Sage.table = (function() { + + // ================================================== + // Functions + // ================================================== + + // column sort functions + function sortEvents() { + var sortableCols = Sage.util.nodelistToArray(document.querySelectorAll('.sage-table__sort')); + + // update sorted column + sortableCols.forEach(function(column) { + column.addEventListener('click', function(e) { + if (e.target.classList.contains('sage-table__sort--selected')) { + this.classList.toggle('sage-table__sort--ascending'); + } else { + // NOTE: IE doesn't support multiple args with classList, so we have to run this twice + removeActiveStyle(sortableCols, 'sage-table__sort--selected'); + removeActiveStyle(sortableCols, 'sage-table__sort--ascending'); + + this.classList.add('sage-table__sort--selected'); + } + }); + }); + } + + + // reset classes on elements + function removeActiveStyle(arr, className) { + arr.forEach(function(ele) { + ele.classList.remove(className); + }); + } + + + function init() { + if (document.querySelector('.sage-table--sortable') !== null) { + sortEvents(); + } + } + + + return { + init: init + }; + +})(); diff --git a/lib/sage-frontend/javascript/system/tooltip.js b/lib/sage-frontend/javascript/system/tooltip.js new file mode 100644 index 000000000..c2113e933 --- /dev/null +++ b/lib/sage-frontend/javascript/system/tooltip.js @@ -0,0 +1,100 @@ +Sage.tooltip = function() { + + // ================================================== + // Variables + // ================================================== + var toolTips = Sage.util.nodelistToArray(document.querySelectorAll("[data-tooltip]")); + var toolTipClassname = ".sage-tooltip"; + + + // ================================================== + // Functions + // ================================================== + + toolTips.forEach(function(item) { + item.addEventListener("mouseover", function(e) { + buildToolTip(e); + }); + + item.addEventListener("mouseout", function(e) { + if (e.target.hasAttribute("data-tooltip")) { + window.requestAnimationFrame(removeTooltip); + } + }); + }); + + + // tooltip template + function buildToolTip(e) { + if (!e.target.hasAttribute("data-tooltip")) return; + + var pos = e.target.getAttribute("data-position") || "top"; + var tooltip = document.createElement("div"); + tooltip.className = "sage-tooltip"; + tooltip.innerHTML = e.target.getAttribute("data-tooltip"); + tooltip.position = e.target.getAttribute("data-position"); + tooltip.dataItems = ["data-tooltip-theme", "data-tooltip-size"]; + + if (!tooltip.innerHTML.length > 0) return; + generateClasses(tooltip, e); + + document.body.appendChild(tooltip); + positionTooltip(e.target, tooltip, pos); + } + + + // Removes tooltip from DOM + function removeTooltip() { + if (document.querySelector(toolTipClassname) !== null) { + document.body.removeChild(document.querySelector(toolTipClassname)); + } + } + + + // Builds list of modifier classes from array of data-attributes + function generateClasses(ele, evt) { + ele.dataItems.forEach(function(item) { + var tgt = evt.target; + if (tgt.hasAttribute(item)) { + ele.classList.add("sage-tooltip--" + tgt.getAttribute(item)); + } + }); + } + + + function positionTooltip(parent, tooltip, position) { + var parentCoords = parent.getBoundingClientRect(), + dist = 8, + left, + top; + + switch (position) { + case "left": + top = (parseInt(parentCoords.top) + parseInt(parentCoords.bottom)) / 2 - tooltip.offsetHeight / 2; + left = parseInt(parentCoords.left) - dist - tooltip.offsetWidth; + if (parseInt(parentCoords.left) - tooltip.offsetWidth < 0) { + left = dist; + } + break; + case "right": + top = (parseInt(parentCoords.top) + parseInt(parentCoords.bottom)) / 2 - tooltip.offsetHeight / 2; + left = parentCoords.right + dist; + if (parseInt(parentCoords.right) + tooltip.offsetWidth > document.documentElement.clientWidth) { + left = document.documentElement.clientWidth - tooltip.offsetWidth - dist; + } + break; + case "bottom": + top = parseInt(parentCoords.bottom) + dist; + left = parseInt(parentCoords.left) + (parent.offsetWidth - tooltip.offsetWidth) / 2; + break; + default: + case "top": + top = parseInt(parentCoords.top) - tooltip.offsetHeight - dist; + left = parseInt(parentCoords.left) + (parent.offsetWidth - tooltip.offsetWidth) / 2; + } + + tooltip.style.left = left + "px"; + tooltip.style.top = top + pageYOffset + "px"; + tooltip.classList.add("sage-tooltip-" + position); + } +}; diff --git a/lib/sage-frontend/javascript/system/util.js b/lib/sage-frontend/javascript/system/util.js new file mode 100644 index 000000000..7f0ff2e1b --- /dev/null +++ b/lib/sage-frontend/javascript/system/util.js @@ -0,0 +1,29 @@ +Sage.util = (function(Sage) { + + // retrieve button target from aria-controls or data attribute + function getBtnTarget(e) { + return e.target.getAttribute('aria-controls') ? e.target.getAttribute('aria-controls') : e.target.getAttribute('data-js-menu'); + } + + + // convert nodelist to array for iteration + function nodelistToArray(selection) { + return Array.prototype.slice.apply(selection); + } + + function isEmptyString(str) { + return (!str || 0 === str.length); + } + + function isIE() { + return document.documentMode ? true : false; + } + + return { + getBtnTarget: getBtnTarget, + nodelistToArray: nodelistToArray, + isEmptyString: isEmptyString, + isIE: isIE + }; + +})(Sage); diff --git a/lib/sage-frontend/packs/docs.js b/lib/sage-frontend/packs/docs.js index db58774e9..107a67c91 100644 --- a/lib/sage-frontend/packs/docs.js +++ b/lib/sage-frontend/packs/docs.js @@ -6,5 +6,3 @@ import 'regenerator-runtime/runtime' require.context('../images/docs', true) import '../stylesheets/docs/index.scss' import '../javascript/docs/index' - -console.warn('WEBPACKER DOCS HAS LOADED'); diff --git a/lib/sage-frontend/packs/system.js b/lib/sage-frontend/packs/system.js index a74b02875..52249798c 100644 --- a/lib/sage-frontend/packs/system.js +++ b/lib/sage-frontend/packs/system.js @@ -6,5 +6,3 @@ import 'regenerator-runtime/runtime' require.context('../images/system', true) import '../stylesheets/system/index.scss' import '../javascript/system/index' - -console.warn('WEBPACKER SYSTEM HAS LOADED'); diff --git a/lib/sage-frontend/stylesheets/system/core/_icons.scss b/lib/sage-frontend/stylesheets/system/core/_icons.scss index c92e98a1d..6823e590c 100644 --- a/lib/sage-frontend/stylesheets/system/core/_icons.scss +++ b/lib/sage-frontend/stylesheets/system/core/_icons.scss @@ -15,6 +15,7 @@ $sage-icon-li-margin-right: 0.4em !default; font-family: "Sage"; src: url("#{$sage-icon-font-path}/Sage.eot"); src: url("#{$sage-icon-font-path}/Sage.eot") format("embedded-opentype"), + url("#{$sage-icon-font-path}/Sage.woff2") format("woff2"), url("#{$sage-icon-font-path}/Sage.woff") format("woff"), url("#{$sage-icon-font-path}/Sage.ttf") format("truetype"), url("#{$sage-icon-font-path}/Sage.svg") format("svg"); diff --git a/lib/sage-frontend/stylesheets/system/core/_mixins.scss b/lib/sage-frontend/stylesheets/system/core/_mixins.scss index eb7d45810..aeed8bd65 100644 --- a/lib/sage-frontend/stylesheets/system/core/_mixins.scss +++ b/lib/sage-frontend/stylesheets/system/core/_mixins.scss @@ -78,6 +78,7 @@ arguments: $content ================================================== */ + /* stylelint-disable */ @mixin placeholder { &::-webkit-input-placeholder { @content; @@ -91,7 +92,8 @@ &:-ms-input-placeholder { @content; } -} /* stylelint-enable */ +} +/* stylelint-enable */ /* ================================================== diff --git a/lib/sage-frontend/stylesheets/system/index.scss b/lib/sage-frontend/stylesheets/system/index.scss index 880d3cb46..b0577a30a 100644 --- a/lib/sage-frontend/stylesheets/system/index.scss +++ b/lib/sage-frontend/stylesheets/system/index.scss @@ -1,13 +1,3 @@ -body::before { - content: "WEBPACKER IS LOADED"; - color: pink; - display: fixed; - background: blue; - padding: 40px; - top: 0; - right: 0; -} - // Reset @import "vendor/reboot"; @@ -55,6 +45,7 @@ body::before { @import "utilities/hidden"; // Elements +@import "patterns/elements/meter"; @import "patterns/elements/live_stream_wrapper"; @import "patterns/elements/description"; @import "patterns/elements/label"; @@ -72,6 +63,8 @@ body::before { @import "patterns/elements/overlay"; // Objects +@import "patterns/objects/input_helper"; +@import "patterns/objects/input_group"; @import "patterns/objects/billboard"; @import "patterns/objects/pagination"; @import "patterns/objects/banner"; diff --git a/lib/sage-frontend/images/docs/apple-touch-icon.png b/public/apple-touch-icon.png similarity index 100% rename from lib/sage-frontend/images/docs/apple-touch-icon.png rename to public/apple-touch-icon.png diff --git a/lib/sage-frontend/images/docs/favicon-16x16.png b/public/favicon-16x16.png similarity index 100% rename from lib/sage-frontend/images/docs/favicon-16x16.png rename to public/favicon-16x16.png diff --git a/lib/sage-frontend/images/docs/favicon-32x32.png b/public/favicon-32x32.png similarity index 100% rename from lib/sage-frontend/images/docs/favicon-32x32.png rename to public/favicon-32x32.png diff --git a/public/favicon.ico b/public/favicon.ico index e69de29bb..f0a67c47e 100644 Binary files a/public/favicon.ico and b/public/favicon.ico differ