Framework updates

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
root
2026-01-06 06:03:05 +00:00
parent 1506573202
commit 71d042ff3c
4 changed files with 208 additions and 24 deletions

View File

@@ -15,6 +15,8 @@
*
* - Elements are tracked individually (not by selector)
* - Calling again with same group name adds more elements to the group
* - If element is already in the same group, no-op (idempotent)
* - If element is in a different group, it's moved to the new group
* - Recalculates immediately and on window resize (debounced 100ms)
* - Returns the jQuery object for chaining
*
@@ -68,8 +70,10 @@
* a. Remove min-width from all elements in group (measure natural width)
* b. Find max scrollWidth across all connected elements
* c. Apply max as min-width to all connected elements
* 3. On window resize (debounced 100ms): recalculate all groups
* 4. Disconnected elements are pruned on each calculation
* 3. Child components are found via shallowFind('.Component') and their
* ready events trigger debounced recalculation
* 4. On window resize (debounced 100ms): recalculate all groups
* 5. Disconnected elements are pruned on each calculation
*
*/
@@ -78,8 +82,8 @@ class Width_Group {
// Registry of groups: { "group-name": [element, element, ...] }
static _groups = {};
// Debounced resize handler (created on first use)
static _resize_handler = null;
// Debounced recalculate handler (shared by resize and component ready)
static _debounced_recalculate = null;
// Whether resize listener is attached
static _resize_attached = false;
@@ -104,17 +108,50 @@ class Width_Group {
Width_Group._groups[group_name] = [];
}
// Add each element to the group (avoid duplicates)
// Add each element to the group
this.each(function () {
const element = this;
if (!Width_Group._groups[group_name].includes(element)) {
Width_Group._groups[group_name].push(element);
const current_group = element._width_group;
// Already in this group - no-op
if (current_group === group_name) {
return;
}
// In a different group - remove from old group first
if (current_group && Width_Group._groups[current_group]) {
const old_group = Width_Group._groups[current_group];
const index = old_group.indexOf(element);
if (index !== -1) {
old_group.splice(index, 1);
element.style.minWidth = '';
}
// Clean up empty group
if (old_group.length === 0) {
delete Width_Group._groups[current_group];
}
}
// Add to new group
Width_Group._groups[group_name].push(element);
element._width_group = group_name;
});
// Ensure resize listener is attached
Width_Group._attach_resize_listener();
// Listen for child component ready events
this.each(function () {
$(this).shallowFind('.Component').each(function () {
const component = $(this).component();
if (component) {
component.on('ready', () => {
Width_Group._schedule_recalculate();
});
}
});
});
// Calculate immediately
Width_Group._calculate_group(group_name);
@@ -152,11 +189,12 @@ class Width_Group {
return;
}
// Clear min-width from elements still in DOM
// Clear min-width and group tracking from elements
for (const element of elements) {
if (element.isConnected) {
element.style.minWidth = '';
}
delete element._width_group;
}
// Remove group from registry
@@ -166,6 +204,20 @@ class Width_Group {
Width_Group._maybe_detach_resize_listener();
}
/**
* Schedule a debounced recalculation of all groups
* Used by resize handler and component ready events
* @private
*/
static _schedule_recalculate() {
if (!Width_Group._debounced_recalculate) {
Width_Group._debounced_recalculate = debounce(() => {
Width_Group._calculate_all();
}, 100);
}
Width_Group._debounced_recalculate();
}
/**
* Attach the resize listener if not already attached
* @private
@@ -175,14 +227,9 @@ class Width_Group {
return;
}
// Create debounced handler on first use
if (!Width_Group._resize_handler) {
Width_Group._resize_handler = debounce(() => {
Width_Group._calculate_all();
}, 100);
}
$(window).on('resize.width_group', Width_Group._resize_handler);
$(window).on('resize.width_group', () => {
Width_Group._schedule_recalculate();
});
Width_Group._resize_attached = true;
}
@@ -218,8 +265,14 @@ class Width_Group {
return;
}
// Filter to only connected elements
elements = elements.filter(el => el.isConnected);
// Filter to only connected elements, clean up disconnected ones
elements = elements.filter(el => {
if (el.isConnected) {
return true;
}
delete el._width_group;
return false;
});
// Update registry with pruned list
Width_Group._groups[group_name] = elements;