@elcrm/form 0.0.63 → 0.0.65

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 (94) hide show
  1. package/README.md +139 -0
  2. package/dist/Form.d.ts +20 -0
  3. package/dist/Form.js +11 -0
  4. package/dist/FormInitContext.d.ts +25 -0
  5. package/dist/FormInitContext.js +20 -0
  6. package/dist/assets/styles/Field.module.css +1 -0
  7. package/dist/assets/styles/Form.module.css +1 -0
  8. package/dist/assets/styles/Select.module.css +1 -0
  9. package/dist/core/Field.d.ts +19 -0
  10. package/dist/core/Field.js +33 -0
  11. package/dist/events/onEvent.d.ts +55 -0
  12. package/dist/events/onEvent.js +67 -0
  13. package/dist/fields/Date.d.ts +13 -0
  14. package/dist/fields/Date.js +352 -0
  15. package/dist/fields/Input.d.ts +12 -0
  16. package/dist/fields/Input.js +127 -0
  17. package/dist/fields/Mask.d.ts +9 -0
  18. package/dist/fields/Mask.js +101 -0
  19. package/dist/fields/Modal.d.ts +25 -0
  20. package/dist/fields/Modal.js +62 -0
  21. package/dist/fields/Money.d.ts +14 -0
  22. package/dist/fields/Money.js +100 -0
  23. package/dist/fields/Numeric.d.ts +9 -0
  24. package/dist/fields/Numeric.js +73 -0
  25. package/dist/fields/Options.d.ts +32 -0
  26. package/dist/fields/Options.js +69 -0
  27. package/dist/fields/Password.d.ts +6 -0
  28. package/dist/fields/Password.js +153 -0
  29. package/dist/fields/Phone.d.ts +7 -0
  30. package/dist/fields/Phone.js +112 -0
  31. package/dist/fields/Range.d.ts +16 -0
  32. package/dist/fields/Range.js +103 -0
  33. package/dist/fields/Select.d.ts +21 -0
  34. package/dist/fields/Select.js +146 -0
  35. package/dist/fields/Textarea.d.ts +7 -0
  36. package/dist/fields/Textarea.js +52 -0
  37. package/dist/fields/Time.d.ts +26 -0
  38. package/dist/fields/Time.js +254 -0
  39. package/dist/fields/type.d.ts +77 -0
  40. package/dist/fields/visibility.d.ts +6 -0
  41. package/dist/fields/visibility.js +6 -0
  42. package/dist/hooks/use.d.ts +41 -0
  43. package/dist/hooks/use.js +57 -0
  44. package/dist/index.d.ts +26 -2
  45. package/dist/index.js +26 -0
  46. package/dist/mask/MaskPhone.d.ts +8 -0
  47. package/dist/mask/MaskPhone.js +1384 -0
  48. package/dist/package.js +96 -0
  49. package/dist/styles/Field.module.js +22 -0
  50. package/dist/styles/Form.module.js +12 -0
  51. package/dist/styles/Select.module.js +8 -0
  52. package/package.json +72 -11
  53. package/src/lib/styles/Field.module.scss +315 -0
  54. package/src/lib/styles/Form.module.scss +313 -0
  55. package/src/lib/styles/Select.module.scss +90 -0
  56. package/src/lib/styles/dark.css +47 -0
  57. package/src/lib/styles/light.css +51 -0
  58. package/dist/index.css +0 -1
  59. package/dist/index.es.js +0 -5045
  60. package/dist/index.umd.js +0 -89
  61. package/dist/src/lib/Captcha.d.ts +0 -1
  62. package/dist/src/lib/Check.d.ts +0 -13
  63. package/dist/src/lib/Code.d.ts +0 -22
  64. package/dist/src/lib/Color.d.ts +0 -22
  65. package/dist/src/lib/Field.d.ts +0 -13
  66. package/dist/src/lib/Files.d.ts +0 -20
  67. package/dist/src/lib/Generator.d.ts +0 -1
  68. package/dist/src/lib/Group.d.ts +0 -21
  69. package/dist/src/lib/Image.d.ts +0 -22
  70. package/dist/src/lib/Init.d.ts +0 -1
  71. package/dist/src/lib/MaskPhone.d.ts +0 -2
  72. package/dist/src/lib/Message.d.ts +0 -15
  73. package/dist/src/lib/Money.d.ts +0 -22
  74. package/dist/src/lib/Month.d.ts +0 -18
  75. package/dist/src/lib/Palette.d.ts +0 -9
  76. package/dist/src/lib/Progress.d.ts +0 -9
  77. package/dist/src/lib/Toogle.d.ts +0 -8
  78. package/dist/src/lib/Users.d.ts +0 -1
  79. package/dist/src/lib/_Time.d.ts +0 -0
  80. package/dist/src/lib/fields/Date.d.ts +0 -18
  81. package/dist/src/lib/fields/Input.d.ts +0 -27
  82. package/dist/src/lib/fields/Mask.d.ts +0 -19
  83. package/dist/src/lib/fields/Modal.d.ts +0 -19
  84. package/dist/src/lib/fields/Numeric.d.ts +0 -6
  85. package/dist/src/lib/fields/Options.d.ts +0 -22
  86. package/dist/src/lib/fields/Password.d.ts +0 -23
  87. package/dist/src/lib/fields/Phone.d.ts +0 -21
  88. package/dist/src/lib/fields/Select copy.d.ts +0 -23
  89. package/dist/src/lib/fields/Select.d.ts +0 -28
  90. package/dist/src/lib/fields/Textarea.d.ts +0 -23
  91. package/dist/src/lib/fields/type.d.ts +0 -30
  92. package/dist/src/lib/index.d.ts +0 -16
  93. package/dist/src/lib/onEvent.d.ts +0 -2
  94. package/dist/src/lib/use.d.ts +0 -10
package/README.md CHANGED
@@ -0,0 +1,139 @@
1
+ # @elcrm/form
2
+
3
+ React-компоненты полей ввода для elCRM: текст, пароль, маски, деньги, даты, время, селект, диапазон и связка с хуком **`useForm`** (подписки по имени поля, без лишних перерисовок всей формы).
4
+
5
+ ## Установка
6
+
7
+ ```bash
8
+ npm install @elcrm/form
9
+ ```
10
+
11
+ **Peer-зависимости:** **`react`** и **`react-dom`** (версии — в `package.json`).
12
+
13
+ ## Стили и темы
14
+
15
+ - Темы: **`@elcrm/form/light.css`**, **`@elcrm/form/dark.css`** — переключение через атрибут **`data-theme`** на контейнере.
16
+ - Стили разметки полей (SCSS-модули): **`import "@elcrm/form/style.css"`** (или **`@elcrm/form/dist/style.css`**).
17
+
18
+ ## Быстрый старт
19
+
20
+ ```tsx
21
+ import { useForm, StringField, PasswordField } from "@elcrm/form";
22
+ import "@elcrm/form/light.css";
23
+
24
+ function Example() {
25
+ const form = useForm({ login: "", password: "" });
26
+
27
+ return (
28
+ <form autoComplete="on" onSubmit={(e) => e.preventDefault()}>
29
+ {/*
30
+ Логин: native + autoComplete — нативный <input> для автозаполнения браузером.
31
+ Без native StringField рендерит contentEditable — автозаполнение логина как у обычной формы не гарантируется.
32
+ */}
33
+ <StringField
34
+ name="login"
35
+ form={form}
36
+ value=""
37
+ label="Логин"
38
+ native
39
+ autoComplete="username"
40
+ />
41
+ <PasswordField
42
+ name="password"
43
+ form={form}
44
+ value=""
45
+ label="Пароль"
46
+ />
47
+ </form>
48
+ );
49
+ }
50
+ ```
51
+
52
+ ### `Form.Init` (опционально)
53
+
54
+ Нужен, если используются **уведомления** (например, копирование телефона в буфер) или **свои модалки** для **ModalField** / **OptionsField** (`modal="module.name"`). Рендерит **`null`**, дочерние элементы не оборачивает.
55
+
56
+ ```tsx
57
+ import { Form, useForm, PhoneField } from "@elcrm/form";
58
+
59
+ function Example() {
60
+ const form = useForm({ phone: "" });
61
+
62
+ return (
63
+ <>
64
+ <Form.Init
65
+ onNotice={(message) => {
66
+ /* тост / snackbar */
67
+ }}
68
+ onModal={({
69
+ module,
70
+ modalName,
71
+ fieldName,
72
+ value,
73
+ callback,
74
+ options,
75
+ }) => {
76
+ /* открыть модалку и передать результат в callback(...) */
77
+ }}
78
+ />
79
+ <PhoneField name="phone" form={form} label="Телефон" />
80
+ </>
81
+ );
82
+ }
83
+ ```
84
+
85
+ Без **`Form.Init`** колбэки **`onNotice`** и **`onModal`** из полей — заглушки (no-op).
86
+
87
+ ## Хук `useForm`
88
+
89
+ - **`useForm(initialValues?)`** — хранение значений, **`onValue`** / **`setValue`** / **`setValues`**, подписки по имени поля.
90
+ - Поля с **`name`** и **`form`** читают значение через **`useFormFieldState`** и обновляют форму согласно своей логике.
91
+
92
+ Подробнее о API — в исходниках **`hooks/use.ts`** и **`CHANGELOG.md`**.
93
+
94
+ ## Общие пропы (`TInput`)
95
+
96
+ База: **`TFieldFormBindings`** (связь с формой) + **`TFieldPresentation`** (оформление).
97
+
98
+ | Проп | Описание |
99
+ | ---------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
100
+ | **`name`**, **`form`**, **`value`**, **`onValue`**, **`onBlur`** | Связь с формой; **`onBlur`** — «коммит» после ухода фокуса, аргумент **`{ value, name }`**, не нативный `FocusEvent`. |
101
+ | **`label`**, **`placeholder`**, **`error`**, **`className`**, **`id`** | Подпись, плейсхолдер, текст ошибки, класс блока, id. |
102
+ | **`disabled`** | Только просмотр / без ввода. |
103
+ | **`hidden`** | При **`true`** поле **не рендерится, только если значение пустое**; при непустом — **показывается**. |
104
+ | **`before`**, **`after`** | Узлы до/после области ввода (например иконки). |
105
+ | **`native`** | Только **`StringField`**: нативный **`<input>`** вместо **contentEditable** — для **автозаполнения** логина/почты; сочетать с **`autoComplete`**, **`inputType`**. |
106
+ | **`autoComplete`**, **`inputType`** | Атрибуты нативного поля при **`native`** (например **`username`**, **`email`**). |
107
+ | **`inputmode`**, **`spellCheck`**, **`maxLength`** | Подсказки ввода (в т.ч. мобильная клавиатура), орфография, лимит длины — по смыслу каждого компонента. |
108
+
109
+ У **`PasswordField`** свой тип **`TPasswordField`**: проп **`native`** там означает **«не рендерить компонент»** (внешний нативный пароль), не путать с **`native`** у **`StringField`**.
110
+
111
+ ### `PasswordField`
112
+
113
+ - Нативный **`<input type="password"`** / **`text`** при показе пароля.
114
+ - Переключатель «показать / скрыть» с **встроенными SVG-иконками**; свои иконки — проп **`eyes={[показать, скрыть]}`**.
115
+
116
+ ### Минимальный бандл (tree-shaking)
117
+
118
+ Пакет собран как **ESM по модулям**. Импорт из корня:
119
+
120
+ ```ts
121
+ import { DateField, useForm } from "@elcrm/form";
122
+ ```
123
+
124
+ Подключение только нужных файлов — **подпути** (имя файла совпадает с компонентом):
125
+
126
+ ```ts
127
+ import DateField from "@elcrm/form/fields/Date";
128
+ import { useForm } from "@elcrm/form/hooks/use";
129
+ ```
130
+
131
+ Префиксы: **`fields/*`**, **`hooks/*`**, **`events/*`**, **`core/*`**, **`mask/*`** — см. **`exports`** в **`package.json`**.
132
+
133
+ Объектные пропы (**`options`** у селекта и т.д.) не пересоздавайте на каждый рендер — вынесите в константы модуля.
134
+
135
+ ## Экспорт компонентов (корень пакета)
136
+
137
+ `StringField`, `PasswordField`, `TextareaField`, `NumberField`, `MoneyField`, `MaskField`, `PhoneField`, `DateField`, `TimeField`, `SelectField`, `RangeField`, `ModalField`, `OptionsField`, **`Form`**, хуки **`useForm`**, **`useFormField`**, **`useFormFieldState`**, **`useFormInit`**.
138
+
139
+ Типы: **`TInput`**, **`TPasswordField`**, **`TValue`**, **`TFieldFormBindings`**, **`TFieldPresentation`**, **`UseFormApi`**, **`FormInitProps`**, **`TModalOpenPayload`** и др.
package/dist/Form.d.ts ADDED
@@ -0,0 +1,20 @@
1
+ import { TModalOpenPayload } from './FormInitContext';
2
+ export type { TModalOpenPayload };
3
+ export type FormInitProps = {
4
+ /** Уведомления (копирование в буфер и т.п.) */
5
+ onNotice?: (message: string) => void;
6
+ /** Модальные окна выбора для полей ModalField / OptionsField (`modal="module.name"`) */
7
+ onModal?: (payload: TModalOpenPayload) => void;
8
+ };
9
+ /**
10
+ * Регистрирует колбэки глобально для полей. Не рендерит разметку и не принимает `children`.
11
+ * Достаточно один раз смонтировать рядом с формой или в корне приложения.
12
+ */
13
+ declare function Init({ onNotice, onModal }: FormInitProps): null;
14
+ declare namespace Init {
15
+ var displayName: string;
16
+ }
17
+ /** Пространство имён: `Form.Init` */
18
+ export declare const Form: {
19
+ Init: typeof Init;
20
+ };
package/dist/Form.js ADDED
@@ -0,0 +1,11 @@
1
+ import { registerFormInitHandlers as e } from "./FormInitContext.js";
2
+ import t from "react";
3
+ //#region src/lib/Form.tsx
4
+ var n = () => {}, r = (e) => {};
5
+ function i({ onNotice: i, onModal: a }) {
6
+ return t.useLayoutEffect(() => e(i ?? n, a ?? r), [i, a]), null;
7
+ }
8
+ i.displayName = "Form.Init";
9
+ var a = { Init: i };
10
+ //#endregion
11
+ export { a as Form };
@@ -0,0 +1,25 @@
1
+ import { TValue } from './fields/type';
2
+ /**
3
+ * Аргументы для колбэка открытия модалки (замена бывшему Modal.Open из @elcrm/modal).
4
+ * `module` и `modalName` — части строки пропа `modal` вида `"module.modalName"`.
5
+ */
6
+ export type TModalOpenPayload = {
7
+ module: string;
8
+ modalName: string;
9
+ /** Имя поля формы */
10
+ fieldName: string;
11
+ value?: unknown;
12
+ options?: Record<string, unknown>;
13
+ callback?: (value: unknown) => void;
14
+ onValue?: (data: TValue) => void | Promise<void>;
15
+ };
16
+ export type FormInitContextValue = {
17
+ /** Текст уведомления (например после копирования в буфер) */
18
+ onNotice: (message: string) => void;
19
+ /** Открыть модалку выбора — реализация на стороне приложения */
20
+ onModal: (payload: TModalOpenPayload) => void;
21
+ };
22
+ /** Регистрация колбэков из `Form.Init`; возвращает cleanup */
23
+ export declare function registerFormInitHandlers(onNotice: FormInitContextValue["onNotice"], onModal: FormInitContextValue["onModal"]): () => void;
24
+ /** Доступ к колбэкам в полях (без React Context и без обёртки-children) */
25
+ export declare function useFormInit(): FormInitContextValue;
@@ -0,0 +1,20 @@
1
+ var e = {
2
+ onNotice: () => {},
3
+ onModal: (e) => {}
4
+ }, t = { current: e }, n = {
5
+ onNotice: (e) => t.current.onNotice(e),
6
+ onModal: (e) => t.current.onModal(e)
7
+ };
8
+ function r(n, r) {
9
+ return t.current = {
10
+ onNotice: n,
11
+ onModal: r
12
+ }, () => {
13
+ t.current = e;
14
+ };
15
+ }
16
+ function i() {
17
+ return n;
18
+ }
19
+ //#endregion
20
+ export { r as registerFormInitHandlers, i as useFormInit };
@@ -0,0 +1 @@
1
+ ._l_zzcgd_2{min-width:var(--field-width);gap:var(--field-block-gap,0);flex-direction:column;margin:0;padding:0;display:flex;position:relative}._l_zzcgd_2>dt,._l_zzcgd_2>dd{margin:0;padding:0}._l_zzcgd_2[data-field=group] div{cursor:pointer;border-bottom:var(--field-border);padding:var(--field-padding);margin:0}._l_zzcgd_2[data-field=group] div:last-child{border-bottom:0}._l_zzcgd_2 [placeholder]:empty:before{content:attr(placeholder);color:var(--field-placeholder);display:block}._l_zzcgd_2 [placeholder]:focus:before{display:none}._f_zzcgd_33{box-sizing:border-box;align-items:center;gap:var(--field-icon-gap,10px);border:var(--field-border);border-radius:var(--field-radius);background:var(--field-background);color:var(--field-color);padding:0 var(--field-side-padding,14px);transition:border-color .16s,box-shadow .16s,background-color .16s,opacity .16s;display:flex;overflow:hidden}._f_zzcgd_33:hover{border-color:var(--field-border-hover,var(--field-border))}._f_zzcgd_33:focus-within{border-color:var(--field-border-focus,var(--field-border));box-shadow:0 0 0 3px var(--field-focus-ring,#0000);background:var(--field-background-focus,var(--field-background))}._f_zzcgd_33._e_zzcgd_57:focus-within{background:var(--field-error-background);color:var(--field-error-color)}._f_zzcgd_33[data-disabled=true]{background:var(--field-background-disabled,var(--field-background));border-color:var(--field-border-disabled,var(--field-border));color:var(--field-color-disabled,var(--field-placeholder));cursor:not-allowed;opacity:.85}._f_zzcgd_33[data-disabled=true]>*{cursor:not-allowed}._f_zzcgd_33>div{min-height:var(--field-height);line-height:calc(var(--field-height) - 2px);padding:var(--field-inner-padding,0 2px);font-size:var(--control-font-size,14px);text-wrap:pretty;outline:0;flex:1;margin:0}._f_zzcgd_33>div::selection{background:var(--field-selection-bg,#b3d4fc);color:var(--field-selection-color,inherit)}._f_zzcgd_33>:not(div){color:var(--field-icon-color,var(--field-placeholder));flex:none;justify-content:center;align-items:center;display:inline-flex}._f_zzcgd_33>:not(div) svg{width:20px;height:20px}._n_zzcgd_97 div{min-height:var(--field-note-height);line-height:var(--field-note-line-height);padding-top:var(--field-note-padding,var(--field-note-padding-top,8px));padding-bottom:var(--field-note-padding,var(--field-note-padding-top,8px))}._w_zzcgd_104>div{text-wrap:nowrap;overflow:scroll hidden}._w_zzcgd_104>div::-webkit-scrollbar{width:0;height:0}._time_zzcgd_114>div{text-wrap:nowrap;align-items:center;min-width:0;display:flex;overflow:visible}._time_zzcgd_114 ._timeInner_zzcgd_121{justify-content:flex-start;align-items:center;gap:4px;width:100%;min-width:0;display:flex}._time_zzcgd_114._timeAlignCenter_zzcgd_132 ._timeInner_zzcgd_121{justify-content:center}._time_zzcgd_114 ._timeSep_zzcgd_135{opacity:.65;-webkit-user-select:none;user-select:none;flex:none;padding:0 2px;font-weight:500;transform:translateY(-1px)}._time_zzcgd_114 ._timePart_zzcgd_146{box-sizing:border-box;width:1em;min-width:0;color:inherit;font:inherit;line-height:inherit;text-align:left;min-height:var(--field-height);cursor:text;background:0 0;border:0;border-radius:6px;outline:none;flex:none;margin:0;padding:0}._time_zzcgd_114 ._timePart_zzcgd_146[contenteditable=false]{cursor:not-allowed;opacity:.7}._time_zzcgd_114 ._timePart_zzcgd_146:empty:before{content:attr(placeholder);color:var(--field-placeholder);opacity:.6}._time_zzcgd_114 ._timePart_zzcgd_146:focus:empty:before{content:none}._time_zzcgd_114 ._timePart_zzcgd_146:focus-visible{background:0 0}._time_zzcgd_114._timeAlignCenter_zzcgd_132 ._timePart_zzcgd_146{text-align:center}._t_zzcgd_114{color:var(--field-label-color);font-size:var(--field-label-size);padding-bottom:10px}._g_zzcgd_192{flex-direction:column}._range_zzcgd_196>div{box-sizing:border-box;min-width:0;min-height:var(--field-height);flex:1;align-items:center;line-height:normal;display:flex}._range_zzcgd_196 ._rangeTrack_zzcgd_205{box-sizing:border-box;width:100%;height:var(--field-range-bar-height,14px);background:var(--field-range-track,#e0e0e0);cursor:pointer;touch-action:none;border-radius:999px;outline:none;flex-shrink:0;position:relative;overflow:hidden}._range_zzcgd_196 ._rangeTrack_zzcgd_205:focus-visible{box-shadow:0 0 0 3px var(--field-focus-ring,#0000)}._range_zzcgd_196 ._rangeTrack_zzcgd_205[data-disabled=true]{cursor:not-allowed;opacity:.55;pointer-events:none}._range_zzcgd_196 ._rangeFill_zzcgd_226{background:var(--field-range-fill,#00b5ad);pointer-events:none;border-radius:999px 0 0 999px;width:0;min-width:0;height:100%}._range_zzcgd_196 ._rangeFillFull_zzcgd_237{border-radius:999px}._h_zzcgd_241{--field-border:0}._h_zzcgd_241 div{border:var(--field-check-box-border,--field-border);width:var(--field-height);height:var(--field-height);border-radius:var(--field-radius);background:var(--field-background);cursor:pointer;flex:none;gap:10px;margin:0;position:relative}._h_zzcgd_241 div[aria-checked=true]{background:var(--field-background-active)}._h_zzcgd_241 div:after{content:"";background:0 0;border-top:none;border-bottom:3px solid #fcfff4;border-left:3px solid #fcfff4;border-right:none;width:9px;height:5px;margin:4px;position:absolute;top:5px;left:4px;transform:rotate(-45deg)}._e_zzcgd_57{border-color:var(--field-error-border);background:var(--field-error-background);color:var(--field-error-color)}._m_zzcgd_280{color:var(--field-error-color);margin-top:6px;font-size:12px;font-style:normal}
@@ -0,0 +1 @@
1
+ ._o_j48yg_2{z-index:98;background:0 0;position:fixed;inset:0}._c_j48yg_13{background:var(--select-background);z-index:99;color:#fff;box-sizing:border-box;border-radius:10px;min-width:259px;max-height:min(92vh,480px);margin:0;padding:10px 12px 12px;display:block;position:absolute;overflow:hidden auto;box-shadow:5px 7px 18px #000000a8}._c_j48yg_13 [grid-calendar]{grid-template-columns:repeat(7,1fr);grid-auto-rows:34px;gap:2px;display:grid}._c_j48yg_13 [grid-calendar]>p{color:var(--color-placeholder);box-sizing:border-box;justify-content:center;align-items:center;margin:0;padding:0;font-size:.75rem;font-weight:500;line-height:1;display:flex}._c_j48yg_13 [grid-month]{grid-template-columns:1fr 1fr 1fr 1fr;width:250px;display:grid}._c_j48yg_13 b{cursor:pointer;text-align:center;border-radius:5px;padding:8px 5px;font-weight:400;display:block}._c_j48yg_13 b.__active_j48yg_64{background:var(--bg-select-active)}._c_j48yg_13 b:hover{background:var(--bg-select-hover)}._c_j48yg_13 p{color:var(--color-placeholder);text-align:center;cursor:default;pointer-events:none;padding:0}._c_j48yg_13 i{text-align:center;cursor:pointer;border-radius:5px;flex:0 30px;padding:9px}._c_j48yg_13 i:hover{background:var(--bg-select-hover)}._c_j48yg_13 i:before{cursor:pointer;display:block}._c_j48yg_13 s{align-items:center;gap:4px;padding-bottom:6px;font-style:normal;text-decoration:none;display:flex}._c_j48yg_13 s h2{text-align:center;color:#fff;cursor:default;flex-wrap:nowrap;flex:auto;justify-content:center;align-items:center;gap:8px;min-width:0;margin:0;padding:0;font-size:16px;font-weight:400;line-height:1.25;display:flex}._c_j48yg_13 ._dateHeaderMonth_j48yg_119,._c_j48yg_13 ._dateHeaderYear_j48yg_119{cursor:pointer;-webkit-user-select:none;user-select:none;white-space:nowrap;border-radius:6px;padding:2px 8px}._c_j48yg_13 ._dateHeaderMonth_j48yg_119:hover,._c_j48yg_13 ._dateHeaderYear_j48yg_119:hover{background:var(--bg-select-hover)}._c_j48yg_13 ._dateHeaderDisabled_j48yg_129{cursor:not-allowed;opacity:.45;pointer-events:none}._c_j48yg_13 ._dateHeaderDisabled_j48yg_129[data-active=true],._c_j48yg_13 ._dateHeaderDisabled_j48yg_129[data-current=true]{opacity:.45}._c_j48yg_13 [grid-calendar] b[data-current=true],._c_j48yg_13 [grid-month] b[data-current=true]{background:color-mix(in srgb, var(--field-background-active) 52%, transparent);font-weight:600}._c_j48yg_13 [grid-calendar] b[data-active=true]:not([data-current=true]),._c_j48yg_13 [grid-month] b[data-active=true]:not([data-current=true]){outline:2px solid var(--field-background-active);outline-offset:-2px}._c_j48yg_13 [grid-calendar] b[data-active=true][data-current=true],._c_j48yg_13 [grid-month] b[data-active=true][data-current=true]{box-shadow:inset 0 0 0 2px var(--field-background-active)}._c_j48yg_13 [grid-calendar] p[data-current=true]{background:color-mix(in srgb, var(--field-background-active) 52%, transparent);color:inherit;border-radius:5px;font-weight:600}._c_j48yg_13 [grid-calendar] p[data-active=true]:not([data-current=true]){outline:2px solid var(--field-background-active);outline-offset:-2px;opacity:.85}._c_j48yg_13 [grid-calendar] p[data-active=true][data-current=true]{box-shadow:inset 0 0 0 2px var(--field-background-active)}._c_j48yg_13 span{text-align:center;padding:2px}._c_j48yg_13 span p{color:var(--color-placeholder);padding:8px 5px}._c_j48yg_13 [grid-calendar]>span{box-sizing:border-box;justify-content:stretch;align-items:stretch;min-height:0;padding:0;display:flex}._c_j48yg_13 [grid-calendar]>span>b,._c_j48yg_13 [grid-calendar]>span>p{box-sizing:border-box;border-radius:5px;flex:auto;justify-content:center;align-items:center;width:100%;min-height:0;margin:0;padding:0;display:flex}._c_j48yg_13 ._as_j48yg_196{cursor:ns-resize}._c_j48yg_13 ._ap_j48yg_199{cursor:pointer}[field=password] dd{white-space:nowrap;font-style:unset;-webkit-text-security:disc;-webkit-user-select:text;user-select:text}[field=password][show] dd,[field=password] dd:before{-webkit-text-security:none}[field=code] div{gap:8px;display:flex}[field=select] dd{cursor:pointer}[field] dd:before{pointer-events:none}[field=check] dd{cursor:pointer;max-width:35px;padding:0}[field=check] [active]:after{content:"";background:#394264;border-radius:5px;width:15px;height:15px;display:block}[field=file] input{display:none}[field=file] dd{aspect-ratio:16/9;cursor:pointer;position:relative}[field=file] img{aspect-ratio:16/9;object-fit:contain;cursor:pointer;width:-webkit-fill-available;display:block}[field=file] label{aspect-ratio:16/9;object-fit:contain;cursor:pointer;width:-webkit-fill-available;display:block;position:absolute}[field=color] dd{border:0;gap:3px;padding:0;display:flex}[field=color] dd s{cursor:pointer;opacity:.6;border:1px solid #dde2e4;border-radius:6px;flex:1}[field=color] dd s:hover{opacity:.9}[field=color] dd s[active=true]{opacity:1}
@@ -0,0 +1 @@
1
+ :root{--select-overlay:#0000;--select-height:52px;--select-separator:1px solid #40434c;--select-color:#e8e8eb;--select-background:#26282e;--select-icon:calc(--select-height / 1.5);--select-icon-padding:calc((--select-height - --select-icon) / 2);--select-font-size:13px}._o_1q26w_12{z-index:98;background:var(--select-overlay);position:fixed;inset:0}._l_1q26w_22{background:var(--select-background);z-index:99;border-radius:20px;max-height:300px;margin:0;padding:0;display:block;position:fixed;overflow:scroll}._l_1q26w_22::-webkit-scrollbar{width:0;height:0}._l_1q26w_22 ul{width:100%;max-height:300px;margin:0;padding:0;list-style:none;display:block;overflow:hidden auto}._l_1q26w_22 li{border-bottom:var(--select-separator);cursor:pointer;color:var(--select-color);height:var(--select-height);line-height:var(--select-height);font-size:var(--select-font-size);white-space:nowrap;text-overflow:ellipsis;opacity:1;margin:0;padding:0 14px;display:block;overflow:hidden;text-align:left!important;border-left:0!important}._l_1q26w_22 li:hover,._l_1q26w_22 li[data-focus=true]{background:#2f323a}._l_1q26w_22 li:last-child{border-bottom:0}._i_1q26w_80{width:var(--select-icon);height:var(--select-icon);color:var(--field-color);right:var(--select-icon-padding);top:var(--select-icon-padding);position:absolute}._f_1q26w_89{cursor:pointer}._f_1q26w_89[aria-disabled=true]{cursor:not-allowed}
@@ -0,0 +1,19 @@
1
+ import { ReactNode } from 'react';
2
+ interface Input {
3
+ element_blok?: {
4
+ className?: string[];
5
+ };
6
+ element_input?: {
7
+ className?: string[];
8
+ props?: Record<string, unknown>;
9
+ };
10
+ /** Текст подписи поля (колонка `<dt>`) */
11
+ label?: string;
12
+ before?: ReactNode;
13
+ type?: string;
14
+ after?: ReactNode;
15
+ children?: ReactNode;
16
+ error?: string;
17
+ }
18
+ declare const Field: ({ element_blok, element_input, type, label, error, before, after, children, }: Input) => import("react/jsx-runtime").JSX.Element;
19
+ export default Field;
@@ -0,0 +1,33 @@
1
+ import e from "../styles/Field.module.js";
2
+ import { jsx as t, jsxs as n } from "react/jsx-runtime";
3
+ //#region src/lib/core/Field.tsx
4
+ var r = ({ element_blok: r = { className: [] }, element_input: i = {
5
+ className: [],
6
+ props: {}
7
+ }, type: a = "input", label: o, error: s, before: c, after: l, children: u }) => /* @__PURE__ */ n("dl", {
8
+ "data-field": a,
9
+ className: [e.l, ...r.className || []].filter((e) => e !== void 0).join(" "),
10
+ children: [
11
+ o ? /* @__PURE__ */ t("dt", {
12
+ className: e.t,
13
+ children: o
14
+ }) : "",
15
+ c,
16
+ /* @__PURE__ */ t("dd", {
17
+ className: [
18
+ e.f,
19
+ ...i.className || [],
20
+ s && s.length > 0 ? e.e : ""
21
+ ].join(" "),
22
+ ...i.props || {},
23
+ children: u
24
+ }),
25
+ s && s.length > 0 ? /* @__PURE__ */ t("em", {
26
+ className: e.m,
27
+ children: s
28
+ }) : "",
29
+ l
30
+ ]
31
+ });
32
+ //#endregion
33
+ export { r as default };
@@ -0,0 +1,55 @@
1
+ /** Публичный тип цели для contentEditable-полей (фокус, вставка) */
2
+ export type EditableFieldTarget = HTMLElement & {
3
+ textContent: string | null;
4
+ scrollLeft: number;
5
+ innerHTML: string;
6
+ querySelector: (selector: string) => HTMLElement | null;
7
+ };
8
+ type EditableTarget = EditableFieldTarget;
9
+ type EditableEvent = {
10
+ key?: string;
11
+ preventDefault: () => void;
12
+ target: EditableTarget;
13
+ };
14
+ /** Событие вставки: target + текст из буфера (синхронно из clipboardData) */
15
+ export type EditableClipboardEvent = {
16
+ preventDefault: () => void;
17
+ target: EditableFieldTarget;
18
+ /** plain text из события paste — без async navigator.clipboard */
19
+ clipboardText: string;
20
+ };
21
+ type BlurLikeEvent = {
22
+ target: HTMLElement;
23
+ };
24
+ /**
25
+ * Вставка уже отфильтрованного текста в позицию каретки и генерация `input`
26
+ * (для полей со своим правилом фильтрации, например Money).
27
+ */
28
+ export declare function pastePlainTextIntoSelection(text: string, el: HTMLElement): void;
29
+ /**
30
+ * Приводит ClipboardEvent к виду для Paste/PasteOne/PasteDigits
31
+ * (синхронный текст из clipboardData — надёжнее, чем navigator.clipboard.readText).
32
+ */
33
+ export declare function asEditableClipboard(e: {
34
+ preventDefault: () => void;
35
+ currentTarget: HTMLElement;
36
+ clipboardData?: DataTransfer | null;
37
+ }): EditableClipboardEvent;
38
+ declare const _default: {
39
+ ContentEditable: string;
40
+ KeyDown(e: EditableEvent): void;
41
+ /**
42
+ * Маска / телефон: в буфере оставляем только цифры, затем вставка и input.
43
+ */
44
+ PasteOne(e: EditableClipboardEvent): void;
45
+ Paste(maxLength: number, e: EditableClipboardEvent): void;
46
+ /**
47
+ * Числовое поле: только цифры (и при необходимости ограничение длины).
48
+ */
49
+ PasteDigits(maxLength: number, e: EditableClipboardEvent): void;
50
+ Focus(e: {
51
+ target: EditableTarget;
52
+ }): void;
53
+ Blur(e: BlurLikeEvent): void;
54
+ };
55
+ export default _default;
@@ -0,0 +1,67 @@
1
+ //#region src/lib/events/onEvent.ts
2
+ var e = (e) => {
3
+ let t = window.getSelection();
4
+ if (!t || t.rangeCount === 0) return;
5
+ let n = t.getRangeAt(0);
6
+ n.deleteContents(), n.insertNode(document.createTextNode(e)), n.collapse(!1), t.removeAllRanges(), t.addRange(n);
7
+ };
8
+ function t(t, n) {
9
+ e(t), n.dispatchEvent(new Event("input", { bubbles: !0 }));
10
+ }
11
+ var n = (e) => {
12
+ let t = window.getSelection();
13
+ if (!t) return;
14
+ let n = document.createRange();
15
+ n.selectNodeContents(e), n.collapse(!1), t.removeAllRanges(), t.addRange(n);
16
+ }, r = (e, t, n) => {
17
+ if (!t) return e;
18
+ let r = window.getSelection(), i = 0;
19
+ if (r && r.rangeCount > 0) {
20
+ let e = r.getRangeAt(0);
21
+ n.contains(e.commonAncestorContainer) && (i = e.toString().length);
22
+ }
23
+ let a = t - ((n.textContent || "").length - i);
24
+ return a <= 0 ? "" : e.slice(0, a);
25
+ };
26
+ function i(e) {
27
+ queueMicrotask(() => {
28
+ e.dispatchEvent(new Event("input", { bubbles: !0 }));
29
+ });
30
+ }
31
+ var a = {
32
+ KeyDown(e) {
33
+ e.key === "Enter" && e.preventDefault();
34
+ },
35
+ PasteOne(t) {
36
+ t.preventDefault(), e(t.clipboardText.replace(/\D/g, "")), i(t.target);
37
+ },
38
+ Paste(t, n) {
39
+ n.preventDefault();
40
+ let a = r(n.clipboardText, t, n.target);
41
+ a && (e(a.replace(/(\r\n|\n|\r)/gm, " ")), i(n.target));
42
+ },
43
+ PasteDigits(t, n) {
44
+ n.preventDefault();
45
+ let a = r(n.clipboardText.replace(/\D/g, ""), t, n.target);
46
+ a && (e(a), i(n.target));
47
+ },
48
+ Focus(e) {
49
+ (e.target.textContent || "").length || (e.target.innerHTML = "<br>"), n(e.target);
50
+ },
51
+ Blur(e) {
52
+ e.target.scrollLeft = 0, e.target.querySelector("br") !== null && e.target.querySelector("br")?.remove();
53
+ }
54
+ }, o = "plaintext-only";
55
+ function s(e) {
56
+ return {
57
+ preventDefault: () => e.preventDefault(),
58
+ target: e.currentTarget,
59
+ clipboardText: e.clipboardData?.getData("text/plain") ?? ""
60
+ };
61
+ }
62
+ var c = {
63
+ ...a,
64
+ ContentEditable: o
65
+ };
66
+ //#endregion
67
+ export { s as asEditableClipboard, c as default, t as pastePlainTextIntoSelection };
@@ -0,0 +1,13 @@
1
+ import { default as React } from 'react';
2
+ import { TInput } from './type';
3
+ type TDate = TInput & {
4
+ max?: Date;
5
+ min?: Date;
6
+ icon?: () => React.JSX.Element;
7
+ };
8
+ /** DateField — дата с выпадающим календарём. */
9
+ declare function DateField({ label, error, hidden, className, placeholder, disabled, onValue, max, min, form, icon, name, value, after, before, }: TDate): import("react/jsx-runtime").JSX.Element;
10
+ declare namespace DateField {
11
+ var displayName: string;
12
+ }
13
+ export default DateField;