@elcrm/form 0.1.8 → 0.1.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (62) hide show
  1. package/README.md +3 -2
  2. package/dist/assets/styles/Field.module.css +1 -1
  3. package/dist/assets/styles/Search.module.css +1 -0
  4. package/dist/assets/styles/Tabs.module.css +1 -1
  5. package/dist/core/Field.js +1 -1
  6. package/dist/dark.css +10 -1
  7. package/dist/fields/Check.d.ts +2 -2
  8. package/dist/fields/Check.js +1 -1
  9. package/dist/fields/Color.d.ts +1 -1
  10. package/dist/fields/Color.js +1 -1
  11. package/dist/fields/Date.d.ts +1 -1
  12. package/dist/fields/Date.js +1 -1
  13. package/dist/fields/DragDrop.d.ts +1 -1
  14. package/dist/fields/DragDrop.js +1 -1
  15. package/dist/fields/FieldGroup.d.ts +8 -1
  16. package/dist/fields/FieldGroup.js +1 -1
  17. package/dist/fields/File.d.ts +1 -1
  18. package/dist/fields/File.js +1 -1
  19. package/dist/fields/Mask.d.ts +1 -1
  20. package/dist/fields/Mask.js +1 -1
  21. package/dist/fields/Modal.d.ts +3 -2
  22. package/dist/fields/Modal.js +1 -1
  23. package/dist/fields/Money.d.ts +1 -1
  24. package/dist/fields/Money.js +1 -1
  25. package/dist/fields/Options.d.ts +3 -2
  26. package/dist/fields/Options.js +1 -1
  27. package/dist/fields/Password.js +1 -1
  28. package/dist/fields/Percent.d.ts +1 -1
  29. package/dist/fields/Percent.js +1 -1
  30. package/dist/fields/Phone.d.ts +1 -1
  31. package/dist/fields/Phone.js +1 -1
  32. package/dist/fields/Radio.d.ts +1 -1
  33. package/dist/fields/Radio.js +1 -1
  34. package/dist/fields/Range.d.ts +1 -1
  35. package/dist/fields/Range.js +1 -1
  36. package/dist/fields/Rating.d.ts +1 -1
  37. package/dist/fields/Rating.js +1 -1
  38. package/dist/fields/RichText.d.ts +1 -1
  39. package/dist/fields/RichText.js +1 -1
  40. package/dist/fields/Search.d.ts +61 -0
  41. package/dist/fields/Search.js +1 -0
  42. package/dist/fields/SearchSuggestions.d.ts +26 -0
  43. package/dist/fields/SearchSuggestions.js +1 -0
  44. package/dist/fields/Tabs.d.ts +16 -6
  45. package/dist/fields/Tabs.js +1 -1
  46. package/dist/fields/Tags.d.ts +1 -1
  47. package/dist/fields/Tags.js +1 -1
  48. package/dist/fields/Time.d.ts +1 -1
  49. package/dist/fields/Time.js +1 -1
  50. package/dist/fields/searchAnnounce.d.ts +2 -0
  51. package/dist/fields/searchAnnounce.js +1 -0
  52. package/dist/fields/searchHotkey.d.ts +5 -0
  53. package/dist/fields/searchHotkey.js +1 -0
  54. package/dist/index.d.ts +3 -1
  55. package/dist/index.js +2 -2
  56. package/dist/index.umd.js +3 -3
  57. package/dist/light.css +10 -1
  58. package/dist/package.js +1 -1
  59. package/dist/style.css +2 -2
  60. package/dist/styles/Field.module.js +1 -1
  61. package/dist/styles/Search.module.js +1 -0
  62. package/package.json +1 -1
@@ -18,7 +18,7 @@ export type TMoney = TInput & {
18
18
  /**
19
19
  * Поле суммы. Клавиатура `decimal`.
20
20
  */
21
- declare function MoneyField({ value, form, onValue, name, placeholder, label, error, hidden, disabled, onBlur: onBlurField, className, after, before, inputmode, course, view, type, isClear, }: TMoney): import("react/jsx-runtime").JSX.Element | "";
21
+ declare function MoneyField({ value, form, onValue, name, placeholder, label, error, hidden, disabled, onBlur: onBlurField, className, after, before, inputmode, course, view, type, isClear, size, }: TMoney): import("react/jsx-runtime").JSX.Element | "";
22
22
  declare namespace MoneyField {
23
23
  var displayName: string;
24
24
  }
@@ -1 +1 @@
1
- import e from"../styles/Field.module.js";import t from"../core/Field.js";import{useFormFieldState as n}from"../hooks/use.js";import{createFieldEmit as r}from"./emit.js";import i,{pastePlainTextIntoSelection as a}from"../events/onEvent.js";import{isEmptyTextLike as o}from"./visibility.js";import s from"react";import{jsx as c,jsxs as l}from"react/jsx-runtime";function u(e){let t=window.getSelection();if(!t||t.rangeCount===0)return 0;let n=t.getRangeAt(0);if(!e.contains(n.startContainer))return 0;let r=document.createRange();return r.selectNodeContents(e),r.setEnd(n.startContainer,n.startOffset),r.toString().length}function d(e,t,n){let r=Math.max(0,Math.min(t,e.length));return n(e.slice(0,r)).length}function f({value:f,form:m,onValue:h,name:g=``,placeholder:_=``,label:v=``,error:y=``,hidden:b=!1,disabled:x=!1,onBlur:S,className:C=``,after:w=``,before:T=``,inputmode:E=`decimal`,course:D=100,view:O,type:k,isClear:A=!1}){let{value:j,version:M}=n(m,g||``,f),N=m&&g?j:f,P=s.useRef(null),F=s.useRef(!1);s.useLayoutEffect(()=>{if(F.current)return;let e=P.current;if(!e)return;let t=N!=null&&(typeof N==`number`?!0:!o(String(N))),n=!_||t?p(N??``,D):``;e.textContent!==n&&(e.textContent=n)},[N,M,_,D]);let I=e=>k===`multi`?e.replace(/[^+\d.+-]/g,``):e.replace(/[^+\d.]/g,``),L=(e,t)=>{let n=t.firstChild;if(!n||n.nodeType!==Node.TEXT_NODE)return;let r=n.textContent?.length??0,i=Math.max(0,Math.min(e,r)),a=document.createRange(),o=window.getSelection();o&&(a.setStart(n,i),a.collapse(!0),o.removeAllRanges(),o.addRange(a),t.focus())},R=r(m,g,h),z=e=>{let t=e.target,n=t.textContent||``,r=u(t),i=I(n),a=d(n,r,I);R(Number(i||0)*D),t.textContent=i,i.length>0&&queueMicrotask(()=>{L(Math.min(a,i.length),t)})},B=e=>{let t=e.target;i.Blur(e),(t.textContent||``)===``&&(t.textContent=`0`);let n=Number(I(t.textContent||``))*D;R(n,!0),S?.({value:n,name:g}),t.textContent=p(I(t.textContent||``).trim()||`0`),F.current=!1},V=e=>{F.current=!0;let t=e.target;t.textContent=I(t.textContent||``),i.Focus({target:e.currentTarget})},H=e=>{let t=e.currentTarget.previousElementSibling;t&&(t.textContent=``),R(0,!0)},U=e=>{e.key===`Enter`&&e.preventDefault()},W=e=>{e.preventDefault(),a(I(e.clipboardData?.getData(`text/plain`)??``),e.currentTarget)},G=!x,K=N==null||(typeof N==`number`?!1:o(String(N??``)));if(b&&K)return``;let q={};return q.inputMode=E??`decimal`,_&&(q.placeholder=_),G&&(q.edit=``),l(t,{type:`input`,label:v,error:y,element_blok:{className:[C]},element_input:{className:[e.w],props:{"data-disabled":x||!G?`true`:void 0}},children:[T?c(`span`,{className:e.a,children:T}):null,c(`div`,{ref:P,...q,onInput:z,onPaste:W,onBlur:B,onKeyDown:U,onFocus:V,role:`textbox`,spellCheck:!1,"aria-label":v||_||`Сумма`,"aria-disabled":!G,tabIndex:x?-1:0,contentEditable:G?`plaintext-only`:!1,suppressContentEditableWarning:!0}),A&&c(`button`,{type:`button`,onClick:H,"aria-label":`Очистить поле`,children:`x`}),w?c(`span`,{className:e.a,children:w}):null]})}f.displayName=`MoneyField`;function p(e,t){let n;if(typeof e==`string`){let t=e.replace(/\s/g,``).replace(`,`,`.`);n=parseFloat(t===``?`0`:t)}else n=Number(e??0);return Number.isNaN(n)&&(n=0),t!=null&&t>0&&(n/=t),n.toFixed(2).replace(/(\d)(?=(\d{3})+\.)/g,`$1 `)}export{f as default};
1
+ import e from"../styles/Field.module.js";import t from"../core/Field.js";import{useFormFieldState as n}from"../hooks/use.js";import{createFieldEmit as r}from"./emit.js";import i,{pastePlainTextIntoSelection as a}from"../events/onEvent.js";import{isEmptyTextLike as o}from"./visibility.js";import s from"react";import{jsx as c,jsxs as l}from"react/jsx-runtime";function u(e){let t=window.getSelection();if(!t||t.rangeCount===0)return 0;let n=t.getRangeAt(0);if(!e.contains(n.startContainer))return 0;let r=document.createRange();return r.selectNodeContents(e),r.setEnd(n.startContainer,n.startOffset),r.toString().length}function d(e,t,n){let r=Math.max(0,Math.min(t,e.length));return n(e.slice(0,r)).length}function f({value:f,form:m,onValue:h,name:g=``,placeholder:_=``,label:v=``,error:y=``,hidden:b=!1,disabled:x=!1,onBlur:S,className:C=``,after:w=``,before:T=``,inputmode:E=`decimal`,course:D=100,view:O,type:k,isClear:A=!1,size:j=`m`}){let{value:M,version:N}=n(m,g||``,f),P=m&&g?M:f,F=s.useRef(null),I=s.useRef(!1);s.useLayoutEffect(()=>{if(I.current)return;let e=F.current;if(!e)return;let t=P!=null&&(typeof P==`number`?!0:!o(String(P))),n=!_||t?p(P??``,D):``;e.textContent!==n&&(e.textContent=n)},[P,N,_,D]);let L=e=>k===`multi`?e.replace(/[^+\d.+-]/g,``):e.replace(/[^+\d.]/g,``),R=(e,t)=>{let n=t.firstChild;if(!n||n.nodeType!==Node.TEXT_NODE)return;let r=n.textContent?.length??0,i=Math.max(0,Math.min(e,r)),a=document.createRange(),o=window.getSelection();o&&(a.setStart(n,i),a.collapse(!0),o.removeAllRanges(),o.addRange(a),t.focus())},z=r(m,g,h),B=e=>{let t=e.target,n=t.textContent||``,r=u(t),i=L(n),a=d(n,r,L);z(Number(i||0)*D),t.textContent=i,i.length>0&&queueMicrotask(()=>{R(Math.min(a,i.length),t)})},V=e=>{let t=e.target;i.Blur(e),(t.textContent||``)===``&&(t.textContent=`0`);let n=Number(L(t.textContent||``))*D;z(n,!0),S?.({value:n,name:g}),t.textContent=p(L(t.textContent||``).trim()||`0`),I.current=!1},H=e=>{I.current=!0;let t=e.target;t.textContent=L(t.textContent||``),i.Focus({target:e.currentTarget})},U=e=>{let t=e.currentTarget.previousElementSibling;t&&(t.textContent=``),z(0,!0)},W=e=>{e.key===`Enter`&&e.preventDefault()},G=e=>{e.preventDefault(),a(L(e.clipboardData?.getData(`text/plain`)??``),e.currentTarget)},K=!x,q=P==null||(typeof P==`number`?!1:o(String(P??``)));if(b&&q)return``;let J={};return J.inputMode=E??`decimal`,_&&(J.placeholder=_),K&&(J.edit=``),l(t,{type:`input`,label:v,error:y,size:j,element_blok:{className:[C]},element_input:{className:[e.w],props:{"data-disabled":x||!K?`true`:void 0}},children:[T?c(`span`,{className:e.a,children:T}):null,c(`div`,{ref:F,...J,onInput:B,onPaste:G,onBlur:V,onKeyDown:W,onFocus:H,role:`textbox`,spellCheck:!1,"aria-label":v||_||`Сумма`,"aria-disabled":!K,tabIndex:x?-1:0,contentEditable:K?`plaintext-only`:!1,suppressContentEditableWarning:!0}),A&&c(`button`,{type:`button`,onClick:U,"aria-label":`Очистить поле`,children:`x`}),w?c(`span`,{className:e.a,children:w}):null]})}f.displayName=`MoneyField`;function p(e,t){let n;if(typeof e==`string`){let t=e.replace(/\s/g,``).replace(`,`,`.`);n=parseFloat(t===``?`0`:t)}else n=Number(e??0);return Number.isNaN(n)&&(n=0),t!=null&&t>0&&(n/=t),n.toFixed(2).replace(/(\d)(?=(\d{3})+\.)/g,`$1 `)}export{f as default};
@@ -1,6 +1,6 @@
1
1
  import { ReactNode } from 'react';
2
2
  import { UseFormApi } from '../hooks/use';
3
- import { TValue } from './type';
3
+ import { TInput, TValue } from './type';
4
4
  /**
5
5
  * Выбор через модалку приложения (`Form.Init.onModal`).
6
6
  *
@@ -28,6 +28,7 @@ export type TOptions = {
28
28
  before?: ReactNode;
29
29
  view?: string;
30
30
  className?: string;
31
+ size?: TInput["size"];
31
32
  /** Имя модуля модалки, если `modal` без точки */
32
33
  module?: string;
33
34
  /** `"module.modalName"` или имя модалки вместе с `module` */
@@ -44,7 +45,7 @@ export type TOptions = {
44
45
  /**
45
46
  * Список выбранных значений; клик по капсуле открывает модалку приложения.
46
47
  */
47
- declare function OptionsField({ value, form, onValue, name, placeholder, separator, label, error, hidden, disabled, outFormat, after, before, modal, options, className, }: TOptions): import("react/jsx-runtime").JSX.Element;
48
+ declare function OptionsField({ value, form, onValue, name, placeholder, separator, label, error, hidden, disabled, outFormat, after, before, modal, options, className, size, }: TOptions): import("react/jsx-runtime").JSX.Element;
48
49
  declare namespace OptionsField {
49
50
  var displayName: string;
50
51
  }
@@ -1 +1 @@
1
- import e from"../styles/Field.module.js";import t from"../core/Field.js";import{useFormFieldState as n}from"../hooks/use.js";import{createFieldEmit as r}from"./emit.js";import{useFormInit as i}from"../FormInitContext.js";import{Fragment as a,jsx as o,jsxs as s}from"react/jsx-runtime";var c=(e,t=`,`)=>(e!==void 0&&e!==``?e.split(t):[]).filter(e=>e!==``).reduce((e,t)=>(e[t]=!0,e),{});function l({value:l,form:u,onValue:d,name:f,placeholder:p=``,separator:m=`,`,label:h,error:g,hidden:_=!1,disabled:v=!1,outFormat:y=`object`,after:b,before:x,modal:S,options:C,className:w}){let{onModal:T}=i(),{value:E}=n(u,f,l),D=E,O=typeof D==`string`?c(D,m):D&&typeof D==`object`?D:{},k=()=>{if(v||!S)return;let e=S.split(`.`);T({module:e[0],modalName:e[1],callback:e=>{let t=e,n=y===`array`?Object.keys(t):y===`string`?Object.keys(t).filter(e=>t[e]).join(m):t;r(u,f,d)(n,!0)},onValue:d,options:C,fieldName:f,value:O})},A={};p&&(A.placeholder=p);let j=Object.keys(O).length===0;return _&&j?o(a,{}):s(t,{type:`options`,label:h,error:g,element_blok:{className:[w||``]},element_input:{className:[e.g],props:{onClick:k,"data-disabled":v?`true`:void 0}},children:[x?o(`span`,{className:e.a,children:x}):null,Object.keys(O).map(e=>o(`div`,{children:C?.[e]?.label},e)),b?o(`span`,{className:e.a,children:b}):null]})}l.displayName=`OptionsField`;export{l as default};
1
+ import e from"../styles/Field.module.js";import t from"../core/Field.js";import{useFormFieldState as n}from"../hooks/use.js";import{createFieldEmit as r}from"./emit.js";import{useFormInit as i}from"../FormInitContext.js";import{Fragment as a,jsx as o,jsxs as s}from"react/jsx-runtime";var c=(e,t=`,`)=>(e!==void 0&&e!==``?e.split(t):[]).filter(e=>e!==``).reduce((e,t)=>(e[t]=!0,e),{});function l({value:l,form:u,onValue:d,name:f,placeholder:p=``,separator:m=`,`,label:h,error:g,hidden:_=!1,disabled:v=!1,outFormat:y=`object`,after:b,before:x,modal:S,options:C,className:w,size:T=`m`}){let{onModal:E}=i(),{value:D}=n(u,f,l),O=D,k=typeof O==`string`?c(O,m):O&&typeof O==`object`?O:{},A=()=>{if(v||!S)return;let e=S.split(`.`);E({module:e[0],modalName:e[1],callback:e=>{let t=e,n=y===`array`?Object.keys(t):y===`string`?Object.keys(t).filter(e=>t[e]).join(m):t;r(u,f,d)(n,!0)},onValue:d,options:C,fieldName:f,value:k})},j={};p&&(j.placeholder=p);let M=Object.keys(k).length===0;return _&&M?o(a,{}):s(t,{type:`options`,label:h,error:g,size:T,element_blok:{className:[w||``]},element_input:{className:[e.g],props:{onClick:A,"data-disabled":v?`true`:void 0}},children:[x?o(`span`,{className:e.a,children:x}):null,Object.keys(k).map(e=>o(`div`,{children:C?.[e]?.label},e)),b?o(`span`,{className:e.a,children:b}):null]})}l.displayName=`OptionsField`;export{l as default};
@@ -1 +1 @@
1
- import e from"../styles/Field.module.js";import t,{useFieldA11y as n}from"../core/Field.js";import{useFormFieldState as r}from"../hooks/use.js";import{createFieldEmit as i}from"./emit.js";import a from"../events/onEvent.js";import{isEmptyTextLike as o}from"./visibility.js";import{generatePasswordValue as s,resolveGeneratePool as c}from"./passwordUtils.js";import l from"react";import{jsx as u,jsxs as d}from"react/jsx-runtime";function f(){return d(`svg`,{xmlns:`http://www.w3.org/2000/svg`,width:`20`,height:`20`,viewBox:`0 0 24 24`,fill:`none`,stroke:`currentColor`,strokeWidth:`2`,strokeLinecap:`round`,strokeLinejoin:`round`,"aria-hidden":!0,children:[u(`path`,{d:`M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z`}),u(`circle`,{cx:`12`,cy:`12`,r:`3`})]})}function p(){return d(`svg`,{xmlns:`http://www.w3.org/2000/svg`,width:`20`,height:`20`,viewBox:`0 0 24 24`,fill:`none`,stroke:`currentColor`,strokeWidth:`2`,strokeLinecap:`round`,strokeLinejoin:`round`,"aria-hidden":!0,children:[u(`path`,{d:`M17.94 17.94A10.07 10.07 0 0 1 12 20c-7 0-11-8-11-8a18.45 18.45 0 0 1 5.06-5.94M9.9 4.24A9.12 9.12 0 0 1 12 4c7 0 11 8 11 8a18.5 18.5 0 0 1-2.16 3.19m-6.72-1.07a3 3 0 1 1-4.24-4.24`}),u(`line`,{x1:`1`,y1:`1`,x2:`23`,y2:`23`})]})}function m({value:n,form:m,onValue:g,name:_=``,placeholder:v=``,label:y,error:b,hidden:x=!1,disabled:S=!1,onBlur:C,className:w,after:T=``,before:E=``,native:D=!1,maxLength:O,eyes:k,generate:A,id:j,size:M=`m`}){let{value:N}=r(m,_,n),[P,F]=l.useState(!1),I=l.useRef(null),L=typeof N==`string`?N:N==null?``:String(N);l.useEffect(()=>{let e=I.current;e&&e.value!==L&&(e.value=L)},[L]);let R=i(m,_,g),z=e=>{R(e.target.value)},B=e=>{e.key===`Enter`&&e.preventDefault()},V=e=>{a.Blur(e),C?.({value:(e.target.value||``).trim(),name:_||``})};if(D)return``;let H=!S;if(x&&o(L))return``;let U=k?.[0]??u(f,{}),W=k?.[1]??u(p,{}),G=c(A),K=O??12,[q,J]=l.useState(0);return d(t,{type:`input`,label:y,error:b,id:j,size:M,element_blok:{className:[w||``]},element_input:{className:[e.w],props:{"data-disabled":S||!H?`true`:void 0}},children:[E?u(`span`,{className:e.a,children:E}):null,u(h,{inputRef:I,passwordVisible:P,currentValue:L,disabled:S,editable:H,maxLength:O,placeholder:v,label:y,onChangeInput:z,keyDown:B,handleBlur:V}),G?u(`button`,{type:`button`,className:e.a,tabIndex:S?-1:0,disabled:S,"aria-label":`Сгенерировать пароль`,title:`Сгенерировать пароль`,onClick:()=>{!H||!G||(J(e=>e+1),R(s(G,K),!0),I.current?.focus())},children:d(`svg`,{className:q>0?e.spin:void 0,fill:`none`,stroke:`currentColor`,strokeLinecap:`round`,strokeLinejoin:`round`,strokeWidth:`1.5`,viewBox:`0 0 24 24`,children:[u(`path`,{d:`m18.75 6.938-.99-1.152A8.973 8.973 0 0 0 11.25 3c-4.969 0-9 4.031-9 9s4.031 9 9 9a9.004 9.004 0 0 0 8.488-6`}),u(`path`,{fill:`currentColor`,stroke:`none`,d:`M21.75 4.565v5.183a.75.75 0 0 1-.75.75h-5.184a.75.75 0 0 1-.53-1.28l5.184-5.184a.75.75 0 0 1 1.28.53Z`})]},q)}):null,u(`button`,{type:`button`,className:e.a,tabIndex:S?-1:0,"aria-label":P?`Скрыть пароль`:`Показать пароль`,"aria-pressed":P,disabled:S,onClick:()=>!S&&F(!P),children:P?W:U}),T?u(`span`,{className:e.a,children:T}):null]})}function h({inputRef:t,passwordVisible:r,currentValue:i,disabled:a,editable:o,maxLength:s,placeholder:c,label:l,onChangeInput:d,keyDown:f,handleBlur:p}){let m=n();return u(`div`,{className:e.x,children:u(`input`,{id:m?.controlId,className:e.y,type:r?`text`:`password`,defaultValue:i,ref:t,onChange:d,onKeyDown:f,onBlur:p,disabled:a,readOnly:a,maxLength:s,spellCheck:!1,autoComplete:`current-password`,"aria-label":l?void 0:c||`Пароль`,"aria-describedby":m?.describedBy,"aria-invalid":m?.errorId?!0:void 0,"aria-disabled":a||!o,tabIndex:a?-1:0,placeholder:c})})}m.displayName=`PasswordField`;export{m as default};
1
+ import e from"../styles/Field.module.js";import t,{useFieldA11y as n}from"../core/Field.js";import{useFormFieldState as r}from"../hooks/use.js";import{createFieldEmit as i}from"./emit.js";import a from"../events/onEvent.js";import{isEmptyTextLike as o}from"./visibility.js";import{generatePasswordValue as s,resolveGeneratePool as c}from"./passwordUtils.js";import l from"react";import{jsx as u,jsxs as d}from"react/jsx-runtime";function f(){return d(`svg`,{xmlns:`http://www.w3.org/2000/svg`,width:`20`,height:`20`,viewBox:`0 0 24 24`,fill:`none`,stroke:`currentColor`,strokeWidth:`2`,strokeLinecap:`round`,strokeLinejoin:`round`,"aria-hidden":!0,children:[u(`path`,{d:`M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z`}),u(`circle`,{cx:`12`,cy:`12`,r:`3`})]})}function p(){return d(`svg`,{xmlns:`http://www.w3.org/2000/svg`,width:`20`,height:`20`,viewBox:`0 0 24 24`,fill:`none`,stroke:`currentColor`,strokeWidth:`2`,strokeLinecap:`round`,strokeLinejoin:`round`,"aria-hidden":!0,children:[u(`path`,{d:`M17.94 17.94A10.07 10.07 0 0 1 12 20c-7 0-11-8-11-8a18.45 18.45 0 0 1 5.06-5.94M9.9 4.24A9.12 9.12 0 0 1 12 4c7 0 11 8 11 8a18.5 18.5 0 0 1-2.16 3.19m-6.72-1.07a3 3 0 1 1-4.24-4.24`}),u(`line`,{x1:`1`,y1:`1`,x2:`23`,y2:`23`})]})}function m({value:n,form:m,onValue:g,name:_=``,placeholder:v=``,label:y,error:b,hidden:x=!1,disabled:S=!1,onBlur:C,className:w,after:T=``,before:E=``,native:D=!1,maxLength:O,eyes:k,generate:A,id:j,size:M=`m`}){let{value:N}=r(m,_,n),[P,F]=l.useState(!1),I=l.useRef(null),L=typeof N==`string`?N:N==null?``:String(N);l.useEffect(()=>{let e=I.current;e&&e.value!==L&&(e.value=L)},[L]);let R=i(m,_,g),z=e=>{R(e.target.value)},B=e=>{e.key===`Enter`&&e.preventDefault()},V=e=>{a.Blur(e),C?.({value:(e.target.value||``).trim(),name:_||``})};if(D)return``;let H=!S;if(x&&o(L))return``;let U=k?.[0]??u(f,{}),W=k?.[1]??u(p,{}),G=c(A),K=O??12,[q,J]=l.useState(0);return d(t,{type:`input`,label:y,error:b,id:j,size:M,element_blok:{className:[w||``]},element_input:{className:[e.w],props:{"data-disabled":S||!H?`true`:void 0}},children:[E?u(`span`,{className:e.a,children:E}):null,u(h,{inputRef:I,passwordVisible:P,currentValue:L,disabled:S,editable:H,maxLength:O,placeholder:v,label:y,onChangeInput:z,keyDown:B,handleBlur:V}),G?u(`button`,{type:`button`,className:e.a,tabIndex:S?-1:0,disabled:S,"aria-label":`Сгенерировать пароль`,title:`Сгенерировать пароль`,onClick:()=>{!H||!G||(J(e=>e+1),R(s(G,K),!0),I.current?.focus())},children:d(`svg`,{className:q>0?e.j:void 0,fill:`none`,stroke:`currentColor`,strokeLinecap:`round`,strokeLinejoin:`round`,strokeWidth:`1.5`,viewBox:`0 0 24 24`,children:[u(`path`,{d:`m18.75 6.938-.99-1.152A8.973 8.973 0 0 0 11.25 3c-4.969 0-9 4.031-9 9s4.031 9 9 9a9.004 9.004 0 0 0 8.488-6`}),u(`path`,{fill:`currentColor`,stroke:`none`,d:`M21.75 4.565v5.183a.75.75 0 0 1-.75.75h-5.184a.75.75 0 0 1-.53-1.28l5.184-5.184a.75.75 0 0 1 1.28.53Z`})]},q)}):null,u(`button`,{type:`button`,className:e.a,tabIndex:S?-1:0,"aria-label":P?`Скрыть пароль`:`Показать пароль`,"aria-pressed":P,disabled:S,onClick:()=>!S&&F(!P),children:P?W:U}),T?u(`span`,{className:e.a,children:T}):null]})}function h({inputRef:t,passwordVisible:r,currentValue:i,disabled:a,editable:o,maxLength:s,placeholder:c,label:l,onChangeInput:d,keyDown:f,handleBlur:p}){let m=n();return u(`div`,{className:e.x,children:u(`input`,{id:m?.controlId,className:e.y,type:r?`text`:`password`,defaultValue:i,ref:t,onChange:d,onKeyDown:f,onBlur:p,disabled:a,readOnly:a,maxLength:s,spellCheck:!1,autoComplete:`current-password`,"aria-label":l?void 0:c||`Пароль`,"aria-describedby":m?.describedBy,"aria-invalid":m?.errorId?!0:void 0,"aria-disabled":a||!o,tabIndex:a?-1:0,placeholder:c})})}m.displayName=`PasswordField`;export{m as default};
@@ -17,7 +17,7 @@ export type TPercent = TInput & {
17
17
  /**
18
18
  * Поле процента. Не путать с {@link NumberField} (там строка цифр).
19
19
  */
20
- declare function PercentField({ value, form, onValue, onBlur: onBlurField, name, placeholder, label, error, hidden, disabled, className, after, before, min, max, decimals, inputmode, }: TPercent): import("react/jsx-runtime").JSX.Element | null;
20
+ declare function PercentField({ value, form, onValue, onBlur: onBlurField, name, placeholder, label, error, hidden, disabled, className, after, before, min, max, decimals, inputmode, size, }: TPercent): import("react/jsx-runtime").JSX.Element | null;
21
21
  declare namespace PercentField {
22
22
  var displayName: string;
23
23
  }
@@ -1 +1 @@
1
- import e from"../styles/Field.module.js";import t from"../core/Field.js";import{useFormFieldState as n}from"../hooks/use.js";import{createFieldEmit as r}from"./emit.js";import i,{asEditableClipboard as a}from"../events/onEvent.js";import o from"react";import{jsx as s,jsxs as c}from"react/jsx-runtime";function l(e,t,n){return Number.isFinite(e)?Math.min(n,Math.max(t,e)):t}function u(e,t){let n=e.replace(`,`,`.`).replace(/[^\d.]/g,``);if(!n)return null;let r=Number(n);if(!Number.isFinite(r))return null;if(t<=0)return Math.round(r);let i=10**t;return Math.round(r*i)/i}function d(e,t){return Number.isFinite(e)?String(t<=0?Math.round(e):Number(e.toFixed(t))):``}function f({value:f=0,form:p,onValue:m,onBlur:h,name:g=``,placeholder:_=`0`,label:v=``,error:y=``,hidden:b=!1,disabled:x=!1,className:S=``,after:C,before:w=``,min:T=0,max:E=100,decimals:D=0,inputmode:O=`decimal`}){let{value:k,version:A}=n(p,g,f),j=!x,M=l(Number(k),T,E),N=k==null||k===``?``:d(M,D),P=o.useRef(null),F=o.useRef(!1);o.useLayoutEffect(()=>{if(F.current)return;let e=P.current;e&&e.textContent!==N&&(e.textContent=N)},[N,A]);let I=r(p,g,m),L=e=>{let t=(e.currentTarget.textContent||``).replace(/[^\d.,]/g,``);e.currentTarget.textContent!==t&&(e.currentTarget.textContent=t);let n=u(t,D);if(n===null){I(``);return}I(l(n,T,E))},R=e=>{i.Blur(e),F.current=!1;let t=u(e.currentTarget.textContent||``,D),n=t===null?T:l(t,T,E),r=d(n,D);e.currentTarget.textContent!==r&&(e.currentTarget.textContent=r),I(n,!0),h?.({value:n,name:g})};if(b&&(k==null||k===``))return null;let z={};return _&&(z.placeholder=_),j&&(z.edit=``),z.inputMode=O||`decimal`,c(t,{type:`percent`,label:v,error:y,element_blok:{className:[S||``]},element_input:{className:[e.w],props:{"data-disabled":x||!j?`true`:void 0}},children:[w?s(`span`,{className:e.a,children:w}):null,s(`div`,{ref:P,onInput:L,onFocus:e=>{F.current=!0,i.Focus({target:e.currentTarget})},onBlur:R,onPaste:e=>i.Paste(12,a(e)),onKeyDown:e=>{e.key===`Enter`&&e.preventDefault(),e.key.length===1&&!/[\d.,]/.test(e.key)&&!e.metaKey&&!e.ctrlKey&&e.preventDefault()},spellCheck:!1,role:`textbox`,tabIndex:j?0:-1,"aria-label":v||_||`Процент`,contentEditable:j?`plaintext-only`:!1,suppressContentEditableWarning:!0,...z}),C===void 0?s(`span`,{className:e.a,children:`%`}):s(`span`,{className:e.a,children:C})]})}f.displayName=`PercentField`;export{f as default};
1
+ import e from"../styles/Field.module.js";import t from"../core/Field.js";import{useFormFieldState as n}from"../hooks/use.js";import{createFieldEmit as r}from"./emit.js";import i,{asEditableClipboard as a}from"../events/onEvent.js";import o from"react";import{jsx as s,jsxs as c}from"react/jsx-runtime";function l(e,t,n){return Number.isFinite(e)?Math.min(n,Math.max(t,e)):t}function u(e,t){let n=e.replace(`,`,`.`).replace(/[^\d.]/g,``);if(!n)return null;let r=Number(n);if(!Number.isFinite(r))return null;if(t<=0)return Math.round(r);let i=10**t;return Math.round(r*i)/i}function d(e,t){return Number.isFinite(e)?String(t<=0?Math.round(e):Number(e.toFixed(t))):``}function f({value:f=0,form:p,onValue:m,onBlur:h,name:g=``,placeholder:_=`0`,label:v=``,error:y=``,hidden:b=!1,disabled:x=!1,className:S=``,after:C,before:w=``,min:T=0,max:E=100,decimals:D=0,inputmode:O=`decimal`,size:k=`m`}){let{value:A,version:j}=n(p,g,f),M=!x,N=l(Number(A),T,E),P=A==null||A===``?``:d(N,D),F=o.useRef(null),I=o.useRef(!1);o.useLayoutEffect(()=>{if(I.current)return;let e=F.current;e&&e.textContent!==P&&(e.textContent=P)},[P,j]);let L=r(p,g,m),R=e=>{let t=(e.currentTarget.textContent||``).replace(/[^\d.,]/g,``);e.currentTarget.textContent!==t&&(e.currentTarget.textContent=t);let n=u(t,D);if(n===null){L(``);return}L(l(n,T,E))},z=e=>{i.Blur(e),I.current=!1;let t=u(e.currentTarget.textContent||``,D),n=t===null?T:l(t,T,E),r=d(n,D);e.currentTarget.textContent!==r&&(e.currentTarget.textContent=r),L(n,!0),h?.({value:n,name:g})};if(b&&(A==null||A===``))return null;let B={};return _&&(B.placeholder=_),M&&(B.edit=``),B.inputMode=O||`decimal`,c(t,{type:`percent`,label:v,error:y,size:k,element_blok:{className:[S||``]},element_input:{className:[e.w],props:{"data-disabled":x||!M?`true`:void 0}},children:[w?s(`span`,{className:e.a,children:w}):null,s(`div`,{ref:F,onInput:R,onFocus:e=>{I.current=!0,i.Focus({target:e.currentTarget})},onBlur:z,onPaste:e=>i.Paste(12,a(e)),onKeyDown:e=>{e.key===`Enter`&&e.preventDefault(),e.key.length===1&&!/[\d.,]/.test(e.key)&&!e.metaKey&&!e.ctrlKey&&e.preventDefault()},spellCheck:!1,role:`textbox`,tabIndex:M?0:-1,"aria-label":v||_||`Процент`,contentEditable:M?`plaintext-only`:!1,suppressContentEditableWarning:!0,...B}),C===void 0?s(`span`,{className:e.a,children:`%`}):s(`span`,{className:e.a,children:C})]})}f.displayName=`PercentField`;export{f as default};
@@ -12,7 +12,7 @@ import { TInput } from './type';
12
12
  * @example
13
13
  * <PhoneField name="phone" form={form} label="Телефон" />
14
14
  */
15
- declare function PhoneField({ value, form, onValue, onBlur: onBlurField, name, placeholder, label, error, hidden, disabled, className, after, before, inputmode, id, }: TInput): import("react/jsx-runtime").JSX.Element | null;
15
+ declare function PhoneField({ value, form, onValue, onBlur: onBlurField, name, placeholder, label, error, hidden, disabled, className, after, before, inputmode, id, size, }: TInput): import("react/jsx-runtime").JSX.Element | null;
16
16
  declare namespace PhoneField {
17
17
  var displayName: string;
18
18
  }
@@ -1 +1 @@
1
- import e from"../styles/Field.module.js";import t,{useFieldA11y as n}from"../core/Field.js";import{useFormFieldState as r}from"../hooks/use.js";import{createFieldEmit as i}from"./emit.js";import a,{asEditableClipboard as o}from"../events/onEvent.js";import{isEmptyTextLike as s}from"./visibility.js";import{PHONE_MASK_DEFAULTS as c}from"../mask/phoneDefaults.js";import{useFormInit as l}from"../FormInitContext.js";import u from"react";import{jsx as d,jsxs as f}from"react/jsx-runtime";var p={...c},m=!1,h=null;function g(){return m?Promise.resolve(!1):h||(h=import(`../mask/MaskPhone.js`).then(e=>(p={...c,...e.default},m=!0,!0)),h)}function _(e){let t=window.getSelection();if(!t||t.rangeCount===0)return 0;let n=t.getRangeAt(0);if(!e.contains(n.startContainer))return 0;let r=document.createRange();return r.selectNodeContents(e),r.setEnd(n.startContainer,n.startOffset),r.toString().length}function v(e,t){if(t<=0)return 0;let n=0;for(let r=0;r<e.length;r++)if(/\d/.test(e[r])&&(n++,n===t))return r+1;return e.length}function y(e){let t=`+_(___) ___-__-__`,n=!0,r=0,i=0,a=``,o=e.replace(/\D/g,``);o===``&&(n=!0);let s=o.split(``),c=``;s.forEach(e=>{n&&(c+=e,p[c]!==void 0&&n?(n=!1,t=p[c].mask.replace(RegExp(`[0-9]`,`g`),`_`),a=p[c].code):(n&&(r=(``+c).length,t=`+${c}_(___) ___-__-__`.replace(RegExp(`[0-9]`,`g`),`_`),a=``),r>(``+c).length&&(n=!0,t=`+${c}_(___) ___-__-__`.replace(RegExp(`[0-9]`,`g`),`_`),a=``)))});let l=t.replace(/\D/g,``);return l.length>=o.length&&(o=l),{q:t.replace(/[_\d]/g,function(){return o.charAt(i++)||`_`}),i,v:o,f:a}}function b({value:n,form:c,onValue:p,onBlur:m,name:h=``,placeholder:b=``,label:S=``,error:C=``,hidden:w=!1,disabled:T=!1,className:E=``,after:D=``,before:O=``,inputmode:k=`tel`,id:A}){let{onNotice:j}=l(),M=!T,{value:N,version:P}=r(c,h,n),[,F]=u.useState(0),I=u.useRef(null),L=u.useRef(!1),R=(e,t)=>{let n=t.firstChild;if(!n||n.nodeType!==Node.TEXT_NODE)return;let r=n.textContent?.length??0,i=Math.max(0,Math.min(e,r)),a=document.createRange(),o=window.getSelection();o&&(a.setStart(n,i),a.collapse(!0),o.removeAllRanges(),o.addRange(a),t.focus())},z=i(c,h,p),B=e=>{let t=e.target,n=t.textContent||``,r=_(t),i=n.slice(0,r).replace(/\D/g,``).length,a=y(n);t.textContent=a.q;let o=v(a.q,i);a.q.length>0&&queueMicrotask(()=>{R(Math.min(o,a.q.length),t)}),z(a.q.replace(/\D/g,``))},V=e=>a.PasteOne(o(e));u.useLayoutEffect(()=>{if(L.current)return;let e=I.current;if(!e)return;let t=y(String(N||``));e.textContent!==t.q&&(e.textContent=t.q)},[N,P]);let H=e=>{e.preventDefault();let t=e.target;navigator.clipboard.writeText((t.textContent||``).replace(/\D/g,``)).then(function(){j(`Данные в буфер обмене`)},function(e){})},U=e=>{e.key===`Enter`&&e.preventDefault()},W=e=>{a.Blur(e),m&&m({value:(e.target.textContent||``).replace(/\D/g,``),name:h||``}),L.current=!1},G=e=>{L.current=!0,a.Focus({target:e.currentTarget}),g().then(e=>{if(!e)return;F(e=>e+1);let t=I.current;if(!t||document.activeElement!==t)return;let n=t.textContent||``,r=_(t),i=n.slice(0,r).replace(/\D/g,``).length,a=y(n);t.textContent!==a.q&&(t.textContent=a.q,queueMicrotask(()=>{R(Math.min(v(a.q,i),a.q.length),t)}))})},K={};b&&(K.placeholder=b),K.inputMode=k??`tel`;let q=String(N??``).replace(/\D/g,``);return w&&s(q)?null:f(t,{type:`input`,label:S,error:C,id:A,element_blok:{className:[E]},element_input:{className:[e.w],props:{"data-disabled":T||!M?`true`:void 0}},children:[O?d(`span`,{className:e.a,children:O}):null,d(x,{divRef:I,editable:M,disabled:T,label:S,placeholder:b,dd:K,onPaste:V,onInput:B,onKeyDown:U,onContextMenu:H,onBlur:W,onFocus:G}),D?d(`span`,{className:e.a,children:D}):null]})}function x({divRef:e,editable:t,disabled:r,label:i,placeholder:a,dd:o,onPaste:s,onInput:c,onKeyDown:l,onContextMenu:u,onBlur:f,onFocus:p}){let m=n();return d(`div`,{ref:e,id:m?.controlId,onPaste:s,onInput:c,onKeyDown:l,onContextMenu:u,onBlur:f,onFocus:p,spellCheck:!1,role:`textbox`,"aria-label":i?void 0:a||`Телефон`,"aria-describedby":m?.describedBy,"aria-invalid":m?.errorId?!0:void 0,"aria-disabled":!t,tabIndex:r?-1:0,"data-disabled":t?void 0:`true`,contentEditable:t?`plaintext-only`:!1,suppressContentEditableWarning:!0,...o})}b.displayName=`PhoneField`;export{b as default};
1
+ import e from"../styles/Field.module.js";import t,{useFieldA11y as n}from"../core/Field.js";import{useFormFieldState as r}from"../hooks/use.js";import{createFieldEmit as i}from"./emit.js";import a,{asEditableClipboard as o}from"../events/onEvent.js";import{isEmptyTextLike as s}from"./visibility.js";import{PHONE_MASK_DEFAULTS as c}from"../mask/phoneDefaults.js";import{useFormInit as l}from"../FormInitContext.js";import u from"react";import{jsx as d,jsxs as f}from"react/jsx-runtime";var p={...c},m=!1,h=null;function g(){return m?Promise.resolve(!1):h||(h=import(`../mask/MaskPhone.js`).then(e=>(p={...c,...e.default},m=!0,!0)),h)}function _(e){let t=window.getSelection();if(!t||t.rangeCount===0)return 0;let n=t.getRangeAt(0);if(!e.contains(n.startContainer))return 0;let r=document.createRange();return r.selectNodeContents(e),r.setEnd(n.startContainer,n.startOffset),r.toString().length}function v(e,t){if(t<=0)return 0;let n=0;for(let r=0;r<e.length;r++)if(/\d/.test(e[r])&&(n++,n===t))return r+1;return e.length}function y(e){let t=`+_(___) ___-__-__`,n=!0,r=0,i=0,a=``,o=e.replace(/\D/g,``);o===``&&(n=!0);let s=o.split(``),c=``;s.forEach(e=>{n&&(c+=e,p[c]!==void 0&&n?(n=!1,t=p[c].mask.replace(RegExp(`[0-9]`,`g`),`_`),a=p[c].code):(n&&(r=(``+c).length,t=`+${c}_(___) ___-__-__`.replace(RegExp(`[0-9]`,`g`),`_`),a=``),r>(``+c).length&&(n=!0,t=`+${c}_(___) ___-__-__`.replace(RegExp(`[0-9]`,`g`),`_`),a=``)))});let l=t.replace(/\D/g,``);return l.length>=o.length&&(o=l),{q:t.replace(/[_\d]/g,function(){return o.charAt(i++)||`_`}),i,v:o,f:a}}function b({value:n,form:c,onValue:p,onBlur:m,name:h=``,placeholder:b=``,label:S=``,error:C=``,hidden:w=!1,disabled:T=!1,className:E=``,after:D=``,before:O=``,inputmode:k=`tel`,id:A,size:j=`m`}){let{onNotice:M}=l(),N=!T,{value:P,version:F}=r(c,h,n),[,I]=u.useState(0),L=u.useRef(null),R=u.useRef(!1),z=(e,t)=>{let n=t.firstChild;if(!n||n.nodeType!==Node.TEXT_NODE)return;let r=n.textContent?.length??0,i=Math.max(0,Math.min(e,r)),a=document.createRange(),o=window.getSelection();o&&(a.setStart(n,i),a.collapse(!0),o.removeAllRanges(),o.addRange(a),t.focus())},B=i(c,h,p),V=e=>{let t=e.target,n=t.textContent||``,r=_(t),i=n.slice(0,r).replace(/\D/g,``).length,a=y(n);t.textContent=a.q;let o=v(a.q,i);a.q.length>0&&queueMicrotask(()=>{z(Math.min(o,a.q.length),t)}),B(a.q.replace(/\D/g,``))},H=e=>a.PasteOne(o(e));u.useLayoutEffect(()=>{if(R.current)return;let e=L.current;if(!e)return;let t=y(String(P||``));e.textContent!==t.q&&(e.textContent=t.q)},[P,F]);let U=e=>{e.preventDefault();let t=e.target;navigator.clipboard.writeText((t.textContent||``).replace(/\D/g,``)).then(function(){M(`Данные в буфер обмене`)},function(e){})},W=e=>{e.key===`Enter`&&e.preventDefault()},G=e=>{a.Blur(e),m&&m({value:(e.target.textContent||``).replace(/\D/g,``),name:h||``}),R.current=!1},K=e=>{R.current=!0,a.Focus({target:e.currentTarget}),g().then(e=>{if(!e)return;I(e=>e+1);let t=L.current;if(!t||document.activeElement!==t)return;let n=t.textContent||``,r=_(t),i=n.slice(0,r).replace(/\D/g,``).length,a=y(n);t.textContent!==a.q&&(t.textContent=a.q,queueMicrotask(()=>{z(Math.min(v(a.q,i),a.q.length),t)}))})},q={};b&&(q.placeholder=b),q.inputMode=k??`tel`;let J=String(P??``).replace(/\D/g,``);return w&&s(J)?null:f(t,{type:`input`,label:S,error:C,id:A,size:j,element_blok:{className:[E]},element_input:{className:[e.w],props:{"data-disabled":T||!N?`true`:void 0}},children:[O?d(`span`,{className:e.a,children:O}):null,d(x,{divRef:L,editable:N,disabled:T,label:S,placeholder:b,dd:q,onPaste:H,onInput:V,onKeyDown:W,onContextMenu:U,onBlur:G,onFocus:K}),D?d(`span`,{className:e.a,children:D}):null]})}function x({divRef:e,editable:t,disabled:r,label:i,placeholder:a,dd:o,onPaste:s,onInput:c,onKeyDown:l,onContextMenu:u,onBlur:f,onFocus:p}){let m=n();return d(`div`,{ref:e,id:m?.controlId,onPaste:s,onInput:c,onKeyDown:l,onContextMenu:u,onBlur:f,onFocus:p,spellCheck:!1,role:`textbox`,"aria-label":i?void 0:a||`Телефон`,"aria-describedby":m?.describedBy,"aria-invalid":m?.errorId?!0:void 0,"aria-disabled":!t,tabIndex:r?-1:0,"data-disabled":t?void 0:`true`,contentEditable:t?`plaintext-only`:!1,suppressContentEditableWarning:!0,...o})}b.displayName=`PhoneField`;export{b as default};
@@ -31,7 +31,7 @@ export type TRadio = TInput & {
31
31
  /**
32
32
  * Радиогруппа. Один выбранный id в форме.
33
33
  */
34
- declare function RadioField({ value, form, onValue, onBlur: onBlurField, name, placeholder, label, error, hidden, disabled, className, after, before, options, inline, align, }: TRadio): import("react/jsx-runtime").JSX.Element | null;
34
+ declare function RadioField({ value, form, onValue, onBlur: onBlurField, name, placeholder, label, error, hidden, disabled, className, after, before, options, inline, align, size, }: TRadio): import("react/jsx-runtime").JSX.Element | null;
35
35
  declare namespace RadioField {
36
36
  var displayName: string;
37
37
  }
@@ -1 +1 @@
1
- import e from"../styles/Field.module.js";import t from"../core/Field.js";import{useFormFieldState as n}from"../hooks/use.js";import{createFieldEmit as r}from"./emit.js";import i from"../styles/Radio.module.js";import a from"react";import{jsx as o,jsxs as s}from"react/jsx-runtime";function c(e){return e?Array.isArray(e)?e.map(e=>({id:e.id??e.i??``,label:e.n||``,hidden:e.s===0})).filter(e=>e.label.length>0&&e.id!==``):Object.keys(e).map(t=>{let n=e[t],r=Number(t);return{id:Number.isFinite(r)&&String(r)===t?r:t,label:n?.n||``,hidden:n?.s===0}}).filter(e=>e.label.length>0):[]}function l(e,t){return e===t?!0:String(e)===String(t)}function u({value:u=``,form:d,onValue:f,onBlur:p,name:m=``,placeholder:h=``,label:g=``,error:_=``,hidden:v=!1,disabled:y=!1,className:b=``,after:x=``,before:S=``,options:C,inline:w=!1,align:T=`center`}){let{value:E}=n(d,m,u),D=!y,O=c(C).filter(e=>!e.hidden),k=a.useId(),A=e=>{r(d,m,f)(e,!0)};return v&&(E==null||E===``)?null:s(t,{type:`radio`,label:g,error:_,element_blok:{className:[b||``]},element_input:{className:[i.d,w?i.i:``],props:{"data-disabled":y||!D?`true`:void 0,role:`radiogroup`,"aria-label":g||h||`Выбор`}},children:[S?o(`span`,{className:e.a,children:S}):null,o(`div`,{children:O.map(e=>{let t=l(E,e.id);return s(`button`,{type:`button`,className:i.t,role:`radio`,"aria-checked":t,"aria-disabled":y||!D?!0:void 0,disabled:y||!D,"data-align":T,name:k,onClick:()=>{D&&A(e.id)},onBlur:()=>{!p||!m||p({value:d?d.getValue(m,E):E,name:m})},children:[o(`span`,{className:i.o,"aria-hidden":!0,children:t?o(`span`,{className:i.f}):null}),o(`span`,{className:i.x,children:e.label})]},String(e.id))})}),x?o(`span`,{className:e.a,children:x}):null]})}u.displayName=`RadioField`;export{u as default};
1
+ import e from"../styles/Field.module.js";import t from"../core/Field.js";import{useFormFieldState as n}from"../hooks/use.js";import{createFieldEmit as r}from"./emit.js";import i from"../styles/Radio.module.js";import a from"react";import{jsx as o,jsxs as s}from"react/jsx-runtime";function c(e){return e?Array.isArray(e)?e.map(e=>({id:e.id??e.i??``,label:e.n||``,hidden:e.s===0})).filter(e=>e.label.length>0&&e.id!==``):Object.keys(e).map(t=>{let n=e[t],r=Number(t);return{id:Number.isFinite(r)&&String(r)===t?r:t,label:n?.n||``,hidden:n?.s===0}}).filter(e=>e.label.length>0):[]}function l(e,t){return e===t?!0:String(e)===String(t)}function u({value:u=``,form:d,onValue:f,onBlur:p,name:m=``,placeholder:h=``,label:g=``,error:_=``,hidden:v=!1,disabled:y=!1,className:b=``,after:x=``,before:S=``,options:C,inline:w=!1,align:T=`center`,size:E=`m`}){let{value:D}=n(d,m,u),O=!y,k=c(C).filter(e=>!e.hidden),A=a.useId(),j=e=>{r(d,m,f)(e,!0)};return v&&(D==null||D===``)?null:s(t,{type:`radio`,label:g,error:_,size:E,element_blok:{className:[b||``]},element_input:{className:[i.d,w?i.i:``],props:{"data-disabled":y||!O?`true`:void 0,role:`radiogroup`,"aria-label":g||h||`Выбор`}},children:[S?o(`span`,{className:e.a,children:S}):null,o(`div`,{children:k.map(e=>{let t=l(D,e.id);return s(`button`,{type:`button`,className:i.t,role:`radio`,"aria-checked":t,"aria-disabled":y||!O?!0:void 0,disabled:y||!O,"data-align":T,name:A,onClick:()=>{O&&j(e.id)},onBlur:()=>{!p||!m||p({value:d?d.getValue(m,D):D,name:m})},children:[o(`span`,{className:i.o,"aria-hidden":!0,children:t?o(`span`,{className:i.f}):null}),o(`span`,{className:i.x,children:e.label})]},String(e.id))})}),x?o(`span`,{className:e.a,children:x}):null]})}u.displayName=`RadioField`;export{u as default};
@@ -22,7 +22,7 @@ export type TRange = TInput & {
22
22
  /**
23
23
  * Диапазон. Клавиши стрелок при фокусе на треке.
24
24
  */
25
- declare function RangeField({ value, form, onValue, onBlur: onBlurField, name, placeholder, label, error, hidden, disabled, className, after, before, min, max, step, variant, }: TRange): import("react/jsx-runtime").JSX.Element | null;
25
+ declare function RangeField({ value, form, onValue, onBlur: onBlurField, name, placeholder, label, error, hidden, disabled, className, after, before, min, max, step, variant, size, }: TRange): import("react/jsx-runtime").JSX.Element | null;
26
26
  declare namespace RangeField {
27
27
  var displayName: string;
28
28
  }
@@ -1 +1 @@
1
- import e from"../styles/Field.module.js";import t from"../core/Field.js";import{useFormFieldState as n}from"../hooks/use.js";import{createFieldEmit as r}from"./emit.js";import i from"react";import{jsx as a,jsxs as o}from"react/jsx-runtime";function s(e,t,n){let r=e;return Number.isFinite(r)||(r=t),Math.min(n,Math.max(t,r))}function c(e,t,n,r){return s(!Number.isFinite(r)||r<=0?e:t+Math.round((e-t)/r)*r,t,n)}function l({value:l=0,form:u,onValue:d,onBlur:f,name:p=``,placeholder:m=``,label:h=``,error:g=``,hidden:_=!1,disabled:v=!1,className:y=``,after:b=``,before:x=``,min:S=0,max:C=100,step:w=1,variant:T=`bar`}){let{value:E}=n(u,p,l),D=s(Number(E),S,C),O=C===S?0:(D-S)/(C-S)*100,k=O>=99.999,A=!v,j=i.useRef(null),M=i.useCallback(e=>{let t=c(e,S,C,w);r(u,p,d)(t,!0)},[u,p,d,S,C,w]),N=i.useCallback(e=>{let t=j.current;if(!t)return S;let n=t.getBoundingClientRect(),r=n.width||1;return c(S+(e-n.left)/r*(C-S),S,C,w)},[S,C,w]),P=e=>{A&&(e.preventDefault(),e.currentTarget.setPointerCapture(e.pointerId),M(N(e.clientX)))},F=e=>{A&&e.currentTarget.hasPointerCapture(e.pointerId)&&M(N(e.clientX))},I=e=>{try{e.currentTarget.releasePointerCapture(e.pointerId)}catch{}},L=e=>{if(!A)return;let t=D;if(e.key===`ArrowRight`||e.key===`ArrowUp`)t=D+w;else if(e.key===`ArrowLeft`||e.key===`ArrowDown`)t=D-w;else if(e.key===`Home`)t=S;else if(e.key===`End`)t=C;else if(e.key===`PageUp`)t=D+w*10;else if(e.key===`PageDown`)t=D-w*10;else return;e.preventDefault(),M(c(t,S,C,w))},R=()=>{if(!f||!p)return;let e=u&&p?u.getValue(p,l):D;f({value:s(Number(e),S,C),name:p})};return _&&(E==null||E===``)?null:o(t,{type:`range`,label:h,error:g,element_blok:{className:[y||``]},element_input:{className:[e.w,e.r],props:{"data-disabled":v||!A?`true`:void 0,"data-variant":T}},children:[x?a(`span`,{className:e.a,children:x}):null,a(`div`,{children:o(`div`,{ref:j,className:e.k,role:`slider`,tabIndex:A?0:-1,"aria-label":h||m||`Диапазон`,"aria-valuemin":S,"aria-valuemax":C,"aria-valuenow":D,"data-disabled":v||!A?`true`:void 0,onPointerDown:P,onPointerMove:F,onPointerUp:I,onPointerCancel:I,onKeyDown:L,onBlur:R,children:[a(`div`,{className:k?`${e.u} ${e.v}`:e.u,style:{width:`${O}%`},"aria-hidden":!0}),T===`line`?a(`div`,{className:e.h,style:{left:`${O}%`},"aria-hidden":!0}):null]})}),b?a(`span`,{className:e.a,children:b}):null]})}l.displayName=`RangeField`;export{l as default};
1
+ import e from"../styles/Field.module.js";import t from"../core/Field.js";import{useFormFieldState as n}from"../hooks/use.js";import{createFieldEmit as r}from"./emit.js";import i from"react";import{jsx as a,jsxs as o}from"react/jsx-runtime";function s(e,t,n){let r=e;return Number.isFinite(r)||(r=t),Math.min(n,Math.max(t,r))}function c(e,t,n,r){return s(!Number.isFinite(r)||r<=0?e:t+Math.round((e-t)/r)*r,t,n)}function l({value:l=0,form:u,onValue:d,onBlur:f,name:p=``,placeholder:m=``,label:h=``,error:g=``,hidden:_=!1,disabled:v=!1,className:y=``,after:b=``,before:x=``,min:S=0,max:C=100,step:w=1,variant:T=`bar`,size:E=`m`}){let{value:D}=n(u,p,l),O=s(Number(D),S,C),k=C===S?0:(O-S)/(C-S)*100,A=k>=99.999,j=!v,M=i.useRef(null),N=i.useCallback(e=>{let t=c(e,S,C,w);r(u,p,d)(t,!0)},[u,p,d,S,C,w]),P=i.useCallback(e=>{let t=M.current;if(!t)return S;let n=t.getBoundingClientRect(),r=n.width||1;return c(S+(e-n.left)/r*(C-S),S,C,w)},[S,C,w]),F=e=>{j&&(e.preventDefault(),e.currentTarget.setPointerCapture(e.pointerId),N(P(e.clientX)))},I=e=>{j&&e.currentTarget.hasPointerCapture(e.pointerId)&&N(P(e.clientX))},L=e=>{try{e.currentTarget.releasePointerCapture(e.pointerId)}catch{}},R=e=>{if(!j)return;let t=O;if(e.key===`ArrowRight`||e.key===`ArrowUp`)t=O+w;else if(e.key===`ArrowLeft`||e.key===`ArrowDown`)t=O-w;else if(e.key===`Home`)t=S;else if(e.key===`End`)t=C;else if(e.key===`PageUp`)t=O+w*10;else if(e.key===`PageDown`)t=O-w*10;else return;e.preventDefault(),N(c(t,S,C,w))},z=()=>{if(!f||!p)return;let e=u&&p?u.getValue(p,l):O;f({value:s(Number(e),S,C),name:p})};return _&&(D==null||D===``)?null:o(t,{type:`range`,label:h,error:g,size:E,element_blok:{className:[y||``]},element_input:{className:[e.w,e.r],props:{"data-disabled":v||!j?`true`:void 0,"data-variant":T}},children:[x?a(`span`,{className:e.a,children:x}):null,a(`div`,{children:o(`div`,{ref:M,className:e.k,role:`slider`,tabIndex:j?0:-1,"aria-label":h||m||`Диапазон`,"aria-valuemin":S,"aria-valuemax":C,"aria-valuenow":O,"data-disabled":v||!j?`true`:void 0,onPointerDown:F,onPointerMove:I,onPointerUp:L,onPointerCancel:L,onKeyDown:R,onBlur:z,children:[a(`div`,{className:A?`${e.u} ${e.v}`:e.u,style:{width:`${k}%`},"aria-hidden":!0}),T===`line`?a(`div`,{className:e.h,style:{left:`${k}%`},"aria-hidden":!0}):null]})}),b?a(`span`,{className:e.a,children:b}):null]})}l.displayName=`RangeField`;export{l as default};
@@ -17,7 +17,7 @@ export type TRating = TInput & {
17
17
  /**
18
18
  * Звёздный рейтинг.
19
19
  */
20
- declare function RatingField({ value, form, onValue, onBlur: onBlurField, name, placeholder, label, error, hidden, disabled, className, after, before, max, allowClear, }: TRating): import("react/jsx-runtime").JSX.Element | null;
20
+ declare function RatingField({ value, form, onValue, onBlur: onBlurField, name, placeholder, label, error, hidden, disabled, className, after, before, max, allowClear, size, }: TRating): import("react/jsx-runtime").JSX.Element | null;
21
21
  declare namespace RatingField {
22
22
  var displayName: string;
23
23
  }
@@ -1 +1 @@
1
- import e from"../styles/Field.module.js";import t from"../core/Field.js";import{useFormFieldState as n}from"../hooks/use.js";import{createFieldEmit as r}from"./emit.js";import i from"../styles/Rating.module.js";import a from"react";import{jsx as o,jsxs as s}from"react/jsx-runtime";function c(e,t){return Number.isFinite(e)?Math.min(t,Math.max(0,Math.round(e))):0}function l({value:l=0,form:u,onValue:d,onBlur:f,name:p=``,placeholder:m=``,label:h=``,error:g=``,hidden:_=!1,disabled:v=!1,className:y=``,after:b=``,before:x=``,max:S=5,allowClear:C=!0}){let{value:w}=n(u,p,l),T=c(Number(w),S),E=!v,[D,O]=a.useState(0),k=e=>{r(u,p,d)(e,!0)};if(_&&!T)return null;let A=D||T;return s(t,{type:`rating`,label:h,error:g,element_blok:{className:[y||``]},element_input:{className:[i.r],props:{"data-disabled":v||!E?`true`:void 0}},children:[x?o(`span`,{className:e.a,children:x}):null,o(`div`,{role:`slider`,"aria-label":h||m||`Оценка`,"aria-valuemin":0,"aria-valuemax":S,"aria-valuenow":T,tabIndex:E?0:-1,onMouseLeave:()=>O(0),onBlur:()=>{O(0),f?.({value:T,name:p})},onKeyDown:e=>{if(!E)return;let t=T;if(e.key===`ArrowRight`||e.key===`ArrowUp`)t=Math.min(S,T+1);else if(e.key===`ArrowLeft`||e.key===`ArrowDown`)t=Math.max(0,T-1);else if(e.key===`Home`)t=0;else if(e.key===`End`)t=S;else return;e.preventDefault(),k(t)},children:Array.from({length:S},(e,t)=>{let n=t+1;return o(`button`,{type:`button`,className:n<=A?`${i.s} ${i.o}`:i.s,"aria-label":`${n} из ${S}`,disabled:!E,onMouseEnter:()=>E&&O(n),onClick:()=>{E&&k(C&&T===n?0:n)},children:`★`},n)})}),b?o(`span`,{className:e.a,children:b}):null]})}l.displayName=`RatingField`;export{l as default};
1
+ import e from"../styles/Field.module.js";import t from"../core/Field.js";import{useFormFieldState as n}from"../hooks/use.js";import{createFieldEmit as r}from"./emit.js";import i from"../styles/Rating.module.js";import a from"react";import{jsx as o,jsxs as s}from"react/jsx-runtime";function c(e,t){return Number.isFinite(e)?Math.min(t,Math.max(0,Math.round(e))):0}function l({value:l=0,form:u,onValue:d,onBlur:f,name:p=``,placeholder:m=``,label:h=``,error:g=``,hidden:_=!1,disabled:v=!1,className:y=``,after:b=``,before:x=``,max:S=5,allowClear:C=!0,size:w=`m`}){let{value:T}=n(u,p,l),E=c(Number(T),S),D=!v,[O,k]=a.useState(0),A=e=>{r(u,p,d)(e,!0)};if(_&&!E)return null;let j=O||E;return s(t,{type:`rating`,label:h,error:g,size:w,element_blok:{className:[y||``]},element_input:{className:[i.r],props:{"data-disabled":v||!D?`true`:void 0}},children:[x?o(`span`,{className:e.a,children:x}):null,o(`div`,{role:`slider`,"aria-label":h||m||`Оценка`,"aria-valuemin":0,"aria-valuemax":S,"aria-valuenow":E,tabIndex:D?0:-1,onMouseLeave:()=>k(0),onBlur:()=>{k(0),f?.({value:E,name:p})},onKeyDown:e=>{if(!D)return;let t=E;if(e.key===`ArrowRight`||e.key===`ArrowUp`)t=Math.min(S,E+1);else if(e.key===`ArrowLeft`||e.key===`ArrowDown`)t=Math.max(0,E-1);else if(e.key===`Home`)t=0;else if(e.key===`End`)t=S;else return;e.preventDefault(),A(t)},children:Array.from({length:S},(e,t)=>{let n=t+1;return o(`button`,{type:`button`,className:n<=j?`${i.s} ${i.o}`:i.s,"aria-label":`${n} из ${S}`,disabled:!D,onMouseEnter:()=>D&&k(n),onClick:()=>{D&&A(C&&E===n?0:n)},children:`★`},n)})}),b?o(`span`,{className:e.a,children:b}):null]})}l.displayName=`RatingField`;export{l as default};
@@ -15,7 +15,7 @@ export type TRichText = TInput & {
15
15
  /**
16
16
  * Rich-текст. Значение — HTML, не plain text.
17
17
  */
18
- declare function RichTextField({ value, form, onValue, onBlur: onBlurField, name, placeholder, label, error, hidden, disabled, className, after, before, maxLength, spellCheck, toolbar, }: TRichText): import("react/jsx-runtime").JSX.Element | null;
18
+ declare function RichTextField({ value, form, onValue, onBlur: onBlurField, name, placeholder, label, error, hidden, disabled, className, after, before, maxLength, spellCheck, toolbar, size, }: TRichText): import("react/jsx-runtime").JSX.Element | null;
19
19
  declare namespace RichTextField {
20
20
  var displayName: string;
21
21
  }
@@ -1 +1 @@
1
- import e from"../styles/Field.module.js";import t from"../core/Field.js";import{useFormFieldState as n}from"../hooks/use.js";import{createFieldEmit as r}from"./emit.js";import{isEmptyTextLike as i}from"./visibility.js";import a from"../styles/Rich.module.js";import o from"react";import{jsx as s,jsxs as c}from"react/jsx-runtime";function l({value:l=``,form:u,onValue:d,onBlur:f,name:p=``,placeholder:m=``,label:h=``,error:g=``,hidden:_=!1,disabled:v=!1,className:y=``,after:b=``,before:x=``,maxLength:S,spellCheck:C=!0,toolbar:w=!0}){let{value:T,version:E}=n(u,p,l),D=!v,O=typeof T==`string`?T:``,k=o.useRef(null),A=o.useRef(!1);o.useLayoutEffect(()=>{if(A.current)return;let e=k.current;e&&e.innerHTML!==O&&(e.innerHTML=O||``)},[O,E]);let j=r(u,p,d),M=(e,t=!1)=>{S&&e.replace(/<[^>]+>/g,``).length>S||j(e,t)},N=e=>{if(D){k.current?.focus();try{document.execCommand(e,!1)}catch{}M(k.current?.innerHTML||``)}};if(_&&i(O.replace(/<[^>]+>/g,``)))return null;let P={};return m&&!O&&(P.placeholder=m),D&&(P.edit=``),c(t,{type:`richtext`,label:h,error:g,element_blok:{className:[y||``]},element_input:{className:[a.r],props:{"data-disabled":v||!D?`true`:void 0}},children:[x?s(`span`,{className:e.a,children:x}):null,c(`div`,{className:a.w,children:[w?c(`div`,{className:a.t,role:`toolbar`,children:[s(`button`,{type:`button`,className:a.b,disabled:!D,"aria-label":`Жирный`,onMouseDown:e=>e.preventDefault(),onClick:()=>N(`bold`),children:`B`}),s(`button`,{type:`button`,className:a.b,disabled:!D,"aria-label":`Курсив`,onMouseDown:e=>e.preventDefault(),onClick:()=>N(`italic`),children:s(`em`,{children:`I`})}),s(`button`,{type:`button`,className:a.b,disabled:!D,"aria-label":`Подчёркивание`,onMouseDown:e=>e.preventDefault(),onClick:()=>N(`underline`),children:s(`u`,{children:`U`})}),s(`button`,{type:`button`,className:a.b,disabled:!D,"aria-label":`Маркированный список`,onMouseDown:e=>e.preventDefault(),onClick:()=>N(`insertUnorderedList`),children:`•`}),s(`button`,{type:`button`,className:a.b,disabled:!D,"aria-label":`Нумерованный список`,onMouseDown:e=>e.preventDefault(),onClick:()=>N(`insertOrderedList`),children:`1.`})]}):null,s(`div`,{ref:k,className:a.e,contentEditable:D,suppressContentEditableWarning:!0,spellCheck:C,role:`textbox`,"aria-multiline":!0,"aria-label":h||m||`Текст`,tabIndex:D?0:-1,onFocus:()=>{A.current=!0},onInput:()=>M(k.current?.innerHTML||``),onBlur:()=>{A.current=!1;let e=k.current?.innerHTML||``;M(e,!0),f?.({value:e,name:p})},...P})]}),b?s(`span`,{className:e.a,children:b}):null]})}l.displayName=`RichTextField`;export{l as default};
1
+ import e from"../styles/Field.module.js";import t from"../core/Field.js";import{useFormFieldState as n}from"../hooks/use.js";import{createFieldEmit as r}from"./emit.js";import{isEmptyTextLike as i}from"./visibility.js";import a from"../styles/Rich.module.js";import o from"react";import{jsx as s,jsxs as c}from"react/jsx-runtime";function l({value:l=``,form:u,onValue:d,onBlur:f,name:p=``,placeholder:m=``,label:h=``,error:g=``,hidden:_=!1,disabled:v=!1,className:y=``,after:b=``,before:x=``,maxLength:S,spellCheck:C=!0,toolbar:w=!0,size:T=`m`}){let{value:E,version:D}=n(u,p,l),O=!v,k=typeof E==`string`?E:``,A=o.useRef(null),j=o.useRef(!1);o.useLayoutEffect(()=>{if(j.current)return;let e=A.current;e&&e.innerHTML!==k&&(e.innerHTML=k||``)},[k,D]);let M=r(u,p,d),N=(e,t=!1)=>{S&&e.replace(/<[^>]+>/g,``).length>S||M(e,t)},P=e=>{if(O){A.current?.focus();try{document.execCommand(e,!1)}catch{}N(A.current?.innerHTML||``)}};if(_&&i(k.replace(/<[^>]+>/g,``)))return null;let F={};return m&&!k&&(F.placeholder=m),O&&(F.edit=``),c(t,{type:`richtext`,label:h,error:g,size:T,element_blok:{className:[y||``]},element_input:{className:[a.r],props:{"data-disabled":v||!O?`true`:void 0}},children:[x?s(`span`,{className:e.a,children:x}):null,c(`div`,{className:a.w,children:[w?c(`div`,{className:a.t,role:`toolbar`,children:[s(`button`,{type:`button`,className:a.b,disabled:!O,"aria-label":`Жирный`,onMouseDown:e=>e.preventDefault(),onClick:()=>P(`bold`),children:`B`}),s(`button`,{type:`button`,className:a.b,disabled:!O,"aria-label":`Курсив`,onMouseDown:e=>e.preventDefault(),onClick:()=>P(`italic`),children:s(`em`,{children:`I`})}),s(`button`,{type:`button`,className:a.b,disabled:!O,"aria-label":`Подчёркивание`,onMouseDown:e=>e.preventDefault(),onClick:()=>P(`underline`),children:s(`u`,{children:`U`})}),s(`button`,{type:`button`,className:a.b,disabled:!O,"aria-label":`Маркированный список`,onMouseDown:e=>e.preventDefault(),onClick:()=>P(`insertUnorderedList`),children:`•`}),s(`button`,{type:`button`,className:a.b,disabled:!O,"aria-label":`Нумерованный список`,onMouseDown:e=>e.preventDefault(),onClick:()=>P(`insertOrderedList`),children:`1.`})]}):null,s(`div`,{ref:A,className:a.e,contentEditable:O,suppressContentEditableWarning:!0,spellCheck:C,role:`textbox`,"aria-multiline":!0,"aria-label":h||m||`Текст`,tabIndex:O?0:-1,onFocus:()=>{j.current=!0},onInput:()=>N(A.current?.innerHTML||``),onBlur:()=>{j.current=!1;let e=A.current?.innerHTML||``;N(e,!0),f?.({value:e,name:p})},...F})]}),b?s(`span`,{className:e.a,children:b}):null]})}l.displayName=`RichTextField`;export{l as default};
@@ -0,0 +1,61 @@
1
+ import { ReactNode } from 'react';
2
+ import { TInput } from './type';
3
+ import { SearchHotkey } from './searchHotkey';
4
+ import { SearchSuggestion } from './SearchSuggestions';
5
+ export type SearchWidth = "s" | "m" | "l";
6
+ export type SearchVariant = "default" | "ghost" | "filled";
7
+ export type { SearchHotkey, SearchSuggestion };
8
+ /**
9
+ * Поиск. **В форме:** `string`.
10
+ *
11
+ * **Элементы:** капсула → лупа (`before` по умолчанию) | `<input type="search">` | clear | `after`.
12
+ * Список подсказок — портал. Debounce `timeout` (по умолчанию 250 мс).
13
+ *
14
+ * @example
15
+ * <SearchField name="q" form={form} placeholder="Поиск…" timeout={0} />
16
+ * <SearchField name="q" form={form} variant="ghost" minimal hotkey="/" />
17
+ */
18
+ export type TSearch = TInput & {
19
+ /** Debounce перед записью в form / `onSearch`, мс. `0` = сразу. @default 250 */
20
+ timeout?: number;
21
+ /**
22
+ * Async-поиск. Promise → спиннер вместо лупы до settle.
23
+ * Вызывается с тем же debounce, что и запись в форму.
24
+ */
25
+ onSearch?: (query: string) => void | Promise<void>;
26
+ /** Внешний флаг загрузки */
27
+ loading?: boolean;
28
+ suggestions?: SearchSuggestion[];
29
+ loadSuggestions?: (query: string) => SearchSuggestion[] | Promise<SearchSuggestion[]>;
30
+ onSuggestionSelect?: (item: SearchSuggestion) => void;
31
+ renderSuggestion?: (item: SearchSuggestion, index: number, active: boolean) => ReactNode;
32
+ suggestionsOpen?: boolean;
33
+ onSuggestionsOpenChange?: (open: boolean) => void;
34
+ /** `s` по контенту, `m` min-width, `l` 100%. @default "m" */
35
+ width?: SearchWidth;
36
+ /** `default` | `ghost` | `filled`. @default "default" */
37
+ variant?: SearchVariant;
38
+ dir?: "ltr" | "rtl";
39
+ resultsCount?: number | null;
40
+ resultsAnnounce?: string | ((count: number) => string);
41
+ /** Свёрнутая иконка, по фокусу раскрывается. */
42
+ minimal?: boolean;
43
+ /** Задержка сворачивания minimal после blur, мс. @default 180 */
44
+ collapseDelay?: number;
45
+ hotkeyBadge?: boolean;
46
+ /** Кнопка очистки. @default true */
47
+ clearable?: boolean;
48
+ /**
49
+ * Горячая клавиша фокуса: `/` · `mod+/` · `mod+k`.
50
+ * Не срабатывает в input/textarea и при открытой модалке.
51
+ */
52
+ hotkey?: SearchHotkey;
53
+ };
54
+ /**
55
+ * Поле поиска. Лупа / спиннер слева, clear справа, подсказки в портале.
56
+ */
57
+ declare function SearchField({ value, form, onValue, onBlur: onBlurField, name, placeholder, label, error, hidden, disabled, className, after, before, id, size, maxLength, autoComplete, timeout, onSearch, loading, suggestions: suggestionsProp, loadSuggestions, onSuggestionSelect, renderSuggestion, suggestionsOpen, onSuggestionsOpenChange, width, variant, dir, resultsCount, resultsAnnounce, minimal, collapseDelay, hotkeyBadge, clearable, hotkey, }: TSearch): import("react/jsx-runtime").JSX.Element | null;
58
+ declare namespace SearchField {
59
+ var displayName: string;
60
+ }
61
+ export default SearchField;
@@ -0,0 +1 @@
1
+ import e,{useFieldA11y as t}from"../core/Field.js";import{useFormFieldState as n}from"../hooks/use.js";import{createFieldEmit as ee}from"./emit.js";import{isEmptyTextLike as r}from"./visibility.js";import i from"../styles/Search.module.js";import{formatResultsCount as te}from"./searchAnnounce.js";import{hotkeyBadgeLabel as ne,matchHotkey as re}from"./searchHotkey.js";import{SearchSuggestions as ie}from"./SearchSuggestions.js";import{useCallback as a,useEffect as o,useId as s,useRef as c,useState as l}from"react";import{jsx as u,jsxs as d}from"react/jsx-runtime";import{createPortal as ae}from"react-dom";function oe(e){return e?e.tagName===`INPUT`||e.tagName===`TEXTAREA`||e.tagName===`SELECT`||e.isContentEditable:!1}function se(){return!!document.querySelector(`[data-elcrm-modal], .elcrm-modal, [role="dialog"]`)}function ce(){return u(`svg`,{"aria-hidden":!0,viewBox:`0 0 24 24`,className:i.v,children:u(`path`,{d:`M17.5 17.5L22 22m-2-11a9 9 0 1 0-18 0a9 9 0 0 0 18 0`})})}function le(){return u(`svg`,{"aria-hidden":!0,viewBox:`0 0 24 24`,className:i.v,children:u(`path`,{d:`M17 6L6 17M6 6L17 17`})})}function f(){return u(`svg`,{"aria-hidden":!0,viewBox:`0 0 24 24`,className:`${i.v} ${i.i}`,children:u(`circle`,{cx:`12`,cy:`12`,r:`9`,fill:`none`,strokeDasharray:`40 20`})})}function p({value:t,form:p,onValue:de,onBlur:fe,name:m=``,placeholder:pe=`Поиск…`,label:me=``,error:he=``,hidden:ge=!1,disabled:h=!1,className:_e=``,after:ve=``,before:ye,id:be,size:xe=`m`,maxLength:Se,autoComplete:Ce=`off`,timeout:we=250,onSearch:g,loading:Te=!1,suggestions:_,loadSuggestions:v,onSuggestionSelect:Ee,renderSuggestion:De,suggestionsOpen:y,onSuggestionsOpenChange:b,width:Oe=`m`,variant:ke=`default`,dir:Ae,resultsCount:x=null,resultsAnnounce:S,minimal:C=!1,collapseDelay:je=180,hotkeyBadge:Me,clearable:Ne=!0,hotkey:w=!1}){let{value:T}=n(p,m,t),E=typeof T==`string`?T:T==null?``:String(T),Pe=`${s()}-list`,D=c(null),O=c(null),k=c(null),A=c(null),j=c(0),M=c(0),N=c(!1),P=c(E),[F,I]=l(E),[Fe,L]=l(!1),[Ie,R]=l(!1),[Le,z]=l(!1),[Re,ze]=l(!1),[Be,B]=l(null),[Ve,V]=l(!1),[H,U]=l(-1),[He,Ue]=l(null),We=Me??!!(C&&w),Ge=Te||Le||Re,Ke=!h,W=Be??_??[],G=!!(v||_!==void 0);o(()=>{N.current||(I(E),P.current=E)},[E]);let K=e=>{e.current!=null&&(window.clearTimeout(e.current),e.current=null)},q=ee(p,m,de),J=a(async e=>{if(!v){B(null);return}let t=++M.current;ze(!0);try{let n=await Promise.resolve(v(e));if(t!==M.current)return;B(n),U(n.length?0:-1)}catch{if(t!==M.current)return;B([]),U(-1)}finally{t===M.current&&ze(!1)}},[v]),qe=a((e,t=!1)=>{K(k);let n=()=>{if(P.current=e,q(e,!0),g){let t=++j.current,n=g(e);n&&typeof n.then==`function`&&(z(!0),Promise.resolve(n).finally(()=>{t===j.current&&z(!1)}))}v&&J(e)};t||we<=0?n():k.current=window.setTimeout(n,we)},[q,g,v,J,we]);o(()=>()=>{K(k),K(A)},[]);let Y=a(()=>{O.current?.focus()},[]);o(()=>{if(!w||h)return;let e=e=>{oe(e.target)||se()||re(e,w)&&(e.preventDefault(),Y(),O.current?.select())};return document.addEventListener(`keydown`,e),()=>document.removeEventListener(`keydown`,e)},[w,h,Y]);let Je=a(()=>{!G||h||(V(!0),b?.(!0))},[G,h,b]),X=a(()=>{V(!1),U(-1),b?.(!1)},[b]);o(()=>{y!==void 0&&(V(y),y||U(-1))},[y]);let Z=y===void 0?Ve:y,Q=a(()=>{let e=D.current;e&&Ue(e.getBoundingClientRect())},[]);o(()=>{if(!Z)return;Q();let e=()=>Q();return window.addEventListener(`scroll`,e,!0),window.addEventListener(`resize`,e),()=>{window.removeEventListener(`scroll`,e,!0),window.removeEventListener(`resize`,e)}},[Z,Q]);let Ye=a(e=>{let t=e.value??e.label;if(I(t),P.current=t,q(t,!0),Ee?.(e),X(),g){let e=++j.current,n=g(t);n&&typeof n.then==`function`&&(z(!0),Promise.resolve(n).finally(()=>{e===j.current&&z(!1)}))}Y()},[q,Ee,g,X,Y]),Xe=e=>{let t=e.target.value;I(t),Je(),qe(t)},Ze=()=>{I(``),P.current=``,qe(``,!0),Je(),Y()},Qe=e=>{if(Z&&W.length){if(e.key===`ArrowDown`){e.preventDefault(),U(e=>(e+1)%W.length);return}if(e.key===`ArrowUp`){e.preventDefault(),U(e=>e<=0?W.length-1:e-1);return}if(e.key===`Enter`&&H>=0){e.preventDefault(),Ye(W[H]);return}}if(e.key===`Escape`){if(Z){e.preventDefault(),X();return}F&&(e.preventDefault(),Ze())}},$e=()=>{N.current=!0,K(A),R(!1),L(!0),Je(),v?J(F):_&&U(_.length?0:-1)},et=()=>{N.current=!1,F!==P.current&&qe(F,!0),fe?.({value:F,name:m});let e=document.activeElement;if(e&&D.current?.contains(e)){L(!1);return}L(!1),C&&(F||Z||je>0)?(R(!0),K(A),A.current=window.setTimeout(()=>{R(!1),X()},Math.max(0,je))):X()},$=!C||Fe||Ie||!!F||Z,tt=Z&&G&&$,nt=x==null?``:typeof S==`string`?S:typeof S==`function`?S(x):te(x),rt=e=>{!C||h||$||e.target!==O.current&&(e.preventDefault(),Y())};if(ge&&r(F)&&r(E))return null;let it=Ge?u(f,{}):ye??u(ce,{}),at=Oe===`s`?i.s:Oe===`l`?i.l:i.m;return d(e,{type:`search`,label:me,error:he,id:be,size:xe,element_blok:{className:[_e||``,i.c,at,C?i.p:``,C&&$?i.e:``,C&&We&&!$?i.y:``]},element_input:{className:[i.r],props:{"data-disabled":h||!Ke?`true`:void 0,"data-variant":ke===`default`?void 0:ke,"data-minimal":C?`true`:void 0,"data-expanded":C?$?`true`:`false`:void 0,"data-loading":Ge?`true`:void 0,dir:Ae,onMouseDown:rt}},children:[d(`div`,{ref:D,className:i.d,role:`search`,children:[u(`span`,{className:i.b,"aria-hidden":!0,children:it}),u(ue,{inputRef:O,draft:F,disabled:h,maxLength:Se,placeholder:pe,autoComplete:Ce,name:m,id:be,expanded:$,minimal:C,hasSuggestSource:G,showList:tt,listId:Pe,activeIndex:H,label:me,onChange:Xe,onKeyDown:Qe,onBlur:et,onFocus:$e}),C&&We&&!$&&w?u(`kbd`,{className:i.k,children:ne(w)}):null,Ne&&F&&$?u(`button`,{type:`button`,className:i.x,"aria-label":`Очистить поиск`,tabIndex:-1,disabled:h,onClick:Ze,children:u(le,{})}):u(`span`,{className:i.u,"aria-hidden":!0}),ve?u(`span`,{className:i.w,children:ve}):null,u(`span`,{"data-live":!0,"aria-live":`polite`,"aria-atomic":`true`,children:nt})]}),tt&&He?ae(u(ie,{id:Pe,items:W,activeIndex:H,parent:He,onHover:U,onSelect:e=>Ye(e),renderItem:De}),document.body):null]})}function ue({inputRef:e,draft:n,disabled:ee,maxLength:r,placeholder:te,autoComplete:ne,name:re,id:ie,expanded:a,minimal:o,hasSuggestSource:s,showList:c,listId:l,activeIndex:d,label:ae,onChange:oe,onKeyDown:se,onBlur:ce,onFocus:le}){let f=t();return u(`input`,{ref:e,id:ie||f?.controlId,name:re||void 0,type:`search`,className:i.n,placeholder:te,value:n,disabled:ee,maxLength:r,autoComplete:ne,tabIndex:o&&!a?-1:void 0,role:s?`combobox`:void 0,"aria-label":ae?void 0:te||`Поиск`,"aria-expanded":s?c:o?a:void 0,"aria-controls":c?l:void 0,"aria-activedescendant":c&&d>=0?`${l}-opt-${d}`:void 0,"aria-autocomplete":s?`list`:void 0,"aria-describedby":f?.describedBy,"aria-invalid":f?.errorId?!0:void 0,onChange:oe,onKeyDown:se,onBlur:ce,onFocus:le})}p.displayName=`SearchField`;export{p as default};
@@ -0,0 +1,26 @@
1
+ import { default as React } from 'react';
2
+ export type SearchSuggestion = {
3
+ /** Стабильный id; иначе используется index */
4
+ id?: string;
5
+ label: string;
6
+ /** Значение в input; по умолчанию `label` */
7
+ value?: string;
8
+ description?: string;
9
+ recent?: boolean;
10
+ icon?: React.ReactNode;
11
+ data?: unknown;
12
+ };
13
+ type SuggestionsProps = {
14
+ id: string;
15
+ items: SearchSuggestion[];
16
+ activeIndex: number;
17
+ parent: DOMRect;
18
+ onHover: (index: number) => void;
19
+ onSelect: (item: SearchSuggestion, index: number) => void;
20
+ renderItem?: (item: SearchSuggestion, index: number, active: boolean) => React.ReactNode;
21
+ };
22
+ /**
23
+ * Список подсказок в портале (якорь к капсуле).
24
+ */
25
+ export declare function SearchSuggestions({ id, items, activeIndex, parent, onHover, onSelect, renderItem, }: SuggestionsProps): import("react/jsx-runtime").JSX.Element;
26
+ export {};
@@ -0,0 +1 @@
1
+ import{acquireOverlayZIndex as e,releaseOverlayZIndex as t}from"../overlayZ.js";import n from"../styles/Search.module.js";import r from"react";import{Fragment as i,jsx as a,jsxs as o}from"react/jsx-runtime";function s({id:s,items:c,activeIndex:l,parent:u,onHover:d,onSelect:f,renderItem:p}){let[m]=r.useState(()=>e());r.useEffect(()=>()=>t(m),[m]);let h=window.innerHeight-u.bottom<246?u.top-240-6:u.bottom+6;h=Math.min(h,window.innerHeight-240-6),h=Math.max(6,h);let g=Math.min(Math.max(6,u.left),Math.max(6,window.innerWidth-u.width-6));return a(`ul`,{id:s,className:n.q,role:`listbox`,"aria-label":`Подсказки`,style:{top:h,left:g,width:u.width,zIndex:m},children:c.length===0?a(`li`,{className:n.o,role:`presentation`,children:`Нет подсказок`}):c.map((e,t)=>{let r=t===l,c=e.id??`${e.label}-${t}`;return a(`li`,{id:`${s}-opt-${t}`,role:`option`,"aria-selected":r,className:[n.a,r?n.h:``].filter(Boolean).join(` `),onMouseEnter:()=>d(t),onMouseDown:n=>{n.preventDefault(),f(e,t)},children:p?p(e,t,r):o(i,{children:[e.icon==null?null:a(`span`,{className:n.f,"aria-hidden":!0,children:e.icon}),o(`span`,{className:n.z,children:[a(`span`,{className:n.g,children:e.label}),e.description?a(`span`,{className:n.t,children:e.description}):null]})]})},c)})})}export{s as SearchSuggestions};
@@ -20,25 +20,35 @@ type TabsOptions = TabsOptionObject | TabsOptionArrayItem[];
20
20
  *
21
21
  * **В форме:** `string | number` (id активного сегмента).
22
22
  *
23
- * **Элементы:** капсула без внутреннего padding → кнопки-сегменты.
24
- * `options[].icon` — слот слева в сегменте. `s === 0` — сегмент виден, но disabled.
25
- * `equal` — равная ширина (по умолчанию true).
23
+ * **Элементы:** капсула кнопки `role="tab"`.
24
+ * `variant="field"` — сегменты встык с делителем (по умолчанию).
25
+ * `variant="pill"` — пилюля: внутренний отступ, активный сегмент своей капсулой.
26
+ * `options[].icon` — слот слева. `s === 0` — виден, но disabled.
27
+ * `equal` — равная ширина (`true` у `field`, `false` у `pill`, если не задано).
26
28
  *
27
29
  * @example
28
30
  * <TabsField name="tab" form={form} options={[{ i: "a", n: "А" }, { i: "b", n: "Б" }]} />
31
+ * <TabsField name="status" form={form} variant="pill" options={STATUS} />
29
32
  */
33
+ export type TTabsVariant = "field" | "pill";
30
34
  export type TTabs = TInput & {
31
35
  options?: TabsOptions;
32
36
  /**
33
- * Равная ширина сегментов (по умолчанию `true`).
34
- * `false` ширина по содержимому.
37
+ * Равная ширина сегментов.
38
+ * По умолчанию: `true` для `field`, `false` для `pill`.
35
39
  */
36
40
  equal?: boolean;
41
+ /**
42
+ * `field` — классические сегменты в капсуле поля.
43
+ * `pill` — статус-фильтр: скруглённая капсула и «пилюля» на активном.
44
+ * @default "field"
45
+ */
46
+ variant?: TTabsVariant;
37
47
  };
38
48
  /**
39
49
  * Сегмент-контрол. Фокус на сегменте, не на всей капсуле.
40
50
  */
41
- declare function TabsField({ value, form, onValue, onBlur: onBlurField, name, placeholder, label, error, hidden, disabled, className, after, before, options, equal, size, }: TTabs): import("react/jsx-runtime").JSX.Element | null;
51
+ declare function TabsField({ value, form, onValue, onBlur: onBlurField, name, placeholder, label, error, hidden, disabled, className, after, before, options, equal, variant, size, }: TTabs): import("react/jsx-runtime").JSX.Element | null;
42
52
  declare namespace TabsField {
43
53
  var displayName: string;
44
54
  }
@@ -1 +1 @@
1
- import e from"../styles/Field.module.js";import t from"../core/Field.js";import{useFormFieldState as n}from"../hooks/use.js";import{createFieldEmit as r}from"./emit.js";import i from"../styles/Tabs.module.js";import"react";import{jsx as a,jsxs as o}from"react/jsx-runtime";function s(e){return e?Array.isArray(e)?e.map(e=>({id:e.id??e.i??``,label:e.n||``,disabled:e.s===0,icon:e.icon})).filter(e=>e.label.length>0&&e.id!==``):Object.keys(e).map(t=>{let n=e[t],r=Number(t);return{id:Number.isFinite(r)&&String(r)===t?r:t,label:n?.n||``,disabled:n?.s===0,icon:n?.icon}}).filter(e=>e.label.length>0):[]}function c(e,t){return e===t?!0:String(e)===String(t)}function l({value:l=``,form:u,onValue:d,onBlur:f,name:p=``,placeholder:m=``,label:h=``,error:g=``,hidden:_=!1,disabled:v=!1,className:y=``,after:b=``,before:x=``,options:S,equal:C=!0,size:w}){let{value:T}=n(u,p,l),E=!v,D=s(S),O=e=>{r(u,p,d)(e,!0)};return _&&(T==null||T===``)?null:o(t,{type:`tabs`,label:h,error:g,size:w,element_blok:{className:[y||``]},element_input:{className:[i.r],props:{"data-disabled":v||!E?`true`:void 0}},children:[x?a(`span`,{className:e.a,children:x}):null,a(`div`,{className:i.i,role:`tablist`,"aria-label":h||m||`Вкладки`,style:C?void 0:{justifyContent:`flex-start`},children:D.map(e=>{let t=c(T,e.id),n=v||!E||e.disabled;return o(`button`,{type:`button`,role:`tab`,"aria-selected":t,"aria-disabled":n||void 0,disabled:n,className:[i.t,t?i.a:``].filter(Boolean).join(` `),style:C?void 0:{flex:`0 0 auto`},onClick:()=>{n||O(e.id)},onBlur:()=>{!f||!p||f({value:u?u.getValue(p,T):T,name:p})},children:[e.icon==null?null:a(`span`,{className:i.o,"aria-hidden":!0,children:e.icon}),a(`span`,{className:i.l,children:e.label})]},String(e.id))})}),b?a(`span`,{className:e.a,children:b}):null]})}l.displayName=`TabsField`;export{l as default};
1
+ import e from"../styles/Field.module.js";import t from"../core/Field.js";import{useFormFieldState as n}from"../hooks/use.js";import{createFieldEmit as r}from"./emit.js";import i from"../styles/Tabs.module.js";import"react";import{jsx as a,jsxs as o}from"react/jsx-runtime";function s(e){return e?Array.isArray(e)?e.map(e=>({id:e.id??e.i??``,label:e.n||``,disabled:e.s===0,icon:e.icon})).filter(e=>e.label.length>0&&e.id!==``):Object.keys(e).map(t=>{let n=e[t],r=Number(t);return{id:Number.isFinite(r)&&String(r)===t?r:t,label:n?.n||``,disabled:n?.s===0,icon:n?.icon}}).filter(e=>e.label.length>0):[]}function c(e,t){return e===t?!0:String(e)===String(t)}function l({value:l=``,form:u,onValue:d,onBlur:f,name:p=``,placeholder:m=``,label:h=``,error:g=``,hidden:_=!1,disabled:v=!1,className:y=``,after:b=``,before:x=``,options:S,equal:C,variant:w=`field`,size:T=`m`}){let{value:E}=n(u,p,l),D=!v,O=s(S),k=C??w!==`pill`,A=e=>{r(u,p,d)(e,!0)};return _&&(E==null||E===``)?null:o(t,{type:`tabs`,label:h,error:g,size:T,element_blok:{className:[y||``]},element_input:{className:[i.r],props:{"data-disabled":v||!D?`true`:void 0,"data-variant":w}},children:[x?a(`span`,{className:e.a,children:x}):null,a(`div`,{className:i.i,role:`tablist`,"aria-label":h||m||`Вкладки`,style:k?void 0:{justifyContent:`flex-start`},children:O.map(e=>{let t=c(E,e.id),n=v||!D||e.disabled;return o(`button`,{type:`button`,role:`tab`,"aria-selected":t,"aria-disabled":n||void 0,disabled:n,className:[i.t,t?i.a:``].filter(Boolean).join(` `),style:k?void 0:{flex:`0 0 auto`},onClick:()=>{n||A(e.id)},onBlur:()=>{!f||!p||f({value:u?u.getValue(p,E):E,name:p})},children:[e.icon==null?null:a(`span`,{className:i.o,"aria-hidden":!0,children:e.icon}),a(`span`,{className:i.l,children:e.label})]},String(e.id))})}),b?a(`span`,{className:e.a,children:b}):null]})}l.displayName=`TabsField`;export{l as default};
@@ -17,7 +17,7 @@ export type TTags = TInput & {
17
17
  /**
18
18
  * Поле тегов. Backspace на пустом вводе удаляет последний чип.
19
19
  */
20
- declare function TagsField({ value, form, onValue, onBlur: onBlurField, name, placeholder, label, error, hidden, disabled, className, after, before, maxTags, maxLength, separators, }: TTags): import("react/jsx-runtime").JSX.Element | null;
20
+ declare function TagsField({ value, form, onValue, onBlur: onBlurField, name, placeholder, label, error, hidden, disabled, className, after, before, maxTags, maxLength, separators, size, }: TTags): import("react/jsx-runtime").JSX.Element | null;
21
21
  declare namespace TagsField {
22
22
  var displayName: string;
23
23
  }
@@ -1 +1 @@
1
- import e from"../styles/Field.module.js";import t from"../core/Field.js";import{useFormFieldState as n}from"../hooks/use.js";import{createFieldEmit as r}from"./emit.js";import i from"../styles/Tags.module.js";import a from"react";import{jsx as o,jsxs as s}from"react/jsx-runtime";function c(e){return Array.isArray(e)?e.map(String).map(e=>e.trim()).filter(Boolean):typeof e==`string`&&e.trim()?e.split(`,`).map(e=>e.trim()).filter(Boolean):[]}function l({value:l=[],form:u,onValue:d,onBlur:f,name:p=``,placeholder:m=`Добавить…`,label:h=``,error:g=``,hidden:_=!1,disabled:v=!1,className:y=``,after:b=``,before:x=``,maxTags:S,maxLength:C,separators:w=[`,`,`Enter`]}){let{value:T}=n(u,p,l),E=c(T),D=!v,[O,k]=a.useState(``),A=a.useRef(null),j=e=>{r(u,p,d)(e,!0)},M=e=>{let t=e.trim();if(t&&!(C&&t.length>C)){if(E.some(e=>e.toLowerCase()===t.toLowerCase())){k(``);return}S!==void 0&&E.length>=S||(j([...E,t]),k(``))}},N=e=>{D&&j(E.filter((t,n)=>n!==e))},P=e=>{if(D){if(w.includes(e.key)||e.key===`,`&&w.includes(`,`)){e.preventDefault(),M(O);return}e.key===`Backspace`&&!O&&E.length>0&&(e.preventDefault(),N(E.length-1))}},F=E.length===0;return _&&F?null:s(t,{type:`tags`,label:h,error:g,element_blok:{className:[y||``]},element_input:{className:[i.r],props:{"data-disabled":v||!D?`true`:void 0,onClick:()=>A.current?.focus()}},children:[x?o(`span`,{className:e.a,children:x}):null,s(`div`,{className:i.i,children:[E.map((e,t)=>s(`span`,{className:i.c,children:[o(`span`,{className:i.l,children:e}),D?o(`button`,{type:`button`,className:i.m,"aria-label":`Удалить ${e}`,onClick:e=>{e.stopPropagation(),N(t)},children:`×`}):null]},`${e}-${t}`)),D&&(S===void 0||E.length<S)?o(`input`,{ref:A,className:i.n,value:O,placeholder:E.length===0?m:``,disabled:v,maxLength:C,"aria-label":h||m||`Теги`,onChange:e=>k(e.target.value),onKeyDown:P,onBlur:()=>{O.trim()&&M(O),f?.({value:E,name:p})}}):null]}),b?o(`span`,{className:e.a,children:b}):null]})}l.displayName=`TagsField`;export{l as default};
1
+ import e from"../styles/Field.module.js";import t from"../core/Field.js";import{useFormFieldState as n}from"../hooks/use.js";import{createFieldEmit as r}from"./emit.js";import i from"../styles/Tags.module.js";import a from"react";import{jsx as o,jsxs as s}from"react/jsx-runtime";function c(e){return Array.isArray(e)?e.map(String).map(e=>e.trim()).filter(Boolean):typeof e==`string`&&e.trim()?e.split(`,`).map(e=>e.trim()).filter(Boolean):[]}function l({value:l=[],form:u,onValue:d,onBlur:f,name:p=``,placeholder:m=`Добавить…`,label:h=``,error:g=``,hidden:_=!1,disabled:v=!1,className:y=``,after:b=``,before:x=``,maxTags:S,maxLength:C,separators:w=[`,`,`Enter`],size:T=`m`}){let{value:E}=n(u,p,l),D=c(E),O=!v,[k,A]=a.useState(``),j=a.useRef(null),M=e=>{r(u,p,d)(e,!0)},N=e=>{let t=e.trim();if(t&&!(C&&t.length>C)){if(D.some(e=>e.toLowerCase()===t.toLowerCase())){A(``);return}S!==void 0&&D.length>=S||(M([...D,t]),A(``))}},P=e=>{O&&M(D.filter((t,n)=>n!==e))},F=e=>{if(O){if(w.includes(e.key)||e.key===`,`&&w.includes(`,`)){e.preventDefault(),N(k);return}e.key===`Backspace`&&!k&&D.length>0&&(e.preventDefault(),P(D.length-1))}},I=D.length===0;return _&&I?null:s(t,{type:`tags`,label:h,error:g,size:T,element_blok:{className:[y||``]},element_input:{className:[i.r],props:{"data-disabled":v||!O?`true`:void 0,onClick:()=>j.current?.focus()}},children:[x?o(`span`,{className:e.a,children:x}):null,s(`div`,{className:i.i,children:[D.map((e,t)=>s(`span`,{className:i.c,children:[o(`span`,{className:i.l,children:e}),O?o(`button`,{type:`button`,className:i.m,"aria-label":`Удалить ${e}`,onClick:e=>{e.stopPropagation(),P(t)},children:`×`}):null]},`${e}-${t}`)),O&&(S===void 0||D.length<S)?o(`input`,{ref:j,className:i.n,value:k,placeholder:D.length===0?m:``,disabled:v,maxLength:C,"aria-label":h||m||`Теги`,onChange:e=>A(e.target.value),onKeyDown:F,onBlur:()=>{k.trim()&&N(k),f?.({value:D,name:p})}}):null]}),b?o(`span`,{className:e.a,children:b}):null]})}l.displayName=`TagsField`;export{l as default};
@@ -35,7 +35,7 @@ export type TTime = TInput & {
35
35
  * Поле времени. Пока фокус в группе — в DOM сырые цифры; в форму `HH:mm` уходит на blur.
36
36
  * Popup слотов — при `picker` / `presets`.
37
37
  */
38
- declare function TimeField({ value, form, onValue, onBlur: onBlurField, name, placeholder, label, hidden, disabled, error, className, after, before, step, min, max, id, spellCheck, align, picker, presets, }: TTime): import("react/jsx-runtime").JSX.Element | null;
38
+ declare function TimeField({ value, form, onValue, onBlur: onBlurField, name, placeholder, label, hidden, disabled, error, className, after, before, step, min, max, id, spellCheck, align, picker, presets, size, }: TTime): import("react/jsx-runtime").JSX.Element | null;
39
39
  declare namespace TimeField {
40
40
  var displayName: string;
41
41
  }
@@ -1 +1 @@
1
- import e from"../styles/Field.module.js";import t from"../core/Field.js";import{useFormFieldState as n}from"../hooks/use.js";import{createFieldEmit as r}from"./emit.js";import i from"../events/onEvent.js";import a from"../styles/Time.module.js";import o from"./TimePicker.js";import{buildTimeSlots as s,clampToRange as c,combine as l,digitsOnly as u,getRangeStartOffsetInElement as ee,normalizeTime as d,pad2 as f,parsePartDigits as p,setCursorPosition as m,snapMinute as h,splitTime as g}from"./timeUtils.js";import _ from"react";import{Fragment as te,jsx as v,jsxs as y}from"react/jsx-runtime";import{createPortal as ne}from"react-dom";function re(){return y(`svg`,{viewBox:`0 0 24 24`,width:`20`,height:`20`,fill:`none`,"aria-hidden":!0,children:[v(`circle`,{cx:`12`,cy:`12`,r:`8.25`,stroke:`currentColor`,strokeWidth:`1.75`}),v(`path`,{d:`M12 7.5V12l3 2`,stroke:`currentColor`,strokeWidth:`1.75`,strokeLinecap:`round`,strokeLinejoin:`round`})]})}function b({value:b=``,form:x,onValue:S,onBlur:C,name:w=``,placeholder:T=``,label:E=``,hidden:ie=!1,disabled:D=!1,error:ae=``,className:oe=``,after:O=``,before:k=``,step:A=60,min:j,max:M,id:se,spellCheck:N=!1,align:ce=`start`,picker:P=!1,presets:F}){let{value:le,version:ue}=n(x,w,b),I=d(le),L=!D,R=_.useRef(null),z=_.useRef(null),B=_.useRef(null),V=_.useRef(null),[H,U]=_.useState(!1),[W,G]=_.useState(!1),[K,q]=_.useState(null),[J,Y]=_.useState(0),de=_.useId(),X=_.useMemo(()=>s(A,j,M,F),[A,j,M,F]);_.useLayoutEffect(()=>{if(!H||!L)return;let{h:e,m:t}=g(I),n=(e,t)=>{e&&(t===null?e.innerHTML=`<br>`:e.textContent=String(t))};n(R.current,e),n(z.current,t)},[H,I,ue,L]);let fe=_.useCallback(()=>{let e=p(R.current?.textContent||``,23),t=p(z.current?.textContent||``,59);if(e===null&&t===null)return``;let n=l(e,t);if(!n)return``;let{h:r,m:i}=g(n);return i!==null&&(n=l(r,h(i,A))),n&&=c(n,j,M),n||``},[j,M,A]),Z=_.useCallback(e=>{let t=d(e);if(t){let{h:e,m:n}=g(t);n!==null&&(t=l(e,h(n,A))),t=c(t,j,M)}return r(x,w,S)(t,!0),t},[x,w,S,j,M,A]),pe=_.useCallback(()=>{if(!P||!L||X.length===0)return;let e=V.current;if(!e)return;let t=Math.max(0,X.findIndex(e=>e===I));Y(t>=0?t:0),q(e.getBoundingClientRect()),G(!0)},[P,L,X,I]);_.useEffect(()=>{if(!W)return;let e=()=>{let e=V.current;e&&q(e.getBoundingClientRect())};return window.addEventListener(`scroll`,e,!0),window.addEventListener(`resize`,e),()=>{window.removeEventListener(`scroll`,e,!0),window.removeEventListener(`resize`,e)}},[W]),_.useEffect(()=>{if(!W)return;let e=e=>{if(e.key===`Escape`){e.preventDefault(),G(!1);return}if(X.length!==0){if(e.key===`ArrowDown`)e.preventDefault(),Y(e=>(e+1)%X.length);else if(e.key===`ArrowUp`)e.preventDefault(),Y(e=>e-1<0?X.length-1:e-1);else if(e.key===`Enter`){e.preventDefault();let t=X[J];t&&(Z(t),G(!1))}}};return window.addEventListener(`keydown`,e),()=>window.removeEventListener(`keydown`,e)},[W,X,J,Z]);let me=e=>t=>{if(t.preventDefault(),!L)return;let n=u(t.clipboardData?.getData(`text/plain`)??``),r=e===`hour`?23:59;if(n.length>=4){let e=Math.min(23,Math.max(0,parseInt(n.slice(0,2),10))),t=Math.min(59,Math.max(0,parseInt(n.slice(2,4),10))),r=R.current,i=z.current;r&&(r.textContent=String(e),queueMicrotask(()=>m(String(e).length,r))),i&&(i.textContent=String(t),queueMicrotask(()=>m(String(t).length,i)));return}let i=n.slice(0,2),a=t.currentTarget;if(i===``){a.innerHTML=`<br>`,queueMicrotask(()=>m(0,a));return}let o=parseInt(i,10);if(Number.isNaN(o))return;let s=String(Math.min(r,Math.max(0,o)));a.textContent=s,queueMicrotask(()=>m(s.length,a))},he=e=>{let t=e.target,n=t.textContent||``,r=ee(t),i=n.slice(0,r).replace(/\D/g,``).length,a=u(n).slice(0,2);if(a===``){t.innerHTML=`<br>`,queueMicrotask(()=>m(0,t));return}let o=parseInt(a,10);if(Number.isNaN(o))return;let s=String(Math.min(23,Math.max(0,o)));t.textContent=s;let c=Math.min(i,s.length);queueMicrotask(()=>m(c,t))},ge=e=>{let t=e.target,n=t.textContent||``,r=ee(t),i=n.slice(0,r).replace(/\D/g,``).length,a=u(n).slice(0,2);if(a===``){t.innerHTML=`<br>`,queueMicrotask(()=>m(0,t));return}let o=parseInt(a,10);if(Number.isNaN(o))return;let s=String(Math.min(59,Math.max(0,o)));t.textContent=s;let c=Math.min(i,s.length);queueMicrotask(()=>m(c,t))},_e=e=>{(e.key===`Enter`||e.key===`:`)&&(e.preventDefault(),z.current?.focus())},ve=e=>{e.key===`Enter`&&e.preventDefault()},ye=e=>{let t=e.currentTarget;(t.textContent||``).trim().length||(t.innerHTML=`<br>`),L&&U(!0)},be=e=>{i.Blur(e)};_.useEffect(()=>{let e=B.current;if(!e)return;let t=t=>{let n=t.relatedTarget;if(n&&e.contains(n))return;let i=fe();r(x,w,S)(i,!0),C&&w&&C({value:i,name:w}),U(!1)};return e.addEventListener(`focusout`,t),()=>e.removeEventListener(`focusout`,t)},[x,w,S,C,j,M,A,fe]);let{h:xe,m:Se}=g(I),Q={};L&&(Q.edit=``);let $={...Q},Ce={...Q};T&&($.placeholder=T);let we=I!==``||H;return ie&&I===``?null:y(te,{children:[v(`div`,{ref:V,children:y(t,{type:`time`,label:E,error:ae,element_blok:{className:[oe||``]},element_input:{className:[e.w,a.r,ce===`center`?a.c:``].filter(Boolean),props:{"data-disabled":D||!L?`true`:void 0}},children:[k?v(`span`,{className:e.a,children:k}):null,y(`div`,{ref:B,className:a.i,role:`group`,"aria-label":E||`Время`,children:[v(`div`,{id:se,ref:R,className:a.p,contentEditable:L?`plaintext-only`:!1,suppressContentEditableWarning:!0,spellCheck:N,inputMode:`numeric`,onPaste:me(`hour`),onInput:he,onKeyDown:_e,onFocus:ye,onBlur:be,"aria-label":`Часы, 0–23`,...$,children:!L||!H?xe===null?``:f(xe):null}),we&&v(`span`,{className:a.s,"aria-hidden":`true`,children:`:`}),v(`div`,{ref:z,className:a.p,contentEditable:L?`plaintext-only`:!1,suppressContentEditableWarning:!0,spellCheck:N,inputMode:`numeric`,onPaste:me(`minute`),onInput:ge,onKeyDown:ve,onFocus:ye,onBlur:be,"aria-label":`Минуты, 0–59`,...Ce,children:!L||!H?Se===null?``:f(Se):null})]}),P?v(`button`,{type:`button`,className:a.b,disabled:!L||X.length===0,"aria-label":`Быстрый выбор времени`,"aria-haspopup":`listbox`,"aria-expanded":W,"aria-controls":de,onMouseDown:e=>e.preventDefault(),onClick:pe,children:v(re,{})}):null,O?v(`span`,{className:e.a,children:O}):null]})}),W&&K&&ne(v(o,{parent:K,slots:X,current:I,activeIndex:J,listId:de,className:oe,setOpen:G,setActiveIndex:Y,onPick:e=>{Z(e),G(!1)}}),document.body)]})}b.displayName=`TimeField`;export{b as default};
1
+ import e from"../styles/Field.module.js";import t from"../core/Field.js";import{useFormFieldState as n}from"../hooks/use.js";import{createFieldEmit as r}from"./emit.js";import i from"../events/onEvent.js";import a from"../styles/Time.module.js";import o from"./TimePicker.js";import{buildTimeSlots as s,clampToRange as c,combine as l,digitsOnly as u,getRangeStartOffsetInElement as ee,normalizeTime as d,pad2 as f,parsePartDigits as p,setCursorPosition as m,snapMinute as h,splitTime as g}from"./timeUtils.js";import _ from"react";import{Fragment as te,jsx as v,jsxs as y}from"react/jsx-runtime";import{createPortal as ne}from"react-dom";function re(){return y(`svg`,{viewBox:`0 0 24 24`,width:`20`,height:`20`,fill:`none`,"aria-hidden":!0,children:[v(`circle`,{cx:`12`,cy:`12`,r:`8.25`,stroke:`currentColor`,strokeWidth:`1.75`}),v(`path`,{d:`M12 7.5V12l3 2`,stroke:`currentColor`,strokeWidth:`1.75`,strokeLinecap:`round`,strokeLinejoin:`round`})]})}function b({value:b=``,form:x,onValue:S,onBlur:C,name:w=``,placeholder:T=``,label:E=``,hidden:ie=!1,disabled:D=!1,error:ae=``,className:O=``,after:oe=``,before:se=``,step:k=60,min:A,max:j,id:ce,spellCheck:M=!1,align:le=`start`,picker:N=!1,presets:P,size:ue=`m`}){let{value:de,version:fe}=n(x,w,b),F=d(de),I=!D,L=_.useRef(null),R=_.useRef(null),z=_.useRef(null),B=_.useRef(null),[V,H]=_.useState(!1),[U,W]=_.useState(!1),[G,pe]=_.useState(null),[K,q]=_.useState(0),J=_.useId(),Y=_.useMemo(()=>s(k,A,j,P),[k,A,j,P]);_.useLayoutEffect(()=>{if(!V||!I)return;let{h:e,m:t}=g(F),n=(e,t)=>{e&&(t===null?e.innerHTML=`<br>`:e.textContent=String(t))};n(L.current,e),n(R.current,t)},[V,F,fe,I]);let me=_.useCallback(()=>{let e=p(L.current?.textContent||``,23),t=p(R.current?.textContent||``,59);if(e===null&&t===null)return``;let n=l(e,t);if(!n)return``;let{h:r,m:i}=g(n);return i!==null&&(n=l(r,h(i,k))),n&&=c(n,A,j),n||``},[A,j,k]),X=_.useCallback(e=>{let t=d(e);if(t){let{h:e,m:n}=g(t);n!==null&&(t=l(e,h(n,k))),t=c(t,A,j)}return r(x,w,S)(t,!0),t},[x,w,S,A,j,k]),he=_.useCallback(()=>{if(!N||!I||Y.length===0)return;let e=B.current;if(!e)return;let t=Math.max(0,Y.findIndex(e=>e===F));q(t>=0?t:0),pe(e.getBoundingClientRect()),W(!0)},[N,I,Y,F]);_.useEffect(()=>{if(!U)return;let e=()=>{let e=B.current;e&&pe(e.getBoundingClientRect())};return window.addEventListener(`scroll`,e,!0),window.addEventListener(`resize`,e),()=>{window.removeEventListener(`scroll`,e,!0),window.removeEventListener(`resize`,e)}},[U]),_.useEffect(()=>{if(!U)return;let e=e=>{if(e.key===`Escape`){e.preventDefault(),W(!1);return}if(Y.length!==0){if(e.key===`ArrowDown`)e.preventDefault(),q(e=>(e+1)%Y.length);else if(e.key===`ArrowUp`)e.preventDefault(),q(e=>e-1<0?Y.length-1:e-1);else if(e.key===`Enter`){e.preventDefault();let t=Y[K];t&&(X(t),W(!1))}}};return window.addEventListener(`keydown`,e),()=>window.removeEventListener(`keydown`,e)},[U,Y,K,X]);let ge=e=>t=>{if(t.preventDefault(),!I)return;let n=u(t.clipboardData?.getData(`text/plain`)??``),r=e===`hour`?23:59;if(n.length>=4){let e=Math.min(23,Math.max(0,parseInt(n.slice(0,2),10))),t=Math.min(59,Math.max(0,parseInt(n.slice(2,4),10))),r=L.current,i=R.current;r&&(r.textContent=String(e),queueMicrotask(()=>m(String(e).length,r))),i&&(i.textContent=String(t),queueMicrotask(()=>m(String(t).length,i)));return}let i=n.slice(0,2),a=t.currentTarget;if(i===``){a.innerHTML=`<br>`,queueMicrotask(()=>m(0,a));return}let o=parseInt(i,10);if(Number.isNaN(o))return;let s=String(Math.min(r,Math.max(0,o)));a.textContent=s,queueMicrotask(()=>m(s.length,a))},_e=e=>{let t=e.target,n=t.textContent||``,r=ee(t),i=n.slice(0,r).replace(/\D/g,``).length,a=u(n).slice(0,2);if(a===``){t.innerHTML=`<br>`,queueMicrotask(()=>m(0,t));return}let o=parseInt(a,10);if(Number.isNaN(o))return;let s=String(Math.min(23,Math.max(0,o)));t.textContent=s;let c=Math.min(i,s.length);queueMicrotask(()=>m(c,t))},ve=e=>{let t=e.target,n=t.textContent||``,r=ee(t),i=n.slice(0,r).replace(/\D/g,``).length,a=u(n).slice(0,2);if(a===``){t.innerHTML=`<br>`,queueMicrotask(()=>m(0,t));return}let o=parseInt(a,10);if(Number.isNaN(o))return;let s=String(Math.min(59,Math.max(0,o)));t.textContent=s;let c=Math.min(i,s.length);queueMicrotask(()=>m(c,t))},ye=e=>{(e.key===`Enter`||e.key===`:`)&&(e.preventDefault(),R.current?.focus())},be=e=>{e.key===`Enter`&&e.preventDefault()},xe=e=>{let t=e.currentTarget;(t.textContent||``).trim().length||(t.innerHTML=`<br>`),I&&H(!0)},Se=e=>{i.Blur(e)};_.useEffect(()=>{let e=z.current;if(!e)return;let t=t=>{let n=t.relatedTarget;if(n&&e.contains(n))return;let i=me();r(x,w,S)(i,!0),C&&w&&C({value:i,name:w}),H(!1)};return e.addEventListener(`focusout`,t),()=>e.removeEventListener(`focusout`,t)},[x,w,S,C,A,j,k,me]);let{h:Z,m:Ce}=g(F),Q={};I&&(Q.edit=``);let $={...Q},we={...Q};T&&($.placeholder=T);let Te=F!==``||V;return ie&&F===``?null:y(te,{children:[v(`div`,{ref:B,children:y(t,{type:`time`,label:E,error:ae,size:ue,element_blok:{className:[O||``]},element_input:{className:[e.w,a.r,le===`center`?a.c:``].filter(Boolean),props:{"data-disabled":D||!I?`true`:void 0}},children:[se?v(`span`,{className:e.a,children:se}):null,y(`div`,{ref:z,className:a.i,role:`group`,"aria-label":E||`Время`,children:[v(`div`,{id:ce,ref:L,className:a.p,contentEditable:I?`plaintext-only`:!1,suppressContentEditableWarning:!0,spellCheck:M,inputMode:`numeric`,onPaste:ge(`hour`),onInput:_e,onKeyDown:ye,onFocus:xe,onBlur:Se,"aria-label":`Часы, 0–23`,...$,children:!I||!V?Z===null?``:f(Z):null}),Te&&v(`span`,{className:a.s,"aria-hidden":`true`,children:`:`}),v(`div`,{ref:R,className:a.p,contentEditable:I?`plaintext-only`:!1,suppressContentEditableWarning:!0,spellCheck:M,inputMode:`numeric`,onPaste:ge(`minute`),onInput:ve,onKeyDown:be,onFocus:xe,onBlur:Se,"aria-label":`Минуты, 0–59`,...we,children:!I||!V?Ce===null?``:f(Ce):null})]}),N?v(`button`,{type:`button`,className:a.b,disabled:!I||Y.length===0,"aria-label":`Быстрый выбор времени`,"aria-haspopup":`listbox`,"aria-expanded":U,"aria-controls":J,onMouseDown:e=>e.preventDefault(),onClick:he,children:v(re,{})}):null,oe?v(`span`,{className:e.a,children:oe}):null]})}),U&&G&&ne(v(o,{parent:G,slots:Y,current:F,activeIndex:K,listId:J,className:O,setOpen:W,setActiveIndex:q,onPick:e=>{X(e),W(!1)}}),document.body)]})}b.displayName=`TimeField`;export{b as default};
@@ -0,0 +1,2 @@
1
+ /** Русское склонение для live region результатов поиска. */
2
+ export declare function formatResultsCount(n: number): string;
@@ -0,0 +1 @@
1
+ function e(e){let t=Math.abs(Math.trunc(e))%100,n=t%10;return t>10&&t<20?`${e} результатов`:n===1?`${e} результат`:n>=2&&n<=4?`${e} результата`:`${e} результатов`}export{e as formatResultsCount};
@@ -0,0 +1,5 @@
1
+ /** Подпись hotkey для badge (⌘K / Ctrl+K / /). */
2
+ export type SearchHotkey = false | "/" | "mod+/" | "mod+k";
3
+ export declare function isMacPlatform(): boolean;
4
+ export declare function hotkeyBadgeLabel(hotkey: Exclude<SearchHotkey, false>): string;
5
+ export declare function matchHotkey(e: KeyboardEvent, hotkey: Exclude<SearchHotkey, false>): boolean;
@@ -0,0 +1 @@
1
+ function e(){return typeof navigator>`u`?!1:/Mac|iPhone|iPad|iPod/i.test(navigator.platform||navigator.userAgent)}function t(t){if(t===`/`)return`/`;let n=e()?`⌘`:`Ctrl+`;return t===`mod+k`?`${n}K`:`${n}/`}function n(e,t){return t===`/`?e.key===`/`&&!e.metaKey&&!e.ctrlKey&&!e.altKey:t===`mod+k`?(e.key===`k`||e.key===`K`)&&(e.metaKey||e.ctrlKey)&&!e.altKey:e.key===`/`&&(e.metaKey||e.ctrlKey)}export{t as hotkeyBadgeLabel,n as matchHotkey};
package/dist/index.d.ts CHANGED
@@ -28,6 +28,7 @@ export { default as DragDropField } from './fields/DragDrop';
28
28
  export { default as RichTextField } from './fields/RichText';
29
29
  export { default as HiddenField } from './fields/Hidden';
30
30
  export { default as DisplayField } from './fields/Display';
31
+ export { default as SearchField } from './fields/Search';
31
32
  export { default as FieldGroup } from './fields/FieldGroup';
32
33
  export type { FieldGroupFieldKind, FieldGroupItem, FieldGroupProps, } from './fields/FieldGroup';
33
34
  export { useForm, useFormField, useFormFieldState } from './hooks/use';
@@ -57,12 +58,13 @@ export type { TTags } from './fields/Tags';
57
58
  export type { TRating } from './fields/Rating';
58
59
  export type { TCode } from './fields/Code';
59
60
  export { DEFAULT_PASSWORD_GENERATE, DEFAULT_PASSWORD_GENERATE_LENGTH, charsetFromGenerateSpec, resolveGeneratePool, generatePasswordValue, } from './fields/passwordUtils';
60
- export type { TTabs } from './fields/Tabs';
61
+ export type { TTabs, TTabsVariant } from './fields/Tabs';
61
62
  export type { TFile, TFileMeta } from './fields/File';
62
63
  export type { TDragDrop, TDragDropLayout } from './fields/DragDrop';
63
64
  export type { TRichText } from './fields/RichText';
64
65
  export type { THidden } from './fields/Hidden';
65
66
  export type { TDisplay } from './fields/Display';
67
+ export type { TSearch, SearchWidth, SearchVariant, SearchHotkey, SearchSuggestion, } from './fields/Search';
66
68
  export type { FormValues, UseFormApi, UseFormFieldStateResult, } from './hooks/use';
67
69
  export type { EditableFieldTarget, EditableClipboardEvent, } from './events/onEvent';
68
70
  export { asEditableClipboard } from './events/onEvent';