@wistia/ui 0.14.10 → 0.14.11-beta.89cbbae6.bd1ca73

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 CHANGED
@@ -1,6 +1,6 @@
1
1
 
2
2
  /*
3
- * @license @wistia/ui v0.14.10
3
+ * @license @wistia/ui v0.14.11-beta.89cbbae6.bd1ca73
4
4
  *
5
5
  * Copyright (c) 2024-2025, Wistia, Inc. and its affiliates.
6
6
  *
@@ -11183,6 +11183,7 @@ var Input = forwardRef15(
11183
11183
  {
11184
11184
  $fullWidth: fullWidth,
11185
11185
  $monospace: monospace,
11186
+ "data-wui-input-container": true,
11186
11187
  children: [
11187
11188
  leftIconToDisplay ?? null,
11188
11189
  type === "multiline" ? /* @__PURE__ */ jsx247(
@@ -13552,7 +13553,6 @@ var Menu = forwardRef19(
13552
13553
  isOpen,
13553
13554
  triggerProps = {},
13554
13555
  onOpenChange,
13555
- onInteractOutside,
13556
13556
  ...props
13557
13557
  }, ref) => {
13558
13558
  const contextValue = useMemo13(() => ({ compact }), [compact]);
@@ -16907,6 +16907,449 @@ var ContextMenu = ({
16907
16907
  }
16908
16908
  ) : null;
16909
16909
  };
16910
+
16911
+ // src/components/EditableText/EditableTextDisplay.tsx
16912
+ import { useContext as useContext13, useRef as useRef22, forwardRef as forwardRef36 } from "react";
16913
+ import styled104 from "styled-components";
16914
+
16915
+ // src/components/EditableText/EditableTextRoot.tsx
16916
+ import {
16917
+ createContext as createContext12,
16918
+ useMemo as useMemo16,
16919
+ useState as useState25,
16920
+ useCallback as useCallback19,
16921
+ useId as useId6
16922
+ } from "react";
16923
+ import { isNonEmptyString as isNonEmptyString9 } from "@wistia/type-guards";
16924
+ import styled103 from "styled-components";
16925
+ import { jsx as jsx315 } from "react/jsx-runtime";
16926
+ var StyledEditableTextRoot = styled103.div`
16927
+ display: contents;
16928
+
16929
+ /* Hide display components when editing */
16930
+ &[data-wui-editable-text-state='editing'] [data-wui-editable-text-display] {
16931
+ display: none;
16932
+ }
16933
+
16934
+ /* Hide input when not editing */
16935
+
16936
+ /* This is super hacky, not sure how to do this better */
16937
+ &[data-wui-editable-text-state='idle'] [data-wui-input-container],
16938
+ &[data-wui-editable-text-state='read-only'] [data-wui-input-container] {
16939
+ display: none;
16940
+ }
16941
+
16942
+ /* Hide trigger when editing or read-only */
16943
+ &[data-wui-editable-text-state='editing'] [data-wui-editable-text-trigger],
16944
+ &[data-wui-editable-text-state='read-only'] [data-wui-editable-text-trigger] {
16945
+ display: none;
16946
+ }
16947
+
16948
+ /* Hide submit button when not editing */
16949
+ &[data-wui-editable-text-state='idle'] [data-wui-editable-text-submit],
16950
+ &[data-wui-editable-text-state='read-only'] [data-wui-editable-text-submit] {
16951
+ display: none;
16952
+ }
16953
+
16954
+ /* Hide cancel button when not editing */
16955
+ &[data-wui-editable-text-state='idle'] [data-wui-editable-text-cancel],
16956
+ &[data-wui-editable-text-state='read-only'] [data-wui-editable-text-cancel] {
16957
+ display: none;
16958
+ }
16959
+
16960
+ [data-wui-editable-text-display='placeholder'] {
16961
+ color: var(--wui-color-text-secondary);
16962
+ }
16963
+ `;
16964
+ var EditableTextContext = createContext12(null);
16965
+ var EditableTextRoot = ({
16966
+ children,
16967
+ defaultValue = "",
16968
+ value: controlledValue,
16969
+ onValueChange,
16970
+ onValueCommit,
16971
+ onValueRevert,
16972
+ onEditingChange,
16973
+ typographicVariant = "body2",
16974
+ submitMode = "both",
16975
+ readOnly = false,
16976
+ id,
16977
+ label,
16978
+ placeholder = "Click to edit this text",
16979
+ minLines = 1,
16980
+ maxLines = "infinity",
16981
+ finalFocusEl,
16982
+ ...props
16983
+ }) => {
16984
+ const isControlled = controlledValue !== void 0;
16985
+ const [internalValue, setInternalValue] = useState25(defaultValue);
16986
+ const [originalValue, setOriginalValue] = useState25(defaultValue);
16987
+ const [isEditing, setIsEditing] = useState25(false);
16988
+ const value = isControlled ? controlledValue : internalValue;
16989
+ const generatedId = useId6();
16990
+ const computedId = isNonEmptyString9(id) ? id : `wistia-ui-editable-text-${generatedId}`;
16991
+ const handleSetIsEditing = useCallback19(
16992
+ (editing) => {
16993
+ if (editing && !isEditing) {
16994
+ setOriginalValue(value);
16995
+ }
16996
+ setIsEditing(editing);
16997
+ onEditingChange?.(editing);
16998
+ },
16999
+ [isEditing, value, onEditingChange]
17000
+ );
17001
+ const setValue = useCallback19(
17002
+ (newValue) => {
17003
+ if (!isControlled) {
17004
+ setInternalValue(newValue);
17005
+ }
17006
+ onValueChange?.(newValue);
17007
+ },
17008
+ [isControlled, onValueChange]
17009
+ );
17010
+ const context = useMemo16(() => {
17011
+ return {
17012
+ isEditing,
17013
+ setIsEditing: handleSetIsEditing,
17014
+ value,
17015
+ setValue,
17016
+ originalValue,
17017
+ onValueCommit,
17018
+ onValueRevert,
17019
+ typographicVariant,
17020
+ submitMode,
17021
+ readOnly,
17022
+ id: computedId,
17023
+ label,
17024
+ placeholder,
17025
+ minLines,
17026
+ maxLines,
17027
+ finalFocusEl
17028
+ };
17029
+ }, [
17030
+ isEditing,
17031
+ handleSetIsEditing,
17032
+ value,
17033
+ setValue,
17034
+ originalValue,
17035
+ onValueCommit,
17036
+ onValueRevert,
17037
+ typographicVariant,
17038
+ submitMode,
17039
+ readOnly,
17040
+ computedId,
17041
+ label,
17042
+ placeholder,
17043
+ minLines,
17044
+ maxLines,
17045
+ finalFocusEl
17046
+ ]);
17047
+ const getState = () => {
17048
+ if (readOnly) {
17049
+ return "read-only";
17050
+ }
17051
+ if (isEditing) {
17052
+ return "editing";
17053
+ }
17054
+ return "idle";
17055
+ };
17056
+ return /* @__PURE__ */ jsx315(
17057
+ StyledEditableTextRoot,
17058
+ {
17059
+ "data-wui-editable-text-root": true,
17060
+ "data-wui-editable-text-state": getState(),
17061
+ ...props,
17062
+ children: /* @__PURE__ */ jsx315(EditableTextContext.Provider, { value: context, children })
17063
+ }
17064
+ );
17065
+ };
17066
+
17067
+ // src/private/helpers/getTypographicStyles/getTypographicStyles.ts
17068
+ import { css as css47 } from "styled-components";
17069
+ var typographicVariantStyleMap = { ...variantStyleMap2, ...variantStyleMap };
17070
+ var getTypographicStyles = (variant) => {
17071
+ return css47`
17072
+ ${typographicVariantStyleMap[variant]}
17073
+ font-family: var(--font-family);
17074
+ font-size: var(--font-size);
17075
+ font-weight: var(--font-weight);
17076
+ line-height: var(--line-height);
17077
+ `;
17078
+ };
17079
+ var typographicVariantElementMap = { ...variantElementMap2, ...variantElementMap };
17080
+ var getDefaultTypographicElement = (variant) => {
17081
+ return typographicVariantElementMap[variant] ?? "span";
17082
+ };
17083
+
17084
+ // src/components/EditableText/EditableTextDisplay.tsx
17085
+ import { jsx as jsx316, jsxs as jsxs67 } from "react/jsx-runtime";
17086
+ var StyledEditableTextDisplay = styled104.div`
17087
+ ${({ $typographicVariant }) => getTypographicStyles($typographicVariant)}
17088
+ padding: var(--wui-space-01);
17089
+ border-radius: var(--wui-border-radius-01);
17090
+ margin: 0;
17091
+ transition: all var(--wui-motion-duration-02) var(--wui-motion-ease);
17092
+
17093
+ &:has(button) {
17094
+ user-select: none;
17095
+ cursor: pointer;
17096
+
17097
+ &:hover,
17098
+ &:focus-within {
17099
+ background-color: var(--wui-color-bg-surface-hover);
17100
+ }
17101
+ }
17102
+ `;
17103
+ var EditableTextDisplayComponent = forwardRef36(
17104
+ ({ asTrigger, renderAs, ...props }, ref) => {
17105
+ const context = useContext13(EditableTextContext);
17106
+ if (!context) {
17107
+ throw new Error("EditableTextDisplay must be used within an EditableTextRoot context");
17108
+ }
17109
+ const { value, typographicVariant, setIsEditing, placeholder } = context;
17110
+ const triggerButtonRef = useRef22(null);
17111
+ const handleTriggerClick = () => {
17112
+ setIsEditing(true);
17113
+ };
17114
+ const elementType = renderAs ?? getDefaultTypographicElement(typographicVariant);
17115
+ const displayText = value.length > 0 ? value : placeholder;
17116
+ const isPlaceholderVisible = value.length === 0 && !!placeholder;
17117
+ if (asTrigger && !context.readOnly) {
17118
+ return /* @__PURE__ */ jsx316(ClickRegion, { targetRef: triggerButtonRef, children: /* @__PURE__ */ jsxs67(
17119
+ StyledEditableTextDisplay,
17120
+ {
17121
+ ref,
17122
+ $typographicVariant: typographicVariant,
17123
+ as: elementType,
17124
+ "data-wui-editable-text-display": isPlaceholderVisible ? "placeholder" : "value",
17125
+ ...props,
17126
+ children: [
17127
+ displayText,
17128
+ /* @__PURE__ */ jsx316(
17129
+ "button",
17130
+ {
17131
+ ref: triggerButtonRef,
17132
+ onClick: handleTriggerClick,
17133
+ style: { ...visuallyHiddenStyle },
17134
+ type: "button",
17135
+ children: "Edit text"
17136
+ }
17137
+ )
17138
+ ]
17139
+ }
17140
+ ) });
17141
+ }
17142
+ return /* @__PURE__ */ jsx316(
17143
+ StyledEditableTextDisplay,
17144
+ {
17145
+ ref,
17146
+ $typographicVariant: typographicVariant,
17147
+ as: elementType,
17148
+ "data-placeholder-visible": isPlaceholderVisible || void 0,
17149
+ "data-wui-editable-text-display": true,
17150
+ ...props,
17151
+ children: displayText
17152
+ }
17153
+ );
17154
+ }
17155
+ );
17156
+ EditableTextDisplayComponent.displayName = "EditableTextDisplay_UI";
17157
+ var EditableTextDisplay = makePolymorphic(
17158
+ EditableTextDisplayComponent
17159
+ );
17160
+
17161
+ // src/components/EditableText/EditableTextInput.tsx
17162
+ import { useContext as useContext14, useEffect as useEffect21, useRef as useRef23 } from "react";
17163
+ import styled105 from "styled-components";
17164
+ import { jsx as jsx317 } from "react/jsx-runtime";
17165
+ var StyledInput3 = styled105(Input)`
17166
+ && {
17167
+ --min-lines: ${({ $minLines }) => $minLines};
17168
+ --max-lines: ${({ $maxLines }) => $maxLines};
17169
+
17170
+ min-height: calc(var(--min-lines) * 1lh + calc(var(--wui-space-01) * 2));
17171
+ max-height: calc(var(--max-lines) * 1lh + calc(var(--wui-space-01) * 2));
17172
+ ${({ $typographicVariant }) => getTypographicStyles($typographicVariant)}
17173
+ padding: var(--wui-space-01);
17174
+ border-radius: var(--wui-border-radius-01);
17175
+ background-color: var(--wui-color-bg-surface);
17176
+ }
17177
+ `;
17178
+ var EditableTextInput = (props) => {
17179
+ const context = useContext14(EditableTextContext);
17180
+ if (!context) {
17181
+ throw new Error("EditableTextInput must be used within an EditableTextRoot context");
17182
+ }
17183
+ const {
17184
+ isEditing,
17185
+ value,
17186
+ setValue,
17187
+ onValueCommit,
17188
+ setIsEditing,
17189
+ typographicVariant,
17190
+ submitMode,
17191
+ originalValue,
17192
+ onValueRevert,
17193
+ id,
17194
+ placeholder,
17195
+ minLines,
17196
+ maxLines,
17197
+ finalFocusEl
17198
+ } = context;
17199
+ const inputRef = useRef23(null);
17200
+ useEffect21(() => {
17201
+ if (inputRef.current) {
17202
+ if (isEditing) {
17203
+ const element = inputRef.current;
17204
+ const { style } = element;
17205
+ style.height = "0px";
17206
+ const { scrollHeight } = element;
17207
+ style.height = `${scrollHeight}px`;
17208
+ }
17209
+ if (isEditing) {
17210
+ inputRef.current.focus();
17211
+ }
17212
+ }
17213
+ }, [value, isEditing]);
17214
+ const handleChange = (event) => {
17215
+ setValue(event.target.value);
17216
+ };
17217
+ const handleKeyDown = (event) => {
17218
+ if ((submitMode === "enter" || submitMode === "both") && event.key === "Enter" && !event.shiftKey) {
17219
+ event.preventDefault();
17220
+ onValueCommit?.(value);
17221
+ setIsEditing(false);
17222
+ setTimeout(() => {
17223
+ const element = finalFocusEl?.();
17224
+ if (element) {
17225
+ element.focus();
17226
+ }
17227
+ }, 0);
17228
+ }
17229
+ if (event.key === "Escape") {
17230
+ event.preventDefault();
17231
+ setValue(originalValue);
17232
+ onValueRevert?.(originalValue);
17233
+ setIsEditing(false);
17234
+ setTimeout(() => {
17235
+ const element = finalFocusEl?.();
17236
+ if (element) {
17237
+ element.focus();
17238
+ }
17239
+ }, 0);
17240
+ }
17241
+ };
17242
+ const handleBlur2 = () => {
17243
+ if (submitMode === "blur" || submitMode === "both") {
17244
+ onValueCommit?.(value);
17245
+ setIsEditing(false);
17246
+ setTimeout(() => {
17247
+ const element = finalFocusEl?.();
17248
+ if (element) {
17249
+ element.focus();
17250
+ }
17251
+ }, 0);
17252
+ }
17253
+ };
17254
+ return /* @__PURE__ */ jsx317(
17255
+ StyledInput3,
17256
+ {
17257
+ ref: inputRef,
17258
+ $maxLines: maxLines,
17259
+ $minLines: minLines,
17260
+ $typographicVariant: typographicVariant,
17261
+ "data-wui-editable-text-input": true,
17262
+ id,
17263
+ onBlur: handleBlur2,
17264
+ onChange: handleChange,
17265
+ onKeyDown: handleKeyDown,
17266
+ placeholder,
17267
+ type: "multiline",
17268
+ value,
17269
+ ...props
17270
+ }
17271
+ );
17272
+ };
17273
+
17274
+ // src/components/EditableText/EditableTextLabel.tsx
17275
+ import { useContext as useContext15 } from "react";
17276
+ import { jsx as jsx318 } from "react/jsx-runtime";
17277
+ var EditableTextLabel = ({ disabled, ...props }) => {
17278
+ const context = useContext15(EditableTextContext);
17279
+ if (!context) {
17280
+ throw new Error("EditableTextLabel must be used within an EditableTextRoot context");
17281
+ }
17282
+ const { id, readOnly, label } = context;
17283
+ return /* @__PURE__ */ jsx318(
17284
+ Label,
17285
+ {
17286
+ disabled: disabled ?? readOnly,
17287
+ htmlFor: id,
17288
+ ...props,
17289
+ children: label
17290
+ }
17291
+ );
17292
+ };
17293
+
17294
+ // src/components/EditableText/EditableText.tsx
17295
+ import { jsx as jsx319, jsxs as jsxs68 } from "react/jsx-runtime";
17296
+ var EditableText = ({ hideLabel = true, ...props }) => /* @__PURE__ */ jsxs68(EditableTextRoot, { ...props, children: [
17297
+ /* @__PURE__ */ jsx319(EditableTextLabel, { screenReaderOnly: hideLabel }),
17298
+ /* @__PURE__ */ jsx319(EditableTextInput, {}),
17299
+ /* @__PURE__ */ jsx319(EditableTextDisplay, { asTrigger: true })
17300
+ ] });
17301
+ EditableText.displayName = "EditableText_UI";
17302
+
17303
+ // src/components/EditableText/EditableTextSubmitButton.tsx
17304
+ import { useContext as useContext16, Children as Children8, cloneElement as cloneElement6 } from "react";
17305
+ var EditableTextSubmitButton = ({
17306
+ children
17307
+ }) => {
17308
+ const context = useContext16(EditableTextContext);
17309
+ if (!context) {
17310
+ throw new Error("EditableTextSubmitButton must be used within an EditableTextRoot context");
17311
+ }
17312
+ const { setIsEditing, value, onValueCommit, finalFocusEl } = context;
17313
+ const handleClick = () => {
17314
+ onValueCommit?.(value);
17315
+ setIsEditing(false);
17316
+ setTimeout(() => {
17317
+ const element = finalFocusEl?.();
17318
+ if (element) {
17319
+ element.focus();
17320
+ }
17321
+ }, 0);
17322
+ };
17323
+ const onlyChild = Children8.only(children);
17324
+ const triggerProps = {
17325
+ onClick: handleClick,
17326
+ "data-wui-editable-text-submit": true
17327
+ };
17328
+ return cloneElement6(onlyChild, triggerProps);
17329
+ };
17330
+
17331
+ // src/components/EditableText/EditableTextTrigger.tsx
17332
+ import { useContext as useContext17, Children as Children9, cloneElement as cloneElement7 } from "react";
17333
+ var EditableTextTrigger = ({
17334
+ children,
17335
+ ...props
17336
+ }) => {
17337
+ const context = useContext17(EditableTextContext);
17338
+ if (!context) {
17339
+ throw new Error("EditableTextTrigger must be used within an EditableTextRoot context");
17340
+ }
17341
+ const { setIsEditing } = context;
17342
+ const handleClick = () => {
17343
+ setIsEditing(true);
17344
+ };
17345
+ const onlyChild = Children9.only(children);
17346
+ const triggerProps = {
17347
+ onClick: handleClick,
17348
+ "data-wui-editable-text-trigger": true,
17349
+ ...props
17350
+ };
17351
+ return cloneElement7(onlyChild, triggerProps);
17352
+ };
16910
17353
  export {
16911
17354
  ActionButton,
16912
17355
  Avatar,
@@ -16947,6 +17390,14 @@ export {
16947
17390
  DataCards,
16948
17391
  Divider,
16949
17392
  EditableHeading,
17393
+ EditableText,
17394
+ EditableTextContext,
17395
+ EditableTextDisplay,
17396
+ EditableTextInput,
17397
+ EditableTextLabel,
17398
+ EditableTextRoot,
17399
+ EditableTextSubmitButton,
17400
+ EditableTextTrigger,
16950
17401
  Ellipsis,
16951
17402
  FileAmountLimitValidator,
16952
17403
  FileSizeValidator,