/
githubmirror
/
halo
Обзор
Документация
Войти
/
githubmirror
/
halo
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
ui/src/formkit/inputs/array/renderers/select.ts
163 строки
4 KB
Ryan Wang
Support icons and descriptions in FormKit select options (#10076)
11 июн 2026, 17:19
Не верифицирован
11 июн 2026, 17:19
b0ac6ee
Код
Авторство
О чём код?
import type { FormKitNode } from "@formkit/core"; import { axiosInstance } from "@halo-dev/api-client"; import type { AxiosRequestConfig } from "axios"; import { get, has } from "es-toolkit/compat"; import type { PropertyPath } from "lodash-es"; import { mapItemsToSelectOptions } from "../../select/option-utils"; import type { SelectOption } from "../../select/types"; import { findOptions } from "./helpers/findOption"; import type { LabelValueResult } from "./types"; /** * Parse action remote select response data */ const parseActionRemoteSelectResponse = ( node: FormKitNode<unknown>, data: unknown ): SelectOption[] | undefined => { const { requestOption } = node.props; const { parseData } = requestOption; if (parseData) { return parseData(data); } const { itemsField } = requestOption; if (!has(data, itemsField as PropertyPath)) { console.error( `itemsField: ${itemsField?.toString()} not found in response data.` ); return; } const items = get(data, itemsField as PropertyPath); return mapItemsToSelectOptions(items, requestOption); }; /** * Fetch remote mapped options through action property */ const fetchRemoteMappedOptions = async ( node: FormKitNode<unknown>, unmappedSelectValues: unknown[] ): Promise<SelectOption[] | undefined> => { const { requestOption, action } = node.props; if (!requestOption || !action) { return; } const requestConfig: AxiosRequestConfig = { method: requestOption?.method || "GET", url: action, }; if (requestConfig.method === "GET") { requestConfig.params = { fieldSelector: `${requestOption?.fieldSelectorKey?.toString()}=(${unmappedSelectValues.join( "," )})`, }; } else { requestConfig.data = { fieldSelector: `${requestOption?.fieldSelectorKey?.toString()}=(${unmappedSelectValues.join( "," )})`, }; } const response = await axiosInstance.request(requestConfig); const { data } = response; return parseActionRemoteSelectResponse(node, data); }; /** * Find the selected option by remote data fetching */ async function findSelectedOptionByRemote( node: FormKitNode<unknown>, value: unknown ): Promise< | { label: string; value: unknown; group?: unknown; } | undefined > { // select remote option if ("remote" in node.props && node.props.remote) { const { search, findOptionsByValues } = node.props.remoteOption; if (findOptionsByValues) { const options = await findOptionsByValues([value]); if (options.length > 0) { return { label: options[0].label, value: options[0].value, }; } } if (search) { const options = await search({ keyword: "", page: 1, size: 20, }); if (options.length > 0) { const selectedOption = findOptions(options, value); if (selectedOption) { return selectedOption; } } } } // select action option if ("action" in node.props && node.props.action) { const mappedOptions = await fetchRemoteMappedOptions(node, [value]); if (mappedOptions) { const selectedOption = findOptions(mappedOptions, value); if (selectedOption) { return selectedOption; } } } } /** * Render select label value * * Select has multiple ways to get options, such as: * - Get options through the `remote` property * - Get options through the `action` property * - Get options through the `options` property */ export async function renderSelectLabelValue({ node, value, }: { node: FormKitNode<unknown>; value: unknown; }): Promise<LabelValueResult> { const remoteSelectedOption = await findSelectedOptionByRemote(node, value); if (remoteSelectedOption) { return { value: remoteSelectedOption.label, }; } const options = node.context?.attrs.options; if (typeof value === "string") { const selectedOption = findOptions(options, value); if (selectedOption) { return { value: selectedOption.label, }; } } if (Array.isArray(value)) { return { value: value.map((v) => { const selectedOption = findOptions(options, v); return selectedOption?.label; }), }; } return { value, }; }