@launchpad-ui/inline-edit 0.1.9 → 0.1.11
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/InlineEdit.d.ts +3 -3
- package/dist/InlineEdit.d.ts.map +1 -1
- package/dist/index.es.js +15 -9
- package/dist/index.es.js.map +1 -1
- package/dist/index.js +12 -6
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
package/dist/InlineEdit.d.ts
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
import type { InlineVariants } from './styles/InlineEdit.css';
|
2
|
-
import type { TextAreaProps, TextFieldProps } from '@launchpad-ui/form';
|
2
|
+
import type { IconFieldProps, TextAreaProps, TextFieldProps } from '@launchpad-ui/form';
|
3
3
|
import type { ComponentProps, ReactElement } from 'react';
|
4
4
|
type InlineEditProps = ComponentProps<'div'> & InlineVariants & Pick<ComponentProps<'input'>, 'defaultValue'> & {
|
5
5
|
'data-test-id'?: string;
|
6
6
|
onConfirm: (value: string) => void;
|
7
7
|
hideEdit?: boolean;
|
8
|
-
renderInput?: ReactElement<TextFieldProps | TextAreaProps>;
|
8
|
+
renderInput?: ReactElement<IconFieldProps | TextFieldProps | TextAreaProps>;
|
9
9
|
isEditing?: boolean;
|
10
10
|
onCancel?: () => void;
|
11
11
|
onEdit?: () => void;
|
@@ -19,7 +19,7 @@ declare const InlineEdit: import("react").ForwardRefExoticComponent<Omit<import(
|
|
19
19
|
'data-test-id'?: string | undefined;
|
20
20
|
onConfirm: (value: string) => void;
|
21
21
|
hideEdit?: boolean | undefined;
|
22
|
-
renderInput?: ReactElement<TextFieldProps | TextAreaProps, string | import("react").JSXElementConstructor<any>> | undefined;
|
22
|
+
renderInput?: ReactElement<TextFieldProps | IconFieldProps | TextAreaProps, string | import("react").JSXElementConstructor<any>> | undefined;
|
23
23
|
isEditing?: boolean | undefined;
|
24
24
|
onCancel?: (() => void) | undefined;
|
25
25
|
onEdit?: (() => void) | undefined;
|
package/dist/InlineEdit.d.ts.map
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"InlineEdit.d.ts","sourceRoot":"","sources":["../src/InlineEdit.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAC9D,OAAO,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;
|
1
|
+
{"version":3,"file":"InlineEdit.d.ts","sourceRoot":"","sources":["../src/InlineEdit.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAC9D,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACxF,OAAO,KAAK,EAAE,cAAc,EAAwB,YAAY,EAAE,MAAM,OAAO,CAAC;AAchF,KAAK,eAAe,GAAG,cAAc,CAAC,KAAK,CAAC,GAC1C,cAAc,GACd,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,EAAE,cAAc,CAAC,GAAG;IAC9C,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,SAAS,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACnC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,WAAW,CAAC,EAAE,YAAY,CAAC,cAAc,GAAG,cAAc,GAAG,aAAa,CAAC,CAAC;IAC5E,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B,CAAC;AAEJ,QAAA,MAAM,UAAU;;;;uBAXO,MAAM,KAAK,IAAI;;;;sBAIjB,IAAI;oBACN,IAAI;;;;4DA+JtB,CAAC;AAIF,OAAO,EAAE,UAAU,EAAE,CAAC;AACtB,YAAY,EAAE,eAAe,EAAE,CAAC"}
|
package/dist/index.es.js
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
import './style.css';
|
2
2
|
import { jsx, jsxs, Fragment } from "react/jsx-runtime";
|
3
3
|
import { IconButton, ButtonGroup } from "@launchpad-ui/button";
|
4
|
-
import { TextField } from "@launchpad-ui/form";
|
4
|
+
import { TextField, TextArea } from "@launchpad-ui/form";
|
5
5
|
import { Icon } from "@launchpad-ui/icons";
|
6
6
|
import { useButton } from "@react-aria/button";
|
7
7
|
import { focusSafely } from "@react-aria/focus";
|
8
8
|
import { useFocusWithin } from "@react-aria/interactions";
|
9
|
-
import { useUpdateEffect,
|
9
|
+
import { useUpdateEffect, mergeRefs, mergeProps } from "@react-aria/utils";
|
10
10
|
import { cx } from "classix";
|
11
|
-
import { forwardRef, useState, useRef, cloneElement } from "react";
|
11
|
+
import { forwardRef, useState, useRef, cloneElement, Children } from "react";
|
12
12
|
import { createRuntimeFn } from "@vanilla-extract/recipes/createRuntimeFn";
|
13
13
|
const InlineEdit_css_ts_vanilla = "";
|
14
14
|
var cancelButton = "_1oig0624";
|
@@ -96,14 +96,20 @@ const InlineEdit = /* @__PURE__ */ forwardRef(
|
|
96
96
|
}
|
97
97
|
)
|
98
98
|
] });
|
99
|
+
const inputProps = {
|
100
|
+
ref: mergeRefs(inputRef, ref),
|
101
|
+
defaultValue,
|
102
|
+
onKeyDown: handleKeyDown,
|
103
|
+
"aria-label": ariaLabel
|
104
|
+
};
|
105
|
+
const inputChildren = renderInput.props.children;
|
99
106
|
const input = /* @__PURE__ */ cloneElement(
|
100
107
|
renderInput,
|
101
|
-
mergeProps(renderInput.props, {
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
})
|
108
|
+
mergeProps(renderInput.props, inputChildren ? {} : inputProps),
|
109
|
+
inputChildren && Children.map(
|
110
|
+
inputChildren,
|
111
|
+
(child) => child.type === TextField || child.type === TextArea ? /* @__PURE__ */ cloneElement(child, mergeProps(child.props, inputProps)) : child
|
112
|
+
)
|
107
113
|
);
|
108
114
|
return isEditing ? /* @__PURE__ */ jsxs(
|
109
115
|
"div",
|
package/dist/index.es.js.map
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"index.es.js","sources":["../src/InlineEdit.tsx"],"sourcesContent":["import type { InlineVariants } from './styles/InlineEdit.css';\nimport type { TextAreaProps, TextFieldProps } from '@launchpad-ui/form';\nimport type { ComponentProps, KeyboardEventHandler, ReactElement } from 'react';\n\nimport { ButtonGroup, IconButton } from '@launchpad-ui/button';\nimport { TextField } from '@launchpad-ui/form';\nimport { Icon } from '@launchpad-ui/icons';\nimport { useButton } from '@react-aria/button';\nimport { focusSafely } from '@react-aria/focus';\nimport { useFocusWithin } from '@react-aria/interactions';\nimport { mergeProps, mergeRefs, useUpdateEffect } from '@react-aria/utils';\nimport { cx } from 'classix';\nimport { cloneElement, forwardRef, useRef, useState } from 'react';\n\nimport { container, cancelButton, inline, readButton } from './styles/InlineEdit.css';\n\ntype InlineEditProps = ComponentProps<'div'> &\n InlineVariants &\n Pick<ComponentProps<'input'>, 'defaultValue'> & {\n 'data-test-id'?: string;\n onConfirm: (value: string) => void;\n hideEdit?: boolean;\n renderInput?: ReactElement<TextFieldProps | TextAreaProps>;\n isEditing?: boolean;\n onCancel?: () => void;\n onEdit?: () => void;\n cancelButtonLabel?: string;\n editButtonLabel?: string;\n confirmButtonLabel?: string;\n };\n\nconst InlineEdit = forwardRef<HTMLInputElement, InlineEditProps>(\n (\n {\n 'data-test-id': testId = 'inline-edit',\n layout = 'horizontal',\n children,\n defaultValue,\n onConfirm,\n hideEdit = false,\n renderInput = <TextField />,\n 'aria-label': ariaLabel,\n isEditing: isEditingProp,\n onCancel,\n onEdit,\n cancelButtonLabel = 'cancel',\n editButtonLabel = 'edit',\n confirmButtonLabel = 'confirm',\n className,\n ...rest\n },\n ref\n ) => {\n const [isEditing, setEditing] = useState(isEditingProp ?? false);\n const [isFocusWithin, setFocusWithin] = useState(false);\n const inputRef = useRef<HTMLInputElement>(null);\n const editRef = useRef<HTMLButtonElement>(null);\n const controlled = isEditingProp !== undefined;\n\n useUpdateEffect(() => {\n if (controlled) {\n setEditing(isEditingProp);\n }\n }, [isEditingProp]);\n\n useUpdateEffect(() => {\n if (isFocusWithin) {\n isEditing\n ? inputRef.current && focusSafely(inputRef.current)\n : editRef.current && focusSafely(editRef.current);\n }\n }, [isEditing]);\n\n const handleEdit = () => {\n !controlled && setEditing(true);\n onEdit?.();\n };\n\n const handleCancel = () => {\n !controlled && setEditing(false);\n onCancel?.();\n };\n\n const handleConfirm = () => {\n onConfirm(inputRef.current?.value || '');\n !controlled && setEditing(false);\n };\n\n const handleKeyDown: KeyboardEventHandler<HTMLInputElement> = (event) => {\n if (event.key === 'Enter') {\n event.preventDefault();\n handleConfirm();\n } else if (event.key === 'Escape') {\n event.preventDefault();\n handleCancel();\n }\n };\n\n const { focusWithinProps } = useFocusWithin({\n onBlurWithin: () => isEditing && handleCancel(),\n onFocusWithinChange: (isFocusWithin) => setFocusWithin(isFocusWithin),\n });\n\n const { buttonProps } = useButton(\n {\n 'aria-label': editButtonLabel,\n elementType: 'span',\n onPress: handleEdit,\n },\n editRef\n );\n\n const renderReadContent = hideEdit ? (\n <span ref={editRef} {...buttonProps} className={readButton}>\n {children}\n </span>\n ) : (\n <>\n {children}\n <IconButton\n ref={editRef}\n icon={<Icon name=\"edit\" />}\n aria-label={editButtonLabel}\n size=\"small\"\n onClick={handleEdit}\n />\n </>\n );\n\n const
|
1
|
+
{"version":3,"file":"index.es.js","sources":["../src/InlineEdit.tsx"],"sourcesContent":["import type { InlineVariants } from './styles/InlineEdit.css';\nimport type { IconFieldProps, TextAreaProps, TextFieldProps } from '@launchpad-ui/form';\nimport type { ComponentProps, KeyboardEventHandler, ReactElement } from 'react';\n\nimport { ButtonGroup, IconButton } from '@launchpad-ui/button';\nimport { TextField, TextArea } from '@launchpad-ui/form';\nimport { Icon } from '@launchpad-ui/icons';\nimport { useButton } from '@react-aria/button';\nimport { focusSafely } from '@react-aria/focus';\nimport { useFocusWithin } from '@react-aria/interactions';\nimport { mergeProps, mergeRefs, useUpdateEffect } from '@react-aria/utils';\nimport { cx } from 'classix';\nimport { Children, cloneElement, forwardRef, useRef, useState } from 'react';\n\nimport { container, cancelButton, inline, readButton } from './styles/InlineEdit.css';\n\ntype InlineEditProps = ComponentProps<'div'> &\n InlineVariants &\n Pick<ComponentProps<'input'>, 'defaultValue'> & {\n 'data-test-id'?: string;\n onConfirm: (value: string) => void;\n hideEdit?: boolean;\n renderInput?: ReactElement<IconFieldProps | TextFieldProps | TextAreaProps>;\n isEditing?: boolean;\n onCancel?: () => void;\n onEdit?: () => void;\n cancelButtonLabel?: string;\n editButtonLabel?: string;\n confirmButtonLabel?: string;\n };\n\nconst InlineEdit = forwardRef<HTMLInputElement, InlineEditProps>(\n (\n {\n 'data-test-id': testId = 'inline-edit',\n layout = 'horizontal',\n children,\n defaultValue,\n onConfirm,\n hideEdit = false,\n renderInput = <TextField />,\n 'aria-label': ariaLabel,\n isEditing: isEditingProp,\n onCancel,\n onEdit,\n cancelButtonLabel = 'cancel',\n editButtonLabel = 'edit',\n confirmButtonLabel = 'confirm',\n className,\n ...rest\n },\n ref\n ) => {\n const [isEditing, setEditing] = useState(isEditingProp ?? false);\n const [isFocusWithin, setFocusWithin] = useState(false);\n const inputRef = useRef<HTMLInputElement>(null);\n const editRef = useRef<HTMLButtonElement>(null);\n const controlled = isEditingProp !== undefined;\n\n useUpdateEffect(() => {\n if (controlled) {\n setEditing(isEditingProp);\n }\n }, [isEditingProp]);\n\n useUpdateEffect(() => {\n if (isFocusWithin) {\n isEditing\n ? inputRef.current && focusSafely(inputRef.current)\n : editRef.current && focusSafely(editRef.current);\n }\n }, [isEditing]);\n\n const handleEdit = () => {\n !controlled && setEditing(true);\n onEdit?.();\n };\n\n const handleCancel = () => {\n !controlled && setEditing(false);\n onCancel?.();\n };\n\n const handleConfirm = () => {\n onConfirm(inputRef.current?.value || '');\n !controlled && setEditing(false);\n };\n\n const handleKeyDown: KeyboardEventHandler<HTMLInputElement> = (event) => {\n if (event.key === 'Enter') {\n event.preventDefault();\n handleConfirm();\n } else if (event.key === 'Escape') {\n event.preventDefault();\n handleCancel();\n }\n };\n\n const { focusWithinProps } = useFocusWithin({\n onBlurWithin: () => isEditing && handleCancel(),\n onFocusWithinChange: (isFocusWithin) => setFocusWithin(isFocusWithin),\n });\n\n const { buttonProps } = useButton(\n {\n 'aria-label': editButtonLabel,\n elementType: 'span',\n onPress: handleEdit,\n },\n editRef\n );\n\n const renderReadContent = hideEdit ? (\n <span ref={editRef} {...buttonProps} className={readButton}>\n {children}\n </span>\n ) : (\n <>\n {children}\n <IconButton\n ref={editRef}\n icon={<Icon name=\"edit\" />}\n aria-label={editButtonLabel}\n size=\"small\"\n onClick={handleEdit}\n />\n </>\n );\n\n const inputProps = {\n ref: mergeRefs(inputRef, ref),\n defaultValue,\n onKeyDown: handleKeyDown,\n 'aria-label': ariaLabel,\n };\n\n const inputChildren = renderInput.props.children;\n\n const input = cloneElement(\n renderInput,\n mergeProps(renderInput.props, inputChildren ? {} : inputProps),\n inputChildren &&\n Children.map(inputChildren, (child) =>\n child.type === TextField || child.type === TextArea\n ? cloneElement(child, mergeProps(child.props, inputProps))\n : child\n )\n );\n\n return isEditing ? (\n <div\n {...rest}\n className={cx(container, inline({ layout }), className)}\n data-test-id={testId}\n {...focusWithinProps}\n >\n {input}\n <ButtonGroup spacing=\"compact\">\n <IconButton\n kind=\"primary\"\n icon={<Icon name=\"check\" />}\n aria-label={confirmButtonLabel}\n onClick={handleConfirm}\n />\n <IconButton\n kind=\"default\"\n icon={<Icon name=\"close\" />}\n aria-label={cancelButtonLabel}\n className={cancelButton}\n onClick={handleCancel}\n />\n </ButtonGroup>\n </div>\n ) : (\n <div\n {...rest}\n className={cx(!hideEdit && container, className)}\n data-test-id={testId}\n {...focusWithinProps}\n >\n {renderReadContent}\n </div>\n );\n }\n);\n\nInlineEdit.displayName = 'InlineEdit';\n\nexport { InlineEdit };\nexport type { InlineEditProps };\n"],"names":["isFocusWithin"],"mappings":"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"}
|
package/dist/index.js
CHANGED
@@ -98,14 +98,20 @@ const InlineEdit = /* @__PURE__ */ react.forwardRef(
|
|
98
98
|
}
|
99
99
|
)
|
100
100
|
] });
|
101
|
+
const inputProps = {
|
102
|
+
ref: utils.mergeRefs(inputRef, ref),
|
103
|
+
defaultValue,
|
104
|
+
onKeyDown: handleKeyDown,
|
105
|
+
"aria-label": ariaLabel
|
106
|
+
};
|
107
|
+
const inputChildren = renderInput.props.children;
|
101
108
|
const input = /* @__PURE__ */ react.cloneElement(
|
102
109
|
renderInput,
|
103
|
-
utils.mergeProps(renderInput.props, {
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
})
|
110
|
+
utils.mergeProps(renderInput.props, inputChildren ? {} : inputProps),
|
111
|
+
inputChildren && react.Children.map(
|
112
|
+
inputChildren,
|
113
|
+
(child) => child.type === form.TextField || child.type === form.TextArea ? /* @__PURE__ */ react.cloneElement(child, utils.mergeProps(child.props, inputProps)) : child
|
114
|
+
)
|
109
115
|
);
|
110
116
|
return isEditing ? /* @__PURE__ */ jsxRuntime.jsxs(
|
111
117
|
"div",
|
package/dist/index.js.map
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../src/InlineEdit.tsx"],"sourcesContent":["import type { InlineVariants } from './styles/InlineEdit.css';\nimport type { TextAreaProps, TextFieldProps } from '@launchpad-ui/form';\nimport type { ComponentProps, KeyboardEventHandler, ReactElement } from 'react';\n\nimport { ButtonGroup, IconButton } from '@launchpad-ui/button';\nimport { TextField } from '@launchpad-ui/form';\nimport { Icon } from '@launchpad-ui/icons';\nimport { useButton } from '@react-aria/button';\nimport { focusSafely } from '@react-aria/focus';\nimport { useFocusWithin } from '@react-aria/interactions';\nimport { mergeProps, mergeRefs, useUpdateEffect } from '@react-aria/utils';\nimport { cx } from 'classix';\nimport { cloneElement, forwardRef, useRef, useState } from 'react';\n\nimport { container, cancelButton, inline, readButton } from './styles/InlineEdit.css';\n\ntype InlineEditProps = ComponentProps<'div'> &\n InlineVariants &\n Pick<ComponentProps<'input'>, 'defaultValue'> & {\n 'data-test-id'?: string;\n onConfirm: (value: string) => void;\n hideEdit?: boolean;\n renderInput?: ReactElement<TextFieldProps | TextAreaProps>;\n isEditing?: boolean;\n onCancel?: () => void;\n onEdit?: () => void;\n cancelButtonLabel?: string;\n editButtonLabel?: string;\n confirmButtonLabel?: string;\n };\n\nconst InlineEdit = forwardRef<HTMLInputElement, InlineEditProps>(\n (\n {\n 'data-test-id': testId = 'inline-edit',\n layout = 'horizontal',\n children,\n defaultValue,\n onConfirm,\n hideEdit = false,\n renderInput = <TextField />,\n 'aria-label': ariaLabel,\n isEditing: isEditingProp,\n onCancel,\n onEdit,\n cancelButtonLabel = 'cancel',\n editButtonLabel = 'edit',\n confirmButtonLabel = 'confirm',\n className,\n ...rest\n },\n ref\n ) => {\n const [isEditing, setEditing] = useState(isEditingProp ?? false);\n const [isFocusWithin, setFocusWithin] = useState(false);\n const inputRef = useRef<HTMLInputElement>(null);\n const editRef = useRef<HTMLButtonElement>(null);\n const controlled = isEditingProp !== undefined;\n\n useUpdateEffect(() => {\n if (controlled) {\n setEditing(isEditingProp);\n }\n }, [isEditingProp]);\n\n useUpdateEffect(() => {\n if (isFocusWithin) {\n isEditing\n ? inputRef.current && focusSafely(inputRef.current)\n : editRef.current && focusSafely(editRef.current);\n }\n }, [isEditing]);\n\n const handleEdit = () => {\n !controlled && setEditing(true);\n onEdit?.();\n };\n\n const handleCancel = () => {\n !controlled && setEditing(false);\n onCancel?.();\n };\n\n const handleConfirm = () => {\n onConfirm(inputRef.current?.value || '');\n !controlled && setEditing(false);\n };\n\n const handleKeyDown: KeyboardEventHandler<HTMLInputElement> = (event) => {\n if (event.key === 'Enter') {\n event.preventDefault();\n handleConfirm();\n } else if (event.key === 'Escape') {\n event.preventDefault();\n handleCancel();\n }\n };\n\n const { focusWithinProps } = useFocusWithin({\n onBlurWithin: () => isEditing && handleCancel(),\n onFocusWithinChange: (isFocusWithin) => setFocusWithin(isFocusWithin),\n });\n\n const { buttonProps } = useButton(\n {\n 'aria-label': editButtonLabel,\n elementType: 'span',\n onPress: handleEdit,\n },\n editRef\n );\n\n const renderReadContent = hideEdit ? (\n <span ref={editRef} {...buttonProps} className={readButton}>\n {children}\n </span>\n ) : (\n <>\n {children}\n <IconButton\n ref={editRef}\n icon={<Icon name=\"edit\" />}\n aria-label={editButtonLabel}\n size=\"small\"\n onClick={handleEdit}\n />\n </>\n );\n\n const
|
1
|
+
{"version":3,"file":"index.js","sources":["../src/InlineEdit.tsx"],"sourcesContent":["import type { InlineVariants } from './styles/InlineEdit.css';\nimport type { IconFieldProps, TextAreaProps, TextFieldProps } from '@launchpad-ui/form';\nimport type { ComponentProps, KeyboardEventHandler, ReactElement } from 'react';\n\nimport { ButtonGroup, IconButton } from '@launchpad-ui/button';\nimport { TextField, TextArea } from '@launchpad-ui/form';\nimport { Icon } from '@launchpad-ui/icons';\nimport { useButton } from '@react-aria/button';\nimport { focusSafely } from '@react-aria/focus';\nimport { useFocusWithin } from '@react-aria/interactions';\nimport { mergeProps, mergeRefs, useUpdateEffect } from '@react-aria/utils';\nimport { cx } from 'classix';\nimport { Children, cloneElement, forwardRef, useRef, useState } from 'react';\n\nimport { container, cancelButton, inline, readButton } from './styles/InlineEdit.css';\n\ntype InlineEditProps = ComponentProps<'div'> &\n InlineVariants &\n Pick<ComponentProps<'input'>, 'defaultValue'> & {\n 'data-test-id'?: string;\n onConfirm: (value: string) => void;\n hideEdit?: boolean;\n renderInput?: ReactElement<IconFieldProps | TextFieldProps | TextAreaProps>;\n isEditing?: boolean;\n onCancel?: () => void;\n onEdit?: () => void;\n cancelButtonLabel?: string;\n editButtonLabel?: string;\n confirmButtonLabel?: string;\n };\n\nconst InlineEdit = forwardRef<HTMLInputElement, InlineEditProps>(\n (\n {\n 'data-test-id': testId = 'inline-edit',\n layout = 'horizontal',\n children,\n defaultValue,\n onConfirm,\n hideEdit = false,\n renderInput = <TextField />,\n 'aria-label': ariaLabel,\n isEditing: isEditingProp,\n onCancel,\n onEdit,\n cancelButtonLabel = 'cancel',\n editButtonLabel = 'edit',\n confirmButtonLabel = 'confirm',\n className,\n ...rest\n },\n ref\n ) => {\n const [isEditing, setEditing] = useState(isEditingProp ?? false);\n const [isFocusWithin, setFocusWithin] = useState(false);\n const inputRef = useRef<HTMLInputElement>(null);\n const editRef = useRef<HTMLButtonElement>(null);\n const controlled = isEditingProp !== undefined;\n\n useUpdateEffect(() => {\n if (controlled) {\n setEditing(isEditingProp);\n }\n }, [isEditingProp]);\n\n useUpdateEffect(() => {\n if (isFocusWithin) {\n isEditing\n ? inputRef.current && focusSafely(inputRef.current)\n : editRef.current && focusSafely(editRef.current);\n }\n }, [isEditing]);\n\n const handleEdit = () => {\n !controlled && setEditing(true);\n onEdit?.();\n };\n\n const handleCancel = () => {\n !controlled && setEditing(false);\n onCancel?.();\n };\n\n const handleConfirm = () => {\n onConfirm(inputRef.current?.value || '');\n !controlled && setEditing(false);\n };\n\n const handleKeyDown: KeyboardEventHandler<HTMLInputElement> = (event) => {\n if (event.key === 'Enter') {\n event.preventDefault();\n handleConfirm();\n } else if (event.key === 'Escape') {\n event.preventDefault();\n handleCancel();\n }\n };\n\n const { focusWithinProps } = useFocusWithin({\n onBlurWithin: () => isEditing && handleCancel(),\n onFocusWithinChange: (isFocusWithin) => setFocusWithin(isFocusWithin),\n });\n\n const { buttonProps } = useButton(\n {\n 'aria-label': editButtonLabel,\n elementType: 'span',\n onPress: handleEdit,\n },\n editRef\n );\n\n const renderReadContent = hideEdit ? (\n <span ref={editRef} {...buttonProps} className={readButton}>\n {children}\n </span>\n ) : (\n <>\n {children}\n <IconButton\n ref={editRef}\n icon={<Icon name=\"edit\" />}\n aria-label={editButtonLabel}\n size=\"small\"\n onClick={handleEdit}\n />\n </>\n );\n\n const inputProps = {\n ref: mergeRefs(inputRef, ref),\n defaultValue,\n onKeyDown: handleKeyDown,\n 'aria-label': ariaLabel,\n };\n\n const inputChildren = renderInput.props.children;\n\n const input = cloneElement(\n renderInput,\n mergeProps(renderInput.props, inputChildren ? {} : inputProps),\n inputChildren &&\n Children.map(inputChildren, (child) =>\n child.type === TextField || child.type === TextArea\n ? cloneElement(child, mergeProps(child.props, inputProps))\n : child\n )\n );\n\n return isEditing ? (\n <div\n {...rest}\n className={cx(container, inline({ layout }), className)}\n data-test-id={testId}\n {...focusWithinProps}\n >\n {input}\n <ButtonGroup spacing=\"compact\">\n <IconButton\n kind=\"primary\"\n icon={<Icon name=\"check\" />}\n aria-label={confirmButtonLabel}\n onClick={handleConfirm}\n />\n <IconButton\n kind=\"default\"\n icon={<Icon name=\"close\" />}\n aria-label={cancelButtonLabel}\n className={cancelButton}\n onClick={handleCancel}\n />\n </ButtonGroup>\n </div>\n ) : (\n <div\n {...rest}\n className={cx(!hideEdit && container, className)}\n data-test-id={testId}\n {...focusWithinProps}\n >\n {renderReadContent}\n </div>\n );\n }\n);\n\nInlineEdit.displayName = 'InlineEdit';\n\nexport { InlineEdit };\nexport type { InlineEditProps };\n"],"names":["forwardRef","TextField","useState","useRef","useUpdateEffect","focusSafely","useFocusWithin","isFocusWithin","useButton","jsx","jsxs","Fragment","IconButton","Icon","mergeRefs","cloneElement","mergeProps","Children","TextArea","cx","ButtonGroup"],"mappings":"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"}
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@launchpad-ui/inline-edit",
|
3
|
-
"version": "0.1.
|
3
|
+
"version": "0.1.11",
|
4
4
|
"status": "alpha",
|
5
5
|
"publishConfig": {
|
6
6
|
"access": "public"
|
@@ -32,9 +32,9 @@
|
|
32
32
|
"@react-aria/utils": "3.19.0",
|
33
33
|
"@vanilla-extract/recipes": "^0.5.0",
|
34
34
|
"classix": "2.1.17",
|
35
|
-
"@launchpad-ui/button": "~0.10.
|
36
|
-
"@launchpad-ui/form": "~0.9.
|
37
|
-
"@launchpad-ui/icons": "~0.12.
|
35
|
+
"@launchpad-ui/button": "~0.10.4",
|
36
|
+
"@launchpad-ui/form": "~0.9.12",
|
37
|
+
"@launchpad-ui/icons": "~0.12.2",
|
38
38
|
"@launchpad-ui/tokens": "~0.7.0",
|
39
39
|
"@launchpad-ui/vars": "~0.2.1"
|
40
40
|
},
|