movpushmov / effector-reform

MIT License
18 stars 2 forks source link

сторы с пользовательскими данными для формы, полей, групп полей и списков полей #8

Closed xaota closed 1 month ago

xaota commented 5 months ago

Речь идет про сторы ал-ля $meta.

Обычно в других либах либо сама форма содержит мету и / или каждое поле содержит мету типа any

Но это неудобно как раз из-за того что способы разные воздействия на поля и на списки (потому что они обычно никакой $meta не имеют) и для унификации разработчикам приходится делать свои сторы которые в основном заняты обработкой вспомогательных вещей для формы, а не про бизнес-логику. Итого - в реальности это приводит к появлению стороннего стора рядом с формой типа Record<string, {...}> где ключами является path до поля и обычно с ними надо динамически работать, а такая конструкция неоптимальна и требует нормальной такой обвязки на реакции на что-то там в форме


Идея - добавить $meta в форму, в поля и в arrayField, причем организовать доступ до нее через fields (примерно как до значения поля)

const form = createForm<Values, FormMeta = any>({ schema, meta });

// если создавать поля через конструкторы, то для каждого поля можно прокинуть свою типизацию для $meta
// по-умолчанию any
const field = createField<Value, FieldMeta = any>(initialValue, initialMeta);
const arrayField = createArrayField<Value, ArrayFieldMeta = any>([], initialMeta); 

Что можно хранить в $meta? обычно всякие разные вспомогательные вещи, типа заблокировано поле или нет, спрятано поле или нет, удалено поле или нет (чтобы физически удалять его секунд через 10, если пользователь не нажал во всплывашке "отмена") и так далее;

пример

sample({
  clock: form.fields.useDefaultAddress.changed,
  filter: Boolean,
  source: form.fields.addresses.$meta,
  fn: meta => ({ ...meta, disabled: true }),
  target: form.fields.addresses.setMeta
});

если поставили галочку "использовать адрес доставки по умолчанию" грубо говоря блочим весь список где можно добавлять новые адреса


Если это будет для списков и групп полей это будет прям киллер фича, потому что у остальных форм есть только для полей, или полей в списках и группах, а для самых групп и самих списков надо всегда прикостыливать слева


в react пакете очень хочется достать мету просто вызвав useField или useArrayField

пример

const { value, onChange, meta } = useField(field);
...
return (
  <input
    value={field.value}
    onChange={(event) => field.onChange(event.currentTarget.value)}
    disabled={meta.disabled}
  />
);

пример с ArrayField

const { values, meta } = useArrayField(arrayField);
...
return (
  <div hidden={meta.hidden}>
    {values.map(...)}
  </div>
);
movpushmov commented 1 month ago

Реализовано в 97c9c8cee81a1c2ff8be5df62ced478d1314f6aa