Filter and Sort not updating DOM on Safari iOS
Description
Finsweet Attributes List (@finsweet/attributes@2) initializes correctly on Safari iOS and reads all inputs properly, but the DOM never updates after the initial render when using filters or sort.
Environment
- Package:
@finsweet/attributes@2 (latest)
- Feature:
fs-list
- Platform: Safari iOS (iPhone, iPad real device)
- Works on: Chrome desktop, Safari desktop, Chrome mobile emulator (DevTools)
- Fails on: Safari iOS real device only
Steps to reproduce
- Set up a static
fs-list with filter inputs and a sort select
- Load the page on a real iPhone or iPad with Safari
- Interact with the sort
<select> or filter <input type="radio">
- Observe that the list does not update
Debugging findings
After extensive debugging via Safari remote inspector, here is what we found:
1. Finsweet initializes correctly
The FinsweetAttributes callback fires, listInstances is available, and the initial render hook is triggered with all 12 items.
window.FinsweetAttributes.push(['list', (listInstances) => {
console.log('List loaded'); // ✅ fires on iOS
listInstances[0].addHook('render', (items) => {
console.log('render', items.length); // ✅ fires once on load, never again after interaction
});
}]);
2. Change events fire correctly
The change event on the sort <select> is detected and document.activeElement is correct:
document.querySelector('[fs-list-element="sort-trigger"]').addEventListener('change', function(e) {
console.log('change fired', e.isTrusted); // ✅ true
console.log('activeElement match', document.activeElement === this); // ✅ true
});
3. Internal state is updated
After interacting with the sort select, inspecting the internal state shows interacted: true and the correct fieldKey — meaning Finsweet receives and processes the event:
window._fsList.sorting._rawValue
// {fieldKey: "alpha", direction: "asc", interacted: true}
4. But the DOM never changes
Despite the state being updated, no style="display: none" or reordering is applied to fs-list-element="item" elements. The render hook never fires again after the initial load.
5. setSearchParam resolves but has no effect
Calling setSearchParam manually resolves the promise but does not trigger a DOM update:
await window._fsList.setSearchParam('sort', 'alpha-asc');
// Promise resolves ✅
// DOM does not change ❌
// sorting._rawValue still shows previous value ❌
6. URL param workaround partially works
If the sort/filter param is present in the URL on page load, the initial render applies it correctly. But subsequent interactions still have no effect.
7. Clear works once
Using fs-list-element="clear" after a URL-param-triggered filter correctly resets the list. But any interaction after that has no effect again.
Root cause hypothesis (from Claude)
Finsweet@2 uses Vue 3 reactivity internally (visible via __v_isRef, __v_isShallow, Proxy on internal objects). The state is updated correctly but the Vue reactivity system does not trigger a DOM re-render on Safari iOS. This appears to be a Vue 3 reactivity issue specific to WebKit/Safari iOS.
Available methods on list instance
Object.getOwnPropertyNames(Object.getPrototypeOf(window._fsList))
// ["constructor", "addHook", "triggerHook", "scrollToAnchor",
// "getSearchParam", "getAllSearchParams", "setSearchParam", "listOrWrapper"]
No public render() or refresh() method is available to force a re-render as a workaround.
Expected behavior
The list should filter and sort correctly on Safari iOS real devices, just as it does on desktop browsers.
Actual behavior
The DOM never updates after the initial render when interacting with filters or sort on Safari iOS.
Filter and Sort not updating DOM on Safari iOS
Description
Finsweet Attributes List (
@finsweet/attributes@2) initializes correctly on Safari iOS and reads all inputs properly, but the DOM never updates after the initial render when using filters or sort.Environment
@finsweet/attributes@2(latest)fs-listSteps to reproduce
fs-listwith filter inputs and a sort select<select>or filter<input type="radio">Debugging findings
After extensive debugging via Safari remote inspector, here is what we found:
1. Finsweet initializes correctly
The
FinsweetAttributescallback fires,listInstancesis available, and the initialrenderhook is triggered with all 12 items.2. Change events fire correctly
The
changeevent on the sort<select>is detected anddocument.activeElementis correct:3. Internal state is updated
After interacting with the sort select, inspecting the internal state shows
interacted: trueand the correctfieldKey— meaning Finsweet receives and processes the event:4. But the DOM never changes
Despite the state being updated, no
style="display: none"or reordering is applied tofs-list-element="item"elements. Therenderhook never fires again after the initial load.5.
setSearchParamresolves but has no effectCalling
setSearchParammanually resolves the promise but does not trigger a DOM update:6. URL param workaround partially works
If the sort/filter param is present in the URL on page load, the initial render applies it correctly. But subsequent interactions still have no effect.
7. Clear works once
Using
fs-list-element="clear"after a URL-param-triggered filter correctly resets the list. But any interaction after that has no effect again.Root cause hypothesis (from Claude)
Finsweet@2 uses Vue 3 reactivity internally (visible via
__v_isRef,__v_isShallow,Proxyon internal objects). The state is updated correctly but the Vue reactivity system does not trigger a DOM re-render on Safari iOS. This appears to be a Vue 3 reactivity issue specific to WebKit/Safari iOS.Available methods on list instance
No public
render()orrefresh()method is available to force a re-render as a workaround.Expected behavior
The list should filter and sort correctly on Safari iOS real devices, just as it does on desktop browsers.
Actual behavior
The DOM never updates after the initial render when interacting with filters or sort on Safari iOS.