ariadne_view_components 0.0.13 → 0.0.15
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/assets/builds/ariadne_view_components.css +2355 -0
- data/app/assets/javascripts/ariadne_view_components.js +2 -2
- data/app/assets/javascripts/ariadne_view_components.js.map +1 -1
- data/app/assets/javascripts/comment-component.d.ts +1 -2
- data/app/assets/stylesheets/ariadne_view_components.css +1 -0
- data/app/assets/stylesheets/dropdown.css +46 -0
- data/app/assets/stylesheets/tooltip-component.css +8 -8
- data/app/components/ariadne/ariadne-form-with.d.ts +20 -0
- data/app/components/ariadne/ariadne-form-with.js +85 -0
- data/app/components/ariadne/ariadne-form.d.ts +22 -0
- data/app/components/ariadne/ariadne-form.js +84 -0
- data/app/components/ariadne/ariadne.d.ts +2 -0
- data/app/components/ariadne/ariadne.js +16 -0
- data/app/components/ariadne/ariadne.ts +0 -2
- data/app/components/ariadne/avatar_component.rb +81 -0
- data/app/components/ariadne/avatar_stack_component.html.erb +12 -0
- data/app/components/ariadne/avatar_stack_component.rb +75 -0
- data/app/components/ariadne/base_button.rb +13 -4
- data/app/components/ariadne/blankslate_component.rb +4 -4
- data/app/components/ariadne/body_component.rb +1 -1
- data/app/components/ariadne/button_component.html.erb +1 -1
- data/app/components/ariadne/button_component.rb +9 -3
- data/app/components/ariadne/clipboard-copy-component.d.ts +4 -0
- data/app/components/ariadne/clipboard-copy-component.js +18 -0
- data/app/components/ariadne/clipboard_copy_component.d.ts +4 -0
- data/app/components/ariadne/clipboard_copy_component.js +18 -0
- data/app/components/ariadne/comment-component.d.ts +0 -0
- data/app/components/ariadne/comment-component.js +33 -0
- data/app/components/ariadne/comment-component.ts +32 -50
- data/app/components/ariadne/comment_component.html.erb +32 -10
- data/app/components/ariadne/comment_component.rb +17 -5
- data/app/components/ariadne/component.rb +0 -2
- data/app/components/ariadne/details_component.html.erb +4 -0
- data/app/components/ariadne/details_component.rb +80 -0
- data/app/components/ariadne/dropdown/menu_component.html.erb +20 -0
- data/app/components/ariadne/dropdown/menu_component.rb +101 -0
- data/app/components/ariadne/dropdown/menu_component.ts +1 -0
- data/app/components/ariadne/dropdown_component.html.erb +8 -0
- data/app/components/ariadne/dropdown_component.rb +172 -0
- data/app/components/ariadne/flex_component.rb +1 -1
- data/app/components/ariadne/footer_component.html.erb +1 -1
- data/app/components/ariadne/header_component.rb +3 -3
- data/app/components/ariadne/heroicon_component.rb +6 -4
- data/app/components/ariadne/inline_flex_component.html.erb +1 -0
- data/app/components/ariadne/inline_flex_component.rb +8 -1
- data/app/components/ariadne/link_component.rb +2 -2
- data/app/components/ariadne/list_component.html.erb +2 -9
- data/app/components/ariadne/list_component.rb +11 -15
- data/app/components/ariadne/pill_component.rb +19 -5
- data/app/components/ariadne/rich-text-area-component.d.ts +4 -0
- data/app/components/ariadne/rich-text-area-component.js +27 -0
- data/app/components/ariadne/rich-text-area-component.ts +4 -4
- data/app/components/ariadne/rich_text_area_component.html.erb +1 -1
- data/app/components/ariadne/rich_text_area_component.rb +1 -1
- data/app/components/ariadne/slideover-component.d.ts +9 -0
- data/app/components/ariadne/slideover-component.js +20 -0
- data/app/components/ariadne/slideover_component.d.ts +9 -0
- data/app/components/ariadne/slideover_component.html.erb +1 -1
- data/app/components/ariadne/slideover_component.js +19 -0
- data/app/components/ariadne/tab-component.js +1 -0
- data/app/components/ariadne/tab-container-component copy.d.ts +1 -0
- data/app/components/ariadne/tab-container-component copy.js +23 -0
- data/app/components/ariadne/tab-container-component.d.ts +1 -0
- data/app/components/ariadne/tab-container-component.js +23 -0
- data/app/components/ariadne/tab-container-component.ts +21 -21
- data/app/components/ariadne/tab-nav-component.d.ts +9 -0
- data/app/components/ariadne/tab-nav-component.js +32 -0
- data/app/components/ariadne/tab_component.rb +4 -7
- data/app/components/ariadne/tab_container_component.rb +8 -2
- data/app/components/ariadne/tab_nav_component.html.erb +1 -1
- data/app/components/ariadne/tab_nav_component.rb +1 -1
- data/app/components/ariadne/table_nav_component.html.erb +52 -0
- data/app/components/ariadne/table_nav_component.rb +338 -0
- data/app/components/ariadne/tabs-component.d.ts +0 -0
- data/app/components/ariadne/tabs-component.js +1 -0
- data/app/components/ariadne/time-ago-component.d.ts +1 -0
- data/app/components/ariadne/time-ago-component.js +1 -0
- data/app/components/ariadne/time_ago_component.d.ts +1 -0
- data/app/components/ariadne/time_ago_component.js +1 -0
- data/app/components/ariadne/tooltip-component.d.ts +24 -0
- data/app/components/ariadne/tooltip-component.js +42 -0
- data/app/components/ariadne/tooltip_component.html.erb +1 -1
- data/app/components/ariadne/tooltip_component.rb +4 -4
- data/app/lib/ariadne/action_view_extensions/form_helper.rb +21 -7
- data/app/lib/ariadne/form_builder.rb +4 -4
- data/lib/ariadne/view_components/version.rb +1 -1
- data/lib/tasks/docs.rake +19 -4
- data/static/arguments.yml +103 -22
- data/static/audited_at.json +15 -8
- data/static/classes.yml +51 -47
- data/static/constants.json +180 -55
- data/static/statuses.json +15 -8
- data/tailwind.config.js +25 -1
- metadata +53 -9
- data/app/components/ariadne/main_component.rb +0 -32
- data/app/components/ariadne/table_component.html.erb +0 -17
- data/app/components/ariadne/table_component.rb +0 -281
@@ -9,6 +9,7 @@ module Ariadne
|
|
9
9
|
LINK_SCHEME = :link
|
10
10
|
|
11
11
|
SCHEME_CLASS_MAPPINGS = {
|
12
|
+
link: Ariadne::LinkComponent::DEFAULT_ACTIONABLE_CLASSES,
|
12
13
|
none: "",
|
13
14
|
default: "ariadne-text-purple-800 ariadne-bg-purple-50 hover:ariadne-bg-purple-100 ariadne-border-purple-300 focus:ariadne-ring-offset-purple-50 focus:ariadne-ring-purple-600",
|
14
15
|
info: "ariadne-text-blue-800 ariadne-bg-blue-50 hover:ariadne-bg-blue-100 ariadne-border-blue-300 focus:ariadne-ring-offset-blue-50 focus:ariadne-ring-blue-600",
|
@@ -109,10 +110,10 @@ module Ariadne
|
|
109
110
|
# <% end %>
|
110
111
|
#
|
111
112
|
# @param tag [Symbol] <%= one_of(Ariadne::BaseButton::TAG_OPTIONS) %>
|
112
|
-
# @param type [Symbol] <%= one_of(Ariadne::BaseButton::
|
113
|
+
# @param type [Symbol] <%= one_of(Ariadne::BaseButton::VALID_TYPES) %>
|
113
114
|
# @param scheme [Symbol] <%= one_of(Ariadne::ButtonComponent::VALID_SCHEMES) %>
|
114
115
|
# @param size [Symbol] <%= one_of(Ariadne::BaseButton::VALID_SIZES) %>
|
115
|
-
# @param
|
116
|
+
# @param dropdown [Boolean] Whether or not to render a dropdown caret.
|
116
117
|
# @param classes [String] <%= link_to_classes_docs %>
|
117
118
|
# @param attributes [Hash] <%= link_to_attributes_docs %>
|
118
119
|
def initialize(
|
@@ -120,18 +121,19 @@ module Ariadne
|
|
120
121
|
type: Ariadne::BaseButton::DEFAULT_TYPE,
|
121
122
|
scheme: DEFAULT_SCHEME,
|
122
123
|
size: BaseButton::DEFAULT_SIZE,
|
124
|
+
dropdown: false,
|
123
125
|
classes: "",
|
124
126
|
attributes: {}
|
125
127
|
)
|
126
128
|
@tag = tag
|
127
129
|
@type = type
|
128
|
-
@scheme = scheme
|
129
130
|
|
130
131
|
@attributes = attributes
|
131
132
|
@id = @attributes[:id]
|
132
133
|
|
133
134
|
@size = fetch_or_raise(Ariadne::BaseButton::VALID_SIZES, size)
|
134
135
|
@scheme = fetch_or_raise(VALID_SCHEMES, scheme)
|
136
|
+
@scheme = LINK_SCHEME if @tag == :a
|
135
137
|
|
136
138
|
@classes = class_names(
|
137
139
|
SCHEME_CLASS_MAPPINGS[@scheme],
|
@@ -139,6 +141,10 @@ module Ariadne
|
|
139
141
|
)
|
140
142
|
end
|
141
143
|
|
144
|
+
private def dropdown?
|
145
|
+
@dropdown
|
146
|
+
end
|
147
|
+
|
142
148
|
private def trimmed_content
|
143
149
|
return if content.blank?
|
144
150
|
|
@@ -0,0 +1,18 @@
|
|
1
|
+
import { Controller } from '@hotwired/stimulus';
|
2
|
+
export default class ClipboardCopyComponent extends Controller {
|
3
|
+
copy() {
|
4
|
+
const value = this.element.attributes.getNamedItem('value');
|
5
|
+
const forNode = this.element.attributes.getNamedItem('for');
|
6
|
+
if (value) {
|
7
|
+
navigator.clipboard.writeText(value.value);
|
8
|
+
}
|
9
|
+
else if (forNode) {
|
10
|
+
const node = document.getElementById(forNode.value);
|
11
|
+
navigator.clipboard.writeText((node === null || node === void 0 ? void 0 : node.textContent) || '');
|
12
|
+
}
|
13
|
+
else {
|
14
|
+
// just copy inner text
|
15
|
+
navigator.clipboard.writeText(this.element.textContent || '');
|
16
|
+
}
|
17
|
+
}
|
18
|
+
}
|
@@ -0,0 +1,18 @@
|
|
1
|
+
import { Controller } from '@hotwired/stimulus';
|
2
|
+
export default class ClipboardCopyComponent extends Controller {
|
3
|
+
copy() {
|
4
|
+
const value = this.element.attributes.getNamedItem('value');
|
5
|
+
const forNode = this.element.attributes.getNamedItem('for');
|
6
|
+
if (value) {
|
7
|
+
navigator.clipboard.writeText(value.value);
|
8
|
+
}
|
9
|
+
else if (forNode) {
|
10
|
+
const node = document.getElementById(forNode.value);
|
11
|
+
navigator.clipboard.writeText((node === null || node === void 0 ? void 0 : node.textContent) || '');
|
12
|
+
}
|
13
|
+
else {
|
14
|
+
// just copy inner text
|
15
|
+
navigator.clipboard.writeText(this.element.textContent || '');
|
16
|
+
}
|
17
|
+
}
|
18
|
+
}
|
File without changes
|
@@ -0,0 +1,33 @@
|
|
1
|
+
"use strict";
|
2
|
+
// import {Controller} from '@hotwired/stimulus'
|
3
|
+
// export default class CommentComponent extends Controller {
|
4
|
+
// static targets = ['tab', 'tabBarComponent']
|
5
|
+
// declare readonly commentComponentTarget: HTMLDivElement
|
6
|
+
// declare readonly tabBarComponentTarget: HTMLElement // technically a `nav but typescript can't find it?
|
7
|
+
// declare readonly tabTargets: [HTMLButtonElement]
|
8
|
+
// // keep in sync with comment_component.rb
|
9
|
+
// SELECTED_TAB_CLASSES = ['ariadne-border-indigo-500', 'ariadne-text-indigo-600']
|
10
|
+
// PUBLIC_BACKGROUND_COLOR = 'ariadne-bg-white'
|
11
|
+
// INTERNAL_BACKGROUND_COLOR = 'ariadne-bg-internal-message'
|
12
|
+
// toggleTab() {
|
13
|
+
// for (const tab of this.tabTargets) {
|
14
|
+
// if (tab.hasAttribute('aria-selected')) {
|
15
|
+
// tab.classList.remove(...this.SELECTED_TAB_CLASSES)
|
16
|
+
// this.toggleBackgrounds(tab, false)
|
17
|
+
// tab.removeAttribute('aria-selected')
|
18
|
+
// } else {
|
19
|
+
// tab.setAttribute('aria-selected', 'true')
|
20
|
+
// tab.classList.add(...this.SELECTED_TAB_CLASSES)
|
21
|
+
// this.toggleBackgrounds(tab, true)
|
22
|
+
// }
|
23
|
+
// }
|
24
|
+
// }
|
25
|
+
// toggleBackgrounds(tab: HTMLButtonElement, publicComment: boolean) {
|
26
|
+
// if (publicComment) {
|
27
|
+
// this.tabBarComponentTarget.classList.add(this.PUBLIC_BACKGROUND_COLOR)
|
28
|
+
// this.tabBarComponentTarget.classList.remove(this.INTERNAL_BACKGROUND_COLOR)
|
29
|
+
// this.tabBarComponentTarget.classList.remove(this.PUBLIC_BACKGROUND_COLOR)
|
30
|
+
// this.tabBarComponentTarget.classList.add(this.INTERNAL_BACKGROUND_COLOR)
|
31
|
+
// }
|
32
|
+
// }
|
33
|
+
// }
|
@@ -1,55 +1,37 @@
|
|
1
|
-
import {Controller} from '@hotwired/stimulus'
|
1
|
+
// import {Controller} from '@hotwired/stimulus'
|
2
2
|
|
3
|
-
export default class CommentComponent extends Controller {
|
4
|
-
|
3
|
+
// export default class CommentComponent extends Controller {
|
4
|
+
// static targets = ['tab', 'tabBarComponent']
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
|
6
|
+
// declare readonly commentComponentTarget: HTMLDivElement
|
7
|
+
// declare readonly tabBarComponentTarget: HTMLElement // technically a `nav but typescript can't find it?
|
8
|
+
// declare readonly tabTargets: [HTMLButtonElement]
|
9
9
|
|
10
|
-
|
11
|
-
|
12
|
-
|
10
|
+
// // keep in sync with comment_component.rb
|
11
|
+
// SELECTED_TAB_CLASSES = ['ariadne-border-indigo-500', 'ariadne-text-indigo-600']
|
12
|
+
// PUBLIC_BACKGROUND_COLOR = 'ariadne-bg-white'
|
13
|
+
// INTERNAL_BACKGROUND_COLOR = 'ariadne-bg-internal-message'
|
13
14
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
15
|
+
// toggleTab() {
|
16
|
+
// for (const tab of this.tabTargets) {
|
17
|
+
// if (tab.hasAttribute('aria-selected')) {
|
18
|
+
// tab.classList.remove(...this.SELECTED_TAB_CLASSES)
|
19
|
+
// this.toggleBackgrounds(tab, false)
|
20
|
+
// tab.removeAttribute('aria-selected')
|
21
|
+
// } else {
|
22
|
+
// tab.setAttribute('aria-selected', 'true')
|
23
|
+
// tab.classList.add(...this.SELECTED_TAB_CLASSES)
|
24
|
+
// this.toggleBackgrounds(tab, true)
|
25
|
+
// }
|
26
|
+
// }
|
27
|
+
// }
|
28
|
+
// toggleBackgrounds(tab: HTMLButtonElement, publicComment: boolean) {
|
29
|
+
// if (publicComment) {
|
30
|
+
// this.tabBarComponentTarget.classList.add(this.PUBLIC_BACKGROUND_COLOR)
|
31
|
+
// this.tabBarComponentTarget.classList.remove(this.INTERNAL_BACKGROUND_COLOR)
|
21
32
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
this.toggleBackgrounds(tab)
|
28
|
-
} else {
|
29
|
-
tab.setAttribute('selected', 'true')
|
30
|
-
tab.classList.add(...this.SELECTED_TAB_CLASSES)
|
31
|
-
this.toggleBackgrounds(tab)
|
32
|
-
if (tab.hasAttribute('data-public')) {
|
33
|
-
document.getElementById('message_public')?.setAttribute('value', 'true')
|
34
|
-
} else {
|
35
|
-
document.getElementById('message_public')?.setAttribute('value', 'false')
|
36
|
-
}
|
37
|
-
}
|
38
|
-
}
|
39
|
-
}
|
40
|
-
toggleBackgrounds(tab: HTMLButtonElement) {
|
41
|
-
if (tab.hasAttribute('selected')) {
|
42
|
-
if (tab.hasAttribute('data-public')) {
|
43
|
-
// this.commentComponentTarget.classList.add(this.PUBLIC_BACKGROUND_COLOR)
|
44
|
-
// this.commentComponentTarget.classList.remove(this.INTERNAL_BACKGROUND_COLOR)
|
45
|
-
this.tabBarComponentTarget.classList.add(this.PUBLIC_BACKGROUND_COLOR)
|
46
|
-
this.tabBarComponentTarget.classList.remove(this.INTERNAL_BACKGROUND_COLOR)
|
47
|
-
} else {
|
48
|
-
// this.commentComponentTarget.classList.remove(this.PUBLIC_BACKGROUND_COLOR)
|
49
|
-
// this.commentComponentTarget.classList.add(this.INTERNAL_BACKGROUND_COLOR)
|
50
|
-
this.tabBarComponentTarget.classList.remove(this.PUBLIC_BACKGROUND_COLOR)
|
51
|
-
this.tabBarComponentTarget.classList.add(this.INTERNAL_BACKGROUND_COLOR)
|
52
|
-
}
|
53
|
-
}
|
54
|
-
}
|
55
|
-
}
|
33
|
+
// this.tabBarComponentTarget.classList.remove(this.PUBLIC_BACKGROUND_COLOR)
|
34
|
+
// this.tabBarComponentTarget.classList.add(this.INTERNAL_BACKGROUND_COLOR)
|
35
|
+
// }
|
36
|
+
// }
|
37
|
+
// }
|
@@ -2,17 +2,39 @@
|
|
2
2
|
<div class="ariadne-bg-white" data-comment-component-target="commentComponent">
|
3
3
|
<div class="ariadne-hidden sm:ariadne-block">
|
4
4
|
<div class="ariadne-border-b ariadne-border-gray-200">
|
5
|
+
<%= render(Ariadne::TabContainerComponent.new(sr_label: @sr_label)) do |tab_container| %>
|
6
|
+
<%= tab_container.tab(id: public_tab.id, selected: public_tab.selected, classes: public_tab.classes, attributes: public_tab.attributes) do |tab| %>
|
7
|
+
<% tab.text { @public_tab_text } %>
|
8
|
+
<% tab.panel do %>
|
9
|
+
<%= ariadne_form_with(url: @url, method: @method, classes: @classes, attributes: @attributes) do |comment_box| %>
|
10
|
+
<div class="ariadne-overflow-hidden ariadne-border-x ariadne-border-b ariadne-border-gray-300 ariadne-shadow-sm focus-within:ariadne-border-indigo-500 focus-within:ariadne-ring-1 focus-within:ariadne-ring-indigo-500">
|
11
|
+
<%= hidden_field_tag 'message_public', true %>
|
12
|
+
<%= render(Ariadne::RichTextAreaComponent.new(name: :bodytext, sr_label: "Select reply type", attributes: { required: true})) %>
|
13
|
+
<% comment_box.submit { @submit } %>
|
14
|
+
</div>
|
15
|
+
<div class="ariadne-mt-2 ariadne-flex ariadne-justify-end">
|
16
|
+
<%= submit %>
|
17
|
+
</div>
|
18
|
+
<% end %>
|
19
|
+
<% end %>
|
20
|
+
<% end %>
|
21
|
+
<%= tab_container.tab(id: internal_tab.id, selected: internal_tab.selected, classes: internal_tab.classes, attributes: internal_tab.attributes) do |tab| %>
|
22
|
+
<% tab.text { @internal_tab_text } %>
|
23
|
+
<% tab.panel do %>
|
24
|
+
<%= ariadne_form_with(url: @url, method: @method, classes: @classes, attributes: @attributes) do |comment_box| %>
|
25
|
+
<div class="ariadne-overflow-hidden ariadne-border-x ariadne-border-b ariadne-border-gray-300 ariadne-shadow-sm focus-within:ariadne-border-indigo-500 focus-within:ariadne-ring-1 focus-within:ariadne-ring-indigo-500">
|
26
|
+
<%= hidden_field_tag 'message_public', false %>
|
27
|
+
<%= render(Ariadne::RichTextAreaComponent.new(name: :bodytext, sr_label: "Select reply type", attributes: { required: true})) %>
|
28
|
+
<% comment_box.submit { @submit } %>
|
29
|
+
</div>
|
30
|
+
<div class="ariadne-mt-2 ariadne-flex ariadne-justify-end">
|
31
|
+
<%= submit %>
|
32
|
+
</div>
|
33
|
+
<% end %>
|
34
|
+
<% end %>
|
35
|
+
<% end %>
|
36
|
+
<% end %>
|
5
37
|
</div>
|
6
38
|
</div>
|
7
|
-
<%= ariadne_form_with(url: @url, method: @method, classes: @classes, attributes: @attributes) do |comment_box| %>
|
8
|
-
<div class="ariadne-overflow-hidden ariadne-border-x ariadne-border-b ariadne-border-gray-300 ariadne-shadow-sm focus-within:ariadne-border-indigo-500 focus-within:ariadne-ring-1 focus-within:ariadne-ring-indigo-500">
|
9
|
-
<%= hidden_field_tag 'message_public', true %>
|
10
|
-
<%= render(Ariadne::RichTextAreaComponent.new(name: :bodytext, sr_label: "Select reply type", attributes: { required: true})) %>
|
11
|
-
<% comment_box.submit { @submit } %>
|
12
|
-
</div>
|
13
|
-
<div class="ariadne-mt-2 ariadne-flex ariadne-justify-end">
|
14
|
-
<%= submit %>
|
15
|
-
</div>
|
16
|
-
<% end %>
|
17
39
|
</div>
|
18
40
|
<% end %>
|
@@ -2,6 +2,10 @@
|
|
2
2
|
|
3
3
|
module Ariadne
|
4
4
|
# Defines a submittable form for adding comments to a conversation.
|
5
|
+
#
|
6
|
+
#
|
7
|
+
# Requires JavaScript. Set `data-comment-component-selected-class` to the class name that will be applied to the
|
8
|
+
# selected tab.
|
5
9
|
# @accessibility This component requires you to pass in a `sr_label`
|
6
10
|
# attribute, which will be used to label the tabs for screen readers.
|
7
11
|
class CommentComponent < Ariadne::Component
|
@@ -12,17 +16,21 @@ module Ariadne
|
|
12
16
|
|
13
17
|
renders_one :public_tab, lambda { |selected: false, text:, classes: "", attributes: {}|
|
14
18
|
attributes[:"data-comment-component-target"] ||= "tab"
|
15
|
-
attributes[:"data-action"] ||= "click->comment-component#toggleTab"
|
16
19
|
attributes[:"data-public"] = true
|
17
20
|
@tab_idx += 1
|
18
|
-
|
21
|
+
id = attributes.fetch(:id, "public-tab-#{@tab_idx}")
|
22
|
+
@public_tab_text = text
|
23
|
+
|
24
|
+
Ariadne::TabComponent.new(selected: selected, classes: classes, id: id, with_panel: true, attributes: attributes)
|
19
25
|
}
|
20
26
|
|
21
27
|
renders_one :internal_tab, lambda { |selected: false, text:, classes: "", attributes: {}|
|
22
28
|
attributes[:"data-comment-component-target"] ||= "tab"
|
23
|
-
attributes[:"data-action"] ||= "click->comment-component#toggleTab"
|
24
29
|
@tab_idx += 1
|
25
|
-
|
30
|
+
id = attributes.fetch(:id, "internal-tab-#{@tab_idx}")
|
31
|
+
@internal_tab_text = text
|
32
|
+
|
33
|
+
Ariadne::TabComponent.new(selected: selected, classes: classes, id: id, with_panel: true, attributes: attributes)
|
26
34
|
}
|
27
35
|
|
28
36
|
renders_one :submit, lambda { |classes: "", attributes: {}|
|
@@ -31,7 +39,11 @@ module Ariadne
|
|
31
39
|
|
32
40
|
# @example Default
|
33
41
|
#
|
34
|
-
#
|
42
|
+
# <%= render(Ariadne::CommentComponent.new(url: "/messages", method: :post, sr_label: "Select delivery time")) do |comment| %>
|
43
|
+
# <% comment.public_tab(selected: true, text: "Reply to sender") %>
|
44
|
+
# <% comment.internal_tab(text: "Internal comment") %>
|
45
|
+
# <% comment.submit { "Send" } %>
|
46
|
+
# <% end %>
|
35
47
|
#
|
36
48
|
# @param url [String] The URL to take action against.
|
37
49
|
# @param method [String] The method to use when submitting the form.
|
@@ -16,8 +16,6 @@ module Ariadne
|
|
16
16
|
include LoggerHelper
|
17
17
|
include Ariadne::ActionViewExtensions::FormHelper
|
18
18
|
|
19
|
-
BASE_HTML_CLASSES = "ariadne-h-full ariadne-scroll-smooth ariadne-bg-white ariadne-antialiased"
|
20
|
-
BASE_BODY_CLASSES = "ariadne-flex ariadne-h-full ariadne-flex-col"
|
21
19
|
BASE_WRAPPER_CLASSES = "ariadne-flex ariadne-flex-col ariadne-h-screen ariadne-justify-between"
|
22
20
|
BASE_MAIN_CLASSES = "ariadne-flex-auto"
|
23
21
|
|
@@ -0,0 +1,80 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Ariadne
|
4
|
+
# Use `DetailsComponent` to reveal content after clicking a button.
|
5
|
+
class DetailsComponent < Ariadne::Component
|
6
|
+
DEFAULT_TAG = :details
|
7
|
+
DEFAULT_BODY_TAG = :div
|
8
|
+
|
9
|
+
VALID_BODY_TAGS = [:ul, :"details-menu", :"details-dialog", DEFAULT_BODY_TAG].freeze
|
10
|
+
|
11
|
+
NO_OVERLAY = :none
|
12
|
+
OVERLAY_MAPPINGS = {
|
13
|
+
NO_OVERLAY => "",
|
14
|
+
:default => "",
|
15
|
+
}.freeze
|
16
|
+
|
17
|
+
# Use the Summary as a trigger to reveal the content.
|
18
|
+
#
|
19
|
+
# @param button [Boolean] (true) Whether to render the Summary as a button or not.
|
20
|
+
# @param classes [String] <%= link_to_classes_docs %>
|
21
|
+
# @param attributes [Hash] <%= link_to_attributes_docs %>
|
22
|
+
renders_one :summary, lambda { |button: true, classes: "", attributes: {}|
|
23
|
+
tag = :summary
|
24
|
+
attributes[:role] = "button"
|
25
|
+
|
26
|
+
return Ariadne::BaseComponent.new(tag: tag, classes: classes, attributes: attributes) unless button
|
27
|
+
|
28
|
+
Ariadne::Content.new
|
29
|
+
}
|
30
|
+
|
31
|
+
DEFAULT_BODY_CLASSES = "ariadne-absolute ariadne-right-0 ariadne-z-10 ariadne-mt-2 ariadne-w-56 ariadne-origin-top-right ariadne-divide-y ariadne-divide-gray-100 ariadne-rounded-md ariadne-bg-white ariadne-shadow-lg ariadne-ring-1 ariadne-ring-black ariadne-ring-opacity-5 focus:ariadne-outline-none"
|
32
|
+
# Use the Body slot as the main content to be shown when triggered by the Summary.
|
33
|
+
#
|
34
|
+
# @param tag [Symbol] The tag to use for the body/ <%= one_of(Ariadne::DetailsComponent::VALID_BODY_TAGS) %>
|
35
|
+
# @param classes [String] <%= link_to_classes_docs %>
|
36
|
+
# @param attributes [Hash] <%= link_to_attributes_docs %>
|
37
|
+
renders_one :body, lambda { |tag: DEFAULT_BODY_TAG, classes: "", attributes: {}|
|
38
|
+
tag = fetch_or_raise(VALID_BODY_TAGS, tag)
|
39
|
+
actual_classes = class_names(DEFAULT_BODY_CLASSES, classes)
|
40
|
+
|
41
|
+
Ariadne::BaseComponent.new(tag: tag, classes: actual_classes, attributes: attributes)
|
42
|
+
}
|
43
|
+
|
44
|
+
DEFAULT_CLASSES = ""
|
45
|
+
|
46
|
+
# @example Default
|
47
|
+
#
|
48
|
+
# <%= render Ariadne::DetailsComponent.new do |c| %>
|
49
|
+
# <% c.summary do %>
|
50
|
+
# Summary
|
51
|
+
# <% end %>
|
52
|
+
# <% c.body do %>
|
53
|
+
# Body
|
54
|
+
# <% end %>
|
55
|
+
# <% end %>
|
56
|
+
#
|
57
|
+
# @param overlay [Symbol] Dictates the type of overlay to render with. <%= one_of(Ariadne::DetailsComponent::OVERLAY_MAPPINGS.keys) %>
|
58
|
+
# @param reset [Boolean] If set to true, it will remove the default caret and remove style from the summary element
|
59
|
+
# @param classes [String] <%= link_to_classes_docs %>
|
60
|
+
# @param attributes [Hash] <%= link_to_attributes_docs %>
|
61
|
+
def initialize(overlay: NO_OVERLAY, reset: false, classes: "", attributes: {})
|
62
|
+
@tag = DEFAULT_TAG
|
63
|
+
@reset = reset
|
64
|
+
|
65
|
+
@classes = class_names(
|
66
|
+
DEFAULT_CLASSES,
|
67
|
+
classes,
|
68
|
+
@reset ? "ariadne__details-reset" : "",
|
69
|
+
)
|
70
|
+
|
71
|
+
@attributes = attributes
|
72
|
+
|
73
|
+
@overlay = fetch_or_raise(OVERLAY_MAPPINGS.keys, overlay)
|
74
|
+
end
|
75
|
+
|
76
|
+
def render?
|
77
|
+
true # summary.present? && body.present?
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
<%= render Ariadne::BaseComponent.new(tag: @tag, classes: @classes, attributes: @attributes) do |component| %>
|
2
|
+
<%= header %>
|
3
|
+
<% if list? %>
|
4
|
+
<ul>
|
5
|
+
<% items.each do |item| %>
|
6
|
+
<% if item.divider? %>
|
7
|
+
<%= item %>
|
8
|
+
<% else %>
|
9
|
+
<li>
|
10
|
+
<%= item %>
|
11
|
+
</li>
|
12
|
+
<% end %>
|
13
|
+
<% end %>
|
14
|
+
</ul>
|
15
|
+
<% else %>
|
16
|
+
<% items.each do |item| %>
|
17
|
+
<%= item %>
|
18
|
+
<% end %>
|
19
|
+
<% end %>
|
20
|
+
<% end %>
|
@@ -0,0 +1,101 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Ariadne
|
4
|
+
module Dropdown
|
5
|
+
# This component is part of `DropdownComponent` and should not be
|
6
|
+
# used as a standalone component.
|
7
|
+
class MenuComponent < Ariadne::Component
|
8
|
+
DEFAULT_AS_OPTION = :default
|
9
|
+
VALID_AS_OPTIONS = [DEFAULT_AS_OPTION, :list].freeze
|
10
|
+
|
11
|
+
DEFAULT_DIRECTION = :se
|
12
|
+
VALID_DIRECTIONS = [DEFAULT_DIRECTION, :sw, :w, :e, :ne, :s].freeze
|
13
|
+
|
14
|
+
DEFAULT_HEADER_CLASSES = "ariadne-text-sm ariadne-font-medium ariadne-text-gray-900"
|
15
|
+
# @param classes [String] <%= link_to_classes_docs %>
|
16
|
+
# @param attributes [Hash] <%= link_to_attributes_docs %>
|
17
|
+
renders_one :header, lambda { |classes: "", attributes: {}|
|
18
|
+
actual_classes = class_names(DEFAULT_HEADER_CLASSES, classes)
|
19
|
+
Ariadne::BaseComponent.new(tag: :span, classes: actual_classes, attributes: attributes)
|
20
|
+
}
|
21
|
+
|
22
|
+
# @param tag [Boolean] <%= one_of(Ariadne::Dropdown::MenuComponent::Item::VALID_TAGS) %>.
|
23
|
+
# @param divider [Boolean] Whether the item is a divider without any function.
|
24
|
+
# @param classes [String] <%= link_to_classes_docs %>
|
25
|
+
# @param attributes [Hash] <%= link_to_attributes_docs %>
|
26
|
+
renders_many :items, lambda { |tag: Ariadne::Dropdown::MenuComponent::Item::DEFAULT_TAG, divider: false, classes: "", attributes: {}|
|
27
|
+
Ariadne::Dropdown::MenuComponent::Item.new(tag: tag, as: @as, divider: divider, classes: classes, attributes: attributes)
|
28
|
+
}
|
29
|
+
|
30
|
+
DEFAULT_TAG = :"details-menu"
|
31
|
+
TAG_OPTIONS = [DEFAULT_TAG].freeze
|
32
|
+
|
33
|
+
DEFAULT_CLASSES = ""
|
34
|
+
|
35
|
+
# @param as [Symbol] When `as` is `:list`, wraps the menu in a `<ul>` with a `<li>` for each item.
|
36
|
+
# @param direction [Symbol] <%= one_of(Ariadne::Dropdown::MenuComponent::VALID_DIRECTIONS) %>.
|
37
|
+
# @param classes [String] <%= link_to_classes_docs %>
|
38
|
+
# @param attributes [Hash] <%= link_to_attributes_docs %>
|
39
|
+
def initialize(as: DEFAULT_AS_OPTION, direction: VALID_DIRECTIONS, classes: "", attributes: {})
|
40
|
+
@tag = DEFAULT_TAG
|
41
|
+
@classes = class_names(
|
42
|
+
DEFAULT_CLASSES,
|
43
|
+
classes,
|
44
|
+
)
|
45
|
+
|
46
|
+
@attributes = attributes
|
47
|
+
|
48
|
+
@direction = direction
|
49
|
+
@as = fetch_or_raise(VALID_AS_OPTIONS, as)
|
50
|
+
|
51
|
+
@attributes[:role] = "menu"
|
52
|
+
end
|
53
|
+
|
54
|
+
private def list?
|
55
|
+
@as == :list
|
56
|
+
end
|
57
|
+
|
58
|
+
# Items to be rendered in the `Dropdown` menu.
|
59
|
+
class Item < Ariadne::Component
|
60
|
+
DEFAULT_TAG = :a
|
61
|
+
BUTTON_TAGS = [:button, :summary].freeze
|
62
|
+
VALID_TAGS = [DEFAULT_TAG, *BUTTON_TAGS].freeze
|
63
|
+
|
64
|
+
DEFAULT_ITEM_CLASSES = "ariadne-block ariadne-px-4 ariadne-py-2 ariadne-text-sm ariadne-text-gray-700"
|
65
|
+
|
66
|
+
def initialize(as:, tag: DEFAULT_TAG, divider: false, classes: "", attributes: {})
|
67
|
+
@divider = divider
|
68
|
+
@as = as
|
69
|
+
|
70
|
+
@classes = class_names(DEFAULT_ITEM_CLASSES, classes)
|
71
|
+
@attributes = attributes
|
72
|
+
@tag = fetch_or_raise(VALID_TAGS, tag)
|
73
|
+
@tag = :li if list? && divider?
|
74
|
+
@attributes[:role] ||= :menuitem
|
75
|
+
@attributes[:role] = :separator if @divider
|
76
|
+
end
|
77
|
+
|
78
|
+
def call
|
79
|
+
component = if BUTTON_TAGS.include?(@tag)
|
80
|
+
Ariadne::ButtonComponent.new(scheme: Ariadne::ButtonComponent::LINK_SCHEME, classes: @classes, attributes: @attributes)
|
81
|
+
else
|
82
|
+
Ariadne::BaseComponent.new(tag: @tag, classes: @classes, attributes: @attributes)
|
83
|
+
end
|
84
|
+
|
85
|
+
# divider has no content
|
86
|
+
render(component) if divider?
|
87
|
+
|
88
|
+
render(component) { content }
|
89
|
+
end
|
90
|
+
|
91
|
+
def divider?
|
92
|
+
@divider
|
93
|
+
end
|
94
|
+
|
95
|
+
def list?
|
96
|
+
@as == :list
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
import '@github/details-menu-element'
|