{"version":3,"file":"useOptions-YcqJ438a.cjs","sources":["../../src/composables/useOptions.ts"],"sourcesContent":["import { toValue, type MaybeRefOrGetter } from \"vue\";\nimport { isEqual } from \"@/utils/helpers\";\n\n/**\n * Internal OptionsItem representation object with additional state information.\n *\n * @internal\n */\nexport type OptionsItem<V = unknown> = OptionsPropItem<V> & {\n    /** internal definiton if the element should be hidden */\n    hidden?: boolean;\n    /** internal genereated uniqe option key */\n    key?: string;\n};\n\n/**\n * Options should always be formatted as an array of objects with label and value properties.\n *\n * @public\n */\nexport type OptionsPropItem<V = unknown> = {\n    /** displayed option label */\n    label: string;\n    /** the real option value */\n    value: V;\n    /** additional attributes bound to the option element */\n    attrs?: {\n        disabled?: boolean;\n    } & Record<string, any>;\n    [index: string]: any;\n};\n\nexport type SimpleOptionsProp =\n    | (string | number)[]\n    | Omit<OptionsPropItem<never>, \"value\">[];\n\n/**\n * The types of options that can be passed to the options prop.\n *\n * @public\n */\nexport type OptionsProp<V = string | number | object> =\n    | (string | number)[]\n    | Record<string | number, string>\n    | OptionsPropItem<V>[];\n\n/**\n * Option groups should always be formatted as an array of objects with group and nested options.\n *\n * @internal\n */\nexport type OptionsGroupItem<V = unknown> = {\n    /** displayed option group label */\n    label?: string;\n    /** the real option group value */\n    value?: V;\n    /** list of options */\n    options: OptionsItem<V>[];\n    /** additional attributes bound to the options grouü element */\n    attrs?: Record<string, any>;\n    /** internal definiton if the element should be hidden */\n    hidden?: boolean;\n    /** internal genereated uniqe option key */\n    key?: string;\n};\n\n/**\n * Option groups should always be formatted as an array of objects with group and nested options.\n *\n * @public\n */\nexport type OptionsGroupPropItem<V = unknown> = {\n    /** displayed option group label */\n    label?: string;\n    /** the real option group value */\n    value?: V;\n    /** list of options */\n    options: OptionsProp<V>;\n    /** additional attributes bound to the options grouü element */\n    attrs?: Record<string, any>;\n};\n\n/**\n * An array of option items with a group support — where the `option` of the\n * groups can be any valid OptionsProp type.\n *\n * @public\n */\nexport type OptionsGroupProp<V = string | number | object> =\n    OptionsGroupPropItem<V>[];\n\n/**\n * The types of options that can be passed to the options prop.\n * An array of option items with a group support — where the `option` of the\n * groups can be any valid OptionsProp type.\n *\n * @public\n */\nexport type OptionsPropWithGroups<V = unknown> =\n    | OptionsProp<V>\n    | OptionsGroupProp<V>;\n\n/** Normalized external options prop for internal usage */\ntype NormalizedOptions<\n    V,\n    O extends OptionsPropWithGroups<V> | SimpleOptionsProp | undefined,\n> =\n    O extends OptionsGroupProp<V>\n        ? OptionsGroupItem<V>[]\n        : O extends OptionsProp<V>\n          ? OptionsItem<V>[]\n          : O extends SimpleOptionsProp\n            ? OptionsItem<never>[]\n            : never[];\n\n/**\n * A function to normalize an array of objects, array of strings, or object of\n * key-values to use an array of objects with value and label properties.\n *\n * @param options - An un-normalized {@link OptionsPropWithGroups}.\n *\n * @returns A list of {@link OptionsItem} | {@link OptionsGroupItem}.\n */\nexport function normalizeOptions<\n    V,\n    O extends\n        | SimpleOptionsProp\n        | OptionsPropWithGroups<V> = OptionsPropWithGroups<V>,\n>(options: O | undefined, uuid: () => string): NormalizedOptions<V, O> {\n    if (!options) return [] as NormalizedOptions<V, O>;\n\n    if (Array.isArray(options))\n        return options.map(\n            (option: O[number]): OptionsItem | OptionsGroupItem => {\n                if (typeof option === \"string\" || typeof option === \"number\")\n                    // create options item from primitive\n                    return {\n                        label: String(option),\n                        value: String(option),\n                        key: uuid(),\n                    } as OptionsItem<V>;\n\n                if (typeof option == \"object\") {\n                    if (\"options\" in option) {\n                        // process group options\n                        const options = normalizeOptions(option.options, uuid);\n                        // create options group item\n                        return {\n                            ...option,\n                            options,\n                            key: uuid(),\n                        } as OptionsGroupItem<V>;\n                    } else if (\"value\" in option) {\n                        // create options item\n                        return {\n                            ...option,\n                            key: uuid(),\n                        } as OptionsItem<V>;\n                    }\n                }\n                return option as OptionsItem<V>;\n            },\n        ) as NormalizedOptions<V, O>;\n\n    return Object.keys(options).map(\n        (value: string): OptionsItem<string> => ({\n            // create option from object key/value\n            label: options[value],\n            value,\n            key: uuid(),\n        }),\n    ) as NormalizedOptions<V, O>;\n}\n\n/**\n * A helper to determine if an option is a group or an option.\n * @param option - An option\n *\n * @returns option is OptionsGroupItem\n */\nexport function isGroupOption(\n    option: Partial<OptionsItem | OptionsGroupItem>,\n): option is OptionsGroupItem {\n    return (\n        option && typeof option === \"object\" && Array.isArray(option.options)\n    );\n}\n\nexport function toOptionsGroup<V>(\n    options: OptionsItem<V>[] | OptionsGroupItem<V>[],\n    key: string,\n): OptionsGroupItem<V>[] {\n    if (!Array.isArray(options)) return [];\n\n    const isGroup = options.some((option) => isGroupOption(option));\n\n    // if options are already a list options do nothing\n    if (isGroup) return [...options] as OptionsGroupItem<V>[];\n\n    // create a list with a single group\n    return [{ options, key }] as OptionsGroupItem<V>[];\n}\n\nexport function toOptionsList<V>(\n    options: MaybeRefOrGetter<OptionsGroupItem<V>[]>,\n): OptionsItem<V>[] {\n    if (!Array.isArray(toValue(options))) return [];\n\n    return toValue(options).reduce((list, group) => {\n        list.push(...group.options);\n        return list;\n    }, [] as OptionsItem<V>[]);\n}\n\n/**\n * Applies an filter function for a list of options {@link OptionsItem | OptionsGroupItem}.\n * Options are filtered by setting the hidden attribute.\n * The options reactivity is not triggered by this.\n * @param options - Options to filter\n * @param filter - filter function\n */\nexport function filterOptionsItems<V>(\n    options: MaybeRefOrGetter<OptionsItem<V>[] | OptionsGroupItem<V>[]>,\n    filter: (option: OptionsItem<V>, index: number) => boolean,\n): void {\n    toValue(options).forEach(\n        (option: OptionsItem<V> | OptionsGroupItem<V>, idx: number) => {\n            if (isGroupOption(option)) {\n                filterOptionsItems(option.options, filter);\n                // hide the whole group if every group options is hidden\n                option.hidden = option.options.every((option) => option.hidden);\n            } else {\n                // hide the option if filtered\n                option.hidden = filter(option, idx);\n            }\n        },\n    );\n}\n\n/**\n * Checks if no options are given or every existing options are hidden.\n * @param options - A list of {@link OptionsItem | OptionsGroupItem} to check for a given value\n *\n * @returns boolean\n */\nexport function checkOptionsEmpty(\n    options: MaybeRefOrGetter<OptionsItem[] | OptionsGroupItem[]>,\n): boolean {\n    // check if options are empty\n    if (!Array.isArray(toValue(options))) return true;\n\n    return toValue(options).every((option: OptionsItem | OptionsGroupItem) => {\n        if (isGroupOption(option))\n            // check if every options are hidden\n            return checkOptionsEmpty(option.options);\n        // check if option is hidden\n        else return !isOptionViable(option);\n    });\n}\n\n/**\n * Given an list of {@link OptionsItem | OptionsGroupItem}, find the option item with the given value.\n *\n * @param options - A list of {@link OptionsItem | OptionsGroupItem} to check for a given value\n * @param value - The value to check\n *\n * @returns {@link OptionsItem}\n */\nexport function findOption<V>(\n    options:\n        | MaybeRefOrGetter<OptionsItem<V>[]>\n        | MaybeRefOrGetter<OptionsGroupItem<V>[]>,\n    value: MaybeRefOrGetter<V>,\n): OptionsItem<V> | undefined {\n    if (!Array.isArray(toValue(options))) return undefined;\n\n    for (const option of toValue(options)) {\n        if (typeof option !== \"object\" && option) continue;\n        if (isGroupOption(option)) {\n            // option in group\n            const found = findOption(option.options, value);\n            if (found !== undefined) return found;\n        }\n        // check if option has value\n        else if (isEqual(toValue(value), option.value)) return option;\n    }\n\n    return undefined;\n}\n\n/**\n * Given an options list, find the first value.\n * @param options - An options list (with groups)\n */\nexport function firstViableOption<V>(\n    options:\n        | MaybeRefOrGetter<OptionsItem<V>[]>\n        | MaybeRefOrGetter<OptionsGroupItem<V>[]>,\n): OptionsItem<V> | undefined {\n    if (!Array.isArray(toValue(options))) return undefined;\n\n    for (const option of toValue(options)) {\n        if (typeof option !== \"object\" && option) continue;\n        if (isGroupOption(option)) {\n            // option in group\n            const found = firstViableOption(option.options);\n            if (found !== undefined) return found;\n        }\n        // check if option is viable\n        else if (isOptionViable(option)) return option;\n    }\n\n    return undefined;\n}\n\nexport function isOptionViable(option: MaybeRefOrGetter<OptionsItem>): boolean {\n    return !toValue(option).hidden && !toValue(option).attrs?.disabled;\n}\n"],"names":["options","toValue","option","isEqual"],"mappings":";;;;AA2HgB,SAAA,iBAKd,SAAwB,MAA6C;AAC/D,MAAA,CAAC,QAAS,QAAO,CAAC;AAElB,MAAA,MAAM,QAAQ,OAAO;AACrB,WAAO,QAAQ;AAAA,MACX,CAAC,WAAsD;AACnD,YAAI,OAAO,WAAW,YAAY,OAAO,WAAW;AAEzC,iBAAA;AAAA,YACH,OAAO,OAAO,MAAM;AAAA,YACpB,OAAO,OAAO,MAAM;AAAA,YACpB,KAAK,KAAK;AAAA,UACd;AAEA,YAAA,OAAO,UAAU,UAAU;AAC3B,cAAI,aAAa,QAAQ;AAErB,kBAAMA,WAAU,iBAAiB,OAAO,SAAS,IAAI;AAE9C,mBAAA;AAAA,cACH,GAAG;AAAA,cACH,SAAAA;AAAAA,cACA,KAAK,KAAK;AAAA,YACd;AAAA,UAAA,WACO,WAAW,QAAQ;AAEnB,mBAAA;AAAA,cACH,GAAG;AAAA,cACH,KAAK,KAAK;AAAA,YACd;AAAA,UAAA;AAAA,QACJ;AAEG,eAAA;AAAA,MAAA;AAAA,IAEf;AAEG,SAAA,OAAO,KAAK,OAAO,EAAE;AAAA,IACxB,CAAC,WAAwC;AAAA;AAAA,MAErC,OAAO,QAAQ,KAAK;AAAA,MACpB;AAAA,MACA,KAAK,KAAK;AAAA,IACd;AAAA,EACJ;AACJ;AAQO,SAAS,cACZ,QAC0B;AAC1B,SACI,UAAU,OAAO,WAAW,YAAY,MAAM,QAAQ,OAAO,OAAO;AAE5E;AAEgB,SAAA,eACZ,SACA,KACqB;AACrB,MAAI,CAAC,MAAM,QAAQ,OAAO,UAAU,CAAC;AAErC,QAAM,UAAU,QAAQ,KAAK,CAAC,WAAW,cAAc,MAAM,CAAC;AAG9D,MAAI,QAAS,QAAO,CAAC,GAAG,OAAO;AAG/B,SAAO,CAAC,EAAE,SAAS,KAAK;AAC5B;AAEO,SAAS,cACZ,SACgB;AACZ,MAAA,CAAC,MAAM,QAAQC,IAAA,QAAQ,OAAO,CAAC,UAAU,CAAC;AAE9C,SAAOA,IAAAA,QAAQ,OAAO,EAAE,OAAO,CAAC,MAAM,UAAU;AACvC,SAAA,KAAK,GAAG,MAAM,OAAO;AACnB,WAAA;AAAA,EACX,GAAG,EAAsB;AAC7B;AASgB,SAAA,mBACZ,SACA,QACI;AACJA,MAAA,QAAQ,OAAO,EAAE;AAAA,IACb,CAAC,QAA8C,QAAgB;AACvD,UAAA,cAAc,MAAM,GAAG;AACJ,2BAAA,OAAO,SAAS,MAAM;AAEzC,eAAO,SAAS,OAAO,QAAQ,MAAM,CAACC,YAAWA,QAAO,MAAM;AAAA,MAAA,OAC3D;AAEI,eAAA,SAAS,OAAO,QAAQ,GAAG;AAAA,MAAA;AAAA,IACtC;AAAA,EAER;AACJ;AAQO,SAAS,kBACZ,SACO;AAEP,MAAI,CAAC,MAAM,QAAQD,YAAQ,OAAO,CAAC,EAAU,QAAA;AAE7C,SAAOA,IAAQ,QAAA,OAAO,EAAE,MAAM,CAAC,WAA2C;AACtE,QAAI,cAAc,MAAM;AAEb,aAAA,kBAAkB,OAAO,OAAO;AAAA,QAEtC,QAAO,CAAC,eAAe,MAAM;AAAA,EAAA,CACrC;AACL;AAUgB,SAAA,WACZ,SAGA,OAC0B;AAC1B,MAAI,CAAC,MAAM,QAAQA,YAAQ,OAAO,CAAC,EAAU,QAAA;AAElC,aAAA,UAAUA,YAAQ,OAAO,GAAG;AAC/B,QAAA,OAAO,WAAW,YAAY,OAAQ;AACtC,QAAA,cAAc,MAAM,GAAG;AAEvB,YAAM,QAAQ,WAAW,OAAO,SAAS,KAAK;AAC1C,UAAA,UAAU,OAAkB,QAAA;AAAA,IAAA,WAG3BE,gBAAQF,YAAQ,KAAK,GAAG,OAAO,KAAK,EAAU,QAAA;AAAA,EAAA;AAGpD,SAAA;AACX;AA2BO,SAAS,eAAe,QAAgD;;AACpE,SAAA,CAACA,IAAAA,QAAQ,MAAM,EAAE,UAAU,GAACA,iBAAQ,MAAM,EAAE,UAAhBA,mBAAuB;AAC9D;;;;;;;;;"}