diff --git a/Makefile b/Makefile
index 019294ec..bdeaf233 100644
--- a/Makefile
+++ b/Makefile
@@ -47,7 +47,7 @@ build-html: templ-generate render-showcases
# Step 4: Lint HTML output using ESLint
lint-html:
- npx eslint "out/**/*.html" --ext .html
+ npx eslint --fix "out/**/*.html" --ext .html
# Step 6: Run full pipeline (build + lint)
validate-html: build-html lint-html
diff --git a/cmd/render-showcases/main.go b/cmd/render-showcases/main.go
index ad021343..ae4d59dc 100644
--- a/cmd/render-showcases/main.go
+++ b/cmd/render-showcases/main.go
@@ -28,6 +28,7 @@ func writeHTML(filename string, c templ.Component) error {
func main() {
showcases := map[string]templ.Component{
+ // Accordion
"out/showcase/accordion_default.html": showcase.AccordionDefault(),
// Alert
@@ -104,6 +105,159 @@ func main() {
"out/showcase/chart_pie_legend.html": showcase.ChartPieLegend(),
"out/showcase/chart_pie_stacked.html": showcase.ChartPieStacked(),
"out/showcase/chart_radar.html": showcase.ChartRadar(),
+
+ // Checkbox
+ "out/showcase/checkbox_card_default.html": showcase.CheckboxCardDefault(),
+ "out/showcase/checkbox_checked.html": showcase.CheckboxChecked(),
+ "out/showcase/checkbox_custom_icon.html": showcase.CheckboxCustomIcon(),
+ "out/showcase/checkbox_default.html": showcase.CheckboxDefault(),
+ "out/showcase/checkbox_disabled.html": showcase.CheckboxDisabled(),
+ "out/showcase/checkbox_form.html": showcase.CheckboxForm(),
+ "out/showcase/checkbox_with_label.html": showcase.CheckboxWithLabel(),
+
+ // Code
+ "out/showcase/code_copy_button.html": showcase.CodeCopyButton(),
+ "out/showcase/code_custom_size.html": showcase.CodeCustomSize(),
+ "out/showcase/code_default.html": showcase.CodeDefault(),
+
+ // Date Picker
+ "out/showcase/date_picker_custom_placeholder.html": showcase.DatePickerCustomPlaceholder(),
+ "out/showcase/date_picker_default.html": showcase.DatePickerDefault(),
+ "out/showcase/date_picker_disabled.html": showcase.DatePickerDisabled(),
+ "out/showcase/date_picker_form.html": showcase.DatePickerForm(),
+ "out/showcase/date_picker_formats.html": showcase.DatePickerFormats(),
+ "out/showcase/date_picker_selected_date.html": showcase.DatePickerSelectedDate(),
+ "out/showcase/date_picker_with_label.html": showcase.DatePickerWithLabel(),
+
+ // Drawer
+ "out/showcase/drawer_default.html": showcase.DrawerDefault(),
+ "out/showcase/drawer_positions.html": showcase.DrawerPositions(),
+
+ // Dropdown
+ "out/showcase/dropdown_default.html": showcase.DropdownDefault(),
+
+ // Icon
+ "out/showcase/icon_colored.html": showcase.IconColored(),
+ "out/showcase/icon_default.html": showcase.IconDefault(),
+ "out/showcase/icon_filled.html": showcase.IconFilled(),
+ "out/showcase/icon_sizes.html": showcase.IconSizes(),
+
+ // Input
+ "out/showcase/input_default.html": showcase.InputDefault(),
+ "out/showcase/input_disabled.html": showcase.InputDisabled(),
+ "out/showcase/input_file.html": showcase.InputFile(),
+ "out/showcase/input_form.html": showcase.InputForm(),
+ "out/showcase/input_with_label.html": showcase.InputWithLabel(),
+
+ // Input OTP
+ "out/showcase/input_otp_custom_length.html": showcase.InputOTPCustomLength(),
+ "out/showcase/input_otp_custom_styling.html": showcase.InputOTPCustomStyling(),
+ "out/showcase/input_otp_default.html": showcase.InputOTPDefault(),
+ "out/showcase/input_otp_form.html": showcase.InputOTPForm(),
+ "out/showcase/input_otp_password_type.html": showcase.InputOTPPasswordType(),
+ "out/showcase/input_otp_placeholder.html": showcase.InputOTPPlaceholder(),
+ "out/showcase/input_otp_with_label.html": showcase.InputOTPWithLabel(),
+
+ // Modal
+ "out/showcase/modal_default.html": showcase.ModalDefault(),
+
+ // Pagination
+ "out/showcase/pagination_default.html": showcase.PaginationDefault(),
+ "out/showcase/pagination_with_helper.html": showcase.PaginationWithHelper(),
+
+ // Popover
+ "out/showcase/popover_default.html": showcase.PopoverDefault(),
+ "out/showcase/popover_positions.html": showcase.PopoverPositions(),
+ "out/showcase/popover_triggers.html": showcase.PopoverTriggers(),
+
+ // Progress
+ "out/showcase/progress_colors.html": showcase.ProgressColors(),
+ "out/showcase/progress_default.html": showcase.ProgressDefault(),
+ "out/showcase/progress_sizes.html": showcase.ProgressSizes(),
+
+ // Radio
+ "out/showcase/radio_card_default.html": showcase.RadioCardDefault(),
+ "out/showcase/radio_checked.html": showcase.RadioChecked(),
+ "out/showcase/radio_default.html": showcase.RadioDefault(),
+ "out/showcase/radio_disabled.html": showcase.RadioDisabled(),
+ "out/showcase/radio_form.html": showcase.RadioForm(),
+ "out/showcase/radio_with_label.html": showcase.RadioWithLabel(),
+
+ // Rating
+ "out/showcase/rating_default.html": showcase.RatingDefault(),
+ "out/showcase/rating_form.html": showcase.RatingForm(),
+ "out/showcase/rating_max_values.html": showcase.RatingMaxValues(),
+ "out/showcase/rating_precision.html": showcase.RatingPrecision(),
+ "out/showcase/rating_styles.html": showcase.RatingStyles(),
+ "out/showcase/rating_with_label.html": showcase.RatingWithLabel(),
+
+ // Select Box
+ "out/showcase/select_box_default.html": showcase.SelectBoxDefault(),
+ "out/showcase/select_box_disabled.html": showcase.SelectBoxDisabled(),
+ "out/showcase/select_box_form.html": showcase.SelectBoxForm(),
+ "out/showcase/select_box_with_label.html": showcase.SelectBoxWithLabel(),
+
+ // Separator
+ "out/showcase/separator_decorated.html": showcase.SeparatorDecorated(),
+ "out/showcase/separator_default.html": showcase.SeparatorDefault(),
+ "out/showcase/separator_label.html": showcase.SeparatorLabel(),
+ "out/showcase/separator_vertical.html": showcase.SeparatorVertical(),
+
+ // Skeleton
+ "out/showcase/skeleton_card.html": showcase.SkeletonCard(),
+ "out/showcase/skeleton_dashboard.html": showcase.SkeletonDashboard(),
+ "out/showcase/skeleton_default.html": showcase.SkeletonDefault(),
+ "out/showcase/skeleton_profile.html": showcase.SkeletonProfile(),
+
+ // Slider
+ "out/showcase/slider_default.html": showcase.SliderDefault(),
+ "out/showcase/slider_disabled.html": showcase.SliderDisabled(),
+ "out/showcase/slider_external_value.html": showcase.SliderExternalValue(),
+ "out/showcase/slider_steps.html": showcase.SliderSteps(),
+ "out/showcase/slider_value.html": showcase.SliderValue(),
+
+ // Spinner
+ "out/showcase/spinner_colors.html": showcase.SpinnerColors(),
+ "out/showcase/spinner_default.html": showcase.SpinnerDefault(),
+ "out/showcase/spinner_in_button.html": showcase.SpinnerInButton(),
+ "out/showcase/spinner_sizes.html": showcase.SpinnerSizes(),
+
+ // Table
+ "out/showcase/table.html": showcase.Table(),
+
+ // Tabs
+ "out/showcase/tabs_default.html": showcase.TabsDefault(),
+
+ // Textarea
+ "out/showcase/textarea_auto_resize.html": showcase.TextareaAutoResize(),
+ "out/showcase/textarea_custom_rows.html": showcase.TextareaCustomRows(),
+ "out/showcase/textarea_default.html": showcase.TextareaDefault(),
+ "out/showcase/textarea_disabled.html": showcase.TextareaDisabled(),
+ "out/showcase/textarea_form.html": showcase.TextareaForm(),
+ "out/showcase/textarea_with_label.html": showcase.TextareaWithLabel(),
+
+ // Time Picker
+ "out/showcase/time_picker_12hour.html": showcase.TimePicker12Hour(),
+ "out/showcase/time_picker_custom_placeholder.html": showcase.TimePickerCustomPlaceholder(),
+ "out/showcase/time_picker_default.html": showcase.TimePickerDefault(),
+ "out/showcase/time_picker_form.html": showcase.TimePickerForm(),
+ "out/showcase/time_picker_label.html": showcase.TimePickerLabel(),
+ "out/showcase/time_picker_selected_time.html": showcase.TimePickerSelectedTime(),
+
+ // Toast
+ "out/showcase/toast_default.html": showcase.ToastDefault(),
+ "out/showcase/toast_playground.html": showcase.ToastPlayground(),
+
+ // Toggle
+ "out/showcase/toggle_checked.html": showcase.ToggleChecked(),
+ "out/showcase/toggle_default.html": showcase.ToggleDefault(),
+ "out/showcase/toggle_disabled.html": showcase.ToggleDisabled(),
+ "out/showcase/toggle_form.html": showcase.ToggleForm(),
+ "out/showcase/toggle_with_label.html": showcase.ToggleWithLabel(),
+
+ // Tooltip
+ "out/showcase/tooltip_default.html": showcase.TooltipDefault(),
+ "out/showcase/tooltip_positions.html": showcase.TooltipPositions(),
}
for path, comp := range showcases {
diff --git a/component/drawer/drawer.templ b/component/drawer/drawer.templ
index 837c85f1..dececf7c 100644
--- a/component/drawer/drawer.templ
+++ b/component/drawer/drawer.templ
@@ -117,7 +117,9 @@ templ Content(props ...ContentProps) {
x-transition:leave-end="opacity-0"
>
")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 26, ">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
@@ -383,7 +393,7 @@ func Content(props ...ContentProps) templ.Component {
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 25, "
")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 28, "\" @click.stop>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
@@ -404,7 +414,7 @@ func Content(props ...ContentProps) templ.Component {
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 27, "
")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 29, "")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
@@ -442,30 +452,30 @@ func Header(props ...HeaderProps) templ.Component {
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 28, "")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 35, ">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
@@ -494,7 +504,7 @@ func Header(props ...HeaderProps) templ.Component {
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 34, "
")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 36, "")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
@@ -532,30 +542,30 @@ func Title(props ...TitleProps) templ.Component {
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 35, "")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 42, ">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
@@ -584,7 +594,7 @@ func Title(props ...TitleProps) templ.Component {
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 41, "
")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 43, "")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
@@ -622,30 +632,30 @@ func Description(props ...DescriptionProps) templ.Component {
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 42, "")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 49, ">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
@@ -674,7 +684,7 @@ func Description(props ...DescriptionProps) templ.Component {
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 48, "
")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 50, "")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
@@ -712,30 +722,30 @@ func Footer(props ...FooterProps) templ.Component {
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 49, "")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 56, ">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
@@ -764,7 +774,7 @@ func Footer(props ...FooterProps) templ.Component {
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 55, "
")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 57, "")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
@@ -810,30 +820,30 @@ func Close(props ...CloseProps) templ.Component {
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 56, "")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 64, "")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
@@ -904,20 +914,20 @@ func Script() templ.Component {
}()
}
ctx = templ.InitializeContext(ctx)
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 63, "")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 66, "\">\n document.addEventListener('alpine:init', () => {\n Alpine.data('drawer', () => ({\n isOpen: false,\n open() {\n this.isOpen = true\n document.body.style.overflow = 'hidden'\n },\n close() {\n this.isOpen = false\n document.body.style.overflow = ''\n },\n }))\n })\n ")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
diff --git a/component/modal/modal.templ b/component/modal/modal.templ
index aa7bd8bb..185480c8 100644
--- a/component/modal/modal.templ
+++ b/component/modal/modal.templ
@@ -145,17 +145,15 @@ templ Header(props ...HeaderProps) {
if len(props) > 0 {
{{ p = props[0] }}
}
-
-
- { children... }
-
-
+ { children... }
+
}
templ Body(props ...BodyProps) {
diff --git a/component/modal/modal_templ.go b/component/modal/modal_templ.go
index 7b922bed..fec7a18a 100644
--- a/component/modal/modal_templ.go
+++ b/component/modal/modal_templ.go
@@ -447,12 +447,12 @@ func Header(props ...HeaderProps) templ.Component {
if len(props) > 0 {
p = props[0]
}
- var templ_7745c5c3_Var18 = []any{util.TwMerge("px-4 pt-5 pb-4 sm:p-6 sm:pb-4", p.Class)}
+ var templ_7745c5c3_Var18 = []any{util.TwMerge("px-4 pt-5 pb-4 sm:p-6 sm:pb-4 text-lg leading-6 font-medium text-foreground", p.Class)}
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var18...)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 33, "")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 38, ">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
@@ -504,7 +504,7 @@ func Header(props ...HeaderProps) templ.Component {
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 39, "
")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 39, "")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
@@ -554,7 +554,7 @@ func Body(props ...BodyProps) templ.Component {
var templ_7745c5c3_Var23 string
templ_7745c5c3_Var23, templ_7745c5c3_Err = templ.JoinStringErrs(p.ID)
if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `component/modal/modal.templ`, Line: 168, Col: 12}
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `component/modal/modal.templ`, Line: 166, Col: 12}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var23))
if templ_7745c5c3_Err != nil {
@@ -644,7 +644,7 @@ func Footer(props ...FooterProps) templ.Component {
var templ_7745c5c3_Var27 string
templ_7745c5c3_Var27, templ_7745c5c3_Err = templ.JoinStringErrs(p.ID)
if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `component/modal/modal.templ`, Line: 184, Col: 12}
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `component/modal/modal.templ`, Line: 182, Col: 12}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var27))
if templ_7745c5c3_Err != nil {
@@ -733,7 +733,7 @@ func Script() templ.Component {
var templ_7745c5c3_Var31 string
templ_7745c5c3_Var31, templ_7745c5c3_Err = templ.JoinStringErrs(templ.GetNonce(ctx))
if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `component/modal/modal.templ`, Line: 196, Col: 43}
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `component/modal/modal.templ`, Line: 194, Col: 43}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var31))
if templ_7745c5c3_Err != nil {
diff --git a/component/popover/popover.templ b/component/popover/popover.templ
index 58374242..71ef01ac 100644
--- a/component/popover/popover.templ
+++ b/component/popover/popover.templ
@@ -60,7 +60,7 @@ templ Popover(props ...Props) {
{ children... }
}
@@ -197,7 +197,7 @@ templ Script() {
`;
document.head.appendChild(style);
- const portalContainer = document.getElementById('popover-portal-container');
+ const portalContainer = document.querySelector('[data-popover-portal-container]');
const triggers = document.querySelectorAll('[data-popover-trigger]');
const templates = document.querySelectorAll('[data-popover-content-template]');
diff --git a/component/popover/popover_templ.go b/component/popover/popover_templ.go
index 6cdb8ba3..8eba0842 100644
--- a/component/popover/popover_templ.go
+++ b/component/popover/popover_templ.go
@@ -110,7 +110,7 @@ func Popover(props ...Props) templ.Component {
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
@@ -571,7 +571,7 @@ func Script() templ.Component {
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 37, "\">\n document.addEventListener('DOMContentLoaded', () => {\n // Minimal CSS-Animation for the rubber effect\n const style = document.createElement('style');\n style.textContent = `\n @keyframes popover-in {\n 0% { opacity: 0; transform: scale(0.95); }\n 100% { opacity: 1; transform: scale(1); }\n }\n \n @keyframes popover-out {\n 0% { opacity: 1; transform: scale(1); }\n 100% { opacity: 0; transform: scale(0.95); }\n }\n \n .popover-animate-in {\n animation: popover-in 0.15s cubic-bezier(0.16, 1, 0.3, 1);\n }\n \n .popover-animate-out {\n animation: popover-out 0.1s cubic-bezier(0.16, 1, 0.3, 1) forwards;\n }\n `;\n document.head.appendChild(style);\n \n const portalContainer = document.getElementById('popover-portal-container');\n const triggers = document.querySelectorAll('[data-popover-trigger]');\n const templates = document.querySelectorAll('[data-popover-content-template]');\n \n // Active popovers\n const activePopovers = new Map();\n \n // Function to update the arrow based on the position\n const updateArrow = (popoverElement, position) => {\n if (popoverElement.dataset.popoverShowArrow !== 'true') return;\n \n // Initially hide all arrows\n popoverElement.querySelectorAll('[data-arrow]').forEach(arrow => {\n arrow.classList.add('hidden');\n });\n \n // Get the background and border color from the parent element\n const computedStyle = window.getComputedStyle(popoverElement);\n const bgColor = computedStyle.backgroundColor;\n const borderColor = computedStyle.borderColor;\n \n // Arrow direction is always opposite to the position\n let arrowPosition;\n \n if (position.startsWith('top')) {\n arrowPosition = position.replace('top', 'bottom');\n } else if (position.startsWith('bottom')) {\n arrowPosition = position.replace('bottom', 'top');\n } else if (position.startsWith('left')) {\n arrowPosition = position.replace('left', 'right');\n } else if (position.startsWith('right')) {\n arrowPosition = position.replace('right', 'left');\n } else {\n arrowPosition = position;\n }\n \n // Show the correct arrow based on the direction\n const arrow = popoverElement.querySelector(`[data-arrow=\"${arrowPosition}\"]`);\n if (arrow) {\n arrow.classList.remove('hidden');\n arrow.style.backgroundColor = bgColor;\n arrow.style.borderColor = borderColor;\n }\n };\n \n // Positioning function\n const positionPopover = (trigger, popoverElement) => {\n // Find the actual element the popover refers to\n let triggerElement = trigger;\n let largestArea = 0;\n \n // Check all direct children of the trigger\n const children = trigger.children;\n for (let i = 0; i < children.length; i++) {\n const child = children[i];\n const rect = child.getBoundingClientRect();\n const area = rect.width * rect.height;\n \n if (area > largestArea) {\n largestArea = area;\n triggerElement = child;\n }\n }\n \n const triggerRect = triggerElement.getBoundingClientRect();\n const contentRect = popoverElement.getBoundingClientRect();\n const margin = popoverElement.dataset.popoverShowArrow === 'true' ? 8 : 4;\n const scrollY = window.scrollY || window.pageYOffset;\n const scrollX = window.scrollX || window.pageXOffset;\n\n // Position from the dataset\n const requestedPosition = popoverElement.dataset.popoverPosition || 'bottom';\n // We store the final position, which can be adjusted based on viewport space\n let finalPosition = requestedPosition;\n\n // Viewport dimensions\n const viewportWidth = window.innerWidth;\n const viewportHeight = window.innerHeight;\n\n // Get element heights and widths\n const triggerHeight = triggerRect.height;\n const contentHeight = contentRect.height;\n const contentWidth = contentRect.width;\n \n // Define anchor points\n const triggerTop = triggerRect.top + scrollY;\n const triggerBottom = triggerRect.bottom + scrollY;\n const triggerLeft = triggerRect.left + scrollX;\n const triggerRight = triggerRect.right + scrollX;\n \n // Calculate available space in each direction\n const spaceAbove = triggerRect.top;\n const spaceBelow = viewportHeight - triggerRect.bottom;\n const spaceLeft = triggerRect.left;\n const spaceRight = viewportWidth - triggerRect.right;\n\n // Intelligent position adjustment\n // We check the opposite position if there is not enough space\n if (finalPosition.startsWith('top') && spaceAbove < contentHeight + margin) {\n // If there is not enough space above, show below\n finalPosition = finalPosition.replace('top', 'bottom');\n } else if (finalPosition.startsWith('bottom') && spaceBelow < contentHeight + margin) {\n // If there is not enough space below, show above\n finalPosition = finalPosition.replace('bottom', 'top');\n } else if (finalPosition.startsWith('left') && spaceLeft < contentWidth + margin) {\n // If there is not enough space on the left, show on the right\n finalPosition = finalPosition.replace('left', 'right');\n } else if (finalPosition.startsWith('right') && spaceRight < contentWidth + margin) {\n // If there is not enough space on the right, show on the left\n finalPosition = finalPosition.replace('right', 'left');\n }\n\n // Store the current position in the element for CSS adjustments (e.g., arrow position)\n popoverElement.dataset.popoverCurrentPosition = finalPosition;\n \n // Show the correct arrow\n updateArrow(popoverElement, finalPosition);\n \n let top, left;\n \n // Positioning logic with the final position\n switch (finalPosition) {\n case 'top':\n top = triggerTop - contentHeight - margin;\n left = triggerLeft + (triggerRect.width / 2) - (contentRect.width / 2);\n break;\n case 'top-start':\n top = triggerTop - contentHeight - margin;\n left = triggerLeft;\n break;\n case 'top-end':\n top = triggerTop - contentHeight - margin;\n left = triggerRight - contentRect.width;\n break;\n case 'right':\n top = triggerTop + (triggerHeight / 2) - (contentHeight / 2);\n left = triggerRight + margin;\n break;\n case 'right-start':\n top = triggerTop;\n left = triggerRight + margin;\n break;\n case 'right-end':\n top = triggerBottom - contentHeight;\n left = triggerRight + margin;\n break;\n case 'bottom':\n top = triggerBottom + margin;\n left = triggerLeft + (triggerRect.width / 2) - (contentRect.width / 2);\n break;\n case 'bottom-start':\n top = triggerBottom + margin;\n left = triggerLeft;\n break;\n case 'bottom-end':\n top = triggerBottom + margin;\n left = triggerRight - contentRect.width;\n break;\n case 'left':\n top = triggerTop + (triggerHeight / 2) - (contentHeight / 2);\n left = triggerLeft - contentRect.width - margin;\n break;\n case 'left-start':\n top = triggerTop;\n left = triggerLeft - contentRect.width - margin;\n break;\n case 'left-end':\n top = triggerBottom - contentHeight;\n left = triggerLeft - contentRect.width - margin;\n break;\n default:\n top = triggerBottom + margin;\n left = triggerLeft + (triggerRect.width / 2) - (contentRect.width / 2);\n }\n\n // Horizontal boundary - ensures the popover does not overflow the viewport\n if (left < 10) {\n left = 10; // Minimum distance from the left edge\n } else if (left + contentWidth > viewportWidth - 10) {\n left = viewportWidth - contentWidth - 10; // Minimum distance from the right edge\n }\n\n // Vertical boundary - Optional, can be problematic in some cases\n if (top < 10) {\n top = 10; // Minimum distance from the top edge\n } else if (top + contentHeight > viewportHeight - 10) {\n top = viewportHeight - contentHeight - 10; // Minimum distance from the bottom edge\n }\n\n popoverElement.style.top = `${top}px`;\n popoverElement.style.left = `${left}px`;\n };\n \n // Event handler setup\n function setupTrigger(trigger) {\n const popoverId = trigger.dataset.popoverFor\n const template = document.querySelector(`[data-popover-content-template][data-popover-id=\"${popoverId}\"]`);\n \n if (!template) return;\n \n const triggerType = trigger.dataset.popoverType;\n \n // Click handler\n if (triggerType === 'click') {\n trigger.addEventListener('click', () => {\n // If the popover is already active, remove it\n if (activePopovers.has(popoverId)) {\n const popover = activePopovers.get(popoverId);\n popover.remove();\n activePopovers.delete(popoverId);\n return;\n }\n \n // Otherwise, create a new popover\n const content = template.content.cloneNode(true).firstElementChild;\n \n // Transfer attributes from the template\n Object.keys(template.dataset).forEach(key => {\n if (key.startsWith('popover')) {\n content.dataset[key] = template.dataset[key];\n }\n });\n \n // Set initial position\n content.dataset.popoverCurrentPosition = content.dataset.popoverPosition;\n \n // Add to the portal container\n portalContainer.appendChild(content);\n \n // Position it\n positionPopover(trigger, content);\n \n // Apply transition effect\n content.classList.remove('popover-transition');\n content.classList.remove('show');\n content.classList.add('popover-animate-in');\n \n // Add to active popovers\n activePopovers.set(popoverId, content);\n \n // Clickaway handler\n if (content.dataset.popoverDisableClickaway !== 'true') {\n const clickHandler = (e) => {\n if (!trigger.contains(e.target) && !content.contains(e.target)) {\n // Apply exit animation\n content.classList.remove('popover-animate-in');\n content.classList.add('popover-animate-out');\n \n // Wait for transition to complete before removing\n setTimeout(() => {\n content.remove();\n activePopovers.delete(popoverId);\n }, 100);\n \n document.removeEventListener('click', clickHandler);\n }\n };\n \n // Delay to prevent immediate closing on the current click\n setTimeout(() => {\n document.addEventListener('click', clickHandler);\n }, 0);\n }\n \n // ESC handler\n if (content.dataset.popoverDisableEsc !== 'true') {\n const keyHandler = (e) => {\n if (e.key === 'Escape') {\n // Apply exit animation\n content.classList.remove('popover-animate-in');\n content.classList.add('popover-animate-out');\n \n // Wait for transition to complete before removing\n setTimeout(() => {\n content.remove();\n activePopovers.delete(popoverId);\n }, 100);\n \n document.removeEventListener('keydown', keyHandler);\n }\n };\n document.addEventListener('keydown', keyHandler);\n }\n });\n } else if (triggerType === 'hover') {\n // Hover handlers\n let hoverTimeout;\n let leaveTimeout;\n \n trigger.addEventListener('mouseenter', () => {\n clearTimeout(leaveTimeout);\n \n // Get hover delay from template or use default\n const hoverDelay = parseInt(template.dataset.popoverHoverDelay) || 100;\n \n // If the popover is already active, do not recreate it\n if (activePopovers.has(popoverId)) return;\n \n // Delay for showing the popover\n hoverTimeout = setTimeout(() => {\n // Create a new popover\n const content = template.content.cloneNode(true).firstElementChild;\n \n // Transfer attributes\n Object.keys(template.dataset).forEach(key => {\n if (key.startsWith('popover')) {\n content.dataset[key] = template.dataset[key];\n }\n });\n \n // Add to the portal container\n portalContainer.appendChild(content);\n \n // Position it\n positionPopover(trigger, content);\n \n // Apply animation\n content.classList.add('popover-animate-in');\n \n // Add to active popovers\n activePopovers.set(popoverId, content);\n \n // Hover handler for the content element\n content.addEventListener('mouseenter', () => {\n clearTimeout(leaveTimeout);\n });\n \n content.addEventListener('mouseleave', () => {\n // Get hover out delay from template or use default\n const hoverOutDelay = parseInt(content.dataset.popoverHoverOutDelay) || 200;\n \n leaveTimeout = setTimeout(() => {\n if (activePopovers.has(popoverId)) {\n const popover = activePopovers.get(popoverId);\n \n // Apply exit animation\n popover.classList.remove('popover-animate-in');\n popover.classList.add('popover-animate-out');\n \n // Wait for animation to complete before removing\n setTimeout(() => {\n popover.remove();\n activePopovers.delete(popoverId);\n }, 100);\n }\n }, hoverOutDelay);\n });\n }, hoverDelay);\n });\n \n trigger.addEventListener('mouseleave', (e) => {\n // Clear the show timeout if mouse leaves before popover is shown\n clearTimeout(hoverTimeout);\n \n // Check if we are hovering over the content\n const related = e.relatedTarget;\n const content = activePopovers.get(popoverId);\n \n // If we are directly hovering over the content, do not close\n if (content && content.contains(related)) {\n return;\n }\n \n // Get hover out delay from template or use default\n const hoverOutDelay = content ? \n (parseInt(content.dataset.popoverHoverOutDelay) || 200) : 200;\n \n leaveTimeout = setTimeout(() => {\n if (activePopovers.has(popoverId)) {\n const popover = activePopovers.get(popoverId);\n \n // Apply exit animation\n popover.classList.remove('popover-animate-in');\n popover.classList.add('popover-animate-out');\n \n // Wait for animation to complete before removing\n setTimeout(() => {\n popover.remove();\n activePopovers.delete(popoverId);\n }, 100);\n }\n }, hoverOutDelay);\n });\n }\n }\n \n // Set up handlers for each trigger\n triggers.forEach(setupTrigger);\n \n // Scroll handler for all popovers\n window.addEventListener('scroll', () => {\n activePopovers.forEach((content, popoverId) => {\n const trigger = document.querySelector(`[data-popover-trigger][data-popover-for=\"${popoverId}\"]`);\n if (trigger) {\n positionPopover(trigger, content);\n }\n });\n }, { passive: true });\n \n // Resize handler\n window.addEventListener('resize', () => {\n activePopovers.forEach((content, popoverId) => {\n const trigger = document.querySelector(`[data-popover-trigger][data-popover-for=\"${popoverId}\"]`);\n if (trigger) {\n positionPopover(trigger, content);\n }\n });\n });\n \n // Find all scrollable parent elements and add scroll handlers\n function setupScrollHandlers() {\n const scrollableElements = new Set();\n \n // Find scrollable parents for each trigger\n triggers.forEach(trigger => {\n let element = trigger.parentElement;\n \n while (element) {\n const style = window.getComputedStyle(element);\n const overflow = style.overflow + style.overflowY + style.overflowX;\n \n if (overflow.includes('scroll') || overflow.includes('auto') || \n element.scrollHeight > element.clientHeight) {\n scrollableElements.add(element);\n }\n \n element = element.parentElement;\n }\n });\n \n // Scroll handler for each scrollable element\n scrollableElements.forEach(element => {\n element.addEventListener('scroll', () => {\n activePopovers.forEach((content, popoverId) => {\n const trigger = document.querySelector(`[data-popover-trigger][data-popover-for=\"${popoverId}\"]`);\n if (trigger) {\n positionPopover(trigger, content);\n }\n });\n }, { passive: true });\n });\n }\n \n setupScrollHandlers();\n });\n ")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 37, "\">\n document.addEventListener('DOMContentLoaded', () => {\n // Minimal CSS-Animation for the rubber effect\n const style = document.createElement('style');\n style.textContent = `\n @keyframes popover-in {\n 0% { opacity: 0; transform: scale(0.95); }\n 100% { opacity: 1; transform: scale(1); }\n }\n \n @keyframes popover-out {\n 0% { opacity: 1; transform: scale(1); }\n 100% { opacity: 0; transform: scale(0.95); }\n }\n \n .popover-animate-in {\n animation: popover-in 0.15s cubic-bezier(0.16, 1, 0.3, 1);\n }\n \n .popover-animate-out {\n animation: popover-out 0.1s cubic-bezier(0.16, 1, 0.3, 1) forwards;\n }\n `;\n document.head.appendChild(style);\n \n const portalContainer = document.querySelector('[data-popover-portal-container]');\n const triggers = document.querySelectorAll('[data-popover-trigger]');\n const templates = document.querySelectorAll('[data-popover-content-template]');\n \n // Active popovers\n const activePopovers = new Map();\n \n // Function to update the arrow based on the position\n const updateArrow = (popoverElement, position) => {\n if (popoverElement.dataset.popoverShowArrow !== 'true') return;\n \n // Initially hide all arrows\n popoverElement.querySelectorAll('[data-arrow]').forEach(arrow => {\n arrow.classList.add('hidden');\n });\n \n // Get the background and border color from the parent element\n const computedStyle = window.getComputedStyle(popoverElement);\n const bgColor = computedStyle.backgroundColor;\n const borderColor = computedStyle.borderColor;\n \n // Arrow direction is always opposite to the position\n let arrowPosition;\n \n if (position.startsWith('top')) {\n arrowPosition = position.replace('top', 'bottom');\n } else if (position.startsWith('bottom')) {\n arrowPosition = position.replace('bottom', 'top');\n } else if (position.startsWith('left')) {\n arrowPosition = position.replace('left', 'right');\n } else if (position.startsWith('right')) {\n arrowPosition = position.replace('right', 'left');\n } else {\n arrowPosition = position;\n }\n \n // Show the correct arrow based on the direction\n const arrow = popoverElement.querySelector(`[data-arrow=\"${arrowPosition}\"]`);\n if (arrow) {\n arrow.classList.remove('hidden');\n arrow.style.backgroundColor = bgColor;\n arrow.style.borderColor = borderColor;\n }\n };\n \n // Positioning function\n const positionPopover = (trigger, popoverElement) => {\n // Find the actual element the popover refers to\n let triggerElement = trigger;\n let largestArea = 0;\n \n // Check all direct children of the trigger\n const children = trigger.children;\n for (let i = 0; i < children.length; i++) {\n const child = children[i];\n const rect = child.getBoundingClientRect();\n const area = rect.width * rect.height;\n \n if (area > largestArea) {\n largestArea = area;\n triggerElement = child;\n }\n }\n \n const triggerRect = triggerElement.getBoundingClientRect();\n const contentRect = popoverElement.getBoundingClientRect();\n const margin = popoverElement.dataset.popoverShowArrow === 'true' ? 8 : 4;\n const scrollY = window.scrollY || window.pageYOffset;\n const scrollX = window.scrollX || window.pageXOffset;\n\n // Position from the dataset\n const requestedPosition = popoverElement.dataset.popoverPosition || 'bottom';\n // We store the final position, which can be adjusted based on viewport space\n let finalPosition = requestedPosition;\n\n // Viewport dimensions\n const viewportWidth = window.innerWidth;\n const viewportHeight = window.innerHeight;\n\n // Get element heights and widths\n const triggerHeight = triggerRect.height;\n const contentHeight = contentRect.height;\n const contentWidth = contentRect.width;\n \n // Define anchor points\n const triggerTop = triggerRect.top + scrollY;\n const triggerBottom = triggerRect.bottom + scrollY;\n const triggerLeft = triggerRect.left + scrollX;\n const triggerRight = triggerRect.right + scrollX;\n \n // Calculate available space in each direction\n const spaceAbove = triggerRect.top;\n const spaceBelow = viewportHeight - triggerRect.bottom;\n const spaceLeft = triggerRect.left;\n const spaceRight = viewportWidth - triggerRect.right;\n\n // Intelligent position adjustment\n // We check the opposite position if there is not enough space\n if (finalPosition.startsWith('top') && spaceAbove < contentHeight + margin) {\n // If there is not enough space above, show below\n finalPosition = finalPosition.replace('top', 'bottom');\n } else if (finalPosition.startsWith('bottom') && spaceBelow < contentHeight + margin) {\n // If there is not enough space below, show above\n finalPosition = finalPosition.replace('bottom', 'top');\n } else if (finalPosition.startsWith('left') && spaceLeft < contentWidth + margin) {\n // If there is not enough space on the left, show on the right\n finalPosition = finalPosition.replace('left', 'right');\n } else if (finalPosition.startsWith('right') && spaceRight < contentWidth + margin) {\n // If there is not enough space on the right, show on the left\n finalPosition = finalPosition.replace('right', 'left');\n }\n\n // Store the current position in the element for CSS adjustments (e.g., arrow position)\n popoverElement.dataset.popoverCurrentPosition = finalPosition;\n \n // Show the correct arrow\n updateArrow(popoverElement, finalPosition);\n \n let top, left;\n \n // Positioning logic with the final position\n switch (finalPosition) {\n case 'top':\n top = triggerTop - contentHeight - margin;\n left = triggerLeft + (triggerRect.width / 2) - (contentRect.width / 2);\n break;\n case 'top-start':\n top = triggerTop - contentHeight - margin;\n left = triggerLeft;\n break;\n case 'top-end':\n top = triggerTop - contentHeight - margin;\n left = triggerRight - contentRect.width;\n break;\n case 'right':\n top = triggerTop + (triggerHeight / 2) - (contentHeight / 2);\n left = triggerRight + margin;\n break;\n case 'right-start':\n top = triggerTop;\n left = triggerRight + margin;\n break;\n case 'right-end':\n top = triggerBottom - contentHeight;\n left = triggerRight + margin;\n break;\n case 'bottom':\n top = triggerBottom + margin;\n left = triggerLeft + (triggerRect.width / 2) - (contentRect.width / 2);\n break;\n case 'bottom-start':\n top = triggerBottom + margin;\n left = triggerLeft;\n break;\n case 'bottom-end':\n top = triggerBottom + margin;\n left = triggerRight - contentRect.width;\n break;\n case 'left':\n top = triggerTop + (triggerHeight / 2) - (contentHeight / 2);\n left = triggerLeft - contentRect.width - margin;\n break;\n case 'left-start':\n top = triggerTop;\n left = triggerLeft - contentRect.width - margin;\n break;\n case 'left-end':\n top = triggerBottom - contentHeight;\n left = triggerLeft - contentRect.width - margin;\n break;\n default:\n top = triggerBottom + margin;\n left = triggerLeft + (triggerRect.width / 2) - (contentRect.width / 2);\n }\n\n // Horizontal boundary - ensures the popover does not overflow the viewport\n if (left < 10) {\n left = 10; // Minimum distance from the left edge\n } else if (left + contentWidth > viewportWidth - 10) {\n left = viewportWidth - contentWidth - 10; // Minimum distance from the right edge\n }\n\n // Vertical boundary - Optional, can be problematic in some cases\n if (top < 10) {\n top = 10; // Minimum distance from the top edge\n } else if (top + contentHeight > viewportHeight - 10) {\n top = viewportHeight - contentHeight - 10; // Minimum distance from the bottom edge\n }\n\n popoverElement.style.top = `${top}px`;\n popoverElement.style.left = `${left}px`;\n };\n \n // Event handler setup\n function setupTrigger(trigger) {\n const popoverId = trigger.dataset.popoverFor\n const template = document.querySelector(`[data-popover-content-template][data-popover-id=\"${popoverId}\"]`);\n \n if (!template) return;\n \n const triggerType = trigger.dataset.popoverType;\n \n // Click handler\n if (triggerType === 'click') {\n trigger.addEventListener('click', () => {\n // If the popover is already active, remove it\n if (activePopovers.has(popoverId)) {\n const popover = activePopovers.get(popoverId);\n popover.remove();\n activePopovers.delete(popoverId);\n return;\n }\n \n // Otherwise, create a new popover\n const content = template.content.cloneNode(true).firstElementChild;\n \n // Transfer attributes from the template\n Object.keys(template.dataset).forEach(key => {\n if (key.startsWith('popover')) {\n content.dataset[key] = template.dataset[key];\n }\n });\n \n // Set initial position\n content.dataset.popoverCurrentPosition = content.dataset.popoverPosition;\n \n // Add to the portal container\n portalContainer.appendChild(content);\n \n // Position it\n positionPopover(trigger, content);\n \n // Apply transition effect\n content.classList.remove('popover-transition');\n content.classList.remove('show');\n content.classList.add('popover-animate-in');\n \n // Add to active popovers\n activePopovers.set(popoverId, content);\n \n // Clickaway handler\n if (content.dataset.popoverDisableClickaway !== 'true') {\n const clickHandler = (e) => {\n if (!trigger.contains(e.target) && !content.contains(e.target)) {\n // Apply exit animation\n content.classList.remove('popover-animate-in');\n content.classList.add('popover-animate-out');\n \n // Wait for transition to complete before removing\n setTimeout(() => {\n content.remove();\n activePopovers.delete(popoverId);\n }, 100);\n \n document.removeEventListener('click', clickHandler);\n }\n };\n \n // Delay to prevent immediate closing on the current click\n setTimeout(() => {\n document.addEventListener('click', clickHandler);\n }, 0);\n }\n \n // ESC handler\n if (content.dataset.popoverDisableEsc !== 'true') {\n const keyHandler = (e) => {\n if (e.key === 'Escape') {\n // Apply exit animation\n content.classList.remove('popover-animate-in');\n content.classList.add('popover-animate-out');\n \n // Wait for transition to complete before removing\n setTimeout(() => {\n content.remove();\n activePopovers.delete(popoverId);\n }, 100);\n \n document.removeEventListener('keydown', keyHandler);\n }\n };\n document.addEventListener('keydown', keyHandler);\n }\n });\n } else if (triggerType === 'hover') {\n // Hover handlers\n let hoverTimeout;\n let leaveTimeout;\n \n trigger.addEventListener('mouseenter', () => {\n clearTimeout(leaveTimeout);\n \n // Get hover delay from template or use default\n const hoverDelay = parseInt(template.dataset.popoverHoverDelay) || 100;\n \n // If the popover is already active, do not recreate it\n if (activePopovers.has(popoverId)) return;\n \n // Delay for showing the popover\n hoverTimeout = setTimeout(() => {\n // Create a new popover\n const content = template.content.cloneNode(true).firstElementChild;\n \n // Transfer attributes\n Object.keys(template.dataset).forEach(key => {\n if (key.startsWith('popover')) {\n content.dataset[key] = template.dataset[key];\n }\n });\n \n // Add to the portal container\n portalContainer.appendChild(content);\n \n // Position it\n positionPopover(trigger, content);\n \n // Apply animation\n content.classList.add('popover-animate-in');\n \n // Add to active popovers\n activePopovers.set(popoverId, content);\n \n // Hover handler for the content element\n content.addEventListener('mouseenter', () => {\n clearTimeout(leaveTimeout);\n });\n \n content.addEventListener('mouseleave', () => {\n // Get hover out delay from template or use default\n const hoverOutDelay = parseInt(content.dataset.popoverHoverOutDelay) || 200;\n \n leaveTimeout = setTimeout(() => {\n if (activePopovers.has(popoverId)) {\n const popover = activePopovers.get(popoverId);\n \n // Apply exit animation\n popover.classList.remove('popover-animate-in');\n popover.classList.add('popover-animate-out');\n \n // Wait for animation to complete before removing\n setTimeout(() => {\n popover.remove();\n activePopovers.delete(popoverId);\n }, 100);\n }\n }, hoverOutDelay);\n });\n }, hoverDelay);\n });\n \n trigger.addEventListener('mouseleave', (e) => {\n // Clear the show timeout if mouse leaves before popover is shown\n clearTimeout(hoverTimeout);\n \n // Check if we are hovering over the content\n const related = e.relatedTarget;\n const content = activePopovers.get(popoverId);\n \n // If we are directly hovering over the content, do not close\n if (content && content.contains(related)) {\n return;\n }\n \n // Get hover out delay from template or use default\n const hoverOutDelay = content ? \n (parseInt(content.dataset.popoverHoverOutDelay) || 200) : 200;\n \n leaveTimeout = setTimeout(() => {\n if (activePopovers.has(popoverId)) {\n const popover = activePopovers.get(popoverId);\n \n // Apply exit animation\n popover.classList.remove('popover-animate-in');\n popover.classList.add('popover-animate-out');\n \n // Wait for animation to complete before removing\n setTimeout(() => {\n popover.remove();\n activePopovers.delete(popoverId);\n }, 100);\n }\n }, hoverOutDelay);\n });\n }\n }\n \n // Set up handlers for each trigger\n triggers.forEach(setupTrigger);\n \n // Scroll handler for all popovers\n window.addEventListener('scroll', () => {\n activePopovers.forEach((content, popoverId) => {\n const trigger = document.querySelector(`[data-popover-trigger][data-popover-for=\"${popoverId}\"]`);\n if (trigger) {\n positionPopover(trigger, content);\n }\n });\n }, { passive: true });\n \n // Resize handler\n window.addEventListener('resize', () => {\n activePopovers.forEach((content, popoverId) => {\n const trigger = document.querySelector(`[data-popover-trigger][data-popover-for=\"${popoverId}\"]`);\n if (trigger) {\n positionPopover(trigger, content);\n }\n });\n });\n \n // Find all scrollable parent elements and add scroll handlers\n function setupScrollHandlers() {\n const scrollableElements = new Set();\n \n // Find scrollable parents for each trigger\n triggers.forEach(trigger => {\n let element = trigger.parentElement;\n \n while (element) {\n const style = window.getComputedStyle(element);\n const overflow = style.overflow + style.overflowY + style.overflowX;\n \n if (overflow.includes('scroll') || overflow.includes('auto') || \n element.scrollHeight > element.clientHeight) {\n scrollableElements.add(element);\n }\n \n element = element.parentElement;\n }\n });\n \n // Scroll handler for each scrollable element\n scrollableElements.forEach(element => {\n element.addEventListener('scroll', () => {\n activePopovers.forEach((content, popoverId) => {\n const trigger = document.querySelector(`[data-popover-trigger][data-popover-for=\"${popoverId}\"]`);\n if (trigger) {\n positionPopover(trigger, content);\n }\n });\n }, { passive: true });\n });\n }\n \n setupScrollHandlers();\n });\n ")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
diff --git a/eslint.config.js b/eslint.config.js
index 1ed09a1e..8478e824 100644
--- a/eslint.config.js
+++ b/eslint.config.js
@@ -12,11 +12,6 @@ module.exports = [
},
"rules": {
...htmlPlugin.configs.recommended.rules,
- "@html-eslint/element-newline": "off",
- "@html-eslint/indent": "off",
- "@html-eslint/attrs-newline": "off",
- "@html-eslint/attrs-newline": "off",
- "@html-eslint/no-extra-spacing-attrs": "off",
}
},
]
\ No newline at end of file
diff --git a/internal/ui/showcase/popover_default.templ b/internal/ui/showcase/popover_default.templ
index e39eabf5..40a1d657 100644
--- a/internal/ui/showcase/popover_default.templ
+++ b/internal/ui/showcase/popover_default.templ
@@ -5,6 +5,7 @@ import (
"github.com/axzilla/templui/component/input"
"github.com/axzilla/templui/component/label"
"github.com/axzilla/templui/component/popover"
+ "github.com/axzilla/templui/util"
)
templ PopoverDefault() {
@@ -27,6 +28,7 @@ templ PopoverDefault() {
}
templ PopoverContent() {
+ {{ var id = util.RandomID() }}
Dimensions
@@ -35,12 +37,12 @@ templ PopoverContent() {
@label.Label(label.Props{
- For: "width",
+ For: "width" + id,
}) {
Width
}
@input.Input(input.Props{
- ID: "width",
+ ID: "width" + id,
Placeholder: "Width",
Value: "100%",
Class: "col-span-2",
@@ -48,12 +50,12 @@ templ PopoverContent() {
@label.Label(label.Props{
- For: "height",
+ For: "height" + id,
}) {
Height
}
@input.Input(input.Props{
- ID: "height",
+ ID: "height" + id,
Placeholder: "Height",
Value: "100%",
Class: "col-span-2",