Skip to content
Open
Show file tree
Hide file tree
Changes from all 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