import { getVariableIcon, SelectFieldItem, VevProps } from '@vev/utils'; import { SilkeCSSContextType } from '../silke-css-number-field'; import { ConditionSuggestion, VevConditionSuggestion } from './types'; const operatorOptionsBasic: VevConditionSuggestion[] = [ { value: '==', label: 'Equal to', type: 'operator', icon: 'condition.equals' }, { value: '!=', label: 'Not equal to', type: 'operator', icon: 'condition.notEqual' }, ]; const operatorOptionsTrueFalse: VevConditionSuggestion[] = [ { value: true, prefix: '==', label: 'Is true', type: 'operator', icon: 'condition.equals' }, { value: false, prefix: '==', label: 'Is false', type: 'operator', icon: 'condition.notEqual', }, ]; const operatorOptionsAdvanced: VevConditionSuggestion[] = [ { value: '>', label: 'Greater than', type: 'operator', icon: 'condition.greaterThan' }, { value: '<', label: 'Less than', type: 'operator', icon: 'condition.lessThan' }, { value: '>=', label: 'Greater than or equal to', type: 'operator', icon: 'condition.greaterThanEqual', }, { value: '<=', label: 'Less than or equal to', type: 'operator', icon: 'condition.lessThanEqueal', }, // { value: 'IN', label: 'In', type: 'operator' }, // { value: 'NOT IN', label: 'Not in', type: 'operator' }, // { value: 'LIKE', label: 'Like', type: 'operator' }, // { value: 'NOT LIKE', label: 'Not like', type: 'operator' }, // { value: 'BETWEEN', label: 'Between', type: 'operator' }, // { value: 'NOT BETWEEN', label: 'Not between', type: 'operator' }, // { value: 'IS NULL', label: 'Is null', type: 'operator' }, // { value: 'IS NOT NULL', label: 'Is not null', type: 'operator' }, ]; const combinatorOptions: VevConditionSuggestion[] = [ { value: 'AND', label: 'And', type: 'combinator', icon: 'condition.and' }, { value: 'OR', label: 'Or', type: 'combinator', icon: 'condition.or' }, ]; export const booleanSuggestions: ConditionSuggestion[] = [ { type: 'boolean', label: 'True', value: true, icon: 'condition.true' }, { type: 'boolean', label: 'False', value: false, icon: 'condition.false' }, ]; const searchSuggestions = (searchValue: string, options?: VevConditionSuggestion[]) => { if (!options) return []; if (searchValue.length === 0) return options; return options.filter( (option) => option.label.toLowerCase().includes(searchValue.toLowerCase()) || String(option.value).toLowerCase().includes(searchValue.toLowerCase()), ); }; export const getOperatorSuggestions = (searchValue: string, onlyTrueFalse: boolean) => { const searchOptions = onlyTrueFalse ? operatorOptionsTrueFalse : [...operatorOptionsBasic, ...operatorOptionsAdvanced]; const matches = searchSuggestions(searchValue, searchOptions); return matches.length > 0 ? ['Combinator', ...matches] : []; }; export const getCombinatorSuggestions = (searchValue: string) => { const matches = searchSuggestions(searchValue, combinatorOptions); return matches.length > 0 ? ['Combinator', ...matches] : []; }; const varToSuggestion = (variable: SilkeCSSContextType['variablesv2'][0]): ConditionSuggestion => ({ type: variable.type, label: variable.name, value: `{{${variable.key}}}`, subLabel: variable.type === 'color' ? `${variable.value}${variable.unit ? `${variable.unit}` : ''}` : '', icon: getVariableIcon(variable.type), }); const vevPropToSuggestion = (prop: VevProps): VevConditionSuggestion => ({ type: 'widget', label: prop.description || prop.name || '', value: prop.name || '', icon: 'interaction.inactive', }); // Get dropdown suggestions for a given search value and currentInput type (a, b, operator, combinator) export const getSuggestions = ( searchValue: string, variables: SilkeCSSContextType['variablesv2'], systemOptions?: VevConditionSuggestion[], widgetOptions?: VevProps[], ) => { const varFilter = (variable: SilkeCSSContextType['variablesv2'][0]) => { if (searchValue.length === 0) return true; return variable.name?.toLowerCase().includes(searchValue.toLowerCase()); }; const systemVars = searchSuggestions(searchValue, systemOptions); const widgetVars = searchSuggestions(searchValue, widgetOptions?.map(vevPropToSuggestion)); const numberVars = variables.filter((v) => v.type === 'number').filter(varFilter); const colorVars = variables.filter((v) => v.type === 'color').filter(varFilter); const textVars = variables.filter((v) => v.type === 'text').filter(varFilter); const fontVars = variables.filter((v) => v.type === 'font').filter(varFilter); const widgetItems = widgetVars.length > 0 ? ['Trigger', ...widgetVars] : []; const systemItems = systemVars.length > 0 ? ['System', ...systemVars] : []; const numberItems = numberVars.length > 0 ? ['Number', ...numberVars.map(varToSuggestion)] : []; const colorItems = colorVars.length > 0 ? ['Color', ...colorVars.map(varToSuggestion)] : []; const textItems = textVars.length > 0 ? ['Text', ...textVars.map(varToSuggestion)] : []; const fontItems = fontVars.length > 0 ? ['Font', ...fontVars.map(varToSuggestion)] : []; return [ ...widgetItems, ...systemItems, ...numberItems, ...colorItems, ...textItems, ...fontItems, ]; }; // Get system options for a given value - For example "Device" export const getSystemSuggestionOptions = ( value: string | number | boolean, systemOptions?: VevConditionSuggestion[], ) => { const match = systemOptions?.find((o) => o.value === value); if (match && match.options) { const optionItems = match.options.map((option) => ({ type: 'system', label: option, value: option, })) as ConditionSuggestion[]; return [String(value), ...optionItems]; } return []; }; export const getWidgetSuggestionOptions = ( value: string | number | boolean, widgetOptions?: VevProps[], ) => { const match = widgetOptions?.find((o) => o.name === value); if (match && match.type === 'select' && match.options) { const items = match.options?.items as SelectFieldItem[]; const optionItems = items?.map((option) => ({ type: 'widget', label: option.label, value: option.value, })) as ConditionSuggestion[]; return [String(value), ...optionItems]; } return []; }; export const isWidgetOption = (value: string | number | boolean, widgetOptions?: VevProps[]) => { return !!widgetOptions?.find((o) => o.name === value); }; export const getWidgetOptionType = ( value: string | number | boolean, widgetOptions?: VevProps[], ) => { return widgetOptions?.find((o) => o.name === value)?.type; };