polaris icon indicating copy to clipboard operation
polaris copied to clipboard

Documentation for useIndexResourceState

Open bashunaimiroy opened this issue 3 years ago • 2 comments

Feature request summary

A documentation page within Polaris docs for the useIndexResourceState hook. It would explain how settings and parameters can be passed to this hook to configure its behaviour, and what the default behaviour is.

Rationale

IndexTable relies heavily upon the useIndexResourceState hook to handle all selection logic. This hook is shown clearly in the Code Generator in the documentation for indexTable but it's never really explained. It just shows up in every usage of the component, with some context clues about how to use it but not debug it.

It even surfaces errors like "pass in a ResourceIDResolver function" but doesn't explain what that function should do, how to write it, and how to pass it in. The poster in the linked thread had to find their own solution and post it, for which they should be commended, but Shopify can and should do more to support developers.

Without documentation, devs are left in this tantalising "half-fixable" state where they are given half of the information they need, and the rest of the information is hidden somewhere within node_modules at the end of a deep stack trace.

If instead, there was documentation on how this hook works, we could debug our selection logic easily. For example, if I could have searched and found out that useIndexResourceState will look for an id property on my items by default, but that I can pass in a custom function to specify another field, I would have saved the past 60 minutes, and felt like I'm using a dev-friendly framework, rather than a secret leaked internal tool.

Thanks folks.


🌟 Feature requests that are not yet planned will be closed. We then use the issue’s :+1: upvotes to track and set priorities. See the contribution guidelines for more information.

bashunaimiroy avatar Jan 27 '22 04:01 bashunaimiroy

👋 Thanks for opening your first issue. A contributor should give feedback soon. If you haven’t already, please check out the contributing guidelines.

ghost avatar Jan 27 '22 04:01 ghost

This is probably why it's not described in the documentation: useIndexResourceState doesn't do anything particularly special. Its uses may be inferred from the context in which it is used.

It's a "specialized" implementation of the useState function. The purpose is to tell the function component to use state. It needs to use state to track whatever is identified in the "destructuring assignment." And the last assignment is a callback that's used to set the values.

In the Simple Index Table example (https://polaris.shopify.com/components/lists-and-tables/index-table) those things are the selected resources, a boolean value whether or not "all" have been selected, and a callback. The arguments provided to the callback are supplied through the onSelectChange callback. And they are a resource type (single, all, page) and the all boolean.

GuestDeveloper69 avatar May 30 '22 04:05 GuestDeveloper69

Thanks for the request, @bashunaimiroy. We’re not actively working on this right now, but we’d love for it to make its way into the system. Please feel free to contribute and open a PR to the IndexTable documentation page if this request is still relevant and valuable

yurm04 avatar Aug 24 '22 18:08 yurm04

The examples also show this hook being supplied a fixed array but I'm not sure if there is a way to update it if the array is a state.

ko-lem avatar Nov 17 '22 12:11 ko-lem

I'm trying to add more than one index table to a page that I'm building but I'm getting hung up on this. I'm not able to do a custom assignment/destructuring of the useIndexResourceState return value but I also can't duplicate variables. Anyone have any tips on this besides don't use more than 1 index table in a page?

CalebVDang avatar Mar 22 '23 15:03 CalebVDang

I'm trying to add more than one index table to a page that I'm building but I'm getting hung up on this. I'm not able to do a custom assignment/destructuring of the useIndexResourceState return value but I also can't duplicate variables. Anyone have any tips on this besides don't use more than 1 index table in a page?

I am using Polaris Vue and their migrated version was polaris 9.9.0. I was having same issues as I basically wrapped IndexTable as my component, however you cannot change it once you pass a value into useIndexResourceState, also the multi-selection wont work for me either.

The way I work around it is to create your own useIndexResourceState function where I call it useSelection, with a custom identifier to indicate the selection. it's vue code but i think you can work it out with a react version.

I am wondering how shopify themselves handle this and unfortuantely I can't find any information on it.

If anyone found a solution please also tag me. :)

I hope this helps

`import { ref, computed, watch } from 'vue';

export function useSelection(resources, identifier) { const selectedResources = ref([]); const lastSelected = ref(null); const identifierProperty = ref(identifier); // default identifier property

const allResourcesSelected = computed(() => {
    return resources.value.length > 0 && selectedResources.value.length === resources.value.length;
});

const selectedResourceObjects = computed(() => {
    return resources.value.filter(resource => selectedResources.value.includes(resource[identifierProperty.value]));
});

const handleSelectionChange = (selectionType, toggleType, selection, sortOrder) => {
    const updateSelection = (add, id) => {
        if (add) selectedResources.value.push(id);
        else selectedResources.value = selectedResources.value.filter(item => item !== id);
    };

    if (selectionType === 'single') {
        updateSelection(toggleType, selection);
    } else if (selectionType === 'multi') {
        const range = [lastSelected.value, sortOrder].sort((a, b) => a - b);
        for (let i = range[0]; i <= range[1]; i++) {
            updateSelection(toggleType, resources.value[i]?.[identifierProperty.value]);
        }
    } else if (selectionType === 'page' || selectionType === 'all') {
        if (toggleType) selectedResources.value = resources.value.map(item => item[identifierProperty.value]);
        else selectedResources.value = [];
    }
    lastSelected.value = sortOrder;
};

watch(resources, () => {
    selectedResources.value = [];
});

return {
    selectedResources,
    allResourcesSelected,
    selectedResourceObjects, // The new computed property
    handleSelectionChange,
};

} `

sicko7947 avatar Jan 13 '24 14:01 sicko7947