@destyler/edit 0.0.7-beta.5 → 0.0.7-beta.9

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/index.mjs DELETED
@@ -1,520 +0,0 @@
1
- import { createAnatomy } from '@zag-js/anatomy';
2
- import { createScope, dataAttr, ariaAttr, isComposingEvent, isApple, raf, contains } from '@zag-js/dom-query';
3
- import { createMachine } from '@zag-js/core';
4
- import { trackInteractOutside } from '@zag-js/interact-outside';
5
- import { compact, isEqual, createSplitProps } from '@zag-js/utils';
6
- import { createProps } from '@zag-js/types';
7
-
8
- const anatomy = createAnatomy("edit").parts(
9
- "root",
10
- "area",
11
- "label",
12
- "preview",
13
- "input",
14
- "editTrigger",
15
- "submitTrigger",
16
- "cancelTrigger",
17
- "control"
18
- );
19
- const parts = anatomy.build();
20
-
21
- const dom = createScope({
22
- getRootId: (ctx) => ctx.ids?.root ?? `editable:${ctx.id}`,
23
- getAreaId: (ctx) => ctx.ids?.area ?? `editable:${ctx.id}:area`,
24
- getLabelId: (ctx) => ctx.ids?.label ?? `editable:${ctx.id}:label`,
25
- getPreviewId: (ctx) => ctx.ids?.preview ?? `editable:${ctx.id}:preview`,
26
- getInputId: (ctx) => ctx.ids?.input ?? `editable:${ctx.id}:input`,
27
- getControlId: (ctx) => ctx.ids?.control ?? `editable:${ctx.id}:control`,
28
- getSubmitTriggerId: (ctx) => ctx.ids?.submitTrigger ?? `editable:${ctx.id}:submit`,
29
- getCancelTriggerId: (ctx) => ctx.ids?.cancelTrigger ?? `editable:${ctx.id}:cancel`,
30
- getEditTriggerId: (ctx) => ctx.ids?.editTrigger ?? `editable:${ctx.id}:edit`,
31
- getInputEl: (ctx) => dom.getById(ctx, dom.getInputId(ctx)),
32
- getPreviewEl: (ctx) => dom.getById(ctx, dom.getPreviewId(ctx)),
33
- getSubmitTriggerEl: (ctx) => dom.getById(ctx, dom.getSubmitTriggerId(ctx)),
34
- getCancelTriggerEl: (ctx) => dom.getById(ctx, dom.getCancelTriggerId(ctx)),
35
- getEditTriggerEl: (ctx) => dom.getById(ctx, dom.getEditTriggerId(ctx))
36
- });
37
-
38
- function connect(state, send, normalize) {
39
- const disabled = state.context.disabled;
40
- const interactive = state.context.isInteractive;
41
- const readOnly = state.context.readOnly;
42
- const invalid = state.context.invalid;
43
- const autoResize = state.context.autoResize;
44
- const translations = state.context.translations;
45
- const editing = state.matches("edit");
46
- const placeholderProp = state.context.placeholder;
47
- const placeholder = typeof placeholderProp === "string" ? { edit: placeholderProp, preview: placeholderProp } : placeholderProp;
48
- const value = state.context.value;
49
- const empty = value.trim() === "";
50
- const valueText = empty ? placeholder?.preview ?? "" : value;
51
- return {
52
- editing,
53
- empty,
54
- value,
55
- valueText,
56
- setValue(value2) {
57
- send({ type: "VALUE.SET", value: value2, src: "setValue" });
58
- },
59
- clearValue() {
60
- send({ type: "VALUE.SET", value: "", src: "clearValue" });
61
- },
62
- edit() {
63
- if (!interactive)
64
- return;
65
- send("EDIT");
66
- },
67
- cancel() {
68
- if (!interactive)
69
- return;
70
- send("CANCEL");
71
- },
72
- submit() {
73
- if (!interactive)
74
- return;
75
- send("SUBMIT");
76
- },
77
- getRootProps() {
78
- return normalize.element({
79
- ...parts.root.attrs,
80
- id: dom.getRootId(state.context),
81
- dir: state.context.dir
82
- });
83
- },
84
- getAreaProps() {
85
- return normalize.element({
86
- ...parts.area.attrs,
87
- "id": dom.getAreaId(state.context),
88
- "dir": state.context.dir,
89
- "style": autoResize ? { display: "inline-grid" } : void 0,
90
- "data-focus": dataAttr(editing),
91
- "data-disabled": dataAttr(disabled),
92
- "data-placeholder-shown": dataAttr(empty)
93
- });
94
- },
95
- getLabelProps() {
96
- return normalize.label({
97
- ...parts.label.attrs,
98
- "id": dom.getLabelId(state.context),
99
- "dir": state.context.dir,
100
- "htmlFor": dom.getInputId(state.context),
101
- "data-focus": dataAttr(editing),
102
- "data-invalid": dataAttr(invalid),
103
- onClick() {
104
- if (editing)
105
- return;
106
- const previewEl = dom.getPreviewEl(state.context);
107
- previewEl?.focus({ preventScroll: true });
108
- }
109
- });
110
- },
111
- getInputProps() {
112
- return normalize.input({
113
- ...parts.input.attrs,
114
- "dir": state.context.dir,
115
- "aria-label": translations.input,
116
- "name": state.context.name,
117
- "form": state.context.form,
118
- "id": dom.getInputId(state.context),
119
- "hidden": autoResize ? void 0 : !editing,
120
- "placeholder": placeholder?.edit,
121
- "maxLength": state.context.maxLength,
122
- "required": state.context.required,
123
- "disabled": disabled,
124
- "data-disabled": dataAttr(disabled),
125
- "readOnly": readOnly,
126
- "data-readonly": dataAttr(readOnly),
127
- "aria-invalid": ariaAttr(invalid),
128
- "data-invalid": dataAttr(invalid),
129
- "data-autoresize": dataAttr(autoResize),
130
- "defaultValue": value,
131
- "size": autoResize ? 1 : void 0,
132
- onChange(event) {
133
- send({ type: "VALUE.SET", src: "input.change", value: event.currentTarget.value });
134
- },
135
- onKeyDown(event) {
136
- if (event.defaultPrevented)
137
- return;
138
- if (isComposingEvent(event))
139
- return;
140
- const keyMap = {
141
- Escape() {
142
- send("CANCEL");
143
- event.preventDefault();
144
- },
145
- Enter(event2) {
146
- if (!state.context.submitOnEnter)
147
- return;
148
- const { localName } = event2.currentTarget;
149
- if (localName === "textarea") {
150
- const submitMod = isApple() ? event2.metaKey : event2.ctrlKey;
151
- if (!submitMod)
152
- return;
153
- send({ type: "SUBMIT", src: "keydown.enter" });
154
- return;
155
- }
156
- if (localName === "input" && !event2.shiftKey && !event2.metaKey) {
157
- send({ type: "SUBMIT", src: "keydown.enter" });
158
- event2.preventDefault();
159
- }
160
- }
161
- };
162
- const exec = keyMap[event.key];
163
- if (exec) {
164
- exec(event);
165
- }
166
- },
167
- "style": autoResize ? {
168
- gridArea: "1 / 1 / auto / auto",
169
- visibility: !editing ? "hidden" : void 0
170
- } : void 0
171
- });
172
- },
173
- getPreviewProps() {
174
- return normalize.element({
175
- "id": dom.getPreviewId(state.context),
176
- ...parts.preview.attrs,
177
- "dir": state.context.dir,
178
- "data-placeholder-shown": dataAttr(empty),
179
- "aria-readonly": ariaAttr(readOnly),
180
- "data-readonly": dataAttr(disabled),
181
- "data-disabled": dataAttr(disabled),
182
- "aria-disabled": ariaAttr(disabled),
183
- "aria-invalid": ariaAttr(invalid),
184
- "data-invalid": dataAttr(invalid),
185
- "aria-label": translations.edit,
186
- "data-autoresize": dataAttr(autoResize),
187
- "children": valueText,
188
- "hidden": autoResize ? void 0 : editing,
189
- "tabIndex": interactive ? 0 : void 0,
190
- onClick() {
191
- if (!interactive)
192
- return;
193
- if (state.context.activationMode !== "click")
194
- return;
195
- send({ type: "EDIT", src: "click" });
196
- },
197
- onFocus() {
198
- if (!interactive)
199
- return;
200
- if (state.context.activationMode !== "focus")
201
- return;
202
- send({ type: "EDIT", src: "focus" });
203
- },
204
- onDoubleClick(event) {
205
- if (event.defaultPrevented)
206
- return;
207
- if (!interactive)
208
- return;
209
- if (state.context.activationMode !== "dblclick")
210
- return;
211
- send({ type: "EDIT", src: "dblclick" });
212
- },
213
- "style": autoResize ? {
214
- whiteSpace: "pre",
215
- userSelect: "none",
216
- gridArea: "1 / 1 / auto / auto",
217
- visibility: editing ? "hidden" : void 0,
218
- // in event the preview overflow's the parent element
219
- overflow: "hidden",
220
- textOverflow: "ellipsis"
221
- } : void 0
222
- });
223
- },
224
- getEditTriggerProps() {
225
- return normalize.button({
226
- ...parts.editTrigger.attrs,
227
- "id": dom.getEditTriggerId(state.context),
228
- "dir": state.context.dir,
229
- "aria-label": translations.edit,
230
- "hidden": editing,
231
- "type": "button",
232
- "disabled": disabled,
233
- onClick(event) {
234
- if (event.defaultPrevented)
235
- return;
236
- if (!interactive)
237
- return;
238
- send({ type: "EDIT", src: "edit.click" });
239
- }
240
- });
241
- },
242
- getControlProps() {
243
- return normalize.element({
244
- id: dom.getControlId(state.context),
245
- ...parts.control.attrs,
246
- dir: state.context.dir
247
- });
248
- },
249
- getSubmitTriggerProps() {
250
- return normalize.button({
251
- ...parts.submitTrigger.attrs,
252
- "dir": state.context.dir,
253
- "id": dom.getSubmitTriggerId(state.context),
254
- "aria-label": translations.submit,
255
- "hidden": !editing,
256
- "disabled": disabled,
257
- "type": "button",
258
- onClick(event) {
259
- if (event.defaultPrevented)
260
- return;
261
- if (!interactive)
262
- return;
263
- send({ type: "SUBMIT", src: "submit.click" });
264
- }
265
- });
266
- },
267
- getCancelTriggerProps() {
268
- return normalize.button({
269
- ...parts.cancelTrigger.attrs,
270
- "dir": state.context.dir,
271
- "aria-label": translations.cancel,
272
- "id": dom.getCancelTriggerId(state.context),
273
- "hidden": !editing,
274
- "type": "button",
275
- "disabled": disabled,
276
- onClick(event) {
277
- if (event.defaultPrevented)
278
- return;
279
- if (!interactive)
280
- return;
281
- send({ type: "CANCEL", src: "cancel.click" });
282
- }
283
- });
284
- }
285
- };
286
- }
287
-
288
- const sync = {
289
- value: (ctx) => {
290
- const inputEl = dom.getInputEl(ctx);
291
- dom.setValue(inputEl, ctx.value);
292
- }
293
- };
294
- const invoke = {
295
- change(ctx) {
296
- ctx.onValueChange?.({ value: ctx.value });
297
- sync.value(ctx);
298
- }
299
- };
300
- const set = {
301
- value(ctx, value) {
302
- if (isEqual(ctx.value, value))
303
- return;
304
- ctx.value = value;
305
- invoke.change(ctx);
306
- }
307
- };
308
- const submitOnEnter = (ctx) => ["both", "enter"].includes(ctx.submitMode);
309
- const submitOnBlur = (ctx) => ["both", "blur"].includes(ctx.submitMode);
310
- function machine(userContext) {
311
- const ctx = compact(userContext);
312
- return createMachine(
313
- {
314
- id: "editable",
315
- initial: ctx.edit ? "edit" : "preview",
316
- entry: ctx.edit ? ["focusInput"] : void 0,
317
- context: {
318
- activationMode: "focus",
319
- submitMode: "both",
320
- value: "",
321
- previousValue: "",
322
- selectOnFocus: true,
323
- disabled: false,
324
- readOnly: false,
325
- ...ctx,
326
- translations: {
327
- input: "editable input",
328
- edit: "edit",
329
- submit: "submit",
330
- cancel: "cancel",
331
- ...ctx.translations
332
- }
333
- },
334
- watch: {
335
- value: ["syncInputValue"],
336
- edit: ["toggleEditing"]
337
- },
338
- computed: {
339
- submitOnEnter,
340
- submitOnBlur,
341
- isInteractive: (ctx2) => !(ctx2.disabled || ctx2.readOnly)
342
- },
343
- on: {
344
- "VALUE.SET": {
345
- actions: "setValue"
346
- }
347
- },
348
- states: {
349
- preview: {
350
- // https://bugzilla.mozilla.org/show_bug.cgi?id=559561
351
- entry: ["blurInputIfNeeded"],
352
- on: {
353
- "CONTROLLED.EDIT": {
354
- target: "edit",
355
- actions: ["setPreviousValue", "focusInput"]
356
- },
357
- "EDIT": [
358
- {
359
- guard: "isEditControlled",
360
- actions: ["invokeOnEdit"]
361
- },
362
- {
363
- target: "edit",
364
- actions: ["setPreviousValue", "focusInput", "invokeOnEdit"]
365
- }
366
- ]
367
- }
368
- },
369
- edit: {
370
- activities: ["trackInteractOutside"],
371
- on: {
372
- "CONTROLLED.PREVIEW": [
373
- {
374
- guard: "isSubmitEvent",
375
- target: "preview",
376
- actions: ["setPreviousValue", "restoreFocus", "invokeOnSubmit"]
377
- },
378
- {
379
- target: "preview",
380
- actions: ["revertValue", "restoreFocus", "invokeOnCancel"]
381
- }
382
- ],
383
- "CANCEL": [
384
- {
385
- guard: "isEditControlled",
386
- actions: ["invokeOnPreview"]
387
- },
388
- {
389
- target: "preview",
390
- actions: ["revertValue", "restoreFocus", "invokeOnCancel", "invokeOnPreview"]
391
- }
392
- ],
393
- "SUBMIT": [
394
- {
395
- guard: "isEditControlled",
396
- actions: ["invokeOnPreview"]
397
- },
398
- {
399
- target: "preview",
400
- actions: ["setPreviousValue", "restoreFocus", "invokeOnSubmit", "invokeOnPreview"]
401
- }
402
- ]
403
- }
404
- }
405
- }
406
- },
407
- {
408
- guards: {
409
- isEditControlled: (ctx2) => !!ctx2["edit.controlled"],
410
- isSubmitEvent: (_ctx, evt) => evt.previousEvent?.type === "SUBMIT"
411
- },
412
- activities: {
413
- trackInteractOutside(ctx2, _evt, { send }) {
414
- return trackInteractOutside(dom.getInputEl(ctx2), {
415
- exclude(target) {
416
- const ignore = [dom.getCancelTriggerEl(ctx2), dom.getSubmitTriggerEl(ctx2)];
417
- return ignore.some((el) => contains(el, target));
418
- },
419
- onFocusOutside: ctx2.onFocusOutside,
420
- onPointerDownOutside: ctx2.onPointerDownOutside,
421
- onInteractOutside(event) {
422
- ctx2.onInteractOutside?.(event);
423
- if (event.defaultPrevented)
424
- return;
425
- const { focusable } = event.detail;
426
- send({ type: submitOnBlur(ctx2) ? "SUBMIT" : "CANCEL", src: "interact-outside", focusable });
427
- }
428
- });
429
- }
430
- },
431
- actions: {
432
- restoreFocus(ctx2, evt) {
433
- if (evt.focusable)
434
- return;
435
- raf(() => {
436
- const finalEl = ctx2.finalFocusEl?.() ?? dom.getEditTriggerEl(ctx2);
437
- finalEl?.focus({ preventScroll: true });
438
- });
439
- },
440
- focusInput(ctx2) {
441
- raf(() => {
442
- const inputEl = dom.getInputEl(ctx2);
443
- if (!inputEl)
444
- return;
445
- if (ctx2.selectOnFocus) {
446
- inputEl.select();
447
- } else {
448
- inputEl.focus({ preventScroll: true });
449
- }
450
- });
451
- },
452
- invokeOnCancel(ctx2) {
453
- ctx2.onValueRevert?.({ value: ctx2.previousValue });
454
- },
455
- invokeOnSubmit(ctx2) {
456
- ctx2.onValueCommit?.({ value: ctx2.value });
457
- },
458
- invokeOnEdit(ctx2) {
459
- ctx2.onEditChange?.({ edit: true });
460
- },
461
- invokeOnPreview(ctx2) {
462
- ctx2.onEditChange?.({ edit: false });
463
- },
464
- toggleEditing(ctx2, evt, { send }) {
465
- send({ type: ctx2.edit ? "CONTROLLED.EDIT" : "CONTROLLED.PREVIEW", previousEvent: evt });
466
- },
467
- syncInputValue(ctx2) {
468
- sync.value(ctx2);
469
- },
470
- setValue(ctx2, evt) {
471
- const value = ctx2.maxLength != null ? evt.value.slice(0, ctx2.maxLength) : evt.value;
472
- set.value(ctx2, value);
473
- },
474
- setPreviousValue(ctx2) {
475
- ctx2.previousValue = ctx2.value;
476
- },
477
- revertValue(ctx2) {
478
- set.value(ctx2, ctx2.previousValue);
479
- },
480
- blurInputIfNeeded(ctx2) {
481
- dom.getInputEl(ctx2)?.blur();
482
- }
483
- }
484
- }
485
- );
486
- }
487
-
488
- const props = createProps()([
489
- "activationMode",
490
- "autoResize",
491
- "dir",
492
- "disabled",
493
- "finalFocusEl",
494
- "form",
495
- "getRootNode",
496
- "id",
497
- "ids",
498
- "invalid",
499
- "maxLength",
500
- "name",
501
- "onEditChange",
502
- "onFocusOutside",
503
- "onInteractOutside",
504
- "onPointerDownOutside",
505
- "onValueChange",
506
- "onValueCommit",
507
- "onValueRevert",
508
- "placeholder",
509
- "readOnly",
510
- "required",
511
- "selectOnFocus",
512
- "edit",
513
- "edit.controlled",
514
- "submitMode",
515
- "translations",
516
- "value"
517
- ]);
518
- const splitProps = createSplitProps(props);
519
-
520
- export { anatomy, connect, machine, props, splitProps };