Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions app/assets/stylesheets/essence/beyond.css
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
@import url("beyond/components/expandable_toggle.css");
@import url("beyond/components/flash.css");
@import url("beyond/components/link.css");
@import url("beyond/components/modal.css");
@import url("beyond/components/notification.css");
@import url("beyond/components/paragraph.css");
@import url("beyond/components/scroll_shadow.css");
Expand Down
90 changes: 90 additions & 0 deletions app/assets/stylesheets/essence/beyond/components/modal.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
.modal {
align-items: center;
background-color: rgba(0, 0, 0, 0.75);
bottom: 0;
display: flex;
justify-content: center;
left: 0;
position: fixed;
right: 0;
top: 0;
z-index: 99999;

.modal__dialog {
margin: 25px;
max-width: 560px;
width: 100%;
}

.modal__content {
background: #ffffff;
border-radius: 3px;
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.24);
box-sizing: border-box;
padding: 32px;
position: relative;
}

.modal__header {
margin-bottom: 24px;
}

.modal__title {
color: #333333;
font-size: 22px;
font-weight: 600;
line-height: 1.2;
margin: 0;
padding-right: 28px;
}

.modal__close {
background: none;
border: 0;
color: #999999;
cursor: pointer;
padding: 0;
position: absolute;
right: 20px;
top: 20px;

&:hover {
color: #555555;
}

svg {
display: block;
fill: currentcolor;
height: 13px;
width: 13px;
}
}

.modal__body {
max-height: 65vh;
overflow-x: hidden;
overflow-y: auto;
}

.modal__footer {
display: flex;
flex-direction: row;
margin-top: 28px;

&.modal__footer--start {
justify-content: flex-start;
}

&.modal__footer--center {
justify-content: center;
}

&.modal__footer--end {
justify-content: flex-end;
}

&.modal__footer--space-between {
justify-content: space-between;
}
}
}
1 change: 1 addition & 0 deletions app/assets/stylesheets/essence/now.css
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@

@import url("now/components/button.css");
@import url("now/components/card.css");
@import url("now/components/modal.css");
@import url("now/components/title.css");
94 changes: 94 additions & 0 deletions app/assets/stylesheets/essence/now/components/modal.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
.modal {
align-items: flex-start;
background-color: rgba(0, 0, 0, 0.3);
bottom: 0;
display: flex;
justify-content: center;
left: 0;
padding-top: 60px;
position: fixed;
right: 0;
top: 0;
z-index: 99999;

.modal__dialog {
margin: 0 25px;
max-width: 700px;
width: 100%;
}

.modal__content {
background: #ffffff;
border: 1px solid #e0e0e0;
border-radius: 6px;
box-shadow: 0 4px 24px rgba(0, 0, 0, 0.18);
box-sizing: border-box;
padding: 24px;
position: relative;
}

.modal__header {
margin-bottom: 12px;
min-height: 16px;
}

.modal__title {
color: #333333;
font-size: 18px;
font-weight: 600;
line-height: 1.3;
margin: 0;
padding-right: 24px;
}

.modal__close {
background: none;
border: 0;
color: #999999;
cursor: pointer;
line-height: 1;
padding: 0;
position: absolute;
right: 16px;
top: 16px;

&:hover {
color: #555555;
}

svg {
display: block;
fill: currentcolor;
height: 14px;
width: 14px;
}
}

.modal__body {
max-height: 65vh;
overflow-x: hidden;
overflow-y: auto;
}

.modal__footer {
display: flex;
flex-direction: row;
margin-top: 20px;

&.modal__footer--start {
justify-content: flex-start;
}

&.modal__footer--center {
justify-content: center;
}

&.modal__footer--end {
justify-content: flex-end;
}

&.modal__footer--space-between {
justify-content: space-between;
}
}
}
48 changes: 48 additions & 0 deletions app/components/essence/modal_component.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# frozen_string_literal: true

module Essence
class ModalComponent < ApplicationComponent
attr_reader :title, :footer_alignment, :title_id, :dismiss_icon, :html_options

FOOTER_ALIGNMENT_OPTIONS = ['start', 'center', 'end', 'space-between'].freeze
DEFAULT_FOOTER_ALIGNMENT = 'end'

renders_one :footer

def initialize(title:,
dismiss_icon: false,
dismiss_keyup: false,
dismiss_click: false,
dismiss_submit: false,
footer_alignment: DEFAULT_FOOTER_ALIGNMENT,
**html_options)
@title = title
@dismiss_icon = dismiss_icon
@dismiss_keyup = dismiss_keyup
@dismiss_click = dismiss_click
@dismiss_submit = dismiss_submit
@footer_alignment = fetch_or_fallback(FOOTER_ALIGNMENT_OPTIONS, footer_alignment, DEFAULT_FOOTER_ALIGNMENT)
@title_id = "modal-title-#{object_id}"
@html_options = html_options
end

private

def before_render
set_base_html_options(
'modal',
role: 'dialog',
aria: { modal: 'true', labelledby: title_id },
data: { controller: 'modal', action: modal_actions }.compact
)
end

def modal_actions
actions = []
actions << 'keyup@window->modal#closeWithKeyboard' if @dismiss_keyup
actions << 'click@window->modal#closeBackground' if @dismiss_click
actions << 'turbo:submit-end->modal#submitEnd' if @dismiss_submit
actions.join(' ').presence
end
end
end
22 changes: 22 additions & 0 deletions app/components/essence/modal_component/modal_component.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<%= helpers.turbo_frame_tag 'modal' do %>
<div <%= tag.attributes **html_options %>>
<div class="modal__dialog">
<div class="modal__content" data-modal-target="modalContent">
<% if dismiss_icon %>
<button type="button" class="modal__close" aria-label="Close" data-action="click->modal#hideModal">
<%= render Essence::IconComponent.new(name: 'x_mark', class: 'modal__close-icon') %>
</button>
<% end %>
<div class="modal__header">
<h2 id="<%= title_id %>" class="modal__title"><%= title %></h2>
</div>
<scroll-shadow>
<div class="modal__body"><%= content %></div>
</scroll-shadow>
<% if footer? %>
<div class="modal__footer modal__footer--<%= footer_alignment %>"><%= footer %></div>
<% end %>
</div>
</div>
</div>
<% end %>
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { Controller } from "@hotwired/stimulus";

export default class extends Controller {
static targets = ["modalContent"]

hideModal() {
const frame = this.element.closest("turbo-frame")
if (frame) frame.removeAttribute("src")
this.element.remove()
}

closeWithKeyboard(e) {
if (e.key === "Escape") this.hideModal()
}

closeBackground(e) {
if (!this.modalContentTarget.contains(e.target)) this.hideModal()
}

submitEnd(e) {
if (e.detail.success) this.hideModal()
}
}
3 changes: 3 additions & 0 deletions app/javascript/essence/controllers/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ application.register('expandable-toggle', ExpandableToggleComponentController)
import FlashComponentController from 'components/essence/flash_component/flash_component_controller'
application.register('flash', FlashComponentController)

import ModalComponentController from 'components/essence/modal_component/modal_component_controller'
application.register('modal', ModalComponentController)

import ParagraphComponentController from 'components/essence/paragraph_component/paragraph_component_controller'
application.register('paragraph', ParagraphComponentController)

Expand Down
Loading
Loading