@yamada-ui/editable 0.1.0

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.js ADDED
@@ -0,0 +1,452 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var src_exports = {};
22
+ __export(src_exports, {
23
+ Editable: () => Editable,
24
+ EditableInput: () => EditableInput,
25
+ EditablePreview: () => EditablePreview,
26
+ EditableTextarea: () => EditableTextarea,
27
+ useEditable: () => useEditable,
28
+ useEditableControl: () => useEditableControl
29
+ });
30
+ module.exports = __toCommonJS(src_exports);
31
+
32
+ // src/editable.tsx
33
+ var import_core = require("@yamada-ui/core");
34
+ var import_form_control = require("@yamada-ui/form-control");
35
+ var import_use_controllable_state = require("@yamada-ui/use-controllable-state");
36
+ var import_use_focus = require("@yamada-ui/use-focus");
37
+ var import_utils = require("@yamada-ui/utils");
38
+ var import_react = require("react");
39
+ var import_jsx_runtime = require("react/jsx-runtime");
40
+ var useEditable = (props) => {
41
+ const {
42
+ id,
43
+ placeholder,
44
+ defaultValue,
45
+ required,
46
+ disabled,
47
+ readOnly,
48
+ startWithEditView,
49
+ isPreviewFocusable = true,
50
+ submitOnBlur = true,
51
+ selectAllOnFocus = true,
52
+ ...rest
53
+ } = (0, import_form_control.useFormControlProps)(props);
54
+ rest.onEdit = (0, import_utils.useCallbackRef)(rest.onEdit);
55
+ const [isEditing, setIsEditing] = (0, import_react.useState)(!!startWithEditView && !disabled);
56
+ const [value, setValue] = (0, import_use_controllable_state.useControllableState)({
57
+ defaultValue: defaultValue || "",
58
+ value: rest.value,
59
+ onChange: rest.onChange
60
+ });
61
+ const isInteractive = !isEditing && !disabled;
62
+ const isValueEmpty = value.length === 0;
63
+ const [prevValue, setPrevValue] = (0, import_react.useState)(value);
64
+ const inputRef = (0, import_react.useRef)(null);
65
+ const previewRef = (0, import_react.useRef)(null);
66
+ const editRef = (0, import_react.useRef)(null);
67
+ const cancelRef = (0, import_react.useRef)(null);
68
+ const submitRef = (0, import_react.useRef)(null);
69
+ (0, import_use_focus.useFocusOnPointerDown)({
70
+ ref: inputRef,
71
+ enabled: isEditing,
72
+ elements: [cancelRef, submitRef]
73
+ });
74
+ (0, import_utils.useSafeLayoutEffect)(() => {
75
+ var _a, _b;
76
+ if (!isEditing)
77
+ return;
78
+ (_a = inputRef.current) == null ? void 0 : _a.focus();
79
+ if (selectAllOnFocus)
80
+ (_b = inputRef.current) == null ? void 0 : _b.select();
81
+ }, []);
82
+ (0, import_utils.useUpdateEffect)(() => {
83
+ var _a, _b, _c, _d;
84
+ if (!isEditing) {
85
+ (_a = editRef.current) == null ? void 0 : _a.focus();
86
+ return;
87
+ }
88
+ (_b = inputRef.current) == null ? void 0 : _b.focus();
89
+ if (selectAllOnFocus)
90
+ (_c = inputRef.current) == null ? void 0 : _c.select();
91
+ (_d = rest.onEdit) == null ? void 0 : _d.call(rest);
92
+ }, [isEditing, rest.onEdit, selectAllOnFocus]);
93
+ (0, import_react.useEffect)(() => {
94
+ if (isEditing)
95
+ return;
96
+ const el = inputRef.current;
97
+ const activeEl = el == null ? void 0 : el.ownerDocument.activeElement;
98
+ if (activeEl === el)
99
+ el == null ? void 0 : el.blur();
100
+ }, [isEditing]);
101
+ const onChange = (0, import_react.useCallback)(
102
+ (ev) => setValue(ev.currentTarget.value),
103
+ [setValue]
104
+ );
105
+ const onUpdatePrevValue = (0, import_react.useCallback)(() => setPrevValue(value), [value]);
106
+ const onEdit = (0, import_react.useCallback)(() => {
107
+ if (isInteractive)
108
+ setIsEditing(true);
109
+ }, [isInteractive]);
110
+ const onCancel = (0, import_react.useCallback)(() => {
111
+ var _a;
112
+ setIsEditing(false);
113
+ setValue(prevValue);
114
+ (_a = rest.onCancel) == null ? void 0 : _a.call(rest, prevValue);
115
+ }, [prevValue, rest, setValue]);
116
+ const onSubmit = (0, import_react.useCallback)(() => {
117
+ var _a;
118
+ setIsEditing(false);
119
+ setPrevValue(value);
120
+ (_a = rest.onSubmit) == null ? void 0 : _a.call(rest, value);
121
+ }, [rest, value]);
122
+ const onKeyDown = (0, import_react.useCallback)(
123
+ (ev) => {
124
+ if (ev.key !== "Escape" && ev.key !== "Enter")
125
+ return;
126
+ ev.preventDefault();
127
+ if (ev.key === "Escape") {
128
+ onCancel();
129
+ } else {
130
+ const { shiftKey, metaKey } = ev;
131
+ if (!shiftKey && !metaKey)
132
+ onSubmit();
133
+ }
134
+ },
135
+ [onCancel, onSubmit]
136
+ );
137
+ const onKeyDownWithoutSubmit = (0, import_react.useCallback)(
138
+ (ev) => {
139
+ if (ev.key !== "Escape")
140
+ return;
141
+ ev.preventDefault();
142
+ onCancel();
143
+ },
144
+ [onCancel]
145
+ );
146
+ const onBlur = (0, import_react.useCallback)(
147
+ (ev) => {
148
+ var _a;
149
+ if (!isEditing)
150
+ return;
151
+ const ownerDocument = ev.currentTarget.ownerDocument;
152
+ const relatedTarget = (_a = ev.relatedTarget) != null ? _a : ownerDocument.activeElement;
153
+ const targetIsCancel = (0, import_utils.isContains)(cancelRef.current, relatedTarget);
154
+ const targetIsSubmit = (0, import_utils.isContains)(submitRef.current, relatedTarget);
155
+ const isValidBlur = !targetIsCancel && !targetIsSubmit;
156
+ if (!isValidBlur)
157
+ return;
158
+ if (submitOnBlur) {
159
+ onSubmit();
160
+ } else {
161
+ onCancel();
162
+ }
163
+ },
164
+ [isEditing, submitOnBlur, onSubmit, onCancel]
165
+ );
166
+ const getPreviewProps = (0, import_react.useCallback)(
167
+ (props2 = {}, ref = null) => ({
168
+ ...(0, import_utils.pickObject)(rest, import_form_control.formControlProperties),
169
+ ...props2,
170
+ ref: (0, import_utils.mergeRefs)(ref, previewRef),
171
+ hidden: isEditing,
172
+ tabIndex: isInteractive && isPreviewFocusable ? 0 : void 0,
173
+ children: isValueEmpty ? placeholder : value,
174
+ onFocus: (0, import_utils.handlerAll)(props2.onFocus, onEdit, onUpdatePrevValue)
175
+ }),
176
+ [
177
+ isEditing,
178
+ isInteractive,
179
+ isPreviewFocusable,
180
+ isValueEmpty,
181
+ onEdit,
182
+ onUpdatePrevValue,
183
+ placeholder,
184
+ rest,
185
+ value
186
+ ]
187
+ );
188
+ const getInputProps = (0, import_react.useCallback)(
189
+ (props2 = {}, ref = null) => ({
190
+ ...(0, import_utils.pickObject)(rest, import_form_control.formControlProperties),
191
+ ...props2,
192
+ ref: (0, import_utils.mergeRefs)(ref, inputRef),
193
+ id,
194
+ placeholder,
195
+ hidden: !isEditing,
196
+ value,
197
+ required,
198
+ disabled,
199
+ readOnly,
200
+ onBlur: (0, import_utils.handlerAll)(props2.onBlur, onBlur),
201
+ onChange: (0, import_utils.handlerAll)(props2.onChange, onChange),
202
+ onKeyDown: (0, import_utils.handlerAll)(props2.onKeyDown, onKeyDown),
203
+ onFocus: (0, import_utils.handlerAll)(props2.onFocus, onUpdatePrevValue)
204
+ }),
205
+ [
206
+ disabled,
207
+ id,
208
+ isEditing,
209
+ onBlur,
210
+ onChange,
211
+ onKeyDown,
212
+ onUpdatePrevValue,
213
+ placeholder,
214
+ readOnly,
215
+ required,
216
+ rest,
217
+ value
218
+ ]
219
+ );
220
+ const getTextareaProps = (0, import_react.useCallback)(
221
+ (props2 = {}, ref = null) => ({
222
+ ...(0, import_utils.pickObject)(rest, import_form_control.formControlProperties),
223
+ ...props2,
224
+ ref: (0, import_utils.mergeRefs)(ref, inputRef),
225
+ id,
226
+ placeholder,
227
+ hidden: !isEditing,
228
+ value,
229
+ required,
230
+ disabled,
231
+ readOnly,
232
+ onBlur: (0, import_utils.handlerAll)(props2.onBlur, onBlur),
233
+ onChange: (0, import_utils.handlerAll)(props2.onChange, onChange),
234
+ onKeyDown: (0, import_utils.handlerAll)(props2.onKeyDown, onKeyDownWithoutSubmit),
235
+ onFocus: (0, import_utils.handlerAll)(props2.onFocus, onUpdatePrevValue)
236
+ }),
237
+ [
238
+ disabled,
239
+ id,
240
+ isEditing,
241
+ onBlur,
242
+ onChange,
243
+ onKeyDownWithoutSubmit,
244
+ onUpdatePrevValue,
245
+ placeholder,
246
+ readOnly,
247
+ required,
248
+ rest,
249
+ value
250
+ ]
251
+ );
252
+ const getEditProps = (0, import_react.useCallback)(
253
+ (props2 = {}, ref = null) => ({
254
+ ...props2,
255
+ ...(0, import_utils.omitObject)(rest, ["value", "onChange", "onCancel", "onSubmit", "onEdit"]),
256
+ ref: (0, import_utils.mergeRefs)(ref, editRef),
257
+ type: "button",
258
+ disabled,
259
+ readOnly,
260
+ onClick: (0, import_utils.handlerAll)(props2.onClick, onEdit)
261
+ }),
262
+ [disabled, onEdit, readOnly, rest]
263
+ );
264
+ const getSubmitProps = (0, import_react.useCallback)(
265
+ (props2 = {}, ref = null) => ({
266
+ ...props2,
267
+ ...(0, import_utils.omitObject)(rest, ["value", "onChange", "onCancel", "onSubmit", "onEdit"]),
268
+ ref: (0, import_utils.mergeRefs)(submitRef, ref),
269
+ type: "button",
270
+ disabled,
271
+ readOnly,
272
+ onClick: (0, import_utils.handlerAll)(props2.onClick, onSubmit)
273
+ }),
274
+ [disabled, onSubmit, readOnly, rest]
275
+ );
276
+ const getCancelProps = (0, import_react.useCallback)(
277
+ (props2 = {}, ref = null) => ({
278
+ ...props2,
279
+ ...(0, import_utils.omitObject)(rest, ["value", "onChange", "onCancel", "onSubmit", "onEdit"]),
280
+ ref: (0, import_utils.mergeRefs)(cancelRef, ref),
281
+ type: "button",
282
+ disabled,
283
+ readOnly,
284
+ onClick: (0, import_utils.handlerAll)(props2.onClick, onCancel)
285
+ }),
286
+ [disabled, onCancel, readOnly, rest]
287
+ );
288
+ return {
289
+ isEditing,
290
+ value,
291
+ onEdit,
292
+ onCancel,
293
+ onSubmit,
294
+ getPreviewProps,
295
+ getInputProps,
296
+ getTextareaProps,
297
+ getEditProps,
298
+ getSubmitProps,
299
+ getCancelProps
300
+ };
301
+ };
302
+ var useEditableControl = () => {
303
+ const { isEditing, getEditProps, getCancelProps, getSubmitProps } = useEditableContext();
304
+ return { isEditing, getEditProps, getCancelProps, getSubmitProps };
305
+ };
306
+ var [EditableProvider, useEditableContext] = (0, import_utils.createContext)({
307
+ name: "EditableContext",
308
+ errorMessage: "useEditableContext: context is undefined. Seems you forgot to wrap the editable components in `<Editable />`"
309
+ });
310
+ var Editable = (0, import_core.forwardRef)(
311
+ ({ focusBorderColor, errorBorderColor, ...props }, ref) => {
312
+ const [styles, mergedProps] = (0, import_core.useMultiComponentStyle)("Editable", {
313
+ focusBorderColor,
314
+ errorBorderColor,
315
+ ...props
316
+ });
317
+ const { className, children, ...rest } = (0, import_core.omitThemeProps)(mergedProps);
318
+ const {
319
+ isEditing,
320
+ getPreviewProps,
321
+ getInputProps,
322
+ getTextareaProps,
323
+ getEditProps,
324
+ getCancelProps,
325
+ getSubmitProps,
326
+ onSubmit,
327
+ onCancel,
328
+ onEdit
329
+ } = useEditable(rest);
330
+ const cloneChildren = (0, import_utils.runIfFunc)(children, {
331
+ isEditing,
332
+ onSubmit,
333
+ onCancel,
334
+ onEdit
335
+ });
336
+ const css = { ...styles.container };
337
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
338
+ EditableProvider,
339
+ {
340
+ value: {
341
+ isEditing,
342
+ getPreviewProps,
343
+ getInputProps,
344
+ getTextareaProps,
345
+ getEditProps,
346
+ getCancelProps,
347
+ getSubmitProps,
348
+ styles
349
+ },
350
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
351
+ import_core.ui.div,
352
+ {
353
+ ref,
354
+ className: (0, import_utils.cx)("ui-editable", className),
355
+ ...(0, import_utils.omitObject)(rest, [
356
+ "placeholder",
357
+ "value",
358
+ "defaultValue",
359
+ "isInvalid",
360
+ "isReadOnly",
361
+ "isRequired",
362
+ "isDisabled",
363
+ "startWithEditView",
364
+ "isPreviewFocusable",
365
+ "submitOnBlur",
366
+ "selectAllOnFocus",
367
+ "onChange",
368
+ "onCancel",
369
+ "onSubmit",
370
+ "onEdit"
371
+ ]),
372
+ __css: css,
373
+ children: cloneChildren
374
+ }
375
+ )
376
+ }
377
+ );
378
+ }
379
+ );
380
+ var EditablePreview = (0, import_core.forwardRef)(
381
+ ({ className, ...rest }, ref) => {
382
+ const { styles, getPreviewProps } = useEditableContext();
383
+ const css = {
384
+ cursor: "text",
385
+ display: "inline-block",
386
+ fontSize: "inherit",
387
+ fontWeight: "inherit",
388
+ textAlign: "inherit",
389
+ bg: "transparent",
390
+ ...styles.preview
391
+ };
392
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
393
+ import_core.ui.span,
394
+ {
395
+ className: (0, import_utils.cx)("ui-editable-preview", className),
396
+ ...getPreviewProps(rest, ref),
397
+ __css: css
398
+ }
399
+ );
400
+ }
401
+ );
402
+ var EditableInput = (0, import_core.forwardRef)(
403
+ ({ className, ...rest }, ref) => {
404
+ const { styles, getInputProps } = useEditableContext();
405
+ const css = {
406
+ outline: 0,
407
+ fontSize: "inherit",
408
+ fontWeight: "inherit",
409
+ textAlign: "inherit",
410
+ bg: "transparent",
411
+ ...styles.input
412
+ };
413
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
414
+ import_core.ui.input,
415
+ {
416
+ className: (0, import_utils.cx)("ui-editable-input", className),
417
+ ...getInputProps(rest, ref),
418
+ __css: css
419
+ }
420
+ );
421
+ }
422
+ );
423
+ var EditableTextarea = (0, import_core.forwardRef)(
424
+ ({ className, ...rest }, ref) => {
425
+ const { styles, getTextareaProps } = useEditableContext();
426
+ const css = {
427
+ outline: 0,
428
+ fontSize: "inherit",
429
+ fontWeight: "inherit",
430
+ textAlign: "inherit",
431
+ bg: "transparent",
432
+ ...styles.textarea
433
+ };
434
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
435
+ import_core.ui.textarea,
436
+ {
437
+ className: (0, import_utils.cx)("ui-editable-textarea", className),
438
+ ...getTextareaProps(rest, ref),
439
+ __css: css
440
+ }
441
+ );
442
+ }
443
+ );
444
+ // Annotate the CommonJS export names for ESM import in node:
445
+ 0 && (module.exports = {
446
+ Editable,
447
+ EditableInput,
448
+ EditablePreview,
449
+ EditableTextarea,
450
+ useEditable,
451
+ useEditableControl
452
+ });
package/dist/index.mjs ADDED
@@ -0,0 +1,16 @@
1
+ import {
2
+ Editable,
3
+ EditableInput,
4
+ EditablePreview,
5
+ EditableTextarea,
6
+ useEditable,
7
+ useEditableControl
8
+ } from "./chunk-VFULS7K5.mjs";
9
+ export {
10
+ Editable,
11
+ EditableInput,
12
+ EditablePreview,
13
+ EditableTextarea,
14
+ useEditable,
15
+ useEditableControl
16
+ };
package/package.json ADDED
@@ -0,0 +1,78 @@
1
+ {
2
+ "name": "@yamada-ui/editable",
3
+ "version": "0.1.0",
4
+ "description": "Yamada UI editable component",
5
+ "keywords": [
6
+ "yamada",
7
+ "yamada ui",
8
+ "react",
9
+ "emotion",
10
+ "component",
11
+ "editable",
12
+ "ui",
13
+ "uikit",
14
+ "styled",
15
+ "style-props",
16
+ "styled-component",
17
+ "css-in-js"
18
+ ],
19
+ "author": "Hirotomo Yamada <hirotomo.yamada@avap.co.jp>",
20
+ "license": "MIT",
21
+ "main": "dist/index.js",
22
+ "files": [
23
+ "dist"
24
+ ],
25
+ "sideEffects": false,
26
+ "publishConfig": {
27
+ "access": "public"
28
+ },
29
+ "repository": {
30
+ "type": "git",
31
+ "url": "git+https://github.com/hirotomoyamada/yamada-ui",
32
+ "directory": "packages/components/editable"
33
+ },
34
+ "bugs": {
35
+ "url": "https://github.com/hirotomoyamada/yamada-ui/issues"
36
+ },
37
+ "dependencies": {
38
+ "@yamada-ui/core": "0.1.0",
39
+ "@yamada-ui/utils": "0.1.0",
40
+ "@yamada-ui/form-control": "0.1.0",
41
+ "@yamada-ui/use-focus": "0.1.0",
42
+ "@yamada-ui/use-controllable-state": "0.1.0"
43
+ },
44
+ "devDependencies": {
45
+ "react": "^18.0.0",
46
+ "clean-package": "2.2.0"
47
+ },
48
+ "peerDependencies": {
49
+ "react": ">=18"
50
+ },
51
+ "clean-package": "../../../clean-package.config.json",
52
+ "tsup": {
53
+ "clean": true,
54
+ "target": "es2019",
55
+ "format": [
56
+ "cjs",
57
+ "esm"
58
+ ]
59
+ },
60
+ "module": "dist/index.mjs",
61
+ "types": "dist/index.d.ts",
62
+ "exports": {
63
+ ".": {
64
+ "types": "./dist/index.d.ts",
65
+ "import": "./dist/index.mjs",
66
+ "require": "./dist/index.js"
67
+ },
68
+ "./package.json": "./package.json"
69
+ },
70
+ "scripts": {
71
+ "dev": "pnpm build:fast -- --watch",
72
+ "build": "tsup src --dts",
73
+ "build:fast": "tsup src",
74
+ "clean": "rimraf dist .turbo",
75
+ "typecheck": "tsc --noEmit",
76
+ "gen:docs": "tsx ../../../scripts/generate-docs"
77
+ }
78
+ }