mirror of
https://github.com/invoke-ai/InvokeAI.git
synced 2026-02-11 04:14:56 -05:00
Revert "feat(ui): rough out number generators for number collection fields"
This reverts commit 41cc6f1f96bca2a51727f21bd727ca48eab669bc.
This commit is contained in:
@@ -9,7 +9,6 @@ import {
|
||||
isIntegerFieldCollectionInputInstance,
|
||||
isStringFieldCollectionInputInstance,
|
||||
} from 'features/nodes/types/field';
|
||||
import { getNumberFieldCollectionValue } from 'features/nodes/types/fieldValidators';
|
||||
import type { InvocationNodeEdge } from 'features/nodes/types/invocation';
|
||||
import { isInvocationNode } from 'features/nodes/types/invocation';
|
||||
import { buildNodesGraph } from 'features/nodes/util/graph/buildNodesGraph';
|
||||
@@ -107,7 +106,7 @@ export const addEnqueueRequestedNodes = (startAppListening: AppStartListening) =
|
||||
|
||||
// Find outgoing edges from the batch node, we will remove these from the graph and create batch data collection items from them instead
|
||||
const edgesFromStringBatch = nodes.edges.filter((e) => e.source === node.id && e.sourceHandle === 'value');
|
||||
addBatchDataCollectionItem(edgesFromStringBatch, getNumberFieldCollectionValue(integers.value));
|
||||
addBatchDataCollectionItem(edgesFromStringBatch, integers.value);
|
||||
}
|
||||
|
||||
// Grab float batch nodes for special handling
|
||||
@@ -126,7 +125,7 @@ export const addEnqueueRequestedNodes = (startAppListening: AppStartListening) =
|
||||
|
||||
// Find outgoing edges from the batch node, we will remove these from the graph and create batch data collection items from them instead
|
||||
const edgesFromStringBatch = nodes.edges.filter((e) => e.source === node.id && e.sourceHandle === 'value');
|
||||
addBatchDataCollectionItem(edgesFromStringBatch, getNumberFieldCollectionValue(floats.value));
|
||||
addBatchDataCollectionItem(edgesFromStringBatch, floats.value);
|
||||
}
|
||||
|
||||
const batchConfig: BatchConfig = {
|
||||
|
||||
@@ -1,34 +1,21 @@
|
||||
import type { SystemStyleObject } from '@invoke-ai/ui-library';
|
||||
import {
|
||||
Box,
|
||||
CompositeNumberInput,
|
||||
Flex,
|
||||
FormControl,
|
||||
FormLabel,
|
||||
Grid,
|
||||
GridItem,
|
||||
IconButton,
|
||||
Text,
|
||||
} from '@invoke-ai/ui-library';
|
||||
import { Box, CompositeNumberInput, Flex, Grid, GridItem, IconButton } from '@invoke-ai/ui-library';
|
||||
import { NUMPY_RAND_MAX } from 'app/constants';
|
||||
import { useAppStore } from 'app/store/nanostores/store';
|
||||
import { useAppDispatch } from 'app/store/storeHooks';
|
||||
import { getOverlayScrollbarsParams, overlayScrollbarsStyles } from 'common/components/OverlayScrollbars/constants';
|
||||
import { useFieldIsInvalid } from 'features/nodes/hooks/useFieldIsInvalid';
|
||||
import { fieldNumberCollectionValueChanged } from 'features/nodes/store/nodesSlice';
|
||||
import type {
|
||||
FloatFieldCollectionInputInstance,
|
||||
FloatFieldCollectionInputTemplate,
|
||||
FloatStartStepCountGenerator,
|
||||
IntegerFieldCollectionInputInstance,
|
||||
IntegerFieldCollectionInputTemplate,
|
||||
IntegerStartStepCountGenerator,
|
||||
} from 'features/nodes/types/field';
|
||||
import { isNil } from 'lodash-es';
|
||||
import { OverlayScrollbarsComponent } from 'overlayscrollbars-react';
|
||||
import { memo, useCallback, useMemo } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { PiLightbulbFill, PiPencilSimpleFill, PiPlusBold, PiXBold } from 'react-icons/pi';
|
||||
import { PiPlusBold, PiXBold } from 'react-icons/pi';
|
||||
|
||||
import type { FieldComponentProps } from './types';
|
||||
|
||||
@@ -50,40 +37,68 @@ export const NumberFieldCollectionInputComponent = memo(
|
||||
) => {
|
||||
const { nodeId, field, fieldTemplate } = props;
|
||||
const store = useAppStore();
|
||||
|
||||
const isInvalid = useFieldIsInvalid(nodeId, field.name);
|
||||
const isIntegerField = useMemo(() => fieldTemplate.type.name === 'IntegerField', [fieldTemplate.type]);
|
||||
|
||||
const entryMode = useMemo(() => {
|
||||
if (!field.value) {
|
||||
return 'manual';
|
||||
}
|
||||
if (Array.isArray(field.value)) {
|
||||
return 'manual';
|
||||
}
|
||||
return 'step';
|
||||
}, [field.value]);
|
||||
|
||||
const toggleEntryMode = useCallback(() => {
|
||||
if (!field.value || Array.isArray(field.value)) {
|
||||
const newValue: IntegerStartStepCountGenerator | FloatStartStepCountGenerator = isIntegerField
|
||||
? { type: 'integer-start-step-count-generator', start: 0, step: 1, count: 1 }
|
||||
: { type: 'float-start-step-count-generator', start: 0, step: 1, count: 1 };
|
||||
const onRemoveNumber = useCallback(
|
||||
(index: number) => {
|
||||
const newValue = field.value ? [...field.value] : [];
|
||||
newValue.splice(index, 1);
|
||||
store.dispatch(fieldNumberCollectionValueChanged({ nodeId, fieldName: field.name, value: newValue }));
|
||||
} else {
|
||||
store.dispatch(
|
||||
fieldNumberCollectionValueChanged({
|
||||
nodeId,
|
||||
fieldName: field.name,
|
||||
value: [0],
|
||||
})
|
||||
);
|
||||
}
|
||||
}, [field.name, field.value, isIntegerField, nodeId, store]);
|
||||
},
|
||||
[field.name, field.value, nodeId, store]
|
||||
);
|
||||
|
||||
const onChangeNumber = useCallback(
|
||||
(index: number, value: number) => {
|
||||
const newValue = field.value ? [...field.value] : [];
|
||||
newValue[index] = value;
|
||||
store.dispatch(fieldNumberCollectionValueChanged({ nodeId, fieldName: field.name, value: newValue }));
|
||||
},
|
||||
[field.name, field.value, nodeId, store]
|
||||
);
|
||||
|
||||
const onAddNumber = useCallback(() => {
|
||||
const newValue = field.value && Array.isArray(field.value) ? [...field.value, 0] : [0];
|
||||
const newValue = field.value ? [...field.value, 0] : [0];
|
||||
store.dispatch(fieldNumberCollectionValueChanged({ nodeId, fieldName: field.name, value: newValue }));
|
||||
}, [field.value, field.name, store, nodeId]);
|
||||
}, [field.name, field.value, nodeId, store]);
|
||||
|
||||
const min = useMemo(() => {
|
||||
let min = -NUMPY_RAND_MAX;
|
||||
if (!isNil(fieldTemplate.minimum)) {
|
||||
min = fieldTemplate.minimum;
|
||||
}
|
||||
if (!isNil(fieldTemplate.exclusiveMinimum)) {
|
||||
min = fieldTemplate.exclusiveMinimum + 0.01;
|
||||
}
|
||||
return min;
|
||||
}, [fieldTemplate.exclusiveMinimum, fieldTemplate.minimum]);
|
||||
|
||||
const max = useMemo(() => {
|
||||
let max = NUMPY_RAND_MAX;
|
||||
if (!isNil(fieldTemplate.maximum)) {
|
||||
max = fieldTemplate.maximum;
|
||||
}
|
||||
if (!isNil(fieldTemplate.exclusiveMaximum)) {
|
||||
max = fieldTemplate.exclusiveMaximum - 0.01;
|
||||
}
|
||||
return max;
|
||||
}, [fieldTemplate.exclusiveMaximum, fieldTemplate.maximum]);
|
||||
|
||||
const step = useMemo(() => {
|
||||
if (isNil(fieldTemplate.multipleOf)) {
|
||||
return isIntegerField ? 1 : 0.1;
|
||||
}
|
||||
return fieldTemplate.multipleOf;
|
||||
}, [fieldTemplate.multipleOf, isIntegerField]);
|
||||
|
||||
const fineStep = useMemo(() => {
|
||||
if (isNil(fieldTemplate.multipleOf)) {
|
||||
return isIntegerField ? 1 : 0.01;
|
||||
}
|
||||
return fieldTemplate.multipleOf;
|
||||
}, [fieldTemplate.multipleOf, isIntegerField]);
|
||||
|
||||
return (
|
||||
<Flex
|
||||
@@ -94,48 +109,53 @@ export const NumberFieldCollectionInputComponent = memo(
|
||||
maxH={64}
|
||||
alignItems="stretch"
|
||||
justifyContent="center"
|
||||
flexDir="column"
|
||||
overflow="hidden"
|
||||
gap={1}
|
||||
p={1}
|
||||
borderWidth={1}
|
||||
borderRadius="base"
|
||||
sx={sx}
|
||||
data-error={isInvalid}
|
||||
>
|
||||
<Flex gap={2} w="full" alignItems="center">
|
||||
{!field.value ||
|
||||
(Array.isArray(field.value) && (
|
||||
<>
|
||||
<Text flexGrow={1}>Manual</Text>
|
||||
{(!field.value || field.value.length === 0) && (
|
||||
<Box w="full" sx={sx} data-error={isInvalid} borderRadius="base">
|
||||
<IconButton
|
||||
w="full"
|
||||
onClick={onAddNumber}
|
||||
aria-label="Add Item"
|
||||
icon={<PiPlusBold />}
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
/>
|
||||
</Box>
|
||||
)}
|
||||
{field.value && field.value.length > 0 && (
|
||||
<Box w="full" h="auto" p={1} sx={sx} data-error={isInvalid} borderRadius="base">
|
||||
<OverlayScrollbarsComponent
|
||||
className="nowheel"
|
||||
defer
|
||||
style={overlayScrollbarsStyles}
|
||||
options={overlayscrollbarsOptions}
|
||||
>
|
||||
<Grid w="full" h="full" templateColumns="repeat(1, 1fr)" gap={1}>
|
||||
<IconButton
|
||||
w="full"
|
||||
onClick={onAddNumber}
|
||||
aria-label="Add Item"
|
||||
icon={<PiPlusBold />}
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
/>
|
||||
</>
|
||||
))}
|
||||
{field.value && !Array.isArray(field.value) && (
|
||||
<>
|
||||
<Text flexGrow={1}>Generator</Text>
|
||||
</>
|
||||
)}
|
||||
<IconButton
|
||||
onClick={toggleEntryMode}
|
||||
aria-label="Toggle Entry Mode"
|
||||
icon={entryMode === 'manual' ? <PiLightbulbFill /> : <PiPencilSimpleFill />}
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
/>
|
||||
</Flex>
|
||||
{field.value && !Array.isArray(field.value) && (
|
||||
<GeneratorEntry nodeId={nodeId} fieldName={field.name} value={field.value} fieldTemplate={fieldTemplate} />
|
||||
)}
|
||||
{field.value && Array.isArray(field.value) && field.value.length > 0 && (
|
||||
<ManualEntry nodeId={nodeId} fieldName={field.name} value={field.value} fieldTemplate={fieldTemplate} />
|
||||
{field.value.map((value, index) => (
|
||||
<GridItem key={index} position="relative" className="nodrag">
|
||||
<NumberListItemContent
|
||||
value={value}
|
||||
index={index}
|
||||
min={min}
|
||||
max={max}
|
||||
step={step}
|
||||
fineStep={fineStep}
|
||||
isIntegerField={isIntegerField}
|
||||
onRemoveNumber={onRemoveNumber}
|
||||
onChangeNumber={onChangeNumber}
|
||||
/>
|
||||
</GridItem>
|
||||
))}
|
||||
</Grid>
|
||||
</OverlayScrollbarsComponent>
|
||||
</Box>
|
||||
)}
|
||||
</Flex>
|
||||
);
|
||||
@@ -144,163 +164,6 @@ export const NumberFieldCollectionInputComponent = memo(
|
||||
|
||||
NumberFieldCollectionInputComponent.displayName = 'NumberFieldCollectionInputComponent';
|
||||
|
||||
const GeneratorEntry = ({
|
||||
nodeId,
|
||||
fieldName,
|
||||
value,
|
||||
fieldTemplate,
|
||||
}: {
|
||||
nodeId: string;
|
||||
fieldName: string;
|
||||
value: IntegerStartStepCountGenerator | FloatStartStepCountGenerator;
|
||||
fieldTemplate: IntegerFieldCollectionInputTemplate | FloatFieldCollectionInputTemplate;
|
||||
}) => {
|
||||
const dispatch = useAppDispatch();
|
||||
const isIntegerField = useMemo(() => fieldTemplate.type.name === 'IntegerField', [fieldTemplate.type]);
|
||||
const onChangeStart = useCallback(
|
||||
(v: number) => {
|
||||
const newValue = { ...value, start: v };
|
||||
dispatch(fieldNumberCollectionValueChanged({ nodeId, fieldName, value: newValue }));
|
||||
},
|
||||
[dispatch, fieldName, nodeId, value]
|
||||
);
|
||||
const onChangeCount = useCallback(
|
||||
(v: number) => {
|
||||
const newValue = { ...value, count: v };
|
||||
dispatch(fieldNumberCollectionValueChanged({ nodeId, fieldName, value: newValue }));
|
||||
},
|
||||
[dispatch, fieldName, nodeId, value]
|
||||
);
|
||||
const onChangeStep = useCallback(
|
||||
(v: number) => {
|
||||
const newValue = { ...value, step: v };
|
||||
dispatch(fieldNumberCollectionValueChanged({ nodeId, fieldName, value: newValue }));
|
||||
},
|
||||
[dispatch, fieldName, nodeId, value]
|
||||
);
|
||||
|
||||
return (
|
||||
<Flex gap={2}>
|
||||
<FormControl>
|
||||
<FormLabel m={0}>Start</FormLabel>
|
||||
<CompositeNumberInput value={value.start} onChange={onChangeStart} min={-Infinity} max={Infinity} />
|
||||
</FormControl>
|
||||
<FormControl>
|
||||
<FormLabel m={0}>Count</FormLabel>
|
||||
<CompositeNumberInput value={value.count} onChange={onChangeCount} min={1} max={Infinity} />
|
||||
</FormControl>
|
||||
<FormControl>
|
||||
<FormLabel m={0}>Step</FormLabel>
|
||||
<CompositeNumberInput
|
||||
value={value.step}
|
||||
onChange={onChangeStep}
|
||||
min={-Infinity}
|
||||
max={Infinity}
|
||||
step={isIntegerField ? 1 : 0.1}
|
||||
/>
|
||||
</FormControl>
|
||||
</Flex>
|
||||
);
|
||||
};
|
||||
|
||||
const ManualEntry = ({
|
||||
nodeId,
|
||||
fieldName,
|
||||
value,
|
||||
fieldTemplate,
|
||||
}: {
|
||||
nodeId: string;
|
||||
fieldName: string;
|
||||
value: number[];
|
||||
fieldTemplate: IntegerFieldCollectionInputTemplate | FloatFieldCollectionInputTemplate;
|
||||
}) => {
|
||||
const dispatch = useAppDispatch();
|
||||
const isIntegerField = useMemo(() => fieldTemplate.type.name === 'IntegerField', [fieldTemplate.type]);
|
||||
|
||||
const onRemoveNumber = useCallback(
|
||||
(index: number) => {
|
||||
const newValue = [...value];
|
||||
newValue.splice(index, 1);
|
||||
dispatch(fieldNumberCollectionValueChanged({ nodeId, fieldName, value: newValue }));
|
||||
},
|
||||
[value, dispatch, nodeId, fieldName]
|
||||
);
|
||||
|
||||
const onChangeNumber = useCallback(
|
||||
(index: number, num: number) => {
|
||||
const newValue = [...value];
|
||||
newValue[index] = num;
|
||||
dispatch(fieldNumberCollectionValueChanged({ nodeId, fieldName, value: newValue }));
|
||||
},
|
||||
[value, dispatch, nodeId, fieldName]
|
||||
);
|
||||
|
||||
const min = useMemo(() => {
|
||||
let min = -NUMPY_RAND_MAX;
|
||||
if (!isNil(fieldTemplate.minimum)) {
|
||||
min = fieldTemplate.minimum;
|
||||
}
|
||||
if (!isNil(fieldTemplate.exclusiveMinimum)) {
|
||||
min = fieldTemplate.exclusiveMinimum + 0.01;
|
||||
}
|
||||
return min;
|
||||
}, [fieldTemplate.exclusiveMinimum, fieldTemplate.minimum]);
|
||||
|
||||
const max = useMemo(() => {
|
||||
let max = NUMPY_RAND_MAX;
|
||||
if (!isNil(fieldTemplate.maximum)) {
|
||||
max = fieldTemplate.maximum;
|
||||
}
|
||||
if (!isNil(fieldTemplate.exclusiveMaximum)) {
|
||||
max = fieldTemplate.exclusiveMaximum - 0.01;
|
||||
}
|
||||
return max;
|
||||
}, [fieldTemplate.exclusiveMaximum, fieldTemplate.maximum]);
|
||||
|
||||
const step = useMemo(() => {
|
||||
if (isNil(fieldTemplate.multipleOf)) {
|
||||
return isIntegerField ? 1 : 0.1;
|
||||
}
|
||||
return fieldTemplate.multipleOf;
|
||||
}, [fieldTemplate.multipleOf, isIntegerField]);
|
||||
|
||||
const fineStep = useMemo(() => {
|
||||
if (isNil(fieldTemplate.multipleOf)) {
|
||||
return isIntegerField ? 1 : 0.01;
|
||||
}
|
||||
return fieldTemplate.multipleOf;
|
||||
}, [fieldTemplate.multipleOf, isIntegerField]);
|
||||
|
||||
return (
|
||||
<Box w="full" h="full">
|
||||
<OverlayScrollbarsComponent
|
||||
className="nowheel"
|
||||
defer
|
||||
style={overlayScrollbarsStyles}
|
||||
options={overlayscrollbarsOptions}
|
||||
>
|
||||
<Grid w="full" h="full" templateColumns="repeat(1fr)" gap={1}>
|
||||
{value.map((value, index) => (
|
||||
<GridItem key={index} position="relative" className="nodrag">
|
||||
<NumberListItemContent
|
||||
value={value}
|
||||
index={index}
|
||||
min={min}
|
||||
max={max}
|
||||
step={step}
|
||||
fineStep={fineStep}
|
||||
isIntegerField={isIntegerField}
|
||||
onRemoveNumber={onRemoveNumber}
|
||||
onChangeNumber={onChangeNumber}
|
||||
/>
|
||||
</GridItem>
|
||||
))}
|
||||
</Grid>
|
||||
</OverlayScrollbarsComponent>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
type NumberListItemContentProps = {
|
||||
value: number;
|
||||
index: number;
|
||||
|
||||
@@ -15,7 +15,6 @@ import type {
|
||||
ControlNetModelFieldValue,
|
||||
EnumFieldValue,
|
||||
FieldValue,
|
||||
FloatFieldCollectionValue,
|
||||
FloatFieldValue,
|
||||
FluxVAEModelFieldValue,
|
||||
ImageFieldCollectionValue,
|
||||
@@ -323,10 +322,7 @@ export const nodesSlice = createSlice({
|
||||
fieldNumberValueChanged: (state, action: FieldValueAction<IntegerFieldValue | FloatFieldValue>) => {
|
||||
fieldValueReducer(state, action, zIntegerFieldValue.or(zFloatFieldValue));
|
||||
},
|
||||
fieldNumberCollectionValueChanged: (
|
||||
state,
|
||||
action: FieldValueAction<IntegerFieldCollectionValue | FloatFieldCollectionValue>
|
||||
) => {
|
||||
fieldNumberCollectionValueChanged: (state, action: FieldValueAction<IntegerFieldCollectionValue>) => {
|
||||
fieldValueReducer(state, action, zIntegerFieldCollectionValue.or(zFloatFieldCollectionValue));
|
||||
},
|
||||
fieldBooleanValueChanged: (state, action: FieldValueAction<BooleanFieldValue>) => {
|
||||
|
||||
@@ -279,17 +279,7 @@ export const isIntegerFieldInputTemplate = buildTypeGuard(zIntegerFieldInputTemp
|
||||
// #endregion
|
||||
|
||||
// #region IntegerField Collection
|
||||
const zIntegerStartStepCountGenerator = z.object({
|
||||
type: z.literal('integer-start-step-count-generator'),
|
||||
start: z.number().int(),
|
||||
step: z.number().int(),
|
||||
count: z.number().int().gte(1),
|
||||
});
|
||||
export type IntegerStartStepCountGenerator = z.infer<typeof zIntegerStartStepCountGenerator>;
|
||||
export const isIntegerStartStepCountGenerator = buildTypeGuard(zIntegerStartStepCountGenerator);
|
||||
export const zIntegerFieldCollectionValue = z
|
||||
.union([z.array(zIntegerFieldValue), zIntegerStartStepCountGenerator])
|
||||
.optional();
|
||||
export const zIntegerFieldCollectionValue = z.array(zIntegerFieldValue).optional();
|
||||
const zIntegerFieldCollectionInputInstance = zFieldInputInstanceBase.extend({
|
||||
value: zIntegerFieldCollectionValue,
|
||||
});
|
||||
@@ -327,6 +317,7 @@ export const isIntegerFieldCollectionInputTemplate = buildTypeGuard(zIntegerFiel
|
||||
// #endregion
|
||||
|
||||
// #region FloatField
|
||||
|
||||
export const zFloatFieldValue = z.number();
|
||||
const zFloatFieldInputInstance = zFieldInputInstanceBase.extend({
|
||||
value: zFloatFieldValue,
|
||||
@@ -352,17 +343,7 @@ export const isFloatFieldInputTemplate = buildTypeGuard(zFloatFieldInputTemplate
|
||||
// #endregion
|
||||
|
||||
// #region FloatField Collection
|
||||
const zFloatStartStepCountGenerator = z.object({
|
||||
type: z.literal('float-start-step-count-generator'),
|
||||
start: z.number(),
|
||||
step: z.number(),
|
||||
count: z.number().gte(1),
|
||||
});
|
||||
export type FloatStartStepCountGenerator = z.infer<typeof zFloatStartStepCountGenerator>;
|
||||
export const isFloatStartStepCountGenerator = buildTypeGuard(zFloatStartStepCountGenerator);
|
||||
export const zFloatFieldCollectionValue = z
|
||||
.union([z.array(zFloatFieldValue), zFloatStartStepCountGenerator])
|
||||
.optional();
|
||||
export const zFloatFieldCollectionValue = z.array(zFloatFieldValue).optional();
|
||||
const zFloatFieldCollectionInputInstance = zFieldInputInstanceBase.extend({
|
||||
value: zFloatFieldCollectionValue,
|
||||
});
|
||||
|
||||
@@ -8,7 +8,6 @@ import type {
|
||||
StringFieldCollectionInputTemplate,
|
||||
StringFieldCollectionValue,
|
||||
} from 'features/nodes/types/field';
|
||||
import { numberStartStepCountGenerator } from 'features/nodes/types/generators';
|
||||
import { t } from 'i18next';
|
||||
|
||||
export const validateImageFieldCollectionValue = (
|
||||
@@ -68,24 +67,12 @@ export const validateStringFieldCollectionValue = (
|
||||
return reasons;
|
||||
};
|
||||
|
||||
export const getNumberFieldCollectionValue = (
|
||||
fieldValue: NonNullable<IntegerFieldCollectionValue> | NonNullable<FloatFieldCollectionValue>
|
||||
): number[] => {
|
||||
if (Array.isArray(fieldValue)) {
|
||||
return fieldValue;
|
||||
}
|
||||
return numberStartStepCountGenerator(fieldValue);
|
||||
};
|
||||
|
||||
export const validateNumberFieldCollectionValue = (
|
||||
fieldValue: NonNullable<IntegerFieldCollectionValue> | NonNullable<FloatFieldCollectionValue>,
|
||||
value: NonNullable<IntegerFieldCollectionValue> | NonNullable<FloatFieldCollectionValue>,
|
||||
template: IntegerFieldCollectionInputTemplate | FloatFieldCollectionInputTemplate
|
||||
): string[] => {
|
||||
const reasons: string[] = [];
|
||||
const { minItems, maxItems, minimum, maximum, exclusiveMinimum, exclusiveMaximum, multipleOf } = template;
|
||||
|
||||
const value = getNumberFieldCollectionValue(fieldValue);
|
||||
|
||||
const count = value.length;
|
||||
|
||||
// Image collections may have min or max items to validate
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
import type { FloatStartStepCountGenerator, IntegerStartStepCountGenerator } from 'features/nodes/types/field';
|
||||
|
||||
export const numberStartStepCountGenerator = ({
|
||||
start,
|
||||
step,
|
||||
count,
|
||||
}: FloatStartStepCountGenerator | IntegerStartStepCountGenerator): number[] => {
|
||||
return Array.from({ length: count }, (_, i) => start + i * step);
|
||||
};
|
||||
Reference in New Issue
Block a user