wilday_ui 0.6.0 → 0.8.0
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/wilday_ui/index.js +460 -0
- data/app/assets/builds/wilday_ui/index.js.map +3 -3
- data/app/assets/stylesheets/wilday_ui/components/button/features/clipboard.css +108 -0
- data/app/assets/stylesheets/wilday_ui/components/button/features/confirmation.css +136 -0
- data/app/assets/stylesheets/wilday_ui/components/button/features/tooltip.css +258 -0
- data/app/assets/stylesheets/wilday_ui/components/button/features/variants.css +5 -0
- data/app/assets/stylesheets/wilday_ui/components/button/index.css +4 -0
- data/app/assets/stylesheets/wilday_ui/tokens/colors.css +109 -0
- data/app/helpers/wilday_ui/components/button_helper.rb +253 -2
- data/app/javascript/wilday_ui/controllers/clipboard_controller.js +76 -0
- data/app/javascript/wilday_ui/controllers/confirmation_controller.js +216 -0
- data/app/javascript/wilday_ui/controllers/index.js +6 -1
- data/app/javascript/wilday_ui/controllers/tooltip_controller.js +318 -0
- data/lib/wilday_ui/version.rb +1 -1
- metadata +9 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6aae81001c80b4c0fd86eaca5391e6de697a87b88e38215bd1889a70163dafe7
|
4
|
+
data.tar.gz: 87cff2dba0f7408ae84456cec4b6aac1927f1bcc27ad09309091c2b43c3df45a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: '09d8ec007fb7c0757f65ded7d2e059281752c2fdc07cee90aea77dc82b008adb9e07c6161cd527635ceb289121a030b29234a6d5c306a24e68b3d9378e0bfc0e'
|
7
|
+
data.tar.gz: da49ca71e648b9e527d02668a83cc6130dcb53ada46f195e9bb19dc4e3a5cf716b9d0b7353f4e68cfdc01416c6bdc5b8a15afc8ea349ea9fe8053be3c74bf318
|
@@ -2708,11 +2708,471 @@ var dropdown_controller_default = class extends Controller {
|
|
2708
2708
|
}
|
2709
2709
|
};
|
2710
2710
|
|
2711
|
+
// app/javascript/wilday_ui/controllers/clipboard_controller.js
|
2712
|
+
var clipboard_controller_default = class extends Controller {
|
2713
|
+
static targets = ["button", "feedback"];
|
2714
|
+
static values = {
|
2715
|
+
text: String,
|
2716
|
+
feedbackText: { type: String, default: "Copied!" },
|
2717
|
+
feedbackPosition: { type: String, default: "top" },
|
2718
|
+
feedbackDuration: { type: Number, default: 2e3 }
|
2719
|
+
};
|
2720
|
+
connect() {
|
2721
|
+
}
|
2722
|
+
async copy(event) {
|
2723
|
+
event.preventDefault();
|
2724
|
+
try {
|
2725
|
+
await navigator.clipboard.writeText(this.textValue);
|
2726
|
+
this.showFeedback();
|
2727
|
+
} catch (err) {
|
2728
|
+
console.error("Failed to copy text:", err);
|
2729
|
+
this.fallbackCopy();
|
2730
|
+
}
|
2731
|
+
}
|
2732
|
+
fallbackCopy() {
|
2733
|
+
const textArea = document.createElement("textarea");
|
2734
|
+
textArea.value = this.textValue;
|
2735
|
+
textArea.style.position = "fixed";
|
2736
|
+
textArea.style.left = "-9999px";
|
2737
|
+
document.body.appendChild(textArea);
|
2738
|
+
textArea.select();
|
2739
|
+
try {
|
2740
|
+
document.execCommand("copy");
|
2741
|
+
this.showFeedback();
|
2742
|
+
} catch (err) {
|
2743
|
+
console.error("Fallback: Oops, unable to copy", err);
|
2744
|
+
}
|
2745
|
+
document.body.removeChild(textArea);
|
2746
|
+
}
|
2747
|
+
showFeedback() {
|
2748
|
+
const feedback = this.hasFeedbackTarget ? this.feedbackTarget : this.createFeedbackElement();
|
2749
|
+
feedback.textContent = this.feedbackTextValue;
|
2750
|
+
feedback.className = "w-button-feedback";
|
2751
|
+
const positionClasses = this.feedbackPositionValue.split("-");
|
2752
|
+
positionClasses.forEach((pos) => {
|
2753
|
+
feedback.classList.add(`w-button-feedback-${pos}`);
|
2754
|
+
});
|
2755
|
+
feedback.classList.add("w-button-feedback-show");
|
2756
|
+
setTimeout(() => {
|
2757
|
+
feedback.classList.remove("w-button-feedback-show");
|
2758
|
+
}, this.feedbackDurationValue);
|
2759
|
+
}
|
2760
|
+
createFeedbackElement() {
|
2761
|
+
const feedback = document.createElement("div");
|
2762
|
+
feedback.classList.add("w-button-feedback");
|
2763
|
+
feedback.setAttribute("data-clipboard-target", "feedback");
|
2764
|
+
this.element.appendChild(feedback);
|
2765
|
+
return feedback;
|
2766
|
+
}
|
2767
|
+
};
|
2768
|
+
|
2769
|
+
// app/javascript/wilday_ui/controllers/confirmation_controller.js
|
2770
|
+
var confirmation_controller_default = class extends Controller {
|
2771
|
+
static targets = ["dialog", "confirmButton", "cancelButton"];
|
2772
|
+
static values = {
|
2773
|
+
title: String,
|
2774
|
+
message: String,
|
2775
|
+
iconColor: String,
|
2776
|
+
confirmText: String,
|
2777
|
+
cancelText: String,
|
2778
|
+
confirmStyles: String,
|
2779
|
+
cancelStyles: String
|
2780
|
+
};
|
2781
|
+
// Store the original event to be used later
|
2782
|
+
originalEvent = null;
|
2783
|
+
connect() {
|
2784
|
+
if (!this.hasDialogTarget) {
|
2785
|
+
this.element.insertAdjacentHTML("beforeend", this.dialogHTML);
|
2786
|
+
}
|
2787
|
+
}
|
2788
|
+
disconnect() {
|
2789
|
+
this.originalEvent = null;
|
2790
|
+
this.isConfirmed = false;
|
2791
|
+
}
|
2792
|
+
showDialog(event) {
|
2793
|
+
if (this.isConfirmed) {
|
2794
|
+
this.isConfirmed = false;
|
2795
|
+
return;
|
2796
|
+
}
|
2797
|
+
event.preventDefault();
|
2798
|
+
this.originalEvent = {
|
2799
|
+
type: event.type,
|
2800
|
+
element: event.currentTarget,
|
2801
|
+
ctrlKey: event.ctrlKey,
|
2802
|
+
metaKey: event.metaKey
|
2803
|
+
};
|
2804
|
+
this.dialogTarget.showModal();
|
2805
|
+
this.focusConfirmButton();
|
2806
|
+
}
|
2807
|
+
confirm(event) {
|
2808
|
+
event.preventDefault();
|
2809
|
+
this.dialogTarget.close();
|
2810
|
+
if (this.originalEvent?.element) {
|
2811
|
+
const element = this.originalEvent.element;
|
2812
|
+
if (this.hasTurbo && !element.hasAttribute("data-turbo") && !element.hasAttribute("data-turbo-method")) {
|
2813
|
+
this.resumeOriginalEvent();
|
2814
|
+
return;
|
2815
|
+
}
|
2816
|
+
const confirmEvent = new CustomEvent("confirm", {
|
2817
|
+
bubbles: true,
|
2818
|
+
cancelable: true,
|
2819
|
+
detail: {
|
2820
|
+
element,
|
2821
|
+
originalEvent: this.originalEvent
|
2822
|
+
}
|
2823
|
+
});
|
2824
|
+
const wasHandled = !element.dispatchEvent(confirmEvent);
|
2825
|
+
if (wasHandled) return;
|
2826
|
+
this.resumeOriginalEvent();
|
2827
|
+
}
|
2828
|
+
}
|
2829
|
+
resumeOriginalEvent() {
|
2830
|
+
if (!this.originalEvent) return;
|
2831
|
+
const element = this.originalEvent.element;
|
2832
|
+
this.isConfirmed = true;
|
2833
|
+
if (element.closest("form")) {
|
2834
|
+
const form = element.closest("form");
|
2835
|
+
const submitEvent = new Event("submit", {
|
2836
|
+
bubbles: true,
|
2837
|
+
cancelable: true
|
2838
|
+
});
|
2839
|
+
form.dispatchEvent(submitEvent);
|
2840
|
+
this.originalEvent = null;
|
2841
|
+
return;
|
2842
|
+
}
|
2843
|
+
if (element.tagName === "A" || element.hasAttribute("href")) {
|
2844
|
+
const click = new MouseEvent("click", {
|
2845
|
+
bubbles: true,
|
2846
|
+
cancelable: true,
|
2847
|
+
ctrlKey: this.originalEvent.ctrlKey,
|
2848
|
+
metaKey: this.originalEvent.metaKey
|
2849
|
+
});
|
2850
|
+
element.dispatchEvent(click);
|
2851
|
+
this.originalEvent = null;
|
2852
|
+
return;
|
2853
|
+
}
|
2854
|
+
if (!element.closest("form") && !(element.tagName === "A" || element.hasAttribute("href"))) {
|
2855
|
+
element.click();
|
2856
|
+
this.originalEvent = null;
|
2857
|
+
return;
|
2858
|
+
}
|
2859
|
+
}
|
2860
|
+
cancel(event) {
|
2861
|
+
event.preventDefault();
|
2862
|
+
this.closeDialog();
|
2863
|
+
}
|
2864
|
+
closeDialog() {
|
2865
|
+
this.dialogTarget.close();
|
2866
|
+
this.originalEvent = null;
|
2867
|
+
}
|
2868
|
+
handleKeydown(event) {
|
2869
|
+
if (event.key === "Escape") {
|
2870
|
+
this.cancel(event);
|
2871
|
+
}
|
2872
|
+
}
|
2873
|
+
handleClickOutside(event) {
|
2874
|
+
if (event.target === this.dialogTarget) {
|
2875
|
+
this.cancel(event);
|
2876
|
+
}
|
2877
|
+
}
|
2878
|
+
focusConfirmButton() {
|
2879
|
+
this.confirmButtonTarget.focus();
|
2880
|
+
}
|
2881
|
+
get hasTurbo() {
|
2882
|
+
return typeof Turbo !== "undefined";
|
2883
|
+
}
|
2884
|
+
get dialogHTML() {
|
2885
|
+
return `
|
2886
|
+
<dialog class="w-button-confirmation-dialog"
|
2887
|
+
data-confirmation-target="dialog"
|
2888
|
+
data-action="click->confirmation#handleClickOutside keydown->confirmation#handleKeydown">
|
2889
|
+
<div class="w-button-confirmation-dialog-content">
|
2890
|
+
<div class="w-button-confirmation-dialog-icon ${this.iconColorValue}">
|
2891
|
+
${this.iconHTML}
|
2892
|
+
</div>
|
2893
|
+
|
2894
|
+
<h3 class="w-button-confirmation-dialog-title">
|
2895
|
+
${this.titleValue}
|
2896
|
+
</h3>
|
2897
|
+
|
2898
|
+
<div class="w-button-confirmation-dialog-message">
|
2899
|
+
${this.messageValue}
|
2900
|
+
</div>
|
2901
|
+
|
2902
|
+
<div class="w-button-confirmation-dialog-actions">
|
2903
|
+
<button data-confirmation-target="cancelButton"
|
2904
|
+
data-action="click->confirmation#cancel"
|
2905
|
+
class="w-button w-button-subtle w-button-medium w-button-rounded"
|
2906
|
+
style="${this.cancelStylesValue}">
|
2907
|
+
${this.cancelTextValue}
|
2908
|
+
</button>
|
2909
|
+
|
2910
|
+
<button data-confirmation-target="confirmButton"
|
2911
|
+
data-action="click->confirmation#confirm"
|
2912
|
+
class="w-button w-button-solid w-button-medium w-button-rounded"
|
2913
|
+
style="${this.confirmStylesValue}">
|
2914
|
+
${this.confirmTextValue}
|
2915
|
+
</button>
|
2916
|
+
</div>
|
2917
|
+
</div>
|
2918
|
+
</dialog>
|
2919
|
+
`;
|
2920
|
+
}
|
2921
|
+
get iconHTML() {
|
2922
|
+
const icons = {
|
2923
|
+
info: '<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" /></svg>',
|
2924
|
+
success: '<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z" /></svg>',
|
2925
|
+
warning: '<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z" /></svg>',
|
2926
|
+
danger: '<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" /></svg>'
|
2927
|
+
};
|
2928
|
+
return icons[this.iconColorValue] || icons.info;
|
2929
|
+
}
|
2930
|
+
};
|
2931
|
+
|
2932
|
+
// app/javascript/wilday_ui/controllers/tooltip_controller.js
|
2933
|
+
var tooltip_controller_default = class extends Controller {
|
2934
|
+
static targets = ["trigger"];
|
2935
|
+
static values = {
|
2936
|
+
content: String,
|
2937
|
+
position: { type: String, default: "top" },
|
2938
|
+
align: { type: String, default: "center" },
|
2939
|
+
trigger: { type: String, default: "hover" },
|
2940
|
+
showDelay: { type: Number, default: 0 },
|
2941
|
+
hideDelay: { type: Number, default: 0 },
|
2942
|
+
offset: { type: Number, default: 8 },
|
2943
|
+
theme: { type: String, default: "light" },
|
2944
|
+
size: { type: String, default: "md" },
|
2945
|
+
arrow: { type: Boolean, default: false },
|
2946
|
+
customStyle: String
|
2947
|
+
};
|
2948
|
+
connect() {
|
2949
|
+
this.tooltipElement = null;
|
2950
|
+
this.showTimeoutId = null;
|
2951
|
+
this.hideTimeoutId = null;
|
2952
|
+
this.setupTooltip();
|
2953
|
+
this.scrollHandler = () => {
|
2954
|
+
if (this.tooltipElement.style.display !== "none") {
|
2955
|
+
const triggerRect = this.triggerTarget.getBoundingClientRect();
|
2956
|
+
const isInViewport = triggerRect.top >= 0 && triggerRect.left >= 0 && triggerRect.bottom <= (window.innerHeight || document.documentElement.clientHeight) && triggerRect.right <= (window.innerWidth || document.documentElement.clientWidth);
|
2957
|
+
if (isInViewport) {
|
2958
|
+
this.position();
|
2959
|
+
} else {
|
2960
|
+
this.hide();
|
2961
|
+
}
|
2962
|
+
}
|
2963
|
+
};
|
2964
|
+
window.addEventListener("scroll", this.scrollHandler);
|
2965
|
+
}
|
2966
|
+
disconnect() {
|
2967
|
+
if (this.clickOutsideHandler) {
|
2968
|
+
document.removeEventListener("click", this.clickOutsideHandler);
|
2969
|
+
}
|
2970
|
+
window.removeEventListener("scroll", this.scrollHandler);
|
2971
|
+
this.removeTooltip();
|
2972
|
+
}
|
2973
|
+
setupTooltip() {
|
2974
|
+
this.tooltipElement = this.createTooltipElement();
|
2975
|
+
document.body.appendChild(this.tooltipElement);
|
2976
|
+
if (this.triggerValue === "hover") {
|
2977
|
+
this.triggerTarget.addEventListener("mouseenter", () => this.show());
|
2978
|
+
this.triggerTarget.addEventListener("mouseleave", () => this.hide());
|
2979
|
+
this.triggerTarget.addEventListener("focusin", () => this.show());
|
2980
|
+
this.triggerTarget.addEventListener("focusout", () => this.hide());
|
2981
|
+
} else if (this.triggerValue === "click") {
|
2982
|
+
const hasDropdown = this.element.hasAttribute("data-controller") && this.element.getAttribute("data-controller").includes("dropdown");
|
2983
|
+
const hasClipboard = this.element.hasAttribute("data-controller") && this.element.getAttribute("data-controller").includes("clipboard");
|
2984
|
+
if (hasDropdown || hasClipboard) {
|
2985
|
+
this.triggerTarget.addEventListener("mouseenter", () => this.show());
|
2986
|
+
this.triggerTarget.addEventListener("mouseleave", () => this.hide());
|
2987
|
+
} else {
|
2988
|
+
this.triggerTarget.addEventListener("click", (e) => {
|
2989
|
+
e.stopPropagation();
|
2990
|
+
this.toggle();
|
2991
|
+
});
|
2992
|
+
this.clickOutsideHandler = (e) => {
|
2993
|
+
if (!this.triggerTarget.contains(e.target) && !this.tooltipElement.contains(e.target)) {
|
2994
|
+
this.hide();
|
2995
|
+
}
|
2996
|
+
};
|
2997
|
+
document.addEventListener("click", this.clickOutsideHandler);
|
2998
|
+
}
|
2999
|
+
}
|
3000
|
+
}
|
3001
|
+
createTooltipElement() {
|
3002
|
+
const tooltip = document.createElement("div");
|
3003
|
+
tooltip.id = this.triggerTarget.getAttribute("aria-describedby");
|
3004
|
+
tooltip.className = `w-tooltip w-tooltip-${this.themeValue} w-tooltip-size-${this.sizeValue}`;
|
3005
|
+
if (this.arrowValue) tooltip.classList.add("w-tooltip-arrow");
|
3006
|
+
tooltip.setAttribute("role", "tooltip");
|
3007
|
+
tooltip.setAttribute("data-position", this.positionValue);
|
3008
|
+
tooltip.setAttribute("data-align", this.alignValue);
|
3009
|
+
tooltip.innerHTML = this.contentValue;
|
3010
|
+
if (this.hasCustomStyleValue && this.customStyleValue) {
|
3011
|
+
tooltip.style.cssText += this.customStyleValue;
|
3012
|
+
}
|
3013
|
+
tooltip.style.display = "none";
|
3014
|
+
return tooltip;
|
3015
|
+
}
|
3016
|
+
show() {
|
3017
|
+
clearTimeout(this.hideTimeoutId);
|
3018
|
+
this.showTimeoutId = setTimeout(() => {
|
3019
|
+
this.tooltipElement.style.transform = "none";
|
3020
|
+
this.tooltipElement.style.visibility = "hidden";
|
3021
|
+
this.tooltipElement.style.display = "block";
|
3022
|
+
this.tooltipElement.offsetHeight;
|
3023
|
+
this.position();
|
3024
|
+
this.tooltipElement.style.visibility = "visible";
|
3025
|
+
requestAnimationFrame(() => {
|
3026
|
+
this.tooltipElement.classList.add("w-tooltip-visible");
|
3027
|
+
});
|
3028
|
+
}, this.showDelayValue);
|
3029
|
+
}
|
3030
|
+
hide() {
|
3031
|
+
clearTimeout(this.showTimeoutId);
|
3032
|
+
this.hideTimeoutId = setTimeout(() => {
|
3033
|
+
this.tooltipElement.classList.remove("w-tooltip-visible");
|
3034
|
+
setTimeout(() => {
|
3035
|
+
this.tooltipElement.style.display = "none";
|
3036
|
+
}, 150);
|
3037
|
+
}, this.hideDelayValue);
|
3038
|
+
}
|
3039
|
+
toggle() {
|
3040
|
+
if (this.tooltipElement.style.display === "none") {
|
3041
|
+
this.show();
|
3042
|
+
} else {
|
3043
|
+
this.hide();
|
3044
|
+
}
|
3045
|
+
}
|
3046
|
+
position() {
|
3047
|
+
const triggerRect = this.triggerTarget.getBoundingClientRect();
|
3048
|
+
const tooltipRect = this.tooltipElement.getBoundingClientRect();
|
3049
|
+
const viewportHeight = window.innerHeight;
|
3050
|
+
const viewportWidth = window.innerWidth;
|
3051
|
+
const arrowOffset = this.arrowValue ? 2 : 0;
|
3052
|
+
const scrollX = window.pageXOffset || document.documentElement.scrollLeft;
|
3053
|
+
const scrollY = window.pageYOffset || document.documentElement.scrollTop;
|
3054
|
+
console.log("=== Initial Values ===");
|
3055
|
+
console.log("Viewport Height:", viewportHeight);
|
3056
|
+
console.log("Viewport Width:", viewportWidth);
|
3057
|
+
console.log("Trigger Top:", triggerRect.top);
|
3058
|
+
console.log("Trigger Bottom:", triggerRect.bottom);
|
3059
|
+
console.log("Trigger Left:", triggerRect.left);
|
3060
|
+
console.log("Trigger Right:", triggerRect.right);
|
3061
|
+
console.log("Tooltip Height:", tooltipRect.height);
|
3062
|
+
console.log("Tooltip Width:", tooltipRect.width);
|
3063
|
+
let position = this.positionValue;
|
3064
|
+
let top, left;
|
3065
|
+
const spaceBelow = viewportHeight - triggerRect.bottom;
|
3066
|
+
const spaceAbove = triggerRect.top;
|
3067
|
+
const spaceRight = viewportWidth - triggerRect.right;
|
3068
|
+
const spaceLeft = triggerRect.left;
|
3069
|
+
const requiredSpaceVertical = tooltipRect.height + this.offsetValue + arrowOffset;
|
3070
|
+
const requiredSpaceHorizontal = tooltipRect.width + this.offsetValue + arrowOffset;
|
3071
|
+
console.log("\n=== Space Calculation ===");
|
3072
|
+
console.log("Space Above:", spaceAbove);
|
3073
|
+
console.log("Space Below:", spaceBelow);
|
3074
|
+
console.log("Space Left:", spaceLeft);
|
3075
|
+
console.log("Space Right:", spaceRight);
|
3076
|
+
console.log("Required Space Vertical:", requiredSpaceVertical);
|
3077
|
+
console.log("Required Space Horizontal:", requiredSpaceHorizontal);
|
3078
|
+
if (position === "right" && spaceRight >= requiredSpaceHorizontal) {
|
3079
|
+
position = "right";
|
3080
|
+
console.log("Using right - sufficient space");
|
3081
|
+
} else if (position === "left" && spaceLeft >= requiredSpaceHorizontal) {
|
3082
|
+
position = "left";
|
3083
|
+
console.log("Using left - sufficient space");
|
3084
|
+
} else if (position === "top" && spaceAbove >= requiredSpaceVertical) {
|
3085
|
+
position = "top";
|
3086
|
+
console.log("Using top - sufficient space");
|
3087
|
+
} else if (position === "bottom" && spaceBelow >= requiredSpaceVertical) {
|
3088
|
+
position = "bottom";
|
3089
|
+
console.log("Using bottom - sufficient space");
|
3090
|
+
} else if (spaceBelow >= requiredSpaceVertical) {
|
3091
|
+
position = "bottom";
|
3092
|
+
console.log("Fallback to bottom - sufficient space");
|
3093
|
+
} else {
|
3094
|
+
position = "top";
|
3095
|
+
console.log("Fallback to top - insufficient space below");
|
3096
|
+
}
|
3097
|
+
switch (position) {
|
3098
|
+
case "top":
|
3099
|
+
top = triggerRect.top - tooltipRect.height - this.offsetValue - arrowOffset;
|
3100
|
+
if (this.alignValue === "end") {
|
3101
|
+
left = triggerRect.right - tooltipRect.width;
|
3102
|
+
} else if (this.alignValue === "center") {
|
3103
|
+
left = triggerRect.left + triggerRect.width / 2 - tooltipRect.width / 2;
|
3104
|
+
} else {
|
3105
|
+
left = triggerRect.left;
|
3106
|
+
}
|
3107
|
+
break;
|
3108
|
+
case "bottom":
|
3109
|
+
top = triggerRect.bottom + this.offsetValue + arrowOffset;
|
3110
|
+
if (this.alignValue === "end") {
|
3111
|
+
left = triggerRect.right - tooltipRect.width;
|
3112
|
+
} else if (this.alignValue === "center") {
|
3113
|
+
left = triggerRect.left + triggerRect.width / 2 - tooltipRect.width / 2;
|
3114
|
+
} else {
|
3115
|
+
left = triggerRect.left;
|
3116
|
+
}
|
3117
|
+
break;
|
3118
|
+
case "left":
|
3119
|
+
left = triggerRect.left - tooltipRect.width - this.offsetValue - arrowOffset;
|
3120
|
+
if (this.alignValue === "end") {
|
3121
|
+
top = triggerRect.bottom - tooltipRect.height;
|
3122
|
+
} else if (this.alignValue === "center") {
|
3123
|
+
top = triggerRect.top + triggerRect.height / 2 - tooltipRect.height / 2;
|
3124
|
+
} else {
|
3125
|
+
top = triggerRect.top;
|
3126
|
+
}
|
3127
|
+
break;
|
3128
|
+
case "right":
|
3129
|
+
left = triggerRect.right + this.offsetValue + arrowOffset;
|
3130
|
+
if (this.alignValue === "end") {
|
3131
|
+
top = triggerRect.bottom - tooltipRect.height;
|
3132
|
+
} else if (this.alignValue === "center") {
|
3133
|
+
top = triggerRect.top + triggerRect.height / 2 - tooltipRect.height / 2;
|
3134
|
+
} else {
|
3135
|
+
top = triggerRect.top;
|
3136
|
+
}
|
3137
|
+
break;
|
3138
|
+
}
|
3139
|
+
if (top < 0) {
|
3140
|
+
top = this.offsetValue;
|
3141
|
+
} else if (top + tooltipRect.height > viewportHeight) {
|
3142
|
+
top = viewportHeight - tooltipRect.height - this.offsetValue;
|
3143
|
+
}
|
3144
|
+
if (left < 0) {
|
3145
|
+
left = this.offsetValue;
|
3146
|
+
} else if (left + tooltipRect.width > viewportWidth) {
|
3147
|
+
left = viewportWidth - tooltipRect.width - this.offsetValue;
|
3148
|
+
}
|
3149
|
+
console.log("\n=== Final Position ===");
|
3150
|
+
console.log("Position:", position);
|
3151
|
+
console.log("Top:", top);
|
3152
|
+
console.log("Left:", left);
|
3153
|
+
console.log("Alignment:", this.alignValue);
|
3154
|
+
top += scrollY;
|
3155
|
+
left += scrollX;
|
3156
|
+
this.tooltipElement.setAttribute("data-position", position);
|
3157
|
+
this.tooltipElement.style.top = `${top}px`;
|
3158
|
+
this.tooltipElement.style.left = `${left}px`;
|
3159
|
+
}
|
3160
|
+
removeTooltip() {
|
3161
|
+
if (this.tooltipElement) {
|
3162
|
+
this.tooltipElement.remove();
|
3163
|
+
this.tooltipElement = null;
|
3164
|
+
}
|
3165
|
+
}
|
3166
|
+
};
|
3167
|
+
|
2711
3168
|
// app/javascript/wilday_ui/controllers/index.js
|
2712
3169
|
var application = Application.start();
|
2713
3170
|
window.Stimulus = application;
|
2714
3171
|
application.register("button", ButtonController);
|
2715
3172
|
application.register("dropdown", dropdown_controller_default);
|
3173
|
+
application.register("clipboard", clipboard_controller_default);
|
3174
|
+
application.register("confirmation", confirmation_controller_default);
|
3175
|
+
application.register("tooltip", tooltip_controller_default);
|
2716
3176
|
|
2717
3177
|
// app/javascript/wilday_ui/components/button.js
|
2718
3178
|
document.addEventListener("DOMContentLoaded", () => {
|