ariadne_view_components 0.0.18 → 0.0.19
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +3 -0
- data/app/assets/builds/ariadne_view_components.css +2243 -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/rich-text-area-component.d.ts +2 -0
- 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/base_button.rb +2 -2
- 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.html.erb +2 -2
- data/app/components/ariadne/component.rb +4 -0
- data/app/components/ariadne/inline_flex_component.rb +2 -2
- data/app/components/ariadne/panel_bar_component.html.erb +1 -1
- data/app/components/ariadne/panel_bar_component.rb +1 -0
- data/app/components/ariadne/rich-text-area-component.d.ts +6 -0
- data/app/components/ariadne/rich-text-area-component.js +36 -0
- data/app/components/ariadne/rich-text-area-component.ts +22 -9
- data/app/components/ariadne/rich_text_area_component.html.erb +1 -1
- data/app/components/ariadne/slideover-component.d.ts +9 -0
- data/app/components/ariadne/slideover-component.js +10 -0
- data/app/components/ariadne/slideover-component.ts +0 -9
- data/app/components/ariadne/slideover_component.d.ts +9 -0
- data/app/components/ariadne/slideover_component.html.erb +6 -8
- data/app/components/ariadne/slideover_component.js +19 -0
- data/app/components/ariadne/slideover_component.rb +9 -24
- 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-nav-component.d.ts +9 -0
- data/app/components/ariadne/tab-nav-component.js +32 -0
- data/app/components/ariadne/tab_component.rb +0 -1
- data/app/components/ariadne/tab_container_component.erb +1 -1
- data/app/components/ariadne/tab_container_component.rb +2 -1
- 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/lib/ariadne/view_components/version.rb +1 -1
- data/static/arguments.yml +0 -4
- data/static/classes.yml +3 -5
- data/static/constants.json +7 -8
- metadata +38 -6
@@ -0,0 +1,20 @@
|
|
1
|
+
import { Controller } from '@hotwired/stimulus';
|
2
|
+
import { TemplateResult } from 'lit-html';
|
3
|
+
declare type HTMLFormField = HTMLInputElement | HTMLButtonElement | HTMLSelectElement | HTMLTextAreaElement;
|
4
|
+
export default class AriadneFormWith extends Controller {
|
5
|
+
connect(): void;
|
6
|
+
disconnect(): void;
|
7
|
+
onBlur: (event: Event) => void;
|
8
|
+
onSubmit: (event: Event) => void;
|
9
|
+
validateForm(): boolean;
|
10
|
+
validateField(field: HTMLFormField): boolean;
|
11
|
+
shouldValidateField(field: HTMLFormField): boolean;
|
12
|
+
refreshErrorForInvalidField(field: HTMLFormField, isValid: boolean): void;
|
13
|
+
removeExistingErrorMessage(field: HTMLFormField): void;
|
14
|
+
showErrorForInvalidField(field: HTMLFormField): void;
|
15
|
+
buildFieldErrorHtml(field: HTMLFormField): string;
|
16
|
+
get formFields(): HTMLFormField[];
|
17
|
+
get firstInvalidField(): HTMLFormField | undefined;
|
18
|
+
getRenderString: (data: TemplateResult) => string;
|
19
|
+
}
|
20
|
+
export {};
|
@@ -0,0 +1,85 @@
|
|
1
|
+
import { Controller } from '@hotwired/stimulus';
|
2
|
+
import { html } from 'lit-html';
|
3
|
+
export default class AriadneFormWith extends Controller {
|
4
|
+
constructor() {
|
5
|
+
super(...arguments);
|
6
|
+
this.onBlur = (event) => {
|
7
|
+
this.validateField(event.target);
|
8
|
+
};
|
9
|
+
this.onSubmit = (event) => {
|
10
|
+
var _a;
|
11
|
+
if (!this.validateForm()) {
|
12
|
+
event.preventDefault();
|
13
|
+
(_a = this.firstInvalidField) === null || _a === void 0 ? void 0 : _a.focus();
|
14
|
+
}
|
15
|
+
};
|
16
|
+
this.getRenderString = (data) => {
|
17
|
+
const { strings, values } = data;
|
18
|
+
const v = [...values, ''].map(e => (typeof e === 'object' ? this.getRenderString(e) : e));
|
19
|
+
return strings.reduce((acc, s, i) => acc + s + v[i], '');
|
20
|
+
};
|
21
|
+
}
|
22
|
+
connect() {
|
23
|
+
this.element.setAttribute('novalidate', 'true');
|
24
|
+
this.element.addEventListener('blur', this.onBlur, true);
|
25
|
+
this.element.addEventListener('submit', this.onSubmit);
|
26
|
+
this.element.addEventListener('ajax:beforeSend', this.onSubmit);
|
27
|
+
}
|
28
|
+
disconnect() {
|
29
|
+
this.element.removeEventListener('blur', this.onBlur);
|
30
|
+
this.element.removeEventListener('submit', this.onSubmit);
|
31
|
+
this.element.removeEventListener('ajax:beforeSend', this.onSubmit);
|
32
|
+
}
|
33
|
+
validateForm() {
|
34
|
+
let isValid = true;
|
35
|
+
// Not using `find` because we want to validate all the fields
|
36
|
+
for (const field of this.formFields) {
|
37
|
+
if (this.shouldValidateField(field) && !this.validateField(field))
|
38
|
+
isValid = false;
|
39
|
+
}
|
40
|
+
return isValid;
|
41
|
+
}
|
42
|
+
validateField(field) {
|
43
|
+
if (!this.shouldValidateField(field))
|
44
|
+
return true;
|
45
|
+
const isValid = field.checkValidity();
|
46
|
+
field.classList.toggle('invalid', !isValid);
|
47
|
+
this.refreshErrorForInvalidField(field, isValid);
|
48
|
+
return isValid;
|
49
|
+
}
|
50
|
+
shouldValidateField(field) {
|
51
|
+
return !field.disabled && !['file', 'reset', 'submit', 'button'].includes(field.type);
|
52
|
+
}
|
53
|
+
refreshErrorForInvalidField(field, isValid) {
|
54
|
+
this.removeExistingErrorMessage(field);
|
55
|
+
if (!isValid)
|
56
|
+
this.showErrorForInvalidField(field);
|
57
|
+
}
|
58
|
+
removeExistingErrorMessage(field) {
|
59
|
+
var _a;
|
60
|
+
const fieldContainer = field.closest('.field');
|
61
|
+
if (!fieldContainer)
|
62
|
+
return;
|
63
|
+
const existingErrorMessageElement = fieldContainer.querySelector('.error');
|
64
|
+
if (existingErrorMessageElement) {
|
65
|
+
(_a = existingErrorMessageElement === null || existingErrorMessageElement === void 0 ? void 0 : existingErrorMessageElement.parentNode) === null || _a === void 0 ? void 0 : _a.removeChild(existingErrorMessageElement);
|
66
|
+
}
|
67
|
+
}
|
68
|
+
showErrorForInvalidField(field) {
|
69
|
+
field.insertAdjacentHTML('afterend', this.buildFieldErrorHtml(field));
|
70
|
+
}
|
71
|
+
buildFieldErrorHtml(field) {
|
72
|
+
const data = html `<p class="error">${field.validationMessage}</p>`;
|
73
|
+
return this.getRenderString(data);
|
74
|
+
}
|
75
|
+
get formFields() {
|
76
|
+
return Array.from(this.element.children).filter(node => {
|
77
|
+
const data = node.attributes.getNamedItem('data-ariadne-form-field');
|
78
|
+
if ((data === null || data === void 0 ? void 0 : data.value) === 'true')
|
79
|
+
return true;
|
80
|
+
});
|
81
|
+
}
|
82
|
+
get firstInvalidField() {
|
83
|
+
return this.formFields.find(field => !field.checkValidity());
|
84
|
+
}
|
85
|
+
}
|
@@ -0,0 +1,22 @@
|
|
1
|
+
import { Controller } from '@hotwired/stimulus';
|
2
|
+
import type { TemplateResult } from 'lit-html';
|
3
|
+
declare type HTMLFormField = HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement;
|
4
|
+
export default class AriadneFormWith extends Controller {
|
5
|
+
static targets: string[];
|
6
|
+
readonly formFieldTargets: [HTMLFormField];
|
7
|
+
connect(): void;
|
8
|
+
disconnect(): void;
|
9
|
+
onBlur: (event: Event) => void;
|
10
|
+
onSubmit: (event: Event) => void;
|
11
|
+
validateForm(): boolean;
|
12
|
+
validateField(field: HTMLFormField): boolean;
|
13
|
+
shouldValidateField(field: HTMLFormField): boolean;
|
14
|
+
refreshErrorForInvalidField(field: HTMLFormField, isValid: boolean): void;
|
15
|
+
removeExistingErrorMessage(field: HTMLFormField): void;
|
16
|
+
showErrorForInvalidField(field: HTMLFormField): void;
|
17
|
+
buildFieldErrorHtml(field: HTMLFormField): string;
|
18
|
+
get formFields(): HTMLFormField[];
|
19
|
+
get firstInvalidField(): HTMLFormField | undefined;
|
20
|
+
getRenderString: (data: TemplateResult) => string;
|
21
|
+
}
|
22
|
+
export {};
|
@@ -0,0 +1,84 @@
|
|
1
|
+
import { Controller } from '@hotwired/stimulus';
|
2
|
+
import { html } from 'lit-html';
|
3
|
+
export default class AriadneFormWith extends Controller {
|
4
|
+
constructor() {
|
5
|
+
super(...arguments);
|
6
|
+
this.onBlur = (event) => {
|
7
|
+
this.validateField(event.target);
|
8
|
+
};
|
9
|
+
this.onSubmit = (event) => {
|
10
|
+
var _a;
|
11
|
+
if (!this.validateForm()) {
|
12
|
+
event.preventDefault();
|
13
|
+
(_a = this.firstInvalidField) === null || _a === void 0 ? void 0 : _a.focus();
|
14
|
+
}
|
15
|
+
};
|
16
|
+
this.getRenderString = (data) => {
|
17
|
+
const { strings, values } = data;
|
18
|
+
const v = [...values, ''].map(e => (typeof e === 'object' ? this.getRenderString(e) : e));
|
19
|
+
return strings.reduce((acc, s, i) => acc + s + v[i], '');
|
20
|
+
};
|
21
|
+
}
|
22
|
+
connect() {
|
23
|
+
this.element.setAttribute('novalidate', 'true');
|
24
|
+
this.element.addEventListener('blur', this.onBlur, true);
|
25
|
+
this.element.addEventListener('submit', this.onSubmit);
|
26
|
+
this.element.addEventListener('ajax:beforeSend', this.onSubmit);
|
27
|
+
}
|
28
|
+
disconnect() {
|
29
|
+
this.element.removeEventListener('blur', this.onBlur);
|
30
|
+
this.element.removeEventListener('submit', this.onSubmit);
|
31
|
+
this.element.removeEventListener('ajax:beforeSend', this.onSubmit);
|
32
|
+
}
|
33
|
+
validateForm() {
|
34
|
+
let isValid = true;
|
35
|
+
// Not using `find` because we want to validate all the fields
|
36
|
+
for (const field of this.formFields) {
|
37
|
+
if (this.shouldValidateField(field) && !this.validateField(field))
|
38
|
+
isValid = false;
|
39
|
+
}
|
40
|
+
return isValid;
|
41
|
+
}
|
42
|
+
validateField(field) {
|
43
|
+
if (!this.shouldValidateField(field))
|
44
|
+
return true;
|
45
|
+
const isValid = field.checkValidity();
|
46
|
+
field.classList.toggle('invalid', !isValid);
|
47
|
+
this.refreshErrorForInvalidField(field, isValid);
|
48
|
+
return isValid;
|
49
|
+
}
|
50
|
+
shouldValidateField(field) {
|
51
|
+
return (!field.disabled &&
|
52
|
+
!field.classList.contains('ProseMirror') &&
|
53
|
+
!['file', 'reset', 'submit', 'button'].includes(field.type));
|
54
|
+
}
|
55
|
+
refreshErrorForInvalidField(field, isValid) {
|
56
|
+
this.removeExistingErrorMessage(field);
|
57
|
+
if (!isValid)
|
58
|
+
this.showErrorForInvalidField(field);
|
59
|
+
}
|
60
|
+
removeExistingErrorMessage(field) {
|
61
|
+
var _a;
|
62
|
+
const fieldContainer = field.closest('.field');
|
63
|
+
if (!fieldContainer)
|
64
|
+
return;
|
65
|
+
const existingErrorMessageElement = fieldContainer.querySelector('.error');
|
66
|
+
if (existingErrorMessageElement) {
|
67
|
+
(_a = existingErrorMessageElement === null || existingErrorMessageElement === void 0 ? void 0 : existingErrorMessageElement.parentNode) === null || _a === void 0 ? void 0 : _a.removeChild(existingErrorMessageElement);
|
68
|
+
}
|
69
|
+
}
|
70
|
+
showErrorForInvalidField(field) {
|
71
|
+
field.insertAdjacentHTML('afterend', this.buildFieldErrorHtml(field));
|
72
|
+
}
|
73
|
+
buildFieldErrorHtml(field) {
|
74
|
+
const data = html `<p class="error">${field.validationMessage}</p>`;
|
75
|
+
return this.getRenderString(data);
|
76
|
+
}
|
77
|
+
get formFields() {
|
78
|
+
return Array.from(this.formFieldTargets);
|
79
|
+
}
|
80
|
+
get firstInvalidField() {
|
81
|
+
return this.formFields.find(field => !field.checkValidity());
|
82
|
+
}
|
83
|
+
}
|
84
|
+
AriadneFormWith.targets = ['formField'];
|
@@ -0,0 +1,16 @@
|
|
1
|
+
import { Application } from '@hotwired/stimulus';
|
2
|
+
import AriadneForm from './ariadne-form';
|
3
|
+
import ClipboardCopyComponent from './clipboard-copy-component';
|
4
|
+
import RichTextAreaComponent from './rich-text-area-component';
|
5
|
+
import SlideoverComponent from './slideover-component';
|
6
|
+
import TabNavComponent from './tab-nav-component';
|
7
|
+
import TooltipComponent from './tooltip-component';
|
8
|
+
import './tab-container-component';
|
9
|
+
import './time-ago-component';
|
10
|
+
const application = Application.start();
|
11
|
+
application.register('clipboard-copy-component', ClipboardCopyComponent);
|
12
|
+
application.register('ariadne-form', AriadneForm);
|
13
|
+
application.register('rich-text-area-component', RichTextAreaComponent);
|
14
|
+
application.register('slideover-component', SlideoverComponent);
|
15
|
+
application.register('tab-nav-component', TabNavComponent);
|
16
|
+
application.register('tooltip-component', TooltipComponent);
|
@@ -19,8 +19,8 @@ module Ariadne
|
|
19
19
|
}.freeze
|
20
20
|
VALID_SIZES = SIZE_CLASS_MAPPINGS.keys.freeze
|
21
21
|
|
22
|
-
DEFAULT_CLASSES = "ariadne-
|
23
|
-
DEFAULT_NUDE_CLASSES = "
|
22
|
+
DEFAULT_CLASSES = "ariadne-items-center ariadne-border ariadne-shadow-sm focus:ariadne-outline-none focus:ariadne-ring-2 focus:ariadne-ring-offset-2"
|
23
|
+
DEFAULT_NUDE_CLASSES = "focus:ariadne-outline-none focus:ariadne-ring-2 focus:ariadne-ring-offset-2"
|
24
24
|
|
25
25
|
DEFAULT_SIZE = :md
|
26
26
|
|
@@ -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
|
+
}
|
@@ -4,7 +4,7 @@
|
|
4
4
|
<% tab.text { @public_tab_text } %>
|
5
5
|
<% tab.panel(attributes: {:"data-public" => true}) do %>
|
6
6
|
<%= ariadne_form_with(url: @url, method: @method, classes: @classes, attributes: @attributes) do |comment_box| %>
|
7
|
-
<div class="ariadne-overflow-hidden ariadne-border ariadne-border-gray-300 ariadne-shadow-sm
|
7
|
+
<div class="ariadne-overflow-hidden ariadne-border ariadne-border-gray-300 ariadne-shadow-sm">
|
8
8
|
<%= hidden_field_tag 'message_public', true %>
|
9
9
|
<%= render(Ariadne::RichTextAreaComponent.new(name: :public_bodytext, sr_label: "Select reply type", attributes: { required: true})) %>
|
10
10
|
<% comment_box.submit { @submit } %>
|
@@ -19,7 +19,7 @@
|
|
19
19
|
<% tab.text { @internal_tab_text } %>
|
20
20
|
<% tab.panel do %>
|
21
21
|
<%= ariadne_form_with(url: @url, method: @method, classes: @classes, attributes: @attributes) do |comment_box| %>
|
22
|
-
<div class="ariadne-overflow-hidden ariadne-border ariadne-border-gray-300 ariadne-shadow-sm
|
22
|
+
<div class="ariadne-overflow-hidden ariadne-border ariadne-border-gray-300 ariadne-shadow-sm">
|
23
23
|
<%= hidden_field_tag 'message_public', false %>
|
24
24
|
<%= render(Ariadne::RichTextAreaComponent.new(name: :internal_bodytext, sr_label: "Select reply type", attributes: { required: true})) %>
|
25
25
|
<% comment_box.submit { @submit } %>
|
@@ -19,6 +19,10 @@ module Ariadne
|
|
19
19
|
BASE_WRAPPER_CLASSES = "ariadne-flex ariadne-flex-col ariadne-h-screen ariadne-justify-between"
|
20
20
|
BASE_MAIN_CLASSES = "ariadne-flex-auto"
|
21
21
|
|
22
|
+
# this is defined here for the Tailwind parser to pick up; it can be useful
|
23
|
+
# in situations where hiddenness is defined by a kwarg, eg `selected: false`
|
24
|
+
BASE_HIDDEN_CLASS = "ariadne-hidden"
|
25
|
+
|
22
26
|
INVALID_ARIA_LABEL_TAGS = [:div, :span, :p].freeze
|
23
27
|
|
24
28
|
private def raise_on_invalid_options?
|
@@ -26,7 +26,7 @@ module Ariadne
|
|
26
26
|
|
27
27
|
DEFAULT_TEXT_OPEN_CLASSES = "ariadne-text-state-open"
|
28
28
|
DEFAULT_TEXT_CLOSED_CLASSES = "ariadne-text-state-closed"
|
29
|
-
DEFAULT_TEXT_CLASSES = "ariadne-pl-2 ariadne-text-sm ariadne-font-medium
|
29
|
+
DEFAULT_TEXT_CLASSES = "ariadne-pl-2 ariadne-text-sm ariadne-font-medium"
|
30
30
|
renders_one :icon, lambda { |tag: :svg, icon:, variant:, size: Ariadne::HeroiconComponent::SIZE_DEFAULT, classes: "", attributes: {}, text_classes: "", text_attributes: {}|
|
31
31
|
actual_text_classes = class_names(DEFAULT_TEXT_CLASSES, text_classes)
|
32
32
|
Ariadne::HeroiconComponent.new(tag: tag, icon: icon, variant: variant, size: size, classes: classes, attributes: attributes, text_classes: actual_text_classes, text_attributes: text_attributes) { content }
|
@@ -36,7 +36,7 @@ module Ariadne
|
|
36
36
|
Ariadne::BaseComponent.new(tag: :span, classes: classes, attributes: attributes) { content }
|
37
37
|
}
|
38
38
|
|
39
|
-
DEFAULT_LABEL_CLASSES = "ariadne-pl-2 ariadne-text-sm ariadne-font-medium
|
39
|
+
DEFAULT_LABEL_CLASSES = "ariadne-pl-2 ariadne-text-sm ariadne-font-medium"
|
40
40
|
renders_one :text, lambda { |classes: "", attributes: {}|
|
41
41
|
actual_classes = class_names(DEFAULT_LABEL_CLASSES, classes)
|
42
42
|
Ariadne::BaseComponent.new(tag: :span, classes: actual_classes, attributes: attributes) { content }
|
@@ -5,7 +5,7 @@
|
|
5
5
|
<span class="ariadne-px-6 ariadne-py-4 ariadne-flex ariadne-items-center ariadne-text-sm ariadne-font-medium">
|
6
6
|
<%= panel.icon %>
|
7
7
|
<span class="ariadne-ml-4 ariadne-text-sm ariadne-font-medium ariadne-text-gray-900"><%= panel.label %></span>
|
8
|
-
<!--
|
8
|
+
<!-- TODO: fix this -->
|
9
9
|
<% if idx + 1 < panels.size %>
|
10
10
|
<div class="md:ariadne-block ariadne-hidden ariadne-absolute ariadne-top-0 ariadne-right-0 ariadne-h-full ariadne-w-5" aria-hidden="true">
|
11
11
|
<svg class="ariadne-h-full ariadne-w-full ariadne-text-gray-300" viewBox="0 0 22 80" fill="none" preserveAspectRatio="none">
|
@@ -40,6 +40,7 @@ module Ariadne
|
|
40
40
|
DEFAULT_ITEM_CLASSES = "ariadne-relative md:ariadne-flex-1 md:ariadne-flex"
|
41
41
|
DEFAULT_WRAPPER_CLASSES = "group ariadne-flex ariadne-items-center ariadne-w-full"
|
42
42
|
|
43
|
+
# TODO: fix this
|
43
44
|
renders_one :icon, lambda { |static_content = nil, &block|
|
44
45
|
next static_content if static_content.present?
|
45
46
|
|
@@ -0,0 +1,36 @@
|
|
1
|
+
import { Controller } from '@hotwired/stimulus';
|
2
|
+
import { Editor } from '@tiptap/core';
|
3
|
+
import { Document } from '@tiptap/extension-document';
|
4
|
+
import { Paragraph } from '@tiptap/extension-paragraph';
|
5
|
+
import { Text } from '@tiptap/extension-text';
|
6
|
+
import DropCursor from '@tiptap/extension-dropcursor';
|
7
|
+
import GapCursor from '@tiptap/extension-gapcursor';
|
8
|
+
import { History } from '@tiptap/extension-history';
|
9
|
+
export default class RichTextArea extends Controller {
|
10
|
+
connect() {
|
11
|
+
for (const editorElement of this.editorTargets) {
|
12
|
+
const pmEditor = new Editor({
|
13
|
+
extensions: [DropCursor, GapCursor, History, Document, Paragraph, Text],
|
14
|
+
content: '',
|
15
|
+
injectCSS: false,
|
16
|
+
element: editorElement,
|
17
|
+
editorProps: {
|
18
|
+
attributes: {
|
19
|
+
class: 'ariadne-p-3'
|
20
|
+
}
|
21
|
+
},
|
22
|
+
parseOptions: {
|
23
|
+
preserveWhitespace: true
|
24
|
+
}
|
25
|
+
});
|
26
|
+
const tiptapValueContainer = editorElement.previousElementSibling;
|
27
|
+
if (tiptapValueContainer) {
|
28
|
+
const parentForm = editorElement.closest('form');
|
29
|
+
parentForm === null || parentForm === void 0 ? void 0 : parentForm.addEventListener('submit', () => {
|
30
|
+
tiptapValueContainer.setAttribute('value', pmEditor.getText() || '');
|
31
|
+
});
|
32
|
+
}
|
33
|
+
}
|
34
|
+
}
|
35
|
+
}
|
36
|
+
RichTextArea.targets = ['editor'];
|
@@ -1,21 +1,34 @@
|
|
1
1
|
import {Controller} from '@hotwired/stimulus'
|
2
2
|
|
3
3
|
import {Editor} from '@tiptap/core'
|
4
|
-
|
4
|
+
|
5
|
+
import {Document} from '@tiptap/extension-document'
|
6
|
+
import {Paragraph} from '@tiptap/extension-paragraph'
|
7
|
+
import {Text} from '@tiptap/extension-text'
|
8
|
+
|
9
|
+
import DropCursor from '@tiptap/extension-dropcursor'
|
10
|
+
import GapCursor from '@tiptap/extension-gapcursor'
|
11
|
+
import {History} from '@tiptap/extension-history'
|
5
12
|
|
6
13
|
export default class RichTextArea extends Controller {
|
14
|
+
static targets = ['editor']
|
15
|
+
|
16
|
+
declare readonly editorTargets: [HTMLDivElement]
|
17
|
+
|
7
18
|
connect() {
|
8
|
-
const
|
9
|
-
|
10
|
-
|
11
|
-
element: editorElement,
|
12
|
-
extensions: [StarterKit],
|
19
|
+
for (const editorElement of this.editorTargets) {
|
20
|
+
const pmEditor = new Editor({
|
21
|
+
extensions: [DropCursor, GapCursor, History, Document, Paragraph, Text],
|
13
22
|
content: '',
|
23
|
+
injectCSS: false,
|
24
|
+
element: editorElement,
|
14
25
|
editorProps: {
|
15
26
|
attributes: {
|
16
|
-
class:
|
17
|
-
'focus:ariadne-outline-none ariadne-block ariadne-w-full ariadne-resize-none ariadne-p-0 ariadne-pb-2 ariadne-border-none focus:ariadne-ring-0 sm:ariadne-text-sm'
|
27
|
+
class: 'ariadne-p-3'
|
18
28
|
}
|
29
|
+
},
|
30
|
+
parseOptions: {
|
31
|
+
preserveWhitespace: true
|
19
32
|
}
|
20
33
|
})
|
21
34
|
|
@@ -24,7 +37,7 @@ export default class RichTextArea extends Controller {
|
|
24
37
|
const parentForm = editorElement.closest('form')
|
25
38
|
|
26
39
|
parentForm?.addEventListener('submit', () => {
|
27
|
-
tiptapValueContainer.setAttribute('value',
|
40
|
+
tiptapValueContainer.setAttribute('value', pmEditor.getText() || '')
|
28
41
|
})
|
29
42
|
}
|
30
43
|
}
|
@@ -0,0 +1,9 @@
|
|
1
|
+
import { Controller } from '@hotwired/stimulus';
|
2
|
+
export default class SlideoverComponent extends Controller {
|
3
|
+
static targets: string[];
|
4
|
+
readonly expandableTarget: HTMLDivElement;
|
5
|
+
readonly expandWrapperTarget: HTMLDivElement;
|
6
|
+
readonly slidePanelTargets: [HTMLDivElement];
|
7
|
+
readonly buttonWrapperTarget: HTMLDivElement;
|
8
|
+
toggle(): void;
|
9
|
+
}
|
@@ -0,0 +1,10 @@
|
|
1
|
+
import { Controller } from '@hotwired/stimulus';
|
2
|
+
export default class SlideoverComponent extends Controller {
|
3
|
+
toggle() {
|
4
|
+
this.expandableTarget.classList.toggle('ariadne-hidden');
|
5
|
+
for (const slidePanel of this.slidePanelTargets) {
|
6
|
+
slidePanel.classList.toggle('ariadne-hidden');
|
7
|
+
}
|
8
|
+
}
|
9
|
+
}
|
10
|
+
SlideoverComponent.targets = ['expandable', 'expandWrapper', 'slidePanel', 'buttonWrapper'];
|
@@ -10,17 +10,8 @@ export default class SlideoverComponent extends Controller {
|
|
10
10
|
|
11
11
|
toggle() {
|
12
12
|
this.expandableTarget.classList.toggle('ariadne-hidden')
|
13
|
-
this.expandWrapperTarget.classList.toggle('bg-filter-panel')
|
14
13
|
for (const slidePanel of this.slidePanelTargets) {
|
15
14
|
slidePanel.classList.toggle('ariadne-hidden')
|
16
15
|
}
|
17
|
-
this.buttonWrapperTarget.classList.toggle('bg-filter-panel')
|
18
|
-
if (document.getElementById('btnClose')?.classList.contains('ariadne-hidden')) {
|
19
|
-
const formID = this.buttonWrapperTarget.getAttribute('data-slideover-component-form-id')
|
20
|
-
if (formID) {
|
21
|
-
const form = <HTMLFormElement>document.getElementById(formID)
|
22
|
-
form?.submit()
|
23
|
-
}
|
24
|
-
}
|
25
16
|
}
|
26
17
|
}
|
@@ -0,0 +1,9 @@
|
|
1
|
+
import { Controller } from '@hotwired/stimulus';
|
2
|
+
export default class SlideoverComponent extends Controller {
|
3
|
+
static targets: string[];
|
4
|
+
readonly expandableTarget: HTMLDivElement;
|
5
|
+
readonly expandWrapperTarget: HTMLDivElement;
|
6
|
+
readonly slidePanelTargets: [HTMLDivElement];
|
7
|
+
readonly buttonWrapperTarget: HTMLDivElement;
|
8
|
+
toggle(): void;
|
9
|
+
}
|
@@ -1,11 +1,9 @@
|
|
1
1
|
<%= render Ariadne::BaseComponent.new(tag: @tag, classes: @classes, attributes: @attributes) do |slideover| %>
|
2
|
-
<div data-slideover-component-target="
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
<%= close_button %>
|
9
|
-
</div>
|
2
|
+
<div data-slideover-component-target="expandable" class="ariadne-hidden ariadne-px-3">
|
3
|
+
<%= content %>
|
4
|
+
</div>
|
5
|
+
<div data-slideover-component-target="buttonWrapper" class="ariadne-relative ariadne-flex ariadne-justify-center">
|
6
|
+
<%= open_button %>
|
7
|
+
<%= close_button %>
|
10
8
|
</div>
|
11
9
|
<% end %>
|
@@ -0,0 +1,19 @@
|
|
1
|
+
import { Controller } from '@hotwired/stimulus';
|
2
|
+
export default class SlideoverComponent extends Controller {
|
3
|
+
toggle() {
|
4
|
+
var _a;
|
5
|
+
// eslint-disable-next-line no-debugger
|
6
|
+
debugger;
|
7
|
+
this.expandableTarget.classList.toggle('hidden');
|
8
|
+
this.expandWrapperTarget.classList.toggle('bg-filter-panel');
|
9
|
+
for (const slidePanel of this.slidePanelTargets) {
|
10
|
+
slidePanel.classList.toggle('hidden');
|
11
|
+
}
|
12
|
+
this.buttonWrapperTarget.classList.toggle('bg-filter-panel');
|
13
|
+
if ((_a = document.getElementById('btnClose')) === null || _a === void 0 ? void 0 : _a.classList.contains('hidden')) {
|
14
|
+
const form = this.buttonWrapperTarget.closest('form');
|
15
|
+
form === null || form === void 0 ? void 0 : form.submit();
|
16
|
+
}
|
17
|
+
}
|
18
|
+
}
|
19
|
+
SlideoverComponent.targets = ['expandable', 'expandWrapper', 'slidePanel', 'buttonWrapper'];
|