refactor: Info Card

This commit is contained in:
sokumon 2026-02-08 13:10:15 +05:30
parent 0ab1565444
commit 2ae0da7903
5 changed files with 94 additions and 67 deletions

View file

@ -1,4 +1,4 @@
import { createPopper } from "@popperjs/core";
import { InfoCard } from "../info_card";
frappe.ui.form.ControlInput = class ControlInput extends frappe.ui.form.Control {
static horizontal = true;
make() {
@ -8,7 +8,6 @@ frappe.ui.form.ControlInput = class ControlInput extends frappe.ui.form.Control
// set description
this.set_max_width();
this.info_card_display = false;
// set initial value if set
if (this.df.initial_value) {
this.set_value(this.df.initial_value);
@ -200,71 +199,17 @@ frappe.ui.form.ControlInput = class ControlInput extends frappe.ui.form.Control
this.label_span.innerHTML =
(icon ? '<i class="' + icon + '"></i> ' : "") +
__(this.df.label, null, this.df.parent) || "&nbsp;";
this.show_description_on_click();
this._label = this.df.label;
}
show_description_on_click() {
const me = this;
if (this.df.show_description_on_click) {
$(
`${frappe.utils.icon(
"message-circle-question-mark",
"sm",
"",
"",
"cursor-pointer"
)}`
).appendTo($(this.label_span));
$(this.label_span).find("svg").attr("role", "button");
this.$info_card = $("<div class='info-card'></div>").appendTo(this.label_span);
$(this.label_area).css({
display: "flex",
gap: "6px",
"align-items": "center",
"white-space": "nowrap",
let info_card = new InfoCard({
label_area: this.label_area,
label_span: this.label_span,
df: this.df,
});
let popper = createPopper(
$(this.label_span).find("svg").get(0),
this.$info_card.get(0),
{
modifiers: [
{
name: "offset",
options: {
offset: [0, 8],
},
},
],
}
);
$(this.label_span)
.find("svg")
.on("click", (event) => {
event.preventDefault();
me.$info_card.html("");
let card_args = {
message: me.df.description,
parent: me.$info_card,
close_button: true,
};
if (me.df.documentation_url) {
card_args.primary_action_label = "Read More";
card_args.primary_action_suffix_icon = "square-arrow-out-up-right";
card_args.primary_action = function () {
window.open(me.df.documentation_url);
};
card_args.styles = {
"sidebar-card-button-bg-color": "var(--surface-gray-2)",
"sidebar-card-button-color": "var(--ink-gray-7)",
"sidebar-card-button-outline": "var(--ink-gray-7)",
};
}
let card = new frappe.ui.SidebarCard(card_args);
if (me.info_card_display) {
me.info_card_display = false;
me.$info_card.removeAttr("data-show");
} else {
me.info_card_display = true;
me.$info_card.attr("data-show", "");
popper.update();
}
});
this._label = this.df.label;
}
}
set_doc_url() {

View file

@ -0,0 +1,56 @@
export class InfoCard {
constructor(opts) {
Object.assign(this, opts);
this.make();
this.setup_click();
}
make() {
this.make_toggle_button();
this.make_card();
}
make_toggle_button() {
$(
`${frappe.utils.icon("message-circle-question-mark", "sm", "", "", "cursor-pointer")}`
).appendTo($(this.label_span));
$(this.label_span).find("svg").attr("role", "button");
$(this.label_area).css({
display: "flex",
gap: "6px",
"align-items": "center",
"white-space": "nowrap",
});
}
make_card() {
const me = this;
this.$info_card = $("<div class='info-card'></div>").appendTo(this.label_span);
let card_args = {
message: this.df.description,
parent: this.$info_card,
trigger: $(this.label_span).find("svg").get(0),
close_button: true,
popper: true,
};
if (this.df.documentation_url) {
card_args.primary_action_label = "Read More";
card_args.primary_action_suffix_icon = "square-arrow-out-up-right";
card_args.primary_action = function () {
window.open(me.df.documentation_url);
};
card_args.styles = {
"sidebar-card-button-bg-color": "var(--surface-gray-2)",
"sidebar-card-button-color": "var(--ink-gray-7)",
"sidebar-card-button-outline": "var(--ink-gray-7)",
};
}
this.card = new frappe.ui.SidebarCard(card_args);
}
setup_click() {
const me = this;
$(this.label_span)
.find("svg")
.on("click", (event) => {
event.preventDefault();
me.card.toggle();
});
}
}

View file

@ -14,7 +14,7 @@
<div class="sidebar-card-title">{{ card.title }}</div>
<div class="sidebar-card-description">{{ card.message }}</div>
</span>
{%= frappe.utils.icon("x","sm", "", "", "card-icon") %}
{%= frappe.utils.icon("x","sm", "", "", "card-icon cursor-pointer") %}
</div>
{% } %}
{% if(card.primary_action_label) { %}

View file

@ -1,3 +1,4 @@
import { createPopper } from "@popperjs/core";
frappe.provide("frappe.ui");
// icon, title, message, condition, primary_action_label, primary_action
@ -6,6 +7,7 @@ frappe.ui.SidebarCard = class SidebarCard {
Object.assign(this, opts);
this.make(opts);
this.setup();
this.display = false;
this.set_styles();
}
make() {
@ -17,12 +19,33 @@ frappe.ui.SidebarCard = class SidebarCard {
card: this,
})
);
if (this.popper) {
this.popper = createPopper($(this.trigger).get(0), $(this.parent).get(0), {
modifiers: [
{
name: "offset",
options: {
offset: [0, 8],
},
},
],
});
}
this.card.prependTo(this.parent);
}
setup() {
this.setup_primary_action();
}
toggle() {
if (this.display) {
this.display = false;
this.parent.removeAttr("data-show");
} else {
this.display = true;
this.parent.attr("data-show", "");
this.popper.update();
}
}
setup_primary_action() {
const me = this;
this.card.find(".sidebar-card-button").on("click", function (event) {

View file

@ -51,3 +51,6 @@
outline: 1px solid var(--sidebar-card-button-outline);
color: var(--sidebar-card-button-color);
}
.cursor-pointer {
cursor: pointer;
}