@wistia/ui 3.7.1 → 3.8.0-beta.0376af91.6c91cbd
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.d.ts +65 -46
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +223 -94
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
- package/CHANGELOG.md +0 -2640
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
|
|
2
2
|
/*
|
|
3
|
-
* @license @wistia/ui v3.
|
|
3
|
+
* @license @wistia/ui v3.8.0-beta.0376af91.6c91cbd
|
|
4
4
|
*
|
|
5
5
|
* Copyright (c) 2024-2026, Wistia, Inc. and its affiliates.
|
|
6
6
|
*
|
|
@@ -7156,6 +7156,12 @@ const Thumb$2 = styled(ScrollArea$1.Thumb)`
|
|
|
7156
7156
|
height: ${THUMB_SIZE_PX}px;
|
|
7157
7157
|
}
|
|
7158
7158
|
`;
|
|
7159
|
+
const scrollbarVisibleCss = css`
|
|
7160
|
+
opacity: 1;
|
|
7161
|
+
pointer-events: auto;
|
|
7162
|
+
transition-delay: 0s;
|
|
7163
|
+
transition-duration: var(--wui-motion-duration-01);
|
|
7164
|
+
`;
|
|
7159
7165
|
const Scrollbar = styled(ScrollArea$1.Scrollbar)`
|
|
7160
7166
|
display: flex;
|
|
7161
7167
|
opacity: 0;
|
|
@@ -7175,14 +7181,18 @@ const Scrollbar = styled(ScrollArea$1.Scrollbar)`
|
|
|
7175
7181
|
height: ${SCROLLBAR_SIZE_PX}px;
|
|
7176
7182
|
}
|
|
7177
7183
|
|
|
7178
|
-
|
|
7179
|
-
&[data-scrolling]
|
|
7180
|
-
|
|
7181
|
-
|
|
7182
|
-
transition-delay: 0s;
|
|
7183
|
-
transition-duration: var(--wui-motion-duration-01);
|
|
7184
|
+
/* a scrollbar under the pointer or being dragged stays put once it has appeared */
|
|
7185
|
+
&[data-scrolling],
|
|
7186
|
+
&:is(:hover, :active) {
|
|
7187
|
+
${scrollbarVisibleCss}
|
|
7184
7188
|
}
|
|
7185
7189
|
|
|
7190
|
+
${({ $showOnHover }) => $showOnHover && css`
|
|
7191
|
+
&[data-hovering] {
|
|
7192
|
+
${scrollbarVisibleCss}
|
|
7193
|
+
}
|
|
7194
|
+
`}
|
|
7195
|
+
|
|
7186
7196
|
&:is(:hover, :active) > ${Thumb$2} {
|
|
7187
7197
|
background-color: var(--wui-gray-alpha-9);
|
|
7188
7198
|
}
|
|
@@ -7205,9 +7215,10 @@ const FILL_HEIGHT_CONTENT_STYLE = {
|
|
|
7205
7215
|
/**
|
|
7206
7216
|
* ScrollArea is a scrollable container with shadow or fade effects to indicate
|
|
7207
7217
|
* scrollability. Its scrollbars overlay the content and only appear while the
|
|
7208
|
-
* pointer is over the area or the content is being scrolled
|
|
7218
|
+
* pointer is over the area or the content is being scrolled, or only while it
|
|
7219
|
+
* is being scrolled when `showScrollbarsOnHover` is false.
|
|
7209
7220
|
*/
|
|
7210
|
-
const ScrollArea = ({ children, style, locked = false, fillHeight = false, overflowIndicator = "shadow", ref, ...props }) => {
|
|
7221
|
+
const ScrollArea = ({ children, style, locked = false, fillHeight = false, overflowIndicator = "shadow", showScrollbarsOnHover = true, ref, ...props }) => {
|
|
7211
7222
|
return /* @__PURE__ */ jsxs(Root$1, {
|
|
7212
7223
|
style,
|
|
7213
7224
|
children: [
|
|
@@ -7230,10 +7241,12 @@ const ScrollArea = ({ children, style, locked = false, fillHeight = false, overf
|
|
|
7230
7241
|
}),
|
|
7231
7242
|
locked ? null : /* @__PURE__ */ jsxs(Fragment$1, { children: [
|
|
7232
7243
|
/* @__PURE__ */ jsx(Scrollbar, {
|
|
7244
|
+
$showOnHover: showScrollbarsOnHover,
|
|
7233
7245
|
orientation: "vertical",
|
|
7234
7246
|
children: /* @__PURE__ */ jsx(Thumb$2, {})
|
|
7235
7247
|
}),
|
|
7236
7248
|
/* @__PURE__ */ jsx(Scrollbar, {
|
|
7249
|
+
$showOnHover: showScrollbarsOnHover,
|
|
7237
7250
|
orientation: "horizontal",
|
|
7238
7251
|
children: /* @__PURE__ */ jsx(Thumb$2, {})
|
|
7239
7252
|
}),
|
|
@@ -13126,64 +13139,76 @@ const EditableHeading = ({ children, onValueChange, onEditingChange, tooltipText
|
|
|
13126
13139
|
}) })] });
|
|
13127
13140
|
};
|
|
13128
13141
|
// src/components/EditableText/EditableTextRoot.tsx
|
|
13129
|
-
const
|
|
13130
|
-
|
|
13131
|
-
|
|
13132
|
-
|
|
13133
|
-
|
|
13134
|
-
|
|
13135
|
-
|
|
13136
|
-
|
|
13137
|
-
|
|
13138
|
-
|
|
13139
|
-
|
|
13140
|
-
|
|
13141
|
-
|
|
13142
|
-
|
|
13143
|
-
|
|
13144
|
-
"heading6",
|
|
13145
|
-
"body2",
|
|
13146
|
-
"body3",
|
|
13147
|
-
"body4",
|
|
13148
|
-
"label2",
|
|
13149
|
-
"label3",
|
|
13150
|
-
"label4",
|
|
13151
|
-
"body2Mono",
|
|
13152
|
-
"body3Mono",
|
|
13153
|
-
"body4Mono"
|
|
13154
|
-
];
|
|
13155
|
-
if (largePaddingVariants.includes(variant)) return LARGE_PADDING;
|
|
13156
|
-
if (smallPaddingVariants.includes(variant)) return SMALL_PADDING;
|
|
13157
|
-
return SMALL_PADDING;
|
|
13158
|
-
};
|
|
13142
|
+
const SMALL_PADDING = {
|
|
13143
|
+
block: "2px",
|
|
13144
|
+
inline: "var(--wui-space-01)"
|
|
13145
|
+
};
|
|
13146
|
+
const LARGE_PADDING = {
|
|
13147
|
+
block: "var(--wui-space-01)",
|
|
13148
|
+
inline: "var(--wui-space-02)"
|
|
13149
|
+
};
|
|
13150
|
+
const LARGE_PADDING_VARIANTS = /* @__PURE__ */ new Set([
|
|
13151
|
+
"hero",
|
|
13152
|
+
"heading1",
|
|
13153
|
+
"heading2",
|
|
13154
|
+
"heading3"
|
|
13155
|
+
]);
|
|
13156
|
+
const getPaddingForVariant = (variant) => LARGE_PADDING_VARIANTS.has(variant) ? LARGE_PADDING : SMALL_PADDING;
|
|
13159
13157
|
const StyledEditableTextRoot = styled.div`
|
|
13160
13158
|
display: contents;
|
|
13161
13159
|
|
|
13162
|
-
--wui-editable-text-padding: ${({ $typographicVariant }) => getPaddingForVariant($typographicVariant)};
|
|
13160
|
+
--wui-editable-text-padding-block: ${({ $typographicVariant }) => getPaddingForVariant($typographicVariant).block};
|
|
13161
|
+
--wui-editable-text-padding-inline: ${({ $typographicVariant }) => getPaddingForVariant($typographicVariant).inline};
|
|
13163
13162
|
--wui-editable-text-border-radius: var(--wui-border-radius-01);
|
|
13163
|
+
|
|
13164
|
+
/* Negative margins that pull the display and input out by their padding, so the text
|
|
13165
|
+
* sits where it would without EditableText and doesn't move when editing starts. */
|
|
13166
|
+
--wui-editable-text-bleed-block: ${({ $bleed }) => $bleed ? "calc(var(--wui-editable-text-padding-block) * -1)" : "0px"};
|
|
13167
|
+
--wui-editable-text-bleed-inline: ${({ $bleed }) => $bleed ? "calc(var(--wui-editable-text-padding-inline) * -1)" : "0px"};
|
|
13164
13168
|
`;
|
|
13165
13169
|
const EditableTextContext = createContext(null);
|
|
13166
|
-
const
|
|
13170
|
+
const getEditableTextState = (readOnly, isEditing) => {
|
|
13171
|
+
if (readOnly) return "read-only";
|
|
13172
|
+
if (isEditing) return "editing";
|
|
13173
|
+
return "idle";
|
|
13174
|
+
};
|
|
13175
|
+
/**
|
|
13176
|
+
* Holds the value (controlled or uncontrolled), the value to revert to and the editing state.
|
|
13177
|
+
*/
|
|
13178
|
+
const useEditableTextState = ({ controlledValue, defaultValue, onValueChange, onEditingChange }) => {
|
|
13167
13179
|
const isControlled = controlledValue !== void 0;
|
|
13168
13180
|
const [internalValue, setInternalValue] = useState(defaultValue);
|
|
13169
13181
|
const [originalValue, setOriginalValue] = useState(defaultValue);
|
|
13170
13182
|
const [isEditing, setIsEditing] = useState(false);
|
|
13171
13183
|
const value = isControlled ? controlledValue : internalValue;
|
|
13172
|
-
|
|
13173
|
-
const computedId = isNonEmptyString(id) ? id : `wistia-ui-editable-text-${generatedId}`;
|
|
13174
|
-
const handleSetIsEditing = useCallback((editing) => {
|
|
13175
|
-
if (editing && !isEditing) setOriginalValue(value);
|
|
13176
|
-
setIsEditing(editing);
|
|
13177
|
-
onEditingChange?.(editing);
|
|
13178
|
-
}, [
|
|
13184
|
+
return {
|
|
13179
13185
|
isEditing,
|
|
13186
|
+
handleSetIsEditing: useCallback((editing) => {
|
|
13187
|
+
if (editing && !isEditing) setOriginalValue(value);
|
|
13188
|
+
setIsEditing(editing);
|
|
13189
|
+
onEditingChange?.(editing);
|
|
13190
|
+
}, [
|
|
13191
|
+
isEditing,
|
|
13192
|
+
value,
|
|
13193
|
+
onEditingChange
|
|
13194
|
+
]),
|
|
13180
13195
|
value,
|
|
13196
|
+
setValue: useCallback((newValue) => {
|
|
13197
|
+
if (!isControlled) setInternalValue(newValue);
|
|
13198
|
+
onValueChange?.(newValue);
|
|
13199
|
+
}, [isControlled, onValueChange]),
|
|
13200
|
+
originalValue
|
|
13201
|
+
};
|
|
13202
|
+
};
|
|
13203
|
+
const EditableTextRoot = ({ children, defaultValue = "", value: controlledValue, onValueChange, onValueCommit, onValueRevert, onEditingChange, typographicVariant = "body2", submitMode = "both", readOnly = false, id, label, placeholder = "Click to edit this text", minLines = 1, maxLines, finalFocusEl, bleed = false, ...props }) => {
|
|
13204
|
+
const { isEditing, handleSetIsEditing, value, setValue, originalValue } = useEditableTextState({
|
|
13205
|
+
controlledValue,
|
|
13206
|
+
defaultValue,
|
|
13207
|
+
onValueChange,
|
|
13181
13208
|
onEditingChange
|
|
13182
|
-
|
|
13183
|
-
const
|
|
13184
|
-
|
|
13185
|
-
onValueChange?.(newValue);
|
|
13186
|
-
}, [isControlled, onValueChange]);
|
|
13209
|
+
});
|
|
13210
|
+
const generatedId = useId();
|
|
13211
|
+
const computedId = isNonEmptyString(id) ? id : `wistia-ui-editable-text-${generatedId}`;
|
|
13187
13212
|
const context = useMemo(() => {
|
|
13188
13213
|
return {
|
|
13189
13214
|
isEditing,
|
|
@@ -13221,16 +13246,13 @@ const EditableTextRoot = ({ children, defaultValue = "", value: controlledValue,
|
|
|
13221
13246
|
maxLines,
|
|
13222
13247
|
finalFocusEl
|
|
13223
13248
|
]);
|
|
13224
|
-
const getState = () => {
|
|
13225
|
-
if (readOnly) return "read-only";
|
|
13226
|
-
if (isEditing) return "editing";
|
|
13227
|
-
return "idle";
|
|
13228
|
-
};
|
|
13229
13249
|
return /* @__PURE__ */ jsx(StyledEditableTextRoot, {
|
|
13250
|
+
$bleed: bleed,
|
|
13230
13251
|
$typographicVariant: typographicVariant,
|
|
13231
13252
|
"data-testid": "editable-text-root",
|
|
13253
|
+
"data-wui-editable-text-bleed": bleed || void 0,
|
|
13232
13254
|
"data-wui-editable-text-root": true,
|
|
13233
|
-
"data-wui-editable-text-state":
|
|
13255
|
+
"data-wui-editable-text-state": getEditableTextState(readOnly, isEditing),
|
|
13234
13256
|
...props,
|
|
13235
13257
|
children: /* @__PURE__ */ jsx(EditableTextContext, {
|
|
13236
13258
|
value: context,
|
|
@@ -13240,9 +13262,11 @@ const EditableTextRoot = ({ children, defaultValue = "", value: controlledValue,
|
|
|
13240
13262
|
};
|
|
13241
13263
|
const PolymorphicStyledEditableTextDisplay = withPolymorphicAs(styled.div`
|
|
13242
13264
|
${({ $typographicVariant }) => getTypographicStyles($typographicVariant)}
|
|
13243
|
-
padding: var(--wui-editable-text-padding);
|
|
13265
|
+
padding-block: var(--wui-editable-text-padding-block);
|
|
13266
|
+
padding-inline: var(--wui-editable-text-padding-inline);
|
|
13244
13267
|
border-radius: var(--wui-editable-text-border-radius);
|
|
13245
|
-
margin: 0;
|
|
13268
|
+
margin-block: var(--wui-editable-text-bleed-block, 0);
|
|
13269
|
+
margin-inline: var(--wui-editable-text-bleed-inline, 0);
|
|
13246
13270
|
transition: all var(--wui-motion-duration-02) var(--wui-motion-ease);
|
|
13247
13271
|
${({ $maxLines }) => {
|
|
13248
13272
|
if (isNotNil($maxLines)) return css`
|
|
@@ -13251,7 +13275,7 @@ const PolymorphicStyledEditableTextDisplay = withPolymorphicAs(styled.div`
|
|
|
13251
13275
|
`;
|
|
13252
13276
|
}}
|
|
13253
13277
|
${({ $minLines }) => isNotNil($minLines) && css`
|
|
13254
|
-
min-height: calc(${$minLines}lh + calc(var(--wui-editable-text-padding) * 2));
|
|
13278
|
+
min-height: calc(${$minLines}lh + calc(var(--wui-editable-text-padding-block) * 2));
|
|
13255
13279
|
`}
|
|
13256
13280
|
word-break: normal;
|
|
13257
13281
|
overflow-wrap: anywhere;
|
|
@@ -13315,22 +13339,97 @@ const EditableTextDisplayComponent = ({ ref, asTrigger, renderAs, ...props }) =>
|
|
|
13315
13339
|
};
|
|
13316
13340
|
const EditableTextDisplay = makePolymorphic(EditableTextDisplayComponent);
|
|
13317
13341
|
// src/components/EditableText/EditableTextInput.tsx
|
|
13342
|
+
const StyledInputWrapper = styled.div`
|
|
13343
|
+
display: flex;
|
|
13344
|
+
min-width: 0;
|
|
13345
|
+
|
|
13346
|
+
& > [data-wui-input-container] {
|
|
13347
|
+
flex: 1 1 auto;
|
|
13348
|
+
min-width: 0;
|
|
13349
|
+
}
|
|
13350
|
+
`;
|
|
13318
13351
|
const StyledInput = styled(Input)`
|
|
13319
13352
|
&& {
|
|
13320
|
-
${({ $minLines }) => isNotNil($minLines) && `min-height: calc(${$minLines}lh + calc(var(--wui-editable-text-padding) * 2));`}
|
|
13321
|
-
${({ $maxLines }) => isNotNil($maxLines) && `max-height: calc(${$maxLines}lh + calc(var(--wui-editable-text-padding) * 2));`}
|
|
13353
|
+
${({ $minLines }) => isNotNil($minLines) && `min-height: calc(${$minLines}lh + calc(var(--wui-editable-text-padding-block) * 2));`}
|
|
13354
|
+
${({ $maxLines }) => isNotNil($maxLines) && `max-height: calc(${$maxLines}lh + calc(var(--wui-editable-text-padding-block) * 2));`}
|
|
13322
13355
|
${({ $typographicVariant }) => getTypographicStyles($typographicVariant)}
|
|
13323
|
-
|
|
13356
|
+
/* No fill: the text sits on the page as it does when reading, and the ring marks the field */
|
|
13357
|
+
background-color: transparent;
|
|
13358
|
+
|
|
13359
|
+
/* With no fill of its own, the text takes the surrounding color and alignment, like the display */
|
|
13360
|
+
color: inherit;
|
|
13361
|
+
text-align: inherit;
|
|
13324
13362
|
border-radius: var(--wui-editable-text-border-radius);
|
|
13325
|
-
padding: var(--wui-editable-text-padding);
|
|
13363
|
+
padding-block: var(--wui-editable-text-padding-block);
|
|
13364
|
+
padding-inline: var(--wui-editable-text-padding-inline);
|
|
13365
|
+
margin-block: var(--wui-editable-text-bleed-block, 0);
|
|
13366
|
+
margin-inline: var(--wui-editable-text-bleed-inline, 0);
|
|
13367
|
+
width: calc(100% - (var(--wui-editable-text-bleed-inline, 0px) * 2));
|
|
13326
13368
|
resize: none;
|
|
13369
|
+
|
|
13370
|
+
/*
|
|
13371
|
+
* Size to the text, like the display, instead of the textarea's default 20-column width.
|
|
13372
|
+
* Otherwise the field changes width when editing starts wherever its parent shrink-wraps.
|
|
13373
|
+
*/
|
|
13374
|
+
field-sizing: content;
|
|
13375
|
+
|
|
13376
|
+
/*
|
|
13377
|
+
* maxLines={1}: behave like a single-line text input. The value stays on one line and
|
|
13378
|
+
* scrolls sideways instead of wrapping and scrolling vertically inside a one-line box.
|
|
13379
|
+
*/
|
|
13380
|
+
${({ $maxLines }) => $maxLines === 1 && css`
|
|
13381
|
+
white-space: pre;
|
|
13382
|
+
overflow-x: auto;
|
|
13383
|
+
overflow-y: hidden;
|
|
13384
|
+
scrollbar-width: none;
|
|
13385
|
+
|
|
13386
|
+
&::-webkit-scrollbar {
|
|
13387
|
+
display: none;
|
|
13388
|
+
}
|
|
13389
|
+
`}
|
|
13390
|
+
|
|
13391
|
+
/* Same color as the display's placeholder, so it doesn't change when editing starts */
|
|
13392
|
+
&::placeholder {
|
|
13393
|
+
color: var(--wui-color-text-secondary);
|
|
13394
|
+
}
|
|
13395
|
+
|
|
13396
|
+
/* Full-perimeter focus ring, inset like Input's so an overflow-hidden ancestor can't clip it */
|
|
13397
|
+
&:focus {
|
|
13398
|
+
outline: 2px solid var(--wui-color-focus-ring);
|
|
13399
|
+
outline-offset: -2px;
|
|
13400
|
+
}
|
|
13401
|
+
|
|
13402
|
+
/*
|
|
13403
|
+
* With submitMode "enter" or "none" the field stays open when focus moves to the
|
|
13404
|
+
* save/cancel buttons. Keep a visible 1px boundary so it still meets non-text contrast.
|
|
13405
|
+
*/
|
|
13406
|
+
&:not(:focus) {
|
|
13407
|
+
outline: 1px solid var(--wui-color-border-secondary);
|
|
13408
|
+
outline-offset: -1px;
|
|
13409
|
+
}
|
|
13327
13410
|
}
|
|
13328
13411
|
`;
|
|
13329
|
-
const
|
|
13412
|
+
const KEYBOARD_HINTS = {
|
|
13413
|
+
both: "Press Enter to save or Escape to cancel. Changes also save when you leave the field.",
|
|
13414
|
+
enter: "Press Enter to save or Escape to cancel.",
|
|
13415
|
+
blur: "Changes save when you leave the field. Press Escape to cancel.",
|
|
13416
|
+
none: "Press Escape to cancel."
|
|
13417
|
+
};
|
|
13418
|
+
/** Whether this key press submits: Enter without Shift, in a submit mode that uses Enter */
|
|
13419
|
+
const isCommitEnter = (event, submitMode) => event.key === "Enter" && !event.shiftKey && (submitMode === "enter" || submitMode === "both");
|
|
13420
|
+
/** In a single-line field, scroll sideways so the end of the value (and a caret there) is visible */
|
|
13421
|
+
const scrollToEnd = (element) => {
|
|
13422
|
+
element.scrollLeft = element.scrollWidth;
|
|
13423
|
+
};
|
|
13424
|
+
const EditableTextInput = ({ autoSelect = false, ...props }) => {
|
|
13330
13425
|
const context = useContext(EditableTextContext);
|
|
13331
13426
|
if (!context) throw new Error("EditableTextInput must be used within an EditableTextRoot context");
|
|
13332
13427
|
const { isEditing, value, setValue, onValueCommit, setIsEditing, typographicVariant, submitMode, originalValue, onValueRevert, id, placeholder, minLines, maxLines, finalFocusEl } = context;
|
|
13333
13428
|
const inputRef = useRef(null);
|
|
13429
|
+
const isEnteringRef = useRef(false);
|
|
13430
|
+
useEffect(() => {
|
|
13431
|
+
isEnteringRef.current = isEditing;
|
|
13432
|
+
}, [isEditing]);
|
|
13334
13433
|
useEffect(() => {
|
|
13335
13434
|
if (inputRef.current) {
|
|
13336
13435
|
if (isEditing) {
|
|
@@ -13340,63 +13439,93 @@ const EditableTextInput = (props) => {
|
|
|
13340
13439
|
const { scrollHeight } = element;
|
|
13341
13440
|
style.height = `${scrollHeight}px`;
|
|
13342
13441
|
}
|
|
13343
|
-
if (isEditing)
|
|
13442
|
+
if (isEditing) {
|
|
13443
|
+
inputRef.current.focus();
|
|
13444
|
+
isEnteringRef.current = false;
|
|
13445
|
+
}
|
|
13344
13446
|
}
|
|
13345
13447
|
}, [value, isEditing]);
|
|
13448
|
+
const isSingleLine = maxLines === 1;
|
|
13346
13449
|
const handleChange = (event) => {
|
|
13347
|
-
|
|
13450
|
+
const { target } = event;
|
|
13451
|
+
const nextValue = target.value;
|
|
13452
|
+
if (!isSingleLine) {
|
|
13453
|
+
setValue(nextValue);
|
|
13454
|
+
return;
|
|
13455
|
+
}
|
|
13456
|
+
const singleLineValue = nextValue.replaceAll(/\r\n|\r|\n/g, " ");
|
|
13457
|
+
if (singleLineValue !== nextValue) {
|
|
13458
|
+
const { selectionStart, selectionEnd } = target;
|
|
13459
|
+
target.value = singleLineValue;
|
|
13460
|
+
target.setSelectionRange(selectionStart, selectionEnd);
|
|
13461
|
+
}
|
|
13462
|
+
setValue(singleLineValue);
|
|
13463
|
+
};
|
|
13464
|
+
const closeAndRestoreFocus = () => {
|
|
13465
|
+
setIsEditing(false);
|
|
13466
|
+
setTimeout(() => {
|
|
13467
|
+
finalFocusEl?.()?.focus();
|
|
13468
|
+
}, 0);
|
|
13348
13469
|
};
|
|
13349
13470
|
const handleKeyDown = (event) => {
|
|
13350
|
-
if ((submitMode === "enter" || submitMode === "both") && event.key === "Enter" && !event.shiftKey) {
|
|
13351
|
-
event.preventDefault();
|
|
13352
|
-
onValueCommit?.(value);
|
|
13353
|
-
setIsEditing(false);
|
|
13354
|
-
setTimeout(() => {
|
|
13355
|
-
const element = finalFocusEl?.();
|
|
13356
|
-
if (element) element.focus();
|
|
13357
|
-
}, 0);
|
|
13358
|
-
}
|
|
13359
13471
|
if (event.key === "Escape") {
|
|
13360
13472
|
event.preventDefault();
|
|
13361
13473
|
setValue(originalValue);
|
|
13362
13474
|
onValueRevert?.(originalValue);
|
|
13363
|
-
|
|
13364
|
-
|
|
13365
|
-
const element = finalFocusEl?.();
|
|
13366
|
-
if (element) element.focus();
|
|
13367
|
-
}, 0);
|
|
13475
|
+
closeAndRestoreFocus();
|
|
13476
|
+
return;
|
|
13368
13477
|
}
|
|
13478
|
+
if (isCommitEnter(event, submitMode)) {
|
|
13479
|
+
event.preventDefault();
|
|
13480
|
+
onValueCommit?.(value);
|
|
13481
|
+
closeAndRestoreFocus();
|
|
13482
|
+
return;
|
|
13483
|
+
}
|
|
13484
|
+
if (isSingleLine && event.key === "Enter") event.preventDefault();
|
|
13369
13485
|
};
|
|
13370
13486
|
const handleBlur = () => {
|
|
13371
13487
|
if (submitMode === "blur" || submitMode === "both") {
|
|
13372
13488
|
onValueCommit?.(value);
|
|
13373
|
-
|
|
13374
|
-
setTimeout(() => {
|
|
13375
|
-
const element = finalFocusEl?.();
|
|
13376
|
-
if (element) element.focus();
|
|
13377
|
-
}, 0);
|
|
13489
|
+
closeAndRestoreFocus();
|
|
13378
13490
|
}
|
|
13379
13491
|
};
|
|
13492
|
+
const handleFocus = (event) => {
|
|
13493
|
+
const element = event.currentTarget;
|
|
13494
|
+
const shouldSelect = autoSelect && isEnteringRef.current;
|
|
13495
|
+
isEnteringRef.current = false;
|
|
13496
|
+
const { length } = element.value;
|
|
13497
|
+
element.setSelectionRange(length, length);
|
|
13498
|
+
if (isSingleLine) scrollToEnd(element);
|
|
13499
|
+
if (!shouldSelect && !isSingleLine) return;
|
|
13500
|
+
const valueOnFocus = element.value;
|
|
13501
|
+
requestAnimationFrame(() => {
|
|
13502
|
+
if (shouldSelect && element.value === valueOnFocus) element.select();
|
|
13503
|
+
if (isSingleLine && element.selectionEnd === element.value.length) scrollToEnd(element);
|
|
13504
|
+
});
|
|
13505
|
+
};
|
|
13380
13506
|
if (!isEditing) return null;
|
|
13381
|
-
|
|
13507
|
+
const keyboardHintId = `${id}-keyboard-hint`;
|
|
13508
|
+
return /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(StyledInputWrapper, { children: /* @__PURE__ */ jsx(StyledInput, {
|
|
13382
13509
|
ref: inputRef,
|
|
13383
13510
|
$maxLines: maxLines ?? "infinity",
|
|
13384
13511
|
$minLines: minLines,
|
|
13385
13512
|
$typographicVariant: typographicVariant,
|
|
13513
|
+
"aria-describedby": keyboardHintId,
|
|
13386
13514
|
"data-wui-editable-text-input": true,
|
|
13387
13515
|
id,
|
|
13388
13516
|
onBlur: handleBlur,
|
|
13389
13517
|
onChange: handleChange,
|
|
13390
|
-
onFocus:
|
|
13391
|
-
const { length } = event.currentTarget.value;
|
|
13392
|
-
event.currentTarget.setSelectionRange(length, length);
|
|
13393
|
-
},
|
|
13518
|
+
onFocus: handleFocus,
|
|
13394
13519
|
onKeyDown: handleKeyDown,
|
|
13395
13520
|
placeholder,
|
|
13396
13521
|
type: "multiline",
|
|
13397
13522
|
value,
|
|
13398
13523
|
...props
|
|
13399
|
-
})
|
|
13524
|
+
}) }), /* @__PURE__ */ jsx(ScreenReaderOnly, {
|
|
13525
|
+
"data-wui-editable-text-keyboard-hint": true,
|
|
13526
|
+
id: keyboardHintId,
|
|
13527
|
+
text: KEYBOARD_HINTS[submitMode]
|
|
13528
|
+
})] });
|
|
13400
13529
|
};
|
|
13401
13530
|
// src/components/EditableText/EditableTextLabel.tsx
|
|
13402
13531
|
const EditableTextLabel = ({ ...props }) => {
|