@elcrm/form 0.0.75 → 0.0.78

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.
package/dist/package.js CHANGED
@@ -1,15 +1,26 @@
1
1
  var e = {
2
2
  name: "@elcrm/form",
3
- version: "0.0.75",
3
+ version: "0.0.78",
4
4
  description: "React-компоненты полей формы и хук useForm для elCRM: текст, даты, маски, деньги, селект, связка с формой по имени поля (tree-shakeable ESM).",
5
5
  type: "module",
6
6
  author: "MaSkal <dev@elcrm.online>",
7
7
  license: "MIT",
8
- files: ["dist", "src/lib/styles"],
8
+ repository: {
9
+ type: "git",
10
+ url: "git+https://github.com/elcrm-lib/elcrm.form.git"
11
+ },
12
+ bugs: { url: "https://github.com/elcrm-lib/elcrm.form/issues" },
13
+ homepage: "https://www.npmjs.com/package/@elcrm/form",
14
+ publishConfig: { access: "public" },
15
+ engines: { node: ">=18" },
16
+ files: ["dist"],
9
17
  keywords: [
10
18
  "elcrm",
11
19
  "form",
12
- "react"
20
+ "react",
21
+ "fields",
22
+ "useForm",
23
+ "input"
13
24
  ],
14
25
  sideEffects: [
15
26
  "./dist/index.js",
@@ -57,38 +68,49 @@ var e = {
57
68
  },
58
69
  "./style.css": {
59
70
  import: "./dist/style.css",
60
- require: "./dist/style.css"
71
+ require: "./dist/style.css",
72
+ default: "./dist/style.css"
61
73
  },
62
74
  "./light.css": {
63
- import: "./src/lib/styles/light.css",
64
- require: "./src/lib/styles/light.css"
75
+ import: "./dist/light.css",
76
+ require: "./dist/light.css",
77
+ default: "./dist/light.css"
65
78
  },
66
79
  "./dark.css": {
67
- import: "./src/lib/styles/dark.css",
68
- require: "./src/lib/styles/dark.css"
80
+ import: "./dist/dark.css",
81
+ require: "./dist/dark.css",
82
+ default: "./dist/dark.css"
69
83
  },
70
84
  "./dist/style.css": {
71
85
  import: "./dist/style.css",
72
- require: "./dist/style.css"
73
- }
86
+ require: "./dist/style.css",
87
+ default: "./dist/style.css"
88
+ },
89
+ "./package.json": "./package.json"
74
90
  },
75
91
  scripts: {
76
92
  dev: "vite --config test/vite.config.ts",
77
- prepublishOnly: "npm run build",
78
- build: "vite build && node scripts/merge-dist-css.mjs && node scripts/postbuild-styles.mjs && vite build --config vite.umd.config.ts",
93
+ build: "node scripts/build.mjs",
79
94
  test: "vitest run",
80
95
  "test:watch": "vitest",
81
96
  "test:build": "vite build --config test/vite.config.ts",
82
- "test:preview": "vite preview --config test/vite.config.ts"
97
+ "test:preview": "vite preview --config test/vite.config.ts",
98
+ prepublishOnly: "vitest run && node scripts/build.mjs",
99
+ "pack:check": "npm pack --dry-run"
83
100
  },
84
101
  peerDependencies: {
85
- react: ">=18",
86
- "react-dom": ">=18"
102
+ "@types/react": ">=18.0.0",
103
+ react: ">=18.0.0",
104
+ "react-dom": ">=18.0.0"
87
105
  },
106
+ peerDependenciesMeta: { "@types/react": { optional: !0 } },
88
107
  devDependencies: {
89
108
  "@elcrm/storybook": "^0.0.3",
90
109
  "@testing-library/dom": "^10.4.1",
110
+ "@testing-library/jest-dom": "^6.6.3",
91
111
  "@testing-library/react": "^16.3.2",
112
+ "@testing-library/user-event": "^14.6.1",
113
+ "@types/node": "^22.13.10",
92
114
  "@types/react": "^19.2.14",
93
115
  "@types/react-dom": "^19.2.3",
94
116
  "@vitejs/plugin-react": "^6.0.1",
@@ -96,7 +118,11 @@ var e = {
96
118
  react: "^19.2.4",
97
119
  "react-dom": "^19.2.4",
98
120
  "sass-embedded": "^1.98.0",
121
+ typescript: "^5.8.2",
99
122
  vite: "^8.0.1",
123
+ "vite-plugin-dts": "^4.0.3",
124
+ "vite-plugin-dynamic-import": "^1.6.0",
125
+ "vite-plugin-lib-inject-css": "^2.1.1",
100
126
  vitest: "^4.1.0"
101
127
  }
102
128
  };
package/package.json CHANGED
@@ -1,18 +1,34 @@
1
1
  {
2
2
  "name": "@elcrm/form",
3
- "version": "0.0.75",
3
+ "version": "0.0.78",
4
4
  "description": "React-компоненты полей формы и хук useForm для elCRM: текст, даты, маски, деньги, селект, связка с формой по имени поля (tree-shakeable ESM).",
5
5
  "type": "module",
6
6
  "author": "MaSkal <dev@elcrm.online>",
7
7
  "license": "MIT",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git+https://github.com/elcrm-lib/elcrm.form.git"
11
+ },
12
+ "bugs": {
13
+ "url": "https://github.com/elcrm-lib/elcrm.form/issues"
14
+ },
15
+ "homepage": "https://www.npmjs.com/package/@elcrm/form",
16
+ "publishConfig": {
17
+ "access": "public"
18
+ },
19
+ "engines": {
20
+ "node": ">=18"
21
+ },
8
22
  "files": [
9
- "dist",
10
- "src/lib/styles"
23
+ "dist"
11
24
  ],
12
25
  "keywords": [
13
26
  "elcrm",
14
27
  "form",
15
- "react"
28
+ "react",
29
+ "fields",
30
+ "useForm",
31
+ "input"
16
32
  ],
17
33
  "sideEffects": [
18
34
  "./dist/index.js",
@@ -60,38 +76,53 @@
60
76
  },
61
77
  "./style.css": {
62
78
  "import": "./dist/style.css",
63
- "require": "./dist/style.css"
79
+ "require": "./dist/style.css",
80
+ "default": "./dist/style.css"
64
81
  },
65
82
  "./light.css": {
66
- "import": "./src/lib/styles/light.css",
67
- "require": "./src/lib/styles/light.css"
83
+ "import": "./dist/light.css",
84
+ "require": "./dist/light.css",
85
+ "default": "./dist/light.css"
68
86
  },
69
87
  "./dark.css": {
70
- "import": "./src/lib/styles/dark.css",
71
- "require": "./src/lib/styles/dark.css"
88
+ "import": "./dist/dark.css",
89
+ "require": "./dist/dark.css",
90
+ "default": "./dist/dark.css"
72
91
  },
73
92
  "./dist/style.css": {
74
93
  "import": "./dist/style.css",
75
- "require": "./dist/style.css"
76
- }
94
+ "require": "./dist/style.css",
95
+ "default": "./dist/style.css"
96
+ },
97
+ "./package.json": "./package.json"
77
98
  },
78
99
  "scripts": {
79
100
  "dev": "vite --config test/vite.config.ts",
80
- "prepublishOnly": "npm run build",
81
- "build": "vite build && node scripts/merge-dist-css.mjs && node scripts/postbuild-styles.mjs && vite build --config vite.umd.config.ts",
101
+ "build": "node scripts/build.mjs",
82
102
  "test": "vitest run",
83
103
  "test:watch": "vitest",
84
104
  "test:build": "vite build --config test/vite.config.ts",
85
- "test:preview": "vite preview --config test/vite.config.ts"
105
+ "test:preview": "vite preview --config test/vite.config.ts",
106
+ "prepublishOnly": "vitest run && node scripts/build.mjs",
107
+ "pack:check": "npm pack --dry-run"
86
108
  },
87
109
  "peerDependencies": {
88
- "react": ">=18",
89
- "react-dom": ">=18"
110
+ "@types/react": ">=18.0.0",
111
+ "react": ">=18.0.0",
112
+ "react-dom": ">=18.0.0"
113
+ },
114
+ "peerDependenciesMeta": {
115
+ "@types/react": {
116
+ "optional": true
117
+ }
90
118
  },
91
119
  "devDependencies": {
92
120
  "@elcrm/storybook": "^0.0.3",
93
121
  "@testing-library/dom": "^10.4.1",
122
+ "@testing-library/jest-dom": "^6.6.3",
94
123
  "@testing-library/react": "^16.3.2",
124
+ "@testing-library/user-event": "^14.6.1",
125
+ "@types/node": "^22.13.10",
95
126
  "@types/react": "^19.2.14",
96
127
  "@types/react-dom": "^19.2.3",
97
128
  "@vitejs/plugin-react": "^6.0.1",
@@ -99,7 +130,11 @@
99
130
  "react": "^19.2.4",
100
131
  "react-dom": "^19.2.4",
101
132
  "sass-embedded": "^1.98.0",
133
+ "typescript": "^5.8.2",
102
134
  "vite": "^8.0.1",
135
+ "vite-plugin-dts": "^4.0.3",
136
+ "vite-plugin-dynamic-import": "^1.6.0",
137
+ "vite-plugin-lib-inject-css": "^2.1.1",
103
138
  "vitest": "^4.1.0"
104
139
  }
105
140
  }
@@ -1,434 +0,0 @@
1
- .l {
2
- display: flex;
3
- flex-direction: column;
4
- position: relative;
5
- min-width: var(--field-width);
6
- gap: var(--field-block-gap, 0);
7
- margin: 0;
8
- padding: 0;
9
- & > dt,
10
- & > dd {
11
- margin: 0;
12
- }
13
- &[data-field="group"] {
14
- & div {
15
- cursor: pointer;
16
- border-bottom: var(--field-border);
17
- margin: 0;
18
- padding: var(--field-padding);
19
- }
20
- & div:last-child {
21
- border-bottom: 0;
22
- }
23
- }
24
- /* contentEditable: псевдо-placeholder — тот же вес и насыщенность, что у нативного ::placeholder */
25
- & [placeholder]:empty:before {
26
- content: attr(placeholder);
27
- display: block;
28
- color: var(--field-placeholder);
29
- font-weight: 400;
30
- font-style: normal;
31
- opacity: 1;
32
- }
33
- & [placeholder]:focus:before {
34
- display: none;
35
- }
36
- }
37
-
38
- .f {
39
- box-sizing: border-box;
40
- display: flex;
41
- align-items: center;
42
- gap: var(--field-icon-gap, 10px);
43
- border: var(--field-border);
44
- border-radius: var(--field-radius);
45
- overflow: hidden;
46
- background: var(--field-background);
47
- color: var(--field-color);
48
- /* Внутренний отступ теперь на контейнере dd (.f), а не на дочернем div */
49
- padding: var(--control-inner-padding, 0 var(--field-side-padding, 14px));
50
- transition:
51
- border-color 0.16s ease,
52
- box-shadow 0.16s ease,
53
- background-color 0.16s ease,
54
- opacity 0.16s ease;
55
- &:hover {
56
- border-color: var(--field-border-hover, var(--field-border));
57
- }
58
- &:focus-within {
59
- border-color: var(--field-border-focus, var(--field-border));
60
- box-shadow: 0 0 0 3px var(--field-focus-ring, #0000);
61
- background: var(--field-background-focus, var(--field-background));
62
- }
63
- /* при ошибке оставляем фон ошибки, не подсветку обычного фокуса */
64
- &.e:focus-within {
65
- background: var(--field-error-background);
66
- color: var(--field-error-color);
67
- }
68
- &[data-disabled="true"] {
69
- background: var(--field-background-disabled, var(--field-background));
70
- border-color: var(--field-border-disabled, var(--field-border));
71
- color: var(--field-color-disabled, var(--field-placeholder));
72
- cursor: not-allowed;
73
- opacity: 0.85;
74
- }
75
- &[data-disabled="true"] > * {
76
- cursor: not-allowed;
77
- }
78
- & > div {
79
- outline: 0;
80
-
81
- flex: 1;
82
- margin: 0;
83
- min-height: var(--field-height);
84
- line-height: calc(var(--field-height) - 2px);
85
- padding: 0;
86
- font-size: var(--control-font-size, 14px);
87
- text-wrap: pretty;
88
-
89
- &::selection {
90
- background: var(--field-selection-bg, #b3d4fc);
91
- color: var(--field-selection-color, inherit);
92
- }
93
- }
94
- & > :not(div) {
95
- display: inline-flex;
96
- align-items: center;
97
- justify-content: center;
98
- flex: 0 0 auto;
99
- color: var(--field-icon-color, var(--field-placeholder));
100
- & svg {
101
- width: 20px;
102
- height: 20px;
103
- }
104
- }
105
-
106
- /*
107
- Нативный placeholder: без UA-«обесцвечивания» (Firefox/WebKit снижают opacity по умолчанию).
108
- Цвет = --field-placeholder, как у [placeholder]:empty:before у contentEditable.
109
- */
110
- input::placeholder,
111
- textarea::placeholder {
112
- color: var(--field-placeholder);
113
- opacity: 1;
114
- font-weight: 400;
115
- }
116
- input::-webkit-input-placeholder,
117
- textarea::-webkit-input-placeholder {
118
- color: var(--field-placeholder);
119
- opacity: 1;
120
- font-weight: 400;
121
- }
122
- input::-moz-placeholder,
123
- textarea::-moz-placeholder {
124
- color: var(--field-placeholder);
125
- opacity: 1;
126
- font-weight: 400;
127
- }
128
- }
129
-
130
- // textarea
131
- .n {
132
- & div {
133
- min-height: var(--field-note-height);
134
- line-height: var(--field-note-line-height);
135
- padding-top: var(
136
- --field-note-padding,
137
- var(--field-note-padding-top, 8px)
138
- );
139
- padding-bottom: var(
140
- --field-note-padding,
141
- var(--field-note-padding-top, 8px)
142
- );
143
- }
144
- }
145
-
146
- .w {
147
- & > div {
148
- text-wrap: nowrap;
149
- overflow: hidden;
150
- overflow-x: scroll;
151
- &::-webkit-scrollbar {
152
- width: 0;
153
- height: 0;
154
- }
155
- }
156
- }
157
-
158
- // время: два поля часы / минуты
159
- .time {
160
- & > div {
161
- display: flex;
162
- align-items: center;
163
- min-width: 0;
164
- overflow: visible;
165
- text-wrap: nowrap;
166
- }
167
-
168
- .timeInner {
169
- display: flex;
170
- align-items: center;
171
- justify-content: flex-start;
172
- gap: 4px;
173
- width: 100%;
174
- min-width: 0;
175
- }
176
-
177
- /* центрирование — опционально через проп align="center" у Time */
178
- &.timeAlignCenter .timeInner {
179
- justify-content: center;
180
- }
181
-
182
- .timeSep {
183
- flex: none;
184
- font-weight: 500;
185
- opacity: 0.65;
186
- user-select: none;
187
- padding: 0 2px;
188
- transform: translateY(-1px);
189
- }
190
-
191
- /* contentEditable, как у текстового поля */
192
- .timePart {
193
- box-sizing: border-box;
194
- width: 1em;
195
- min-width: 0;
196
- margin: 0;
197
- padding: 0;
198
- border: 0;
199
- background: transparent;
200
- color: inherit;
201
- font: inherit;
202
- line-height: inherit;
203
- text-align: left;
204
- min-height: var(--field-height);
205
- outline: none;
206
- border-radius: 6px;
207
- cursor: text;
208
- flex: 0 0 auto;
209
-
210
- &[contenteditable="false"] {
211
- cursor: not-allowed;
212
- opacity: 0.7;
213
- }
214
-
215
- &:empty:before {
216
- content: attr(placeholder);
217
- color: var(--field-placeholder);
218
- font-weight: 400;
219
- opacity: 1;
220
- }
221
-
222
- &:focus:empty:before {
223
- content: none;
224
- }
225
-
226
- /* фон капсулы .f уже через :focus-within; здесь не перекрываем */
227
- &:focus-visible {
228
- background: transparent;
229
- }
230
- }
231
-
232
- &.timeAlignCenter .timePart {
233
- text-align: center;
234
- }
235
- }
236
-
237
- .t {
238
- color: var(--field-label-color);
239
- font-size: var(--field-label-size);
240
- padding-bottom: 10px;
241
- }
242
-
243
- .affix {
244
- display: inline-flex;
245
- align-items: center;
246
- justify-content: center;
247
- flex: 0 0 auto;
248
- padding: 0;
249
- margin: 0;
250
- color: var(--field-icon-color, var(--field-placeholder));
251
- font-size: inherit;
252
- line-height: 1;
253
- user-select: none;
254
- }
255
-
256
- /* Отступ аффиксов от краёв капсулы (как визуально у Password), без увеличения зазора до текста */
257
-
258
- .g {
259
- flex-direction: column;
260
- }
261
-
262
- // range — капсула .f + .w как у Input; внутри «таблетка» трек (div): серый фон + бирюзовая заливка слева
263
- .range {
264
- & > div {
265
- box-sizing: border-box;
266
- flex: 1;
267
- min-width: 0;
268
- min-height: var(--field-height);
269
- display: flex;
270
- align-items: center;
271
- line-height: normal;
272
- }
273
-
274
- .rangeTrack {
275
- box-sizing: border-box;
276
- position: relative;
277
- width: 100%;
278
- height: var(--field-range-bar-height, 14px);
279
- flex-shrink: 0;
280
- border-radius: 999px;
281
- background: var(--field-range-track, #e0e0e0);
282
- overflow: hidden;
283
- cursor: pointer;
284
- outline: none;
285
- touch-action: none;
286
-
287
- &:focus-visible {
288
- box-shadow: 0 0 0 3px var(--field-focus-ring, #0000);
289
- }
290
-
291
- &[data-disabled="true"] {
292
- cursor: not-allowed;
293
- opacity: 0.55;
294
- pointer-events: none;
295
- }
296
- }
297
-
298
- .rangeFill {
299
- height: 100%;
300
- width: 0;
301
- min-width: 0;
302
- background: var(--field-range-fill, #00b5ad);
303
- border-radius: 999px 0 0 999px;
304
- pointer-events: none;
305
- }
306
-
307
- /* при 100% — полностью скруглённая «капсула» заливки */
308
- .rangeFillFull {
309
- border-radius: 999px;
310
- }
311
- }
312
-
313
- // checkbox — капсула с квадратом слева и текстом справа
314
- .checkbox {
315
- & > div {
316
- min-height: var(--field-height);
317
- display: flex;
318
- align-items: flex-start;
319
- width: 100%;
320
- padding: 0;
321
- line-height: normal;
322
- }
323
- }
324
-
325
- .checkControl {
326
- width: 100%;
327
- min-height: var(--field-height);
328
- display: flex;
329
- align-items: flex-start;
330
- gap: 12px;
331
- border: 0;
332
- margin: 0;
333
- padding: 10px 0;
334
- background: transparent;
335
- color: inherit;
336
- font: inherit;
337
- text-align: left;
338
- cursor: pointer;
339
- outline: none;
340
-
341
- &:focus-visible {
342
- box-shadow: 0 0 0 3px var(--field-focus-ring, #0000);
343
- border-radius: calc(var(--field-radius) - 2px);
344
- }
345
-
346
- &[aria-disabled="true"] {
347
- cursor: not-allowed;
348
- }
349
- }
350
-
351
- .checkBox {
352
- width: 22px;
353
- height: 22px;
354
- border-radius: 8px;
355
- border: var(--field-check-box-border, var(--field-border));
356
- background: transparent;
357
- display: inline-flex;
358
- align-items: center;
359
- justify-content: center;
360
- flex: 0 0 auto;
361
- transition:
362
- background-color 0.16s ease,
363
- border-color 0.16s ease,
364
- opacity 0.16s ease;
365
- }
366
-
367
- .checkMark {
368
- width: 11px;
369
- height: 6px;
370
- border: 2px solid #fcfff4;
371
- border-top: none;
372
- border-right: none;
373
- transform: translateY(-1px) rotate(-45deg);
374
- }
375
-
376
- .checkText {
377
- flex: 1 1 auto;
378
- min-width: 0;
379
- color: inherit;
380
- font-size: var(--control-font-size, 14px);
381
- line-height: 1.25;
382
- padding-top: 2px;
383
- }
384
-
385
- .checkControl[aria-checked="true"] .checkBox {
386
- background: var(--field-background-active);
387
- }
388
-
389
- // checkBox
390
- .h {
391
- --field-border: 0;
392
- & div {
393
- border: var(--field-check-box-border, --field-border);
394
- width: var(--field-height);
395
- height: var(--field-height);
396
- border-radius: var(--field-radius);
397
- background: var(--field-background);
398
- margin: 0;
399
- flex: none;
400
- cursor: pointer;
401
- position: relative;
402
- gap: 10px;
403
- &[aria-checked="true"] {
404
- background: var(--field-background-active);
405
- }
406
- &:after {
407
- content: "";
408
- width: 9px;
409
- height: 5px;
410
- position: absolute;
411
- top: 5px;
412
- left: 4px;
413
- border: 3px solid #fcfff4;
414
- border-top: none;
415
- border-right: none;
416
- background: transparent;
417
- transform: rotate(-45deg);
418
- margin: 4px;
419
- }
420
- }
421
- }
422
-
423
- .e {
424
- border-color: var(--field-error-border);
425
- background: var(--field-error-background);
426
- color: var(--field-error-color);
427
- }
428
-
429
- .m {
430
- color: var(--field-error-color);
431
- font-size: 12px;
432
- font-style: normal;
433
- margin-top: 6px;
434
- }