@ably/ui 11.7.1 → 12.0.0-dev.31bc8d9
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.
- package/README.md +6 -9
- package/core/.DS_Store +0 -0
- package/core/Code/component.css +2 -0
- package/core/ContactFooter.jsx +8 -8
- package/core/DropdownMenu.jsx +1 -1
- package/core/FeaturedLink/component.css +0 -15
- package/core/FeaturedLink/component.js +1 -1
- package/core/FeaturedLink.jsx +17 -6
- package/core/Flash/component.css +0 -4
- package/core/Flash.jsx +1 -1
- package/core/Footer/component.css +3 -3
- package/core/Footer.jsx +14 -14
- package/core/Meganav/component.css +6 -6
- package/core/Meganav.jsx +23 -12
- package/core/MeganavBlogPostsList.jsx +17 -6
- package/core/MeganavContentCompany.jsx +17 -6
- package/core/MeganavContentProducts.jsx +19 -8
- package/core/MeganavItemsMobile.jsx +17 -6
- package/core/MeganavItemsSignedIn.jsx +17 -6
- package/core/MeganavSearch.jsx +17 -6
- package/core/MeganavSearchPanel.jsx +17 -6
- package/core/MeganavSearchSuggestions.jsx +17 -6
- package/core/Notice/component.js +1 -1
- package/core/Notice.jsx +4 -4
- package/core/Showcase/component.css +2 -0
- package/core/Showcase/component.js +6 -1
- package/core/Showcase.jsx +3 -0
- package/core/Uptime/component.css +4 -3
- package/core/Uptime/component.js +6 -1
- package/core/Uptime.jsx +65 -28
- package/core/fonts/jetBrains-mono.css +3 -0
- package/core/fonts/manrope.css +3 -0
- package/core/scripts.js +1 -1
- package/core/styles.css +232 -124
- package/package.json +2 -5
- package/src/core/.DS_Store +0 -0
- package/src/core/ContactFooter/component.jsx +8 -8
- package/src/core/DropdownMenu/component.jsx +1 -1
- package/src/core/FeaturedLink/component.js +0 -1
- package/src/core/FeaturedLink/component.jsx +27 -4
- package/src/core/Flash/component.css +0 -4
- package/src/core/Flash/component.jsx +1 -1
- package/src/core/Footer/component.css +3 -3
- package/src/core/Footer/component.jsx +14 -14
- package/src/core/Meganav/component.css +6 -6
- package/src/core/MeganavContentProducts/component.jsx +2 -2
- package/src/core/Notice/component.jsx +3 -3
- package/src/core/fonts/jetBrains-mono.css +3 -0
- package/src/core/fonts/manrope.css +3 -0
- package/src/core/react-renderer.js +7 -4
- package/src/core/styles/buttons.css +5 -5
- package/src/core/styles/forms.css +5 -5
- package/src/core/styles/properties.css +153 -52
- package/src/core/styles/text.css +68 -61
- package/src/core/styles.components.css +1 -1
- package/src/core/utils/syntax-highlighter.css +2 -0
- package/tailwind.config.js +194 -69
- package/tailwind.extend.js +1 -4
- package/src/core/Code/component.html.erb +0 -3
- package/src/core/Code/component.rb +0 -12
- package/src/core/ContactFooter/component.html.erb +0 -32
- package/src/core/ContactFooter/component.rb +0 -13
- package/src/core/CustomerLogos/component.html.erb +0 -9
- package/src/core/CustomerLogos/component.rb +0 -14
- package/src/core/FeatureFooter/component.html.erb +0 -54
- package/src/core/FeatureFooter/component.rb +0 -30
- package/src/core/FeaturedLink/component.css +0 -15
- package/src/core/FeaturedLink/component.html.erb +0 -6
- package/src/core/FeaturedLink/component.rb +0 -19
- package/src/core/Footer/component.html.erb +0 -256
- package/src/core/Footer/component.rb +0 -14
- package/src/core/Icon/component.html.erb +0 -3
- package/src/core/Icon/component.rb +0 -25
- package/src/core/Loader/component.html.erb +0 -18
- package/src/core/Loader/component.rb +0 -19
- package/src/core/Logo/component.html.erb +0 -3
- package/src/core/Logo/component.rb +0 -31
- package/src/core/Meganav/component.html.erb +0 -31
- package/src/core/Meganav/component.rb +0 -60
- package/src/core/MeganavBlogPostsList/component.html.erb +0 -5
- package/src/core/MeganavBlogPostsList/component.rb +0 -13
- package/src/core/MeganavContentCompany/component.html.erb +0 -90
- package/src/core/MeganavContentCompany/component.rb +0 -14
- package/src/core/MeganavContentDevelopers/component.html.erb +0 -129
- package/src/core/MeganavContentDevelopers/component.rb +0 -13
- package/src/core/MeganavContentProducts/component.html.erb +0 -83
- package/src/core/MeganavContentProducts/component.rb +0 -14
- package/src/core/MeganavContentUseCases/component.html.erb +0 -135
- package/src/core/MeganavContentUseCases/component.rb +0 -13
- package/src/core/MeganavControl/component.html.erb +0 -6
- package/src/core/MeganavControl/component.rb +0 -20
- package/src/core/MeganavControlMobileDropdown/component.html.erb +0 -7
- package/src/core/MeganavControlMobileDropdown/component.rb +0 -11
- package/src/core/MeganavControlMobilePanelClose/component.html.erb +0 -12
- package/src/core/MeganavControlMobilePanelClose/component.rb +0 -12
- package/src/core/MeganavControlMobilePanelOpen/component.html.erb +0 -7
- package/src/core/MeganavControlMobilePanelOpen/component.rb +0 -9
- package/src/core/MeganavItemsDesktop/component.html.erb +0 -17
- package/src/core/MeganavItemsDesktop/component.rb +0 -23
- package/src/core/MeganavItemsMobile/component.html.erb +0 -75
- package/src/core/MeganavItemsMobile/component.rb +0 -21
- package/src/core/MeganavItemsSignedIn/component.html.erb +0 -53
- package/src/core/MeganavItemsSignedIn/component.rb +0 -33
- package/src/core/MeganavSearch/component.html.erb +0 -15
- package/src/core/MeganavSearch/component.rb +0 -13
- package/src/core/MeganavSearchAutocomplete/component.html.erb +0 -6
- package/src/core/MeganavSearchAutocomplete/component.rb +0 -6
- package/src/core/MeganavSearchPanel/component.html.erb +0 -22
- package/src/core/MeganavSearchPanel/component.rb +0 -13
- package/src/core/MeganavSearchSuggestions/component.html.erb +0 -22
- package/src/core/MeganavSearchSuggestions/component.rb +0 -18
- package/src/core/Notice/component.html.erb +0 -16
- package/src/core/Notice/component.rb +0 -29
- package/src/core/Showcase/component.css +0 -30
- package/src/core/Showcase/component.html.erb +0 -76
- package/src/core/Showcase/component.js +0 -180
- package/src/core/Showcase/component.jsx +0 -0
- package/src/core/Showcase/component.rb +0 -190
- package/src/core/SignOutLink/component.html.erb +0 -1
- package/src/core/SignOutLink/component.rb +0 -17
- package/src/core/Slider/component.html.erb +0 -28
- package/src/core/Slider/component.rb +0 -38
- package/src/core/Uptime/component.css +0 -128
- package/src/core/Uptime/component.html.erb +0 -0
- package/src/core/Uptime/component.js +0 -1
- package/src/core/Uptime/component.jsx +0 -186
- package/src/core/Uptime/component.rb +0 -7
- package/src/core/core.rb +0 -81
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
<ul class="flex md:hidden" data-id="meganav-items-mobile">
|
|
2
|
-
<li>
|
|
3
|
-
<% if @session_data[:signedIn] && @session_data[:logOut] %>
|
|
4
|
-
<%= render(AblyUi::Core::SignOutLink.new(session_data: @session_data, classes: ["ui-meganav-link", theme(:text_color)], url_base: url_base)) %>
|
|
5
|
-
<% else %>
|
|
6
|
-
<%= link_to "Login", abs_url(login_link), data: { id: "meganav-link" }, class: ["ui-meganav-link", theme(:text_color)] %>
|
|
7
|
-
<% end %>
|
|
8
|
-
</li>
|
|
9
|
-
|
|
10
|
-
<li class="ui-meganav-item">
|
|
11
|
-
<%= render(AblyUi::Core::MeganavControlMobileDropdown.new(theme_name: @theme_name)) %>
|
|
12
|
-
|
|
13
|
-
<div class="ui-meganav-mobile-dropdown invisible" id="meganav-mobile-dropdown" data-id="meganav-mobile-dropdown">
|
|
14
|
-
<div class="pt-24 pb-16 ui-grid-px bg-white">
|
|
15
|
-
<%= tag.form class: "mb-16", action: abs_url("/search"), method: "get" do %>
|
|
16
|
-
<div class="relative w-full">
|
|
17
|
-
<%= render(AblyUi::Core::Icon.new(name: "icon-gui-search", size: "1.5rem", color: "text-cool-black", additional_css: "absolute top-12 left-16 hover:text-gui-hover")) %>
|
|
18
|
-
<button
|
|
19
|
-
type="button"
|
|
20
|
-
class="absolute top-12 right-16 p-0 focus:outline-gui-focus m-0 md:hidden invisible"
|
|
21
|
-
data-id="meganav-search-input-clear"
|
|
22
|
-
>
|
|
23
|
-
<%= render(AblyUi::Core::Icon.new(name: "icon-gui-cross-circled-fill", size: "1.5rem", color: "text-dark-grey")) %>
|
|
24
|
-
</button>
|
|
25
|
-
<input
|
|
26
|
-
type="search"
|
|
27
|
-
name="q"
|
|
28
|
-
class="ui-input px-48 h-48"
|
|
29
|
-
style={{ maxWidth: "none" }}
|
|
30
|
-
placeholder="Search"
|
|
31
|
-
autocomplete="off"
|
|
32
|
-
data-id="meganav-mobile-search-input"
|
|
33
|
-
/>
|
|
34
|
-
|
|
35
|
-
<%= render(AblyUi::Core::MeganavSearchAutocomplete.new) %>
|
|
36
|
-
</div>
|
|
37
|
-
<% end %>
|
|
38
|
-
|
|
39
|
-
<div class="max-h-0 overflow-hidden transition-all" data-id="meganav-mobile-search-suggestions">
|
|
40
|
-
<%= render(AblyUi::Core::MeganavSearchSuggestions.new(url_base: url_base, display_support_link: false)) %>
|
|
41
|
-
</div>
|
|
42
|
-
|
|
43
|
-
<ul class="mb-16" data-id="meganav-mobile-panel-controls">
|
|
44
|
-
<% panels.each do |panel| %>
|
|
45
|
-
<li class="ui-meganav-mobile-item">
|
|
46
|
-
<%= render(AblyUi::Core::MeganavControlMobilePanelOpen.new(aria_controls: "#{panel[:id]}-mobile")) do %>
|
|
47
|
-
<%= panel[:label] %>
|
|
48
|
-
<% end %>
|
|
49
|
-
|
|
50
|
-
<%= content_tag(:div, class: "ui-meganav-panel-mobile hidden", id: "#{panel[:id]}-mobile", data: { scroll_lock_scrollable: true }) do %>
|
|
51
|
-
<%= render(AblyUi::Core::MeganavControlMobilePanelClose.new(aria_controls: "#{panel[:id]}-mobile", display_hr: display_hr(panel[:id]))) %>
|
|
52
|
-
<%= render("AblyUi::Core::#{panel[:component]}".constantize.new(url_base: url_base)) %>
|
|
53
|
-
<% end %>
|
|
54
|
-
</li>
|
|
55
|
-
<% end %>
|
|
56
|
-
<li>
|
|
57
|
-
<%= link_to "Pricing", abs_url("/pricing"), class: "ui-meganav-mobile-link" %>
|
|
58
|
-
</li>
|
|
59
|
-
</ul>
|
|
60
|
-
|
|
61
|
-
<hr class="ui-meganav-hr mb-20" />
|
|
62
|
-
|
|
63
|
-
<div class="flex justify-between items-center mb-16">
|
|
64
|
-
<%= link_to "Contact us", abs_url("/contact"), class: "text-menu2 font-medium block ml-0 mr-8 lg:mx-12 p-0 hover:text-gui-hover focus:text-gui-focus focus:outline-none" %>
|
|
65
|
-
|
|
66
|
-
<% if @session_data[:signedIn] && @session_data[:account] %>
|
|
67
|
-
<%= link_to "Dashboard", abs_url(@session_data[:account][:links][:dashboard][:href]), class: "ui-btn-secondary" %>
|
|
68
|
-
<% else %>
|
|
69
|
-
<%= link_to "Sign up free", abs_url("/sign-up"), class: "ui-btn" %>
|
|
70
|
-
<% end %>
|
|
71
|
-
</div>
|
|
72
|
-
</div>
|
|
73
|
-
</div>
|
|
74
|
-
</li>
|
|
75
|
-
</ul>
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
module AblyUi
|
|
2
|
-
module Core
|
|
3
|
-
class MeganavItemsMobile < ViewComponent::Base
|
|
4
|
-
include MeganavConfig
|
|
5
|
-
include Util
|
|
6
|
-
|
|
7
|
-
attr_reader :options, :login_link, :url_base
|
|
8
|
-
|
|
9
|
-
def initialize(session_data:, theme_name:, login_link:, url_base:)
|
|
10
|
-
@theme_name = theme_name
|
|
11
|
-
@session_data = session_data
|
|
12
|
-
@login_link = login_link
|
|
13
|
-
@url_base = url_base
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
def display_hr(panel_id)
|
|
17
|
-
%w[company-panel developers-panel].include?(panel_id)
|
|
18
|
-
end
|
|
19
|
-
end
|
|
20
|
-
end
|
|
21
|
-
end
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
<ul class="hidden md:flex items-center">
|
|
2
|
-
<li class="ui-meganav-item relative">
|
|
3
|
-
<%= render(AblyUi::Core::MeganavControl.new(aria_controls: "account-panel", aria_label: "Account", theme_name: @theme_name, additional_css: "mr-0")) do %>
|
|
4
|
-
<%= account_name %>
|
|
5
|
-
<% end %>
|
|
6
|
-
|
|
7
|
-
<div class="ui-meganav-panel-account invisible" id="account-panel" data-id="meganav-panel">
|
|
8
|
-
<% if account? %>
|
|
9
|
-
<p class="ui-meganav-overline mt-16 mx-16">Your account</p>
|
|
10
|
-
<ul class="mb-16 mx-16">
|
|
11
|
-
<% @session_data[:account][:links].each do |key, link| %>
|
|
12
|
-
<li>
|
|
13
|
-
<%= link_to link[:text], link[:href], class: "ui-meganav-account-link" %>
|
|
14
|
-
</li>
|
|
15
|
-
<% end %>
|
|
16
|
-
</ul>
|
|
17
|
-
<% end %>
|
|
18
|
-
|
|
19
|
-
<p class="ui-meganav-overline mx-16"><%= preferred_email %></p>
|
|
20
|
-
<ul class="mb-8 mx-16">
|
|
21
|
-
<li>
|
|
22
|
-
<%= link_to @session_data[:mySettings][:text], @session_data[:mySettings][:href], class: "ui-meganav-account-link" %>
|
|
23
|
-
</li>
|
|
24
|
-
|
|
25
|
-
<% if access_tokens? %>
|
|
26
|
-
<li>
|
|
27
|
-
<%= link_to @session_data[:myAccessTokens][:href], class: "ui-meganav-account-link" do %>
|
|
28
|
-
<%= @session_data[:myAccessTokens][:text] %><span class="ui-version-tag">preview</span>
|
|
29
|
-
<% end %>
|
|
30
|
-
</li>
|
|
31
|
-
<% end %>
|
|
32
|
-
</ul>
|
|
33
|
-
|
|
34
|
-
<hr class="ui-meganav-hr mb-16" />
|
|
35
|
-
|
|
36
|
-
<div class="mb-16 px-16">
|
|
37
|
-
<% if @session_data[:logOut] %>
|
|
38
|
-
<%= render(AblyUi::Core::SignOutLink.new(session_data: @session_data, classes: "ui-meganav-account-link", url_base: url_base)) %>
|
|
39
|
-
<% end %>
|
|
40
|
-
</div>
|
|
41
|
-
</div>
|
|
42
|
-
</li>
|
|
43
|
-
|
|
44
|
-
<li>
|
|
45
|
-
<%= render(AblyUi::Core::MeganavSearch.new(url_base: url_base)) %>
|
|
46
|
-
</li>
|
|
47
|
-
|
|
48
|
-
<% if account? %>
|
|
49
|
-
<li>
|
|
50
|
-
<%= link_to "Dashboard", @session_data[:account][:links][:dashboard][:href], class: "ui-btn-secondary p-btn-small" %>
|
|
51
|
-
</li>
|
|
52
|
-
<% end %>
|
|
53
|
-
</ul>
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
module AblyUi
|
|
2
|
-
module Core
|
|
3
|
-
class MeganavItemsSignedIn < ViewComponent::Base
|
|
4
|
-
include MeganavConfig
|
|
5
|
-
include Util
|
|
6
|
-
|
|
7
|
-
attr_reader :url_base
|
|
8
|
-
|
|
9
|
-
def initialize(session_data:, theme_name:, url_base:)
|
|
10
|
-
@theme_name = theme_name
|
|
11
|
-
@session_data = session_data
|
|
12
|
-
@url_base = url_base
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
def account?
|
|
16
|
-
@session_data[:account].present?
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
# Access tokens are behind a feature flag
|
|
20
|
-
def access_tokens?
|
|
21
|
-
@session_data[:myAccessTokens].present?
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
def account_name
|
|
25
|
-
truncate(@session_data[:accountName], length: 20)
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
def preferred_email
|
|
29
|
-
truncate(@session_data[:preferredEmail], length: 20)
|
|
30
|
-
end
|
|
31
|
-
end
|
|
32
|
-
end
|
|
33
|
-
end
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
<button
|
|
2
|
-
type="button"
|
|
3
|
-
data-id="meganav-control"
|
|
4
|
-
data-control="search"
|
|
5
|
-
class="h-64 w-24 px-24 pr-48 py-20 group focus:outline-none"
|
|
6
|
-
aria-expanded="false"
|
|
7
|
-
aria-controls="panel-search"
|
|
8
|
-
aria-label="Show Search Panel"
|
|
9
|
-
>
|
|
10
|
-
<%= render(AblyUi::Core::Icon.new(name: "icon-gui-search", size: "1.5rem", color: "text-cool-black", additional_css: "group-hover:text-gui-hover group-focus:text-gui-focus")) %>
|
|
11
|
-
</button>
|
|
12
|
-
|
|
13
|
-
<div class="ui-meganav-panel invisible" id="panel-search" data-id="meganav-panel">
|
|
14
|
-
<%= render(AblyUi::Core::MeganavSearchPanel.new(url_base: url_base)) %>
|
|
15
|
-
</div>
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
<section class="ui-meganav-content grid-cols-12">
|
|
2
|
-
<div class="col-span-8">
|
|
3
|
-
<div class="mb-32">
|
|
4
|
-
<%= tag.form class: "flex items-start", action: abs_url("/search"), method: "get" do %>
|
|
5
|
-
<div class="relative w-full">
|
|
6
|
-
<%= render(AblyUi::Core::Icon.new(name: "icon-gui-search", size: "1.5rem", color: "text-cool-black", additional_css:"absolute top-12 left-16")) %>
|
|
7
|
-
<input type="search" name="q" class="ui-input pl-48 h-48" placeholder="Search" autocomplete="off" data-id="meganav-search-input" />
|
|
8
|
-
|
|
9
|
-
<%= render(AblyUi::Core::MeganavSearchAutocomplete.new) %>
|
|
10
|
-
</div>
|
|
11
|
-
|
|
12
|
-
<button type="submit" class="ui-btn-secondary flex-shrink-0 ml-8 sm:ml-16 md:ml-24 xl:ml-32">
|
|
13
|
-
Search
|
|
14
|
-
</button>
|
|
15
|
-
<% end %>
|
|
16
|
-
</div>
|
|
17
|
-
</div>
|
|
18
|
-
|
|
19
|
-
<div class="col-span-12">
|
|
20
|
-
<%= render(AblyUi::Core::MeganavSearchSuggestions.new(url_base: url_base)) %>
|
|
21
|
-
</div>
|
|
22
|
-
</section>
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
<p class="ui-text-overline2 text-cool-black py-12">Popular pages</p>
|
|
2
|
-
|
|
3
|
-
<div class="flex justify-between items-center overflow-hidden">
|
|
4
|
-
<ul class="flex transition-transform">
|
|
5
|
-
<li class="py-12 pr-8 flex-shrink-0">
|
|
6
|
-
<%= link_to 'How does Ably work?', abs_url("/docs/how-ably-works"), class: "ui-text-p2 hover:text-gui-hover active:text-gui-active focus:text-gui-focus" %>
|
|
7
|
-
</li>
|
|
8
|
-
<li class="py-12 px-8 flex-shrink-0">
|
|
9
|
-
<%= link_to 'Quickstart guide', abs_url("/docs/quick-start-guide"), class: "ui-text-p2 hover:text-gui-hover active:text-gui-active focus:text-gui-focus" %>
|
|
10
|
-
</li>
|
|
11
|
-
<li class="py-12 px-8 flex-shrink-0">
|
|
12
|
-
<%= link_to 'Publish/Subscribe Messaging', abs_url("/docs/core-features/pubsub"), class: "ui-text-p2 hover:text-gui-hover active:text-gui-active focus:text-gui-focus" %>
|
|
13
|
-
</li>
|
|
14
|
-
<li class="py-12 pl-8 flex-shrink-0">
|
|
15
|
-
<%= link_to 'Platform', abs_url("/platform"), class: "ui-text-p2 hover:text-gui-hover active:text-gui-active focus:text-gui-focus" %>
|
|
16
|
-
</li>
|
|
17
|
-
</ul>
|
|
18
|
-
|
|
19
|
-
<% if display_support_link? %>
|
|
20
|
-
<%= render(AblyUi::Core::FeaturedLink.new(url: abs_url("/support"), text_size: "text-p2")) do %>Support<% end %>
|
|
21
|
-
<% end %>
|
|
22
|
-
</div>
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
module AblyUi
|
|
2
|
-
module Core
|
|
3
|
-
class MeganavSearchSuggestions < ViewComponent::Base
|
|
4
|
-
include Util
|
|
5
|
-
|
|
6
|
-
attr_reader :url_base
|
|
7
|
-
|
|
8
|
-
def initialize(url_base:, display_support_link: true)
|
|
9
|
-
@url_base = url_base
|
|
10
|
-
@display_support_link = display_support_link
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
def display_support_link?
|
|
14
|
-
@display_support_link
|
|
15
|
-
end
|
|
16
|
-
end
|
|
17
|
-
end
|
|
18
|
-
end
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
<%# Note the style attribute is used for entry animation %>
|
|
2
|
-
<%= tag.div class: "ui-announcement #{bg_color} #{text_color}", data: { id: "ui-notice" }, style: "max-height: 0; overflow: hidden" do %>
|
|
3
|
-
<div class="ui-grid-px py-16 max-w-screen-xl mx-auto flex items-start">
|
|
4
|
-
<%= content_wrapper class: "font-light w-full pr-8 text-p3 self-center" do %>
|
|
5
|
-
<strong class="font-medium whitespace-nowrap pr-4"><%= @contents[:title] %></strong>
|
|
6
|
-
<span class="pr-4"><%= @contents[:body_text] %></span>
|
|
7
|
-
<span class="underline cursor-pointer whitespace-nowrap"><%= @contents[:button_label] %></span>
|
|
8
|
-
<% end %>
|
|
9
|
-
|
|
10
|
-
<% if close_btn? %>
|
|
11
|
-
<%= button_tag type: 'button', class: 'h-20 w-20 mt-4 ml-auto border-none bg-none self-baseline' do %>
|
|
12
|
-
<%= render(AblyUi::Core::Icon.new(name: "icon-gui-close", size: "1.25rem", color: "text-white")) %>
|
|
13
|
-
<% end %>
|
|
14
|
-
<% end %>
|
|
15
|
-
</div>
|
|
16
|
-
<% end %>
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
module AblyUi
|
|
2
|
-
module Core
|
|
3
|
-
class Notice < ViewComponent::Base
|
|
4
|
-
def initialize(contents)
|
|
5
|
-
@contents = contents
|
|
6
|
-
end
|
|
7
|
-
|
|
8
|
-
def close_btn?
|
|
9
|
-
@contents[:close_btn]
|
|
10
|
-
end
|
|
11
|
-
|
|
12
|
-
def bg_color
|
|
13
|
-
@contents[:bg_color] || 'bg-gradient-active-orange'
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
def text_color
|
|
17
|
-
@contents[:text_color] || 'text-white'
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
def content_wrapper(*args, &block)
|
|
21
|
-
if @contents[:button_link].present?
|
|
22
|
-
link_to(@contents[:button_link], *args, &block)
|
|
23
|
-
else
|
|
24
|
-
tag.div(*args, &block)
|
|
25
|
-
end
|
|
26
|
-
end
|
|
27
|
-
end
|
|
28
|
-
end
|
|
29
|
-
end
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
@layer components {
|
|
2
|
-
.ui-showcase-overflow-container {
|
|
3
|
-
-ms-overflow-style: none; /* Internet Explorer 10+ */
|
|
4
|
-
scrollbar-width: none; /* Firefox */
|
|
5
|
-
|
|
6
|
-
@apply overflow-x-auto;
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
.ui-showcase-overflow-container::-webkit-scrollbar {
|
|
10
|
-
@apply hidden; /* Safari and Chrome */
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
.ui-showcase-logo-wrapper {
|
|
14
|
-
@apply flex bg-white;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
.ui-showcase-logo {
|
|
18
|
-
min-width: var(--ui-showcase-client-logo-min-width);
|
|
19
|
-
@apply w-full py-16 px-12 flex items-center justify-center;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
.ui-showcase-logo-img {
|
|
23
|
-
max-width: var(--ui-showcase-client-logo-max-width);
|
|
24
|
-
@apply w-full;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
.ui-showcase-index-bar {
|
|
28
|
-
@apply bg-mid-grey;
|
|
29
|
-
}
|
|
30
|
-
}
|
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
<section
|
|
2
|
-
aria-roledescription="carousel"
|
|
3
|
-
aria-label="Ably customers showcase"
|
|
4
|
-
aria-live="off"
|
|
5
|
-
class="font-sans antialiased rounded-sm shadow-container-subtle"
|
|
6
|
-
data-id="showcase"
|
|
7
|
-
>
|
|
8
|
-
<div class="ui-showcase-overflow-container">
|
|
9
|
-
<ol class="ui-showcase-logo-wrapper" data-id="showcase-controls">
|
|
10
|
-
<% companies_data.each_with_index do |company, index| %>
|
|
11
|
-
<li class="ui-showcase-logo">
|
|
12
|
-
<%= tag.button class: ['focus:outline-gui-focus', 'border-none', 'p-0', 'transition-filter'],
|
|
13
|
-
type: 'button',
|
|
14
|
-
data: { id: 'showcase-control' },
|
|
15
|
-
aria: { controls: @random_id } do %>
|
|
16
|
-
<%= image_tag company[:logo], alt: "#{company[:name]} logo", class: ['ui-showcase-logo-img', index === 0 ? 'filter-none' : 'filter-grayscale', 'hover:filter-none'], srcset: [["#{company[:logo2x]}", "2x"]] %>
|
|
17
|
-
<% end %>
|
|
18
|
-
</li>
|
|
19
|
-
<% end %>
|
|
20
|
-
</ol>
|
|
21
|
-
|
|
22
|
-
<div class="ui-showcase-index-bar">
|
|
23
|
-
<div data-id="showcase-index-bar" class="transform transition-transform w-1/<%= companies_data.size %> h-4 bg-active-orange relative"></div>
|
|
24
|
-
</div>
|
|
25
|
-
</div>
|
|
26
|
-
|
|
27
|
-
<div class="overflow-x-hidden">
|
|
28
|
-
<ol class="flex transform transition-transform" data-id="showcase-slides" id="<%= @random_id %>">
|
|
29
|
-
<% companies_data.each_with_index do |company, index| %>
|
|
30
|
-
<li
|
|
31
|
-
class="w-full flex-shrink-0 p-24 sm:p-32 xl:p-64 bg-white"
|
|
32
|
-
role="group"
|
|
33
|
-
aria-roledescription="slide"
|
|
34
|
-
aria-label="<%= index + 1 %> of <%= companies_data.size %>"
|
|
35
|
-
>
|
|
36
|
-
<% if company[:layout] == "quotes" %>
|
|
37
|
-
<%= render(AblyUi::Core::Icon.new(name: "quote", size: "1.25rem", color: "text-cool-black")) %>
|
|
38
|
-
|
|
39
|
-
<p class="text-quote font-light mb-24"><%= company[:quote] %></p>
|
|
40
|
-
|
|
41
|
-
<div class="flex items-center">
|
|
42
|
-
<div class="flex-shrink-0 flex-grow-0 mr-16 overflow-hidden rounded-full flex align-center justify-center w-48 h-48">
|
|
43
|
-
<%= image_tag company[:author][:thumbnail], alt: "Picture of #{company[:author][:name]}, #{company[:author][:title]}", class: "w-48 h-48 filter-grayscale" %>
|
|
44
|
-
</div>
|
|
45
|
-
<div>
|
|
46
|
-
<p class="text-p2 font-medium"><%= company[:author][:name] %></p>
|
|
47
|
-
<p class="text-p3 font-light"><%= company[:author][:title] %></p>
|
|
48
|
-
</div>
|
|
49
|
-
</div>
|
|
50
|
-
<% end %>
|
|
51
|
-
|
|
52
|
-
<% if company[:layout] == "casestudies" %>
|
|
53
|
-
<div class="flex justify-evenly text-cool-black full-width flex-col md:flex-row" data-id="showcase-casestudy">
|
|
54
|
-
<% company[:columns].each_with_index do |col, n| %>
|
|
55
|
-
<% if company[:columns].last == col %>
|
|
56
|
-
<div class="flex-1 mt-40 sm:mt-0 <%= col[:classname] %>" data-id="casestudy-column">
|
|
57
|
-
<p class="text-h4 pb-24"><%= col[:heading] %></p>
|
|
58
|
-
<p class="text-p1 font-light"><%= col[:text] %></p>
|
|
59
|
-
<%- if col[:button] %>
|
|
60
|
-
<a class="ui-btn self-start p-btn mt-24" href="<%= col[:button][:href] %>"><%= col[:button][:label] %></a>
|
|
61
|
-
<% end %>
|
|
62
|
-
</div>
|
|
63
|
-
<% else %>
|
|
64
|
-
<div class="flex-1 mt-40 sm:mt-0 mr-24 sm:mr-32 xl:mr-64 <%= col[:classname] %>" data-id="casestudy-column">
|
|
65
|
-
<p class="text-title-xl font-extra-large"><%= col[:heading] %></p>
|
|
66
|
-
<p class="text-p1 font-light mb-0 sm:mb-32"><%= col[:text] %></p>
|
|
67
|
-
</div>
|
|
68
|
-
<% end %>
|
|
69
|
-
<% end %>
|
|
70
|
-
</div>
|
|
71
|
-
<% end %>
|
|
72
|
-
</li>
|
|
73
|
-
<% end %>
|
|
74
|
-
</ol>
|
|
75
|
-
</div>
|
|
76
|
-
</section>
|
|
@@ -1,180 +0,0 @@
|
|
|
1
|
-
import { queryId, queryIdAll } from "../dom-query";
|
|
2
|
-
import { remsToPixelValue } from "../css";
|
|
3
|
-
|
|
4
|
-
import "./component.css";
|
|
5
|
-
|
|
6
|
-
const SLIDE_SHOW_INTERVAL = 5000;
|
|
7
|
-
|
|
8
|
-
const updateLogoOpacity = (logos, currentIndex) => {
|
|
9
|
-
const visible = ["filter-grayscale", "filter-none"];
|
|
10
|
-
const opaque = [...visible].reverse();
|
|
11
|
-
logos.forEach((logo, i) => {
|
|
12
|
-
logo.classList.replace(...(i === currentIndex ? visible : opaque));
|
|
13
|
-
});
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
const translateX = (el, currentIndex, direction = 1) => {
|
|
17
|
-
const percent = currentIndex * 100 * direction;
|
|
18
|
-
el.style.transform = `translateX(${percent}%)`;
|
|
19
|
-
};
|
|
20
|
-
|
|
21
|
-
const moveControlsContainer = (controlsContainer, currentIndex) => {
|
|
22
|
-
const { parentNode, children } = controlsContainer;
|
|
23
|
-
const parentCenter = parentNode.clientWidth / 2;
|
|
24
|
-
const countChildren = children.length;
|
|
25
|
-
const widthChildren = Array.from(children)
|
|
26
|
-
.map((el) => el.clientWidth)
|
|
27
|
-
.reduce((a, c) => a + c);
|
|
28
|
-
|
|
29
|
-
const width = widthChildren / countChildren;
|
|
30
|
-
const firstOrLast = !currentIndex || !(countChildren - currentIndex - 1);
|
|
31
|
-
const offsetLeft = !firstOrLast ? parentCenter - width / 2 : 0;
|
|
32
|
-
const left = currentIndex * width - (offsetLeft >> 0);
|
|
33
|
-
|
|
34
|
-
parentNode.scrollTo({ left, behavior: "smooth" });
|
|
35
|
-
};
|
|
36
|
-
|
|
37
|
-
const propertyValue = (string) => {
|
|
38
|
-
return window
|
|
39
|
-
.getComputedStyle(document.documentElement)
|
|
40
|
-
.getPropertyValue(string);
|
|
41
|
-
};
|
|
42
|
-
|
|
43
|
-
const mobileBreakpoint = (pixelWidth) => {
|
|
44
|
-
if (typeof window === "undefined") return false;
|
|
45
|
-
|
|
46
|
-
// Margin for small breakpoint, but could be different in practice
|
|
47
|
-
const estimatedMargin = 64;
|
|
48
|
-
const breakpointEstimate = `${pixelWidth + estimatedMargin}px`;
|
|
49
|
-
|
|
50
|
-
return !window.matchMedia(`(min-width: ${breakpointEstimate})`).matches;
|
|
51
|
-
};
|
|
52
|
-
|
|
53
|
-
export default (node, enableSlideshow) => {
|
|
54
|
-
const container = node || queryId("showcase");
|
|
55
|
-
const controls = Array.from(queryIdAll("showcase-control", container));
|
|
56
|
-
const logos = controls.map((control) => control.querySelector("img"));
|
|
57
|
-
const controlsContainer = queryId("showcase-controls", container);
|
|
58
|
-
const indexBar = queryId("showcase-index-bar", container);
|
|
59
|
-
const slides = queryId("showcase-slides", container);
|
|
60
|
-
const slideCount = slides.children.length;
|
|
61
|
-
|
|
62
|
-
const logoWidth = propertyValue("--ui-showcase-client-logo-min-width");
|
|
63
|
-
const pixelWidth = remsToPixelValue(logoWidth) * slideCount;
|
|
64
|
-
|
|
65
|
-
// dynamically adjust container width
|
|
66
|
-
[".ui-showcase-logo-wrapper", ".ui-showcase-index-bar"].forEach((s) => {
|
|
67
|
-
const el = container.querySelector(s);
|
|
68
|
-
const minWidth = `${pixelWidth}px`;
|
|
69
|
-
el.style.minWidth = minWidth;
|
|
70
|
-
});
|
|
71
|
-
|
|
72
|
-
let currentIndex = 0;
|
|
73
|
-
let mouseover = false;
|
|
74
|
-
let updateSlideTimeoutId;
|
|
75
|
-
|
|
76
|
-
const updateSlide = (index) => {
|
|
77
|
-
translateX(slides, index, -1);
|
|
78
|
-
translateX(indexBar, index, 1);
|
|
79
|
-
updateLogoOpacity(logos, index);
|
|
80
|
-
|
|
81
|
-
if (mobileBreakpoint(pixelWidth)) {
|
|
82
|
-
moveControlsContainer(controlsContainer, index);
|
|
83
|
-
}
|
|
84
|
-
};
|
|
85
|
-
|
|
86
|
-
const scheduleSlideMove = () =>
|
|
87
|
-
(updateSlideTimeoutId = setTimeout(() => {
|
|
88
|
-
if (mouseover) return;
|
|
89
|
-
if (mobileBreakpoint(pixelWidth)) return;
|
|
90
|
-
|
|
91
|
-
currentIndex = (currentIndex + 1) % controls.length;
|
|
92
|
-
|
|
93
|
-
updateSlide(currentIndex);
|
|
94
|
-
scheduleSlideMove();
|
|
95
|
-
}, SLIDE_SHOW_INTERVAL));
|
|
96
|
-
|
|
97
|
-
const logoClick = () => {
|
|
98
|
-
const clickHandler = (index) => () => {
|
|
99
|
-
currentIndex = index;
|
|
100
|
-
updateSlide(currentIndex);
|
|
101
|
-
};
|
|
102
|
-
|
|
103
|
-
const handlers = controls.map((control, index) => {
|
|
104
|
-
const handler = clickHandler(index);
|
|
105
|
-
control.addEventListener("click", handler);
|
|
106
|
-
return handler;
|
|
107
|
-
});
|
|
108
|
-
|
|
109
|
-
return () => {
|
|
110
|
-
handlers.forEach((handler, i) =>
|
|
111
|
-
controls[i].removeEventListener("click", handler)
|
|
112
|
-
);
|
|
113
|
-
};
|
|
114
|
-
};
|
|
115
|
-
|
|
116
|
-
const pointerOverContainer = () => {
|
|
117
|
-
const handler = () => {
|
|
118
|
-
mouseover = true;
|
|
119
|
-
clearTimeout(updateSlideTimeoutId);
|
|
120
|
-
};
|
|
121
|
-
container.addEventListener("mouseover", handler);
|
|
122
|
-
return () => container.removeEventListener("mouseover", handler);
|
|
123
|
-
};
|
|
124
|
-
|
|
125
|
-
const pointerLeftContainer = () => {
|
|
126
|
-
const handler = () => {
|
|
127
|
-
mouseover = false;
|
|
128
|
-
scheduleSlideMove();
|
|
129
|
-
};
|
|
130
|
-
container.addEventListener("mouseleave", handler);
|
|
131
|
-
return () => container.removeEventListener("mouseleave", handler);
|
|
132
|
-
};
|
|
133
|
-
|
|
134
|
-
const viewportResized = () => {
|
|
135
|
-
const handler = () => {
|
|
136
|
-
clearTimeout(updateSlideTimeoutId);
|
|
137
|
-
scheduleSlideMove();
|
|
138
|
-
};
|
|
139
|
-
document.addEventListener("resize", handler);
|
|
140
|
-
return () => document.removeEventListener("resize", handler);
|
|
141
|
-
};
|
|
142
|
-
|
|
143
|
-
const scrollOverContainer = () => {
|
|
144
|
-
const handler = (event) => event.preventDefault();
|
|
145
|
-
controlsContainer.parentNode.addEventListener("wheel", handler);
|
|
146
|
-
return () =>
|
|
147
|
-
controlsContainer.parentNode.removeEventListener("wheel", handler);
|
|
148
|
-
};
|
|
149
|
-
|
|
150
|
-
const logoClickTeardown = logoClick();
|
|
151
|
-
const scrollOverContainerTeardown = scrollOverContainer();
|
|
152
|
-
|
|
153
|
-
const slideshowInit = () => {
|
|
154
|
-
if (enableSlideshow) {
|
|
155
|
-
scheduleSlideMove();
|
|
156
|
-
container.setAttribute("aria-live", "polite");
|
|
157
|
-
|
|
158
|
-
const teardowns = [
|
|
159
|
-
pointerOverContainer(),
|
|
160
|
-
pointerLeftContainer(),
|
|
161
|
-
viewportResized(),
|
|
162
|
-
];
|
|
163
|
-
return () => teardowns.forEach((t) => t());
|
|
164
|
-
} else {
|
|
165
|
-
return () => {};
|
|
166
|
-
}
|
|
167
|
-
};
|
|
168
|
-
|
|
169
|
-
const slideshowTeardown = slideshowInit();
|
|
170
|
-
|
|
171
|
-
return function teardown() {
|
|
172
|
-
// Restore initial position
|
|
173
|
-
updateSlide(0);
|
|
174
|
-
clearTimeout(updateSlideTimeoutId);
|
|
175
|
-
|
|
176
|
-
logoClickTeardown();
|
|
177
|
-
slideshowTeardown();
|
|
178
|
-
scrollOverContainerTeardown();
|
|
179
|
-
};
|
|
180
|
-
};
|
|
File without changes
|