@wistia/ui 0.14.10 → 0.14.11-beta.7aeed0a2.d2a992b

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.cjs CHANGED
@@ -1,6 +1,6 @@
1
1
 
2
2
  /*
3
- * @license @wistia/ui v0.14.10
3
+ * @license @wistia/ui v0.14.11-beta.7aeed0a2.d2a992b
4
4
  *
5
5
  * Copyright (c) 2024-2025, Wistia, Inc. and its affiliates.
6
6
  *
@@ -78,6 +78,15 @@ __export(index_exports, {
78
78
  DataCards: () => DataCards,
79
79
  Divider: () => Divider,
80
80
  EditableHeading: () => EditableHeading,
81
+ EditableText: () => EditableText,
82
+ EditableTextCancelButton: () => EditableTextCancelButton,
83
+ EditableTextContext: () => EditableTextContext,
84
+ EditableTextDisplay: () => EditableTextDisplay,
85
+ EditableTextInput: () => EditableTextInput,
86
+ EditableTextLabel: () => EditableTextLabel,
87
+ EditableTextRoot: () => EditableTextRoot,
88
+ EditableTextSubmitButton: () => EditableTextSubmitButton,
89
+ EditableTextTrigger: () => EditableTextTrigger,
81
90
  Ellipsis: () => Ellipsis,
82
91
  FileAmountLimitValidator: () => import_validators.FileAmountLimitValidator,
83
92
  FileSizeValidator: () => import_validators.FileSizeValidator,
@@ -11338,6 +11347,7 @@ var Input = (0, import_react47.forwardRef)(
11338
11347
  {
11339
11348
  $fullWidth: fullWidth,
11340
11349
  $monospace: monospace,
11350
+ "data-wui-input-container": true,
11341
11351
  children: [
11342
11352
  leftIconToDisplay ?? null,
11343
11353
  type === "multiline" ? /* @__PURE__ */ (0, import_jsx_runtime247.jsx)(
@@ -13690,7 +13700,6 @@ var Menu = (0, import_react64.forwardRef)(
13690
13700
  isOpen,
13691
13701
  triggerProps = {},
13692
13702
  onOpenChange,
13693
- onInteractOutside,
13694
13703
  ...props
13695
13704
  }, ref) => {
13696
13705
  const contextValue = (0, import_react64.useMemo)(() => ({ compact }), [compact]);
@@ -17018,6 +17027,470 @@ var ContextMenu = ({
17018
17027
  }
17019
17028
  ) : null;
17020
17029
  };
17030
+
17031
+ // src/components/EditableText/EditableTextDisplay.tsx
17032
+ var import_react92 = require("react");
17033
+ var import_styled_components123 = __toESM(require("styled-components"));
17034
+ var import_type_guards73 = require("@wistia/type-guards");
17035
+
17036
+ // src/components/EditableText/EditableTextRoot.tsx
17037
+ var import_react91 = require("react");
17038
+ var import_type_guards72 = require("@wistia/type-guards");
17039
+ var import_styled_components121 = __toESM(require("styled-components"));
17040
+ var import_jsx_runtime317 = require("react/jsx-runtime");
17041
+ var StyledEditableTextRoot = import_styled_components121.default.div`
17042
+ display: contents;
17043
+
17044
+ --wui-editable-text-padding: var(--wui-space-01);
17045
+ --wui-editable-text-border-radius: var(--wui-border-radius-01);
17046
+ `;
17047
+ var EditableTextContext = (0, import_react91.createContext)(null);
17048
+ var EditableTextRoot = ({
17049
+ children,
17050
+ defaultValue = "",
17051
+ value: controlledValue,
17052
+ onValueChange,
17053
+ onValueCommit,
17054
+ onValueRevert,
17055
+ onEditingChange,
17056
+ typographicVariant = "body2",
17057
+ submitMode = "both",
17058
+ readOnly = false,
17059
+ id,
17060
+ label,
17061
+ placeholder = "Click to edit this text",
17062
+ minLines = 1,
17063
+ maxLines,
17064
+ finalFocusEl,
17065
+ ...props
17066
+ }) => {
17067
+ const isControlled = controlledValue !== void 0;
17068
+ const [internalValue, setInternalValue] = (0, import_react91.useState)(defaultValue);
17069
+ const [originalValue, setOriginalValue] = (0, import_react91.useState)(defaultValue);
17070
+ const [isEditing, setIsEditing] = (0, import_react91.useState)(false);
17071
+ const value = isControlled ? controlledValue : internalValue;
17072
+ const generatedId = (0, import_react91.useId)();
17073
+ const computedId = (0, import_type_guards72.isNonEmptyString)(id) ? id : `wistia-ui-editable-text-${generatedId}`;
17074
+ const handleSetIsEditing = (0, import_react91.useCallback)(
17075
+ (editing) => {
17076
+ if (editing && !isEditing) {
17077
+ setOriginalValue(value);
17078
+ }
17079
+ setIsEditing(editing);
17080
+ onEditingChange?.(editing);
17081
+ },
17082
+ [isEditing, value, onEditingChange]
17083
+ );
17084
+ const setValue = (0, import_react91.useCallback)(
17085
+ (newValue) => {
17086
+ if (!isControlled) {
17087
+ setInternalValue(newValue);
17088
+ }
17089
+ onValueChange?.(newValue);
17090
+ },
17091
+ [isControlled, onValueChange]
17092
+ );
17093
+ const context = (0, import_react91.useMemo)(() => {
17094
+ return {
17095
+ isEditing,
17096
+ setIsEditing: handleSetIsEditing,
17097
+ value,
17098
+ setValue,
17099
+ originalValue,
17100
+ onValueCommit,
17101
+ onValueRevert,
17102
+ typographicVariant,
17103
+ submitMode,
17104
+ readOnly,
17105
+ id: computedId,
17106
+ label,
17107
+ placeholder,
17108
+ minLines,
17109
+ maxLines,
17110
+ finalFocusEl
17111
+ };
17112
+ }, [
17113
+ isEditing,
17114
+ handleSetIsEditing,
17115
+ value,
17116
+ setValue,
17117
+ originalValue,
17118
+ onValueCommit,
17119
+ onValueRevert,
17120
+ typographicVariant,
17121
+ submitMode,
17122
+ readOnly,
17123
+ computedId,
17124
+ label,
17125
+ placeholder,
17126
+ minLines,
17127
+ maxLines,
17128
+ finalFocusEl
17129
+ ]);
17130
+ const getState = () => {
17131
+ if (readOnly) {
17132
+ return "read-only";
17133
+ }
17134
+ if (isEditing) {
17135
+ return "editing";
17136
+ }
17137
+ return "idle";
17138
+ };
17139
+ return /* @__PURE__ */ (0, import_jsx_runtime317.jsx)(
17140
+ StyledEditableTextRoot,
17141
+ {
17142
+ "data-wui-editable-text-root": true,
17143
+ "data-wui-editable-text-state": getState(),
17144
+ ...props,
17145
+ children: /* @__PURE__ */ (0, import_jsx_runtime317.jsx)(EditableTextContext.Provider, { value: context, children })
17146
+ }
17147
+ );
17148
+ };
17149
+
17150
+ // src/private/helpers/getTypographicStyles/getTypographicStyles.ts
17151
+ var import_styled_components122 = require("styled-components");
17152
+ var typographicVariantStyleMap = { ...variantStyleMap2, ...variantStyleMap };
17153
+ var getTypographicStyles = (variant) => {
17154
+ return import_styled_components122.css`
17155
+ ${typographicVariantStyleMap[variant]}
17156
+ font-family: var(--font-family);
17157
+ font-size: var(--font-size);
17158
+ font-weight: var(--font-weight);
17159
+ line-height: var(--line-height);
17160
+ `;
17161
+ };
17162
+ var typographicVariantElementMap = { ...variantElementMap2, ...variantElementMap };
17163
+ var getDefaultTypographicElement = (variant) => {
17164
+ return typographicVariantElementMap[variant] ?? "span";
17165
+ };
17166
+
17167
+ // src/components/EditableText/EditableTextDisplay.tsx
17168
+ var import_jsx_runtime318 = require("react/jsx-runtime");
17169
+ var StyledEditableTextDisplay = import_styled_components123.default.div`
17170
+ ${({ $typographicVariant }) => getTypographicStyles($typographicVariant)}
17171
+ padding: var(--wui-editable-text-padding);
17172
+ border-radius: var(--wui-editable-text-border-radius);
17173
+ margin: 0;
17174
+ transition: all var(--wui-motion-duration-02) var(--wui-motion-ease);
17175
+ ${({ $maxLines }) => {
17176
+ if ((0, import_type_guards73.isNotNil)($maxLines)) {
17177
+ return import_styled_components123.css`
17178
+ ${ellipsisStyle};
17179
+ ${lineClampCss($maxLines)};
17180
+ `;
17181
+ }
17182
+ return void 0;
17183
+ }}
17184
+ ${({ $minLines }) => (0, import_type_guards73.isNotNil)($minLines) && import_styled_components123.css`
17185
+ min-height: calc(${$minLines}lh + calc(var(--wui-editable-text-padding) * 2));
17186
+ `}
17187
+ word-break: break-word;
17188
+
17189
+ &[data-wui-editable-text-display='placeholder'] {
17190
+ color: var(--wui-color-text-secondary);
17191
+ }
17192
+
17193
+ &:has(button) {
17194
+ user-select: none;
17195
+ cursor: pointer;
17196
+
17197
+ &:hover,
17198
+ &:focus-within {
17199
+ background-color: var(--wui-color-bg-surface-hover);
17200
+ }
17201
+ }
17202
+ `;
17203
+ var EditableTextDisplayComponent = (0, import_react92.forwardRef)(
17204
+ ({ asTrigger, renderAs, ...props }, ref) => {
17205
+ const context = (0, import_react92.useContext)(EditableTextContext);
17206
+ if (!context) {
17207
+ throw new Error("EditableTextDisplay must be used within an EditableTextRoot context");
17208
+ }
17209
+ const { value, typographicVariant, setIsEditing, placeholder, maxLines, isEditing, minLines } = context;
17210
+ const triggerButtonRef = (0, import_react92.useRef)(null);
17211
+ const handleTriggerClick = () => {
17212
+ setIsEditing(true);
17213
+ };
17214
+ const elementType = renderAs ?? getDefaultTypographicElement(typographicVariant);
17215
+ const displayText = value.length > 0 ? value : placeholder;
17216
+ const isPlaceholderVisible = value.length === 0 && !!placeholder;
17217
+ if (isEditing) {
17218
+ return null;
17219
+ }
17220
+ if (asTrigger && !context.readOnly) {
17221
+ return /* @__PURE__ */ (0, import_jsx_runtime318.jsx)(ClickRegion, { targetRef: triggerButtonRef, children: /* @__PURE__ */ (0, import_jsx_runtime318.jsxs)(
17222
+ StyledEditableTextDisplay,
17223
+ {
17224
+ ref,
17225
+ $maxLines: maxLines,
17226
+ $minLines: minLines,
17227
+ $typographicVariant: typographicVariant,
17228
+ as: elementType,
17229
+ "data-wui-editable-text-display": isPlaceholderVisible ? "placeholder" : "value",
17230
+ ...props,
17231
+ children: [
17232
+ displayText,
17233
+ /* @__PURE__ */ (0, import_jsx_runtime318.jsx)(
17234
+ "button",
17235
+ {
17236
+ ref: triggerButtonRef,
17237
+ onClick: handleTriggerClick,
17238
+ style: { ...visuallyHiddenStyle },
17239
+ type: "button",
17240
+ children: "Edit text"
17241
+ }
17242
+ )
17243
+ ]
17244
+ }
17245
+ ) });
17246
+ }
17247
+ return /* @__PURE__ */ (0, import_jsx_runtime318.jsx)(
17248
+ StyledEditableTextDisplay,
17249
+ {
17250
+ ref,
17251
+ $maxLines: maxLines,
17252
+ $minLines: minLines,
17253
+ $typographicVariant: typographicVariant,
17254
+ as: elementType,
17255
+ "data-placeholder-visible": isPlaceholderVisible || void 0,
17256
+ "data-wui-editable-text-display": true,
17257
+ ...props,
17258
+ children: displayText
17259
+ }
17260
+ );
17261
+ }
17262
+ );
17263
+ EditableTextDisplayComponent.displayName = "EditableTextDisplay_UI";
17264
+ var EditableTextDisplay = makePolymorphic(
17265
+ EditableTextDisplayComponent
17266
+ );
17267
+
17268
+ // src/components/EditableText/EditableTextInput.tsx
17269
+ var import_react93 = require("react");
17270
+ var import_styled_components124 = __toESM(require("styled-components"));
17271
+ var import_type_guards74 = require("@wistia/type-guards");
17272
+ var import_jsx_runtime319 = require("react/jsx-runtime");
17273
+ var StyledInput3 = (0, import_styled_components124.default)(Input)`
17274
+ && {
17275
+ ${({ $minLines }) => (0, import_type_guards74.isNotNil)($minLines) && `min-height: calc(${$minLines}lh + calc(var(--wui-editable-text-padding) * 2));`}
17276
+ ${({ $maxLines }) => (0, import_type_guards74.isNotNil)($maxLines) && `max-height: calc(${$maxLines}lh + calc(var(--wui-editable-text-padding) * 2));`}
17277
+ ${({ $typographicVariant }) => getTypographicStyles($typographicVariant)}
17278
+ padding: var(--wui-editable-text-padding);
17279
+ border-radius: var(--wui-editable-text-border-radius);
17280
+ background-color: var(--wui-color-bg-surface);
17281
+ }
17282
+ `;
17283
+ var EditableTextInput = (props) => {
17284
+ const context = (0, import_react93.useContext)(EditableTextContext);
17285
+ if (!context) {
17286
+ throw new Error("EditableTextInput must be used within an EditableTextRoot context");
17287
+ }
17288
+ const {
17289
+ isEditing,
17290
+ value,
17291
+ setValue,
17292
+ onValueCommit,
17293
+ setIsEditing,
17294
+ typographicVariant,
17295
+ submitMode,
17296
+ originalValue,
17297
+ onValueRevert,
17298
+ id,
17299
+ placeholder,
17300
+ minLines,
17301
+ maxLines,
17302
+ finalFocusEl
17303
+ } = context;
17304
+ const inputRef = (0, import_react93.useRef)(null);
17305
+ (0, import_react93.useEffect)(() => {
17306
+ if (inputRef.current) {
17307
+ if (isEditing) {
17308
+ const element = inputRef.current;
17309
+ const { style } = element;
17310
+ style.height = "0px";
17311
+ const { scrollHeight } = element;
17312
+ style.height = `${scrollHeight}px`;
17313
+ }
17314
+ if (isEditing) {
17315
+ inputRef.current.focus();
17316
+ }
17317
+ }
17318
+ }, [value, isEditing]);
17319
+ const handleChange = (event) => {
17320
+ setValue(event.target.value);
17321
+ };
17322
+ const handleKeyDown = (event) => {
17323
+ if ((submitMode === "enter" || submitMode === "both") && event.key === "Enter" && !event.shiftKey) {
17324
+ event.preventDefault();
17325
+ onValueCommit?.(value);
17326
+ setIsEditing(false);
17327
+ setTimeout(() => {
17328
+ const element = finalFocusEl?.();
17329
+ if (element) {
17330
+ element.focus();
17331
+ }
17332
+ }, 0);
17333
+ }
17334
+ if (event.key === "Escape") {
17335
+ event.preventDefault();
17336
+ setValue(originalValue);
17337
+ onValueRevert?.(originalValue);
17338
+ setIsEditing(false);
17339
+ setTimeout(() => {
17340
+ const element = finalFocusEl?.();
17341
+ if (element) {
17342
+ element.focus();
17343
+ }
17344
+ }, 0);
17345
+ }
17346
+ };
17347
+ const handleBlur2 = () => {
17348
+ if (submitMode === "blur" || submitMode === "both") {
17349
+ onValueCommit?.(value);
17350
+ setIsEditing(false);
17351
+ setTimeout(() => {
17352
+ const element = finalFocusEl?.();
17353
+ if (element) {
17354
+ element.focus();
17355
+ }
17356
+ }, 0);
17357
+ }
17358
+ };
17359
+ if (!isEditing) return null;
17360
+ return /* @__PURE__ */ (0, import_jsx_runtime319.jsx)(
17361
+ StyledInput3,
17362
+ {
17363
+ ref: inputRef,
17364
+ $maxLines: maxLines ?? "infinity",
17365
+ $minLines: minLines,
17366
+ $typographicVariant: typographicVariant,
17367
+ "data-wui-editable-text-input": true,
17368
+ id,
17369
+ onBlur: handleBlur2,
17370
+ onChange: handleChange,
17371
+ onKeyDown: handleKeyDown,
17372
+ placeholder,
17373
+ type: "multiline",
17374
+ value,
17375
+ ...props
17376
+ }
17377
+ );
17378
+ };
17379
+
17380
+ // src/components/EditableText/EditableTextLabel.tsx
17381
+ var import_react94 = require("react");
17382
+ var import_jsx_runtime320 = require("react/jsx-runtime");
17383
+ var EditableTextLabel = ({ disabled, ...props }) => {
17384
+ const context = (0, import_react94.useContext)(EditableTextContext);
17385
+ if (!context) {
17386
+ throw new Error("EditableTextLabel must be used within an EditableTextRoot context");
17387
+ }
17388
+ const { id, readOnly, label } = context;
17389
+ return /* @__PURE__ */ (0, import_jsx_runtime320.jsx)(
17390
+ Label,
17391
+ {
17392
+ disabled: disabled ?? readOnly,
17393
+ htmlFor: id,
17394
+ ...props,
17395
+ children: label
17396
+ }
17397
+ );
17398
+ };
17399
+
17400
+ // src/components/EditableText/EditableText.tsx
17401
+ var import_jsx_runtime321 = require("react/jsx-runtime");
17402
+ var EditableText = ({ hideLabel = true, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime321.jsxs)(EditableTextRoot, { ...props, children: [
17403
+ /* @__PURE__ */ (0, import_jsx_runtime321.jsx)(EditableTextLabel, { screenReaderOnly: hideLabel }),
17404
+ /* @__PURE__ */ (0, import_jsx_runtime321.jsx)(EditableTextInput, {}),
17405
+ /* @__PURE__ */ (0, import_jsx_runtime321.jsx)(EditableTextDisplay, { asTrigger: true })
17406
+ ] });
17407
+ EditableText.displayName = "EditableText_UI";
17408
+
17409
+ // src/components/EditableText/EditableTextSubmitButton.tsx
17410
+ var import_react95 = require("react");
17411
+ var EditableTextSubmitButton = ({
17412
+ /**
17413
+ * A submit button, typically a [Button]() that will commit the value when clicked.
17414
+ */
17415
+ children
17416
+ }) => {
17417
+ const context = (0, import_react95.useContext)(EditableTextContext);
17418
+ if (!context) {
17419
+ throw new Error("EditableTextSubmitButton must be used within an EditableTextRoot context");
17420
+ }
17421
+ const { setIsEditing, value, onValueCommit, finalFocusEl, isEditing } = context;
17422
+ const handleClick = () => {
17423
+ onValueCommit?.(value);
17424
+ setIsEditing(false);
17425
+ setTimeout(() => {
17426
+ const element = finalFocusEl?.();
17427
+ if (element) {
17428
+ element.focus();
17429
+ }
17430
+ }, 0);
17431
+ };
17432
+ const onlyChild = import_react95.Children.only(children);
17433
+ const triggerProps = {
17434
+ onClick: handleClick,
17435
+ "data-wui-editable-text-submit": true
17436
+ };
17437
+ if (!isEditing) return null;
17438
+ return (0, import_react95.cloneElement)(onlyChild, triggerProps);
17439
+ };
17440
+
17441
+ // src/components/EditableText/EditableTextCancelButton.tsx
17442
+ var import_react96 = require("react");
17443
+ var EditableTextCancelButton = ({
17444
+ children
17445
+ }) => {
17446
+ const context = (0, import_react96.useContext)(EditableTextContext);
17447
+ if (!context) {
17448
+ throw new Error("EditableTextCancelButton must be used within an EditableTextRoot context");
17449
+ }
17450
+ const { setIsEditing, originalValue, setValue, onValueRevert, finalFocusEl, isEditing } = context;
17451
+ const handleClick = () => {
17452
+ setValue(originalValue);
17453
+ onValueRevert?.(originalValue);
17454
+ setIsEditing(false);
17455
+ setTimeout(() => {
17456
+ const element = finalFocusEl?.();
17457
+ if (element) {
17458
+ element.focus();
17459
+ }
17460
+ }, 0);
17461
+ };
17462
+ const onlyChild = import_react96.Children.only(children);
17463
+ const triggerProps = {
17464
+ onClick: handleClick,
17465
+ "data-wui-editable-text-cancel": true
17466
+ };
17467
+ if (!isEditing) return null;
17468
+ return (0, import_react96.cloneElement)(onlyChild, triggerProps);
17469
+ };
17470
+
17471
+ // src/components/EditableText/EditableTextTrigger.tsx
17472
+ var import_react97 = require("react");
17473
+ var EditableTextTrigger = ({
17474
+ children,
17475
+ ...props
17476
+ }) => {
17477
+ const context = (0, import_react97.useContext)(EditableTextContext);
17478
+ if (!context) {
17479
+ throw new Error("EditableTextTrigger must be used within an EditableTextRoot context");
17480
+ }
17481
+ const { setIsEditing, isEditing } = context;
17482
+ const handleClick = () => {
17483
+ setIsEditing(true);
17484
+ };
17485
+ const onlyChild = import_react97.Children.only(children);
17486
+ const triggerProps = {
17487
+ onClick: handleClick,
17488
+ "data-wui-editable-text-trigger": true,
17489
+ ...props
17490
+ };
17491
+ if (isEditing) return null;
17492
+ return (0, import_react97.cloneElement)(onlyChild, triggerProps);
17493
+ };
17021
17494
  // Annotate the CommonJS export names for ESM import in node:
17022
17495
  0 && (module.exports = {
17023
17496
  ActionButton,
@@ -17059,6 +17532,15 @@ var ContextMenu = ({
17059
17532
  DataCards,
17060
17533
  Divider,
17061
17534
  EditableHeading,
17535
+ EditableText,
17536
+ EditableTextCancelButton,
17537
+ EditableTextContext,
17538
+ EditableTextDisplay,
17539
+ EditableTextInput,
17540
+ EditableTextLabel,
17541
+ EditableTextRoot,
17542
+ EditableTextSubmitButton,
17543
+ EditableTextTrigger,
17062
17544
  Ellipsis,
17063
17545
  FileAmountLimitValidator,
17064
17546
  FileSizeValidator,