@vuu-ui/vuu-ui-controls 0.8.91 → 0.8.92

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.
@@ -40,7 +40,6 @@ const useDropdownBase = ({
40
40
  }, [onOpenChange, setIsOpen]);
41
41
  const hideDropdown = React.useCallback(
42
42
  (reason) => {
43
- console.log(`hide dropdown ${reason}`);
44
43
  setIsOpen(false);
45
44
  onOpenChange?.(false, reason);
46
45
  },
@@ -1 +1 @@
1
- {"version":3,"file":"useDropdownBase.js","sources":["../../src/dropdown-base/useDropdownBase.ts"],"sourcesContent":["import { useControlled, useForkRef } from \"@salt-ds/core\";\nimport {\n FocusEventHandler,\n KeyboardEvent,\n useCallback,\n useRef,\n useState,\n} from \"react\";\nimport { measurements, useResizeObserver, WidthOnly } from \"../common-hooks\";\nimport {\n CloseReason,\n DropdownHookProps,\n DropdownHookResult,\n DropdownOpenKey,\n} from \"./dropdownTypes\";\nimport { useClickAway, targetWithinSubPopup } from \"./useClickAway\";\n\nconst NO_OBSERVER: string[] = [];\n\nexport const useDropdownBase = ({\n defaultIsOpen,\n disabled,\n // TODO check how we're using fullWidth, do we need a separate value for the popup component\n fullWidth: fullWidthProp,\n id,\n isOpen: isOpenProp,\n onOpenChange,\n onKeyDown: onKeyDownProp,\n openKeys = [\"Enter\", \"ArrowDown\", \" \"],\n openOnFocus,\n popupComponent,\n popupWidth: popupWidthProp,\n rootRef,\n width,\n}: DropdownHookProps): DropdownHookResult => {\n const justFocused = useRef<number | null>(null);\n const popperRef = useRef<HTMLElement | null>(null);\n\n const [isOpen, setIsOpen] = useControlled({\n controlled: isOpenProp,\n default: Boolean(defaultIsOpen),\n name: \"useDropdown\",\n state: \"isOpen\",\n });\n const [popup, setPopup] = useState<measurements>({\n width: popupWidthProp ?? width ?? 0,\n });\n\n const showDropdown = useCallback(() => {\n setIsOpen(true);\n onOpenChange?.(true);\n }, [onOpenChange, setIsOpen]);\n\n const hideDropdown = useCallback(\n (reason: CloseReason) => {\n console.log(`hide dropdown ${reason}`);\n setIsOpen(false);\n onOpenChange?.(false, reason);\n },\n [onOpenChange, setIsOpen]\n );\n\n // Focus is not usually applied to the popped up component, we\n // manipulate active descendant whilst keeping focus in the\n // trigger. Some component, like Calendar ARE focussed, as they\n // have more complicated navigation. In these cases, we need to\n // listen for focus out.\n const handleComponentFocusOut = useCallback(\n (evt: FocusEvent) => {\n const target = evt.relatedTarget as HTMLElement;\n if (target === null) {\n // if component sets focus on a timeout (as calendar does when\n // transitioning month) wait before testing\n requestAnimationFrame(() => {\n if (!popperRef.current?.contains(document.activeElement)) {\n hideDropdown(\"Tab\");\n }\n });\n } else if (!popperRef.current?.contains(target)) {\n if (!targetWithinSubPopup(popperRef.current, target)) {\n hideDropdown(\"Tab\");\n }\n }\n },\n [hideDropdown]\n );\n\n const popperCallbackRef = useCallback(\n (element: HTMLElement | null) => {\n if (element) {\n element.addEventListener(\"focusout\", handleComponentFocusOut);\n } else if (popperRef.current) {\n popperRef.current.removeEventListener(\n \"focusout\",\n handleComponentFocusOut\n );\n }\n popperRef.current = element;\n },\n [handleComponentFocusOut]\n );\n\n useClickAway({\n popperRef,\n rootRef,\n isOpen,\n onClose: hideDropdown,\n });\n\n const handleTriggerFocus = useCallback(() => {\n if (!disabled) {\n if (openOnFocus) {\n setIsOpen(true);\n onOpenChange?.(true);\n // Suppress response to click if click was the cause of focus\n justFocused.current = window.setTimeout(() => {\n justFocused.current = null;\n }, 1000);\n }\n }\n }, [disabled, onOpenChange, openOnFocus, setIsOpen]);\n\n const handleTriggerToggle = useCallback(\n (e: MouseEvent) => {\n // Do not trigger menu open for 'Enter' and 'SPACE' key as they're handled in `handleKeyDown`\n if (\n [\"Enter\", \" \"].indexOf(\n (e as unknown as KeyboardEvent<HTMLDivElement>).key\n ) === -1\n ) {\n const newIsOpen = !isOpen;\n setIsOpen(newIsOpen);\n onOpenChange?.(newIsOpen);\n }\n },\n [isOpen, setIsOpen, onOpenChange]\n );\n\n const handleKeydown = useCallback(\n (evt: KeyboardEvent<HTMLElement>) => {\n if (/* evt.key === \"Tab\" || */ evt.key === \"Escape\" && isOpen) {\n // No preventDefault for Tab, but if we've handled Escape, we should own it\n if (evt.key === \"Escape\") {\n evt.stopPropagation();\n evt.preventDefault();\n }\n hideDropdown(evt.key);\n } else if (openKeys.includes(evt.key as DropdownOpenKey) && !isOpen) {\n evt.preventDefault();\n showDropdown();\n } else {\n onKeyDownProp?.(evt);\n }\n },\n [hideDropdown, isOpen, onKeyDownProp, openKeys, showDropdown]\n );\n\n const handleBlur = useCallback<FocusEventHandler<HTMLElement>>(\n (evt) => {\n if (isOpen) {\n if (popperRef.current?.contains(evt.relatedTarget)) {\n // ignore\n } else {\n hideDropdown(\"blur\");\n }\n }\n },\n [hideDropdown, isOpen]\n );\n\n const fullWidth = fullWidthProp ?? false;\n const measurements = fullWidth ? WidthOnly : NO_OBSERVER;\n useResizeObserver(rootRef, measurements, setPopup, fullWidth);\n\n const componentId = `${id}-dropdown`;\n\n // TODO do we use aria-popup - valid values are menu, disloag, grid, tree, listbox\n const triggerProps = {\n \"aria-expanded\": isOpen,\n \"aria-owns\": isOpen ? componentId : undefined,\n id: `${id}-control`,\n onClick: disabled || openOnFocus ? undefined : handleTriggerToggle,\n onFocus: handleTriggerFocus,\n role: \"listbox\",\n onBlur: handleBlur,\n onKeyDown: disabled ? undefined : handleKeydown,\n style: { width: fullWidth ? undefined : width },\n };\n\n const dropdownComponentProps = {\n id: componentId,\n width: popup.width,\n };\n\n const popupComponentRef = useForkRef(popperCallbackRef, popupComponent.ref);\n\n return {\n componentProps: dropdownComponentProps,\n popupComponentRef,\n isOpen,\n label: \"Dropdown Button\",\n triggerProps,\n };\n};\n"],"names":["useRef","useControlled","useState","useCallback","targetWithinSubPopup","useClickAway","measurements","WidthOnly","useResizeObserver","useForkRef"],"mappings":"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"}
1
+ {"version":3,"file":"useDropdownBase.js","sources":["../../src/dropdown-base/useDropdownBase.ts"],"sourcesContent":["import { useControlled, useForkRef } from \"@salt-ds/core\";\nimport {\n FocusEventHandler,\n KeyboardEvent,\n useCallback,\n useRef,\n useState,\n} from \"react\";\nimport { measurements, useResizeObserver, WidthOnly } from \"../common-hooks\";\nimport {\n CloseReason,\n DropdownHookProps,\n DropdownHookResult,\n DropdownOpenKey,\n} from \"./dropdownTypes\";\nimport { useClickAway, targetWithinSubPopup } from \"./useClickAway\";\n\nconst NO_OBSERVER: string[] = [];\n\nexport const useDropdownBase = ({\n defaultIsOpen,\n disabled,\n // TODO check how we're using fullWidth, do we need a separate value for the popup component\n fullWidth: fullWidthProp,\n id,\n isOpen: isOpenProp,\n onOpenChange,\n onKeyDown: onKeyDownProp,\n openKeys = [\"Enter\", \"ArrowDown\", \" \"],\n openOnFocus,\n popupComponent,\n popupWidth: popupWidthProp,\n rootRef,\n width,\n}: DropdownHookProps): DropdownHookResult => {\n const justFocused = useRef<number | null>(null);\n const popperRef = useRef<HTMLElement | null>(null);\n\n const [isOpen, setIsOpen] = useControlled({\n controlled: isOpenProp,\n default: Boolean(defaultIsOpen),\n name: \"useDropdown\",\n state: \"isOpen\",\n });\n const [popup, setPopup] = useState<measurements>({\n width: popupWidthProp ?? width ?? 0,\n });\n\n const showDropdown = useCallback(() => {\n setIsOpen(true);\n onOpenChange?.(true);\n }, [onOpenChange, setIsOpen]);\n\n const hideDropdown = useCallback(\n (reason: CloseReason) => {\n setIsOpen(false);\n onOpenChange?.(false, reason);\n },\n [onOpenChange, setIsOpen],\n );\n\n // Focus is not usually applied to the popped up component, we\n // manipulate active descendant whilst keeping focus in the\n // trigger. Some component, like Calendar ARE focussed, as they\n // have more complicated navigation. In these cases, we need to\n // listen for focus out.\n const handleComponentFocusOut = useCallback(\n (evt: FocusEvent) => {\n const target = evt.relatedTarget as HTMLElement;\n if (target === null) {\n // if component sets focus on a timeout (as calendar does when\n // transitioning month) wait before testing\n requestAnimationFrame(() => {\n if (!popperRef.current?.contains(document.activeElement)) {\n hideDropdown(\"Tab\");\n }\n });\n } else if (!popperRef.current?.contains(target)) {\n if (!targetWithinSubPopup(popperRef.current, target)) {\n hideDropdown(\"Tab\");\n }\n }\n },\n [hideDropdown],\n );\n\n const popperCallbackRef = useCallback(\n (element: HTMLElement | null) => {\n if (element) {\n element.addEventListener(\"focusout\", handleComponentFocusOut);\n } else if (popperRef.current) {\n popperRef.current.removeEventListener(\n \"focusout\",\n handleComponentFocusOut,\n );\n }\n popperRef.current = element;\n },\n [handleComponentFocusOut],\n );\n\n useClickAway({\n popperRef,\n rootRef,\n isOpen,\n onClose: hideDropdown,\n });\n\n const handleTriggerFocus = useCallback(() => {\n if (!disabled) {\n if (openOnFocus) {\n setIsOpen(true);\n onOpenChange?.(true);\n // Suppress response to click if click was the cause of focus\n justFocused.current = window.setTimeout(() => {\n justFocused.current = null;\n }, 1000);\n }\n }\n }, [disabled, onOpenChange, openOnFocus, setIsOpen]);\n\n const handleTriggerToggle = useCallback(\n (e: MouseEvent) => {\n // Do not trigger menu open for 'Enter' and 'SPACE' key as they're handled in `handleKeyDown`\n if (\n [\"Enter\", \" \"].indexOf(\n (e as unknown as KeyboardEvent<HTMLDivElement>).key,\n ) === -1\n ) {\n const newIsOpen = !isOpen;\n setIsOpen(newIsOpen);\n onOpenChange?.(newIsOpen);\n }\n },\n [isOpen, setIsOpen, onOpenChange],\n );\n\n const handleKeydown = useCallback(\n (evt: KeyboardEvent<HTMLElement>) => {\n if (/* evt.key === \"Tab\" || */ evt.key === \"Escape\" && isOpen) {\n // No preventDefault for Tab, but if we've handled Escape, we should own it\n if (evt.key === \"Escape\") {\n evt.stopPropagation();\n evt.preventDefault();\n }\n hideDropdown(evt.key);\n } else if (openKeys.includes(evt.key as DropdownOpenKey) && !isOpen) {\n evt.preventDefault();\n showDropdown();\n } else {\n onKeyDownProp?.(evt);\n }\n },\n [hideDropdown, isOpen, onKeyDownProp, openKeys, showDropdown],\n );\n\n const handleBlur = useCallback<FocusEventHandler<HTMLElement>>(\n (evt) => {\n if (isOpen) {\n if (popperRef.current?.contains(evt.relatedTarget)) {\n // ignore\n } else {\n hideDropdown(\"blur\");\n }\n }\n },\n [hideDropdown, isOpen],\n );\n\n const fullWidth = fullWidthProp ?? false;\n const measurements = fullWidth ? WidthOnly : NO_OBSERVER;\n useResizeObserver(rootRef, measurements, setPopup, fullWidth);\n\n const componentId = `${id}-dropdown`;\n\n // TODO do we use aria-popup - valid values are menu, disloag, grid, tree, listbox\n const triggerProps = {\n \"aria-expanded\": isOpen,\n \"aria-owns\": isOpen ? componentId : undefined,\n id: `${id}-control`,\n onClick: disabled || openOnFocus ? undefined : handleTriggerToggle,\n onFocus: handleTriggerFocus,\n role: \"listbox\",\n onBlur: handleBlur,\n onKeyDown: disabled ? undefined : handleKeydown,\n style: { width: fullWidth ? undefined : width },\n };\n\n const dropdownComponentProps = {\n id: componentId,\n width: popup.width,\n };\n\n const popupComponentRef = useForkRef(popperCallbackRef, popupComponent.ref);\n\n return {\n componentProps: dropdownComponentProps,\n popupComponentRef,\n isOpen,\n label: \"Dropdown Button\",\n triggerProps,\n };\n};\n"],"names":["useRef","useControlled","useState","useCallback","targetWithinSubPopup","useClickAway","measurements","WidthOnly","useResizeObserver","useForkRef"],"mappings":"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"}
@@ -27,9 +27,9 @@ const useEditableText = ({
27
27
  (target) => {
28
28
  if (isDirtyRef.current) {
29
29
  hasCommittedRef.current = true;
30
- const warningMessage = clientSideEditValidationCheck?.(value);
31
- if (warningMessage) {
32
- setMessage(warningMessage);
30
+ const result = clientSideEditValidationCheck?.(value);
31
+ if (result?.ok === false) {
32
+ setMessage(result?.messages?.join(","));
33
33
  } else {
34
34
  setMessage(void 0);
35
35
  console.log(`commit value ${value}`);
@@ -82,13 +82,13 @@ const useEditableText = ({
82
82
  isDirtyRef.current = value !== initialValueRef.current;
83
83
  setValue(typedValue);
84
84
  if (hasCommittedRef.current && value !== void 0) {
85
- const warningMessage = clientSideEditValidationCheck?.(value);
86
- if (warningMessage !== message && warningMessage !== false) {
87
- setMessage(warningMessage);
85
+ const result = clientSideEditValidationCheck?.(value);
86
+ if (result?.ok === false) {
87
+ setMessage(result.messages?.join(","));
88
88
  }
89
89
  }
90
90
  },
91
- [clientSideEditValidationCheck, message, type, value]
91
+ [clientSideEditValidationCheck, type, value]
92
92
  );
93
93
  return {
94
94
  inputProps: {
@@ -1 +1 @@
1
- {"version":3,"file":"useEditableText.js","sources":["../../src/editable/useEditableText.ts"],"sourcesContent":["import {\n ClientSideValidationChecker,\n DataItemCommitHandler,\n} from \"@vuu-ui/vuu-table-types\";\nimport { useLayoutEffectSkipFirst } from \"@vuu-ui/vuu-utils\";\nimport { VuuRowDataItemType } from \"@vuu-ui/vuu-protocol-types\";\nimport { dispatchCustomEvent } from \"@vuu-ui/vuu-utils\";\nimport {\n FocusEventHandler,\n FormEventHandler,\n KeyboardEvent,\n useCallback,\n useRef,\n useState,\n} from \"react\";\n\nexport const WarnCommit = (): Promise<true> => {\n console.warn(\n \"onCommit handler has not been provided to InputCell cell renderer\",\n );\n return Promise.resolve(true);\n};\n\nexport interface EditableTextHookProps<\n T extends VuuRowDataItemType = VuuRowDataItemType,\n> {\n clientSideEditValidationCheck?: ClientSideValidationChecker;\n initialValue?: T;\n onCommit: DataItemCommitHandler<T>;\n type?: \"string\" | \"number\" | \"boolean\";\n}\n\nexport const useEditableText = <T extends string | number = string>({\n clientSideEditValidationCheck,\n initialValue,\n onCommit,\n type,\n}: EditableTextHookProps<T>) => {\n const [message, setMessage] = useState<string | undefined>();\n const [value, setValue] = useState<T | undefined>(initialValue);\n const initialValueRef = useRef<T | undefined>(initialValue);\n const isDirtyRef = useRef(false);\n const hasCommittedRef = useRef(false);\n\n useLayoutEffectSkipFirst(() => {\n //TODO this isn't right, review the state we're using\n setValue(initialValue);\n }, [initialValue]);\n\n const commit = useCallback(\n (target: HTMLElement) => {\n if (isDirtyRef.current) {\n hasCommittedRef.current = true;\n const warningMessage = clientSideEditValidationCheck?.(value);\n if (warningMessage) {\n setMessage(warningMessage);\n } else {\n setMessage(undefined);\n console.log(`commit value ${value}`);\n onCommit(value as T).then((response) => {\n if (response === true) {\n isDirtyRef.current = false;\n dispatchCustomEvent(target, \"vuu-commit\");\n } else {\n setMessage(response);\n }\n });\n }\n } else {\n // why, if not dirty ?\n dispatchCustomEvent(target, \"vuu-commit\");\n hasCommittedRef.current = false;\n }\n },\n [clientSideEditValidationCheck, onCommit, value],\n );\n\n const handleKeyDown = useCallback(\n (evt: KeyboardEvent<HTMLElement>) => {\n if (evt.key === \"Enter\") {\n commit(evt.target as HTMLElement);\n } else if (\n evt.key === \"ArrowRight\" ||\n evt.key === \"ArrowLeft\" ||\n evt.key === \"ArrowUp\" ||\n evt.key === \"ArrowDown\"\n ) {\n evt.stopPropagation();\n } else if (evt.key === \"Escape\") {\n if (isDirtyRef.current) {\n isDirtyRef.current = false;\n setMessage(undefined);\n setValue(initialValueRef.current);\n }\n }\n },\n [commit],\n );\n\n const handleBlur = useCallback<FocusEventHandler<HTMLElement>>(\n (evt) => {\n if (isDirtyRef.current) {\n commit(evt.target as HTMLElement);\n }\n },\n [commit],\n );\n\n const handleChange = useCallback<FormEventHandler>(\n (evt) => {\n let typedValue: VuuRowDataItemType = (evt.target as HTMLInputElement)\n .value;\n if (type === \"number\" && !isNaN(parseFloat(typedValue))) {\n typedValue = parseFloat(typedValue);\n }\n isDirtyRef.current = value !== initialValueRef.current;\n setValue(typedValue as T);\n if (hasCommittedRef.current && value !== undefined) {\n const warningMessage = clientSideEditValidationCheck?.(value);\n if (warningMessage !== message && warningMessage !== false) {\n setMessage(warningMessage);\n }\n }\n },\n [clientSideEditValidationCheck, message, type, value],\n );\n\n return {\n inputProps: {\n onBlur: handleBlur,\n onKeyDown: handleKeyDown,\n },\n onChange: handleChange,\n value: value ?? \"\",\n warningMessage: message,\n };\n};\n"],"names":["useState","useRef","useLayoutEffectSkipFirst","useCallback","dispatchCustomEvent"],"mappings":"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"}
1
+ {"version":3,"file":"useEditableText.js","sources":["../../src/editable/useEditableText.ts"],"sourcesContent":["import { DataValueValidationChecker } from \"@vuu-ui/vuu-data-types\";\nimport { DataItemCommitHandler } from \"@vuu-ui/vuu-table-types\";\nimport { useLayoutEffectSkipFirst } from \"@vuu-ui/vuu-utils\";\nimport { VuuRowDataItemType } from \"@vuu-ui/vuu-protocol-types\";\nimport { dispatchCustomEvent } from \"@vuu-ui/vuu-utils\";\nimport {\n FocusEventHandler,\n FormEventHandler,\n KeyboardEvent,\n useCallback,\n useRef,\n useState,\n} from \"react\";\n\nexport const WarnCommit = (): Promise<true> => {\n console.warn(\n \"onCommit handler has not been provided to InputCell cell renderer\",\n );\n return Promise.resolve(true);\n};\n\nexport interface EditableTextHookProps<\n T extends VuuRowDataItemType = VuuRowDataItemType,\n> {\n clientSideEditValidationCheck?: DataValueValidationChecker;\n initialValue?: T;\n onCommit: DataItemCommitHandler<T>;\n type?: \"string\" | \"number\" | \"boolean\";\n}\n\nexport const useEditableText = <T extends string | number = string>({\n clientSideEditValidationCheck,\n initialValue,\n onCommit,\n type,\n}: EditableTextHookProps<T>) => {\n const [message, setMessage] = useState<string | undefined>();\n const [value, setValue] = useState<T | undefined>(initialValue);\n const initialValueRef = useRef<T | undefined>(initialValue);\n const isDirtyRef = useRef(false);\n const hasCommittedRef = useRef(false);\n\n useLayoutEffectSkipFirst(() => {\n //TODO this isn't right, review the state we're using\n setValue(initialValue);\n }, [initialValue]);\n\n const commit = useCallback(\n (target: HTMLElement) => {\n if (isDirtyRef.current) {\n hasCommittedRef.current = true;\n const result = clientSideEditValidationCheck?.(value);\n if (result?.ok === false) {\n setMessage(result?.messages?.join(\",\"));\n } else {\n setMessage(undefined);\n console.log(`commit value ${value}`);\n onCommit(value as T).then((response) => {\n if (response === true) {\n isDirtyRef.current = false;\n dispatchCustomEvent(target, \"vuu-commit\");\n } else {\n setMessage(response);\n }\n });\n }\n } else {\n // why, if not dirty ?\n dispatchCustomEvent(target, \"vuu-commit\");\n hasCommittedRef.current = false;\n }\n },\n [clientSideEditValidationCheck, onCommit, value],\n );\n\n const handleKeyDown = useCallback(\n (evt: KeyboardEvent<HTMLElement>) => {\n if (evt.key === \"Enter\") {\n commit(evt.target as HTMLElement);\n } else if (\n evt.key === \"ArrowRight\" ||\n evt.key === \"ArrowLeft\" ||\n evt.key === \"ArrowUp\" ||\n evt.key === \"ArrowDown\"\n ) {\n evt.stopPropagation();\n } else if (evt.key === \"Escape\") {\n if (isDirtyRef.current) {\n isDirtyRef.current = false;\n setMessage(undefined);\n setValue(initialValueRef.current);\n }\n }\n },\n [commit],\n );\n\n const handleBlur = useCallback<FocusEventHandler<HTMLElement>>(\n (evt) => {\n if (isDirtyRef.current) {\n commit(evt.target as HTMLElement);\n }\n },\n [commit],\n );\n\n const handleChange = useCallback<FormEventHandler>(\n (evt) => {\n let typedValue: VuuRowDataItemType = (evt.target as HTMLInputElement)\n .value;\n if (type === \"number\" && !isNaN(parseFloat(typedValue))) {\n typedValue = parseFloat(typedValue);\n }\n isDirtyRef.current = value !== initialValueRef.current;\n setValue(typedValue as T);\n if (hasCommittedRef.current && value !== undefined) {\n const result = clientSideEditValidationCheck?.(value);\n if (result?.ok === false) {\n setMessage(result.messages?.join(\",\"));\n }\n }\n },\n [clientSideEditValidationCheck, type, value],\n );\n\n return {\n inputProps: {\n onBlur: handleBlur,\n onKeyDown: handleKeyDown,\n },\n onChange: handleChange,\n value: value ?? \"\",\n warningMessage: message,\n };\n};\n"],"names":["useState","useRef","useLayoutEffectSkipFirst","useCallback","dispatchCustomEvent"],"mappings":"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"}
@@ -12,7 +12,7 @@ const classBase = "vuuExpandoInput";
12
12
  const noop = () => void 0;
13
13
  const ExpandoInput = React.forwardRef(function ExpandoInput2({
14
14
  className: classNameProp,
15
- TooltipProps,
15
+ errorMessage,
16
16
  value,
17
17
  inputProps,
18
18
  onCommit = noop,
@@ -28,14 +28,14 @@ const ExpandoInput = React.forwardRef(function ExpandoInput2({
28
28
  "div",
29
29
  {
30
30
  className: cx(classBase, classNameProp, {
31
- [`${classBase}-error`]: TooltipProps
31
+ [`${classBase}-error`]: errorMessage
32
32
  }),
33
33
  "data-text": value,
34
34
  children: /* @__PURE__ */ jsxRuntime.jsx(
35
35
  VuuInput.VuuInput,
36
36
  {
37
37
  ...props,
38
- TooltipProps,
38
+ errorMessage,
39
39
  inputProps: { ...inputProps, className: `${classBase}-input` },
40
40
  onCommit,
41
41
  ref: forwardedRef,
@@ -1 +1 @@
1
- {"version":3,"file":"ExpandoInput.js","sources":["../../src/expando-input/ExpandoInput.tsx"],"sourcesContent":["import cx from \"clsx\";\nimport { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\nimport { ForwardedRef, forwardRef } from \"react\";\nimport { VuuInput, VuuInputProps } from \"../vuu-input\";\n\nimport expandoInputCss from \"./ExpandoInput.css\";\n\nconst classBase = \"vuuExpandoInput\";\n\nconst noop = () => undefined;\n\nexport interface ExpandoInputProps extends Omit<VuuInputProps, \"onCommit\"> {\n onCommit?: VuuInputProps[\"onCommit\"];\n}\n\nexport const ExpandoInput = forwardRef(function ExpandoInput(\n {\n className: classNameProp,\n TooltipProps,\n value,\n inputProps,\n onCommit = noop,\n ...props\n }: ExpandoInputProps,\n forwardedRef: ForwardedRef<HTMLDivElement>\n) {\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"vuu-expando-input\",\n css: expandoInputCss,\n window: targetWindow,\n });\n\n return (\n <div\n className={cx(classBase, classNameProp, {\n [`${classBase}-error`]: TooltipProps,\n })}\n data-text={value}\n >\n <VuuInput\n {...props}\n TooltipProps={TooltipProps}\n inputProps={{ ...inputProps, className: `${classBase}-input` }}\n onCommit={onCommit}\n ref={forwardedRef}\n style={{ padding: 0 }}\n textAlign=\"left\"\n value={value}\n variant=\"secondary\"\n />\n </div>\n );\n});\n"],"names":["forwardRef","ExpandoInput","useWindow","useComponentCssInjection","expandoInputCss","jsx","VuuInput"],"mappings":";;;;;;;;;;AAQA,MAAM,SAAY,GAAA,iBAAA,CAAA;AAElB,MAAM,OAAO,MAAM,KAAA,CAAA,CAAA;AAMN,MAAA,YAAA,GAAeA,gBAAW,CAAA,SAASC,aAC9C,CAAA;AAAA,EACE,SAAW,EAAA,aAAA;AAAA,EACX,YAAA;AAAA,EACA,KAAA;AAAA,EACA,UAAA;AAAA,EACA,QAAW,GAAA,IAAA;AAAA,EACX,GAAG,KAAA;AACL,CAAA,EACA,YACA,EAAA;AACA,EAAA,MAAM,eAAeC,gBAAU,EAAA,CAAA;AAC/B,EAAyBC,+BAAA,CAAA;AAAA,IACvB,MAAQ,EAAA,mBAAA;AAAA,IACR,GAAK,EAAAC,cAAA;AAAA,IACL,MAAQ,EAAA,YAAA;AAAA,GACT,CAAA,CAAA;AAED,EACE,uBAAAC,cAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,SAAA,EAAW,EAAG,CAAA,SAAA,EAAW,aAAe,EAAA;AAAA,QACtC,CAAC,CAAA,EAAG,SAAS,CAAA,MAAA,CAAQ,GAAG,YAAA;AAAA,OACzB,CAAA;AAAA,MACD,WAAW,EAAA,KAAA;AAAA,MAEX,QAAA,kBAAAA,cAAA;AAAA,QAACC,iBAAA;AAAA,QAAA;AAAA,UACE,GAAG,KAAA;AAAA,UACJ,YAAA;AAAA,UACA,YAAY,EAAE,GAAG,YAAY,SAAW,EAAA,CAAA,EAAG,SAAS,CAAS,MAAA,CAAA,EAAA;AAAA,UAC7D,QAAA;AAAA,UACA,GAAK,EAAA,YAAA;AAAA,UACL,KAAA,EAAO,EAAE,OAAA,EAAS,CAAE,EAAA;AAAA,UACpB,SAAU,EAAA,MAAA;AAAA,UACV,KAAA;AAAA,UACA,OAAQ,EAAA,WAAA;AAAA,SAAA;AAAA,OACV;AAAA,KAAA;AAAA,GACF,CAAA;AAEJ,CAAC;;;;"}
1
+ {"version":3,"file":"ExpandoInput.js","sources":["../../src/expando-input/ExpandoInput.tsx"],"sourcesContent":["import cx from \"clsx\";\nimport { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\nimport { ForwardedRef, forwardRef } from \"react\";\nimport { VuuInput, VuuInputProps } from \"../vuu-input\";\n\nimport expandoInputCss from \"./ExpandoInput.css\";\n\nconst classBase = \"vuuExpandoInput\";\n\nconst noop = () => undefined;\n\nexport interface ExpandoInputProps extends Omit<VuuInputProps, \"onCommit\"> {\n onCommit?: VuuInputProps[\"onCommit\"];\n}\n\nexport const ExpandoInput = forwardRef(function ExpandoInput(\n {\n className: classNameProp,\n errorMessage,\n value,\n inputProps,\n onCommit = noop,\n ...props\n }: ExpandoInputProps,\n forwardedRef: ForwardedRef<HTMLDivElement>,\n) {\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"vuu-expando-input\",\n css: expandoInputCss,\n window: targetWindow,\n });\n\n return (\n <div\n className={cx(classBase, classNameProp, {\n [`${classBase}-error`]: errorMessage,\n })}\n data-text={value}\n >\n <VuuInput\n {...props}\n errorMessage={errorMessage}\n inputProps={{ ...inputProps, className: `${classBase}-input` }}\n onCommit={onCommit}\n ref={forwardedRef}\n style={{ padding: 0 }}\n textAlign=\"left\"\n value={value}\n variant=\"secondary\"\n />\n </div>\n );\n});\n"],"names":["forwardRef","ExpandoInput","useWindow","useComponentCssInjection","expandoInputCss","jsx","VuuInput"],"mappings":";;;;;;;;;;AAQA,MAAM,SAAY,GAAA,iBAAA,CAAA;AAElB,MAAM,OAAO,MAAM,KAAA,CAAA,CAAA;AAMN,MAAA,YAAA,GAAeA,gBAAW,CAAA,SAASC,aAC9C,CAAA;AAAA,EACE,SAAW,EAAA,aAAA;AAAA,EACX,YAAA;AAAA,EACA,KAAA;AAAA,EACA,UAAA;AAAA,EACA,QAAW,GAAA,IAAA;AAAA,EACX,GAAG,KAAA;AACL,CAAA,EACA,YACA,EAAA;AACA,EAAA,MAAM,eAAeC,gBAAU,EAAA,CAAA;AAC/B,EAAyBC,+BAAA,CAAA;AAAA,IACvB,MAAQ,EAAA,mBAAA;AAAA,IACR,GAAK,EAAAC,cAAA;AAAA,IACL,MAAQ,EAAA,YAAA;AAAA,GACT,CAAA,CAAA;AAED,EACE,uBAAAC,cAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,SAAA,EAAW,EAAG,CAAA,SAAA,EAAW,aAAe,EAAA;AAAA,QACtC,CAAC,CAAA,EAAG,SAAS,CAAA,MAAA,CAAQ,GAAG,YAAA;AAAA,OACzB,CAAA;AAAA,MACD,WAAW,EAAA,KAAA;AAAA,MAEX,QAAA,kBAAAA,cAAA;AAAA,QAACC,iBAAA;AAAA,QAAA;AAAA,UACE,GAAG,KAAA;AAAA,UACJ,YAAA;AAAA,UACA,YAAY,EAAE,GAAG,YAAY,SAAW,EAAA,CAAA,EAAG,SAAS,CAAS,MAAA,CAAA,EAAA;AAAA,UAC7D,QAAA;AAAA,UACA,GAAK,EAAA,YAAA;AAAA,UACL,KAAA,EAAO,EAAE,OAAA,EAAS,CAAE,EAAA;AAAA,UACpB,SAAU,EAAA,MAAA;AAAA,UACV,KAAA;AAAA,UACA,OAAQ,EAAA,WAAA;AAAA,SAAA;AAAA,OACV;AAAA,KAAA;AAAA,GACF,CAAA;AAEJ,CAAC;;;;"}
package/cjs/index.js CHANGED
@@ -25,7 +25,6 @@ var useGlobalDragDrop = require('./drag-drop/useGlobalDragDrop.js');
25
25
  var DatePopup = require('./date-popup/DatePopup.js');
26
26
  var DropdownBase = require('./dropdown-base/DropdownBase.js');
27
27
  var useDropdownBase = require('./dropdown-base/useDropdownBase.js');
28
- var editableUtils = require('./editable/editable-utils.js');
29
28
  var useEditableText = require('./editable/useEditableText.js');
30
29
  var EditableLabel = require('./editable-label/EditableLabel.js');
31
30
  var ExpandoInput = require('./expando-input/ExpandoInput.js');
@@ -130,7 +129,6 @@ exports.useGlobalDragDrop = useGlobalDragDrop.useGlobalDragDrop;
130
129
  exports.DatePopup = DatePopup.DatePopup;
131
130
  exports.DropdownBase = DropdownBase.DropdownBase;
132
131
  exports.useDropdownBase = useDropdownBase.useDropdownBase;
133
- exports.buildValidationChecker = editableUtils.buildValidationChecker;
134
132
  exports.WarnCommit = useEditableText.WarnCommit;
135
133
  exports.useEditableText = useEditableText.useEditableText;
136
134
  exports.EditableLabel = EditableLabel.EditableLabel;
package/cjs/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -1,26 +1,22 @@
1
1
  'use strict';
2
2
 
3
3
  var jsxRuntime = require('react/jsx-runtime');
4
- var vuuPopups = require('@vuu-ui/vuu-popups');
5
4
  var vuuUtils = require('@vuu-ui/vuu-utils');
6
5
  var core = require('@salt-ds/core');
7
- var cx = require('clsx');
8
6
  var styles = require('@salt-ds/styles');
9
7
  var window = require('@salt-ds/window');
8
+ var cx = require('clsx');
10
9
  var React = require('react');
11
10
  var VuuInput$1 = require('./VuuInput.css.js');
12
11
 
13
12
  const classBase = "vuuInput";
14
- const constantInputProps = {
15
- autoComplete: "off"
16
- };
17
13
  const VuuInput = React.forwardRef(function VuuInput2({
18
14
  className,
15
+ errorMessage,
19
16
  id: idProp,
20
17
  onCommit,
21
18
  onKeyDown,
22
19
  type,
23
- TooltipProps,
24
20
  ...props
25
21
  }, forwardedRef) {
26
22
  const targetWindow = window.useWindow();
@@ -30,11 +26,6 @@ const VuuInput = React.forwardRef(function VuuInput2({
30
26
  window: targetWindow
31
27
  });
32
28
  const id = vuuUtils.useId(idProp);
33
- const { anchorProps, tooltipProps } = vuuPopups.useTooltip({
34
- id,
35
- placement: TooltipProps?.placement,
36
- tooltipContent: TooltipProps?.tooltipContent
37
- });
38
29
  const commitValue = React.useCallback(
39
30
  (evt, value) => {
40
31
  if (type === "number") {
@@ -71,35 +62,25 @@ const VuuInput = React.forwardRef(function VuuInput2({
71
62
  },
72
63
  [commitValue]
73
64
  );
74
- const endAdornment = TooltipProps?.tooltipContent ? /* @__PURE__ */ jsxRuntime.jsx(
75
- "span",
65
+ const endAdornment = errorMessage ? /* @__PURE__ */ jsxRuntime.jsx(core.Tooltip, { content: errorMessage, status: "error", children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: `${classBase}-errorIcon`, "data-icon": "error" }) }) : void 0;
66
+ return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: /* @__PURE__ */ jsxRuntime.jsx(
67
+ core.Input,
76
68
  {
77
- ...anchorProps,
78
- className: `${classBase}-errorIcon`,
79
- "data-icon": "error"
69
+ ...props,
70
+ endAdornment,
71
+ id,
72
+ inputProps: {
73
+ autoComplete: "off",
74
+ ...props.inputProps
75
+ },
76
+ className: cx(classBase, className, {
77
+ [`${classBase}-error`]: errorMessage
78
+ }),
79
+ onBlur: handleBlur,
80
+ ref: forwardedRef,
81
+ onKeyDown: handleKeyDown
80
82
  }
81
- ) : void 0;
82
- return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
83
- /* @__PURE__ */ jsxRuntime.jsx(
84
- core.Input,
85
- {
86
- ...props,
87
- endAdornment,
88
- id,
89
- inputProps: {
90
- ...constantInputProps,
91
- ...props.inputProps
92
- },
93
- className: cx(classBase, className, {
94
- [`${classBase}-error`]: TooltipProps?.tooltipContent
95
- }),
96
- onBlur: handleBlur,
97
- ref: forwardedRef,
98
- onKeyDown: handleKeyDown
99
- }
100
- ),
101
- tooltipProps ? /* @__PURE__ */ jsxRuntime.jsx(vuuPopups.Tooltip, { ...tooltipProps, status: "error" }) : null
102
- ] });
83
+ ) });
103
84
  });
104
85
 
105
86
  exports.VuuInput = VuuInput;
@@ -1 +1 @@
1
- {"version":3,"file":"VuuInput.js","sources":["../../src/vuu-input/VuuInput.tsx"],"sourcesContent":["import { Tooltip, TooltipHookProps, useTooltip } from \"@vuu-ui/vuu-popups\";\nimport { VuuRowDataItemType } from \"@vuu-ui/vuu-protocol-types\";\nimport { CommitHandler, isValidNumber, useId } from \"@vuu-ui/vuu-utils\";\nimport { Input, InputProps } from \"@salt-ds/core\";\nimport cx from \"clsx\";\nimport { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\nimport {\n FocusEventHandler,\n ForwardedRef,\n forwardRef,\n KeyboardEventHandler,\n ReactElement,\n useCallback,\n} from \"react\";\n\nimport vuuInputCss from \"./VuuInput.css\";\n\nconst classBase = \"vuuInput\";\n\nconst constantInputProps = {\n autoComplete: \"off\",\n};\n\nexport interface VuuInputProps<T extends VuuRowDataItemType = string>\n extends InputProps {\n onCommit: CommitHandler<HTMLInputElement, T | undefined>;\n type?: T;\n TooltipProps?: Pick<TooltipHookProps, \"placement\" | \"tooltipContent\">;\n}\n\n/**\n * A variant of Salt Input that provides a commit callback prop,\n * TODO along with cancel behaviour ?\n */\nexport const VuuInput = forwardRef(function VuuInput<\n T extends VuuRowDataItemType = string,\n>(\n {\n className,\n id: idProp,\n onCommit,\n onKeyDown,\n type,\n TooltipProps,\n ...props\n }: VuuInputProps<T>,\n forwardedRef: ForwardedRef<HTMLDivElement>,\n) {\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"vuu-input\",\n css: vuuInputCss,\n window: targetWindow,\n });\n\n const id = useId(idProp);\n const { anchorProps, tooltipProps } = useTooltip({\n id,\n placement: TooltipProps?.placement,\n tooltipContent: TooltipProps?.tooltipContent,\n });\n\n const commitValue = useCallback<CommitHandler>(\n (evt, value) => {\n if (type === \"number\") {\n const numericValue = parseFloat(value);\n if (isValidNumber(numericValue)) {\n onCommit(evt, numericValue as T);\n } else {\n //TODO add validation logic\n throw Error(\"Invalid value\");\n }\n } else if (type === \"boolean\") {\n onCommit(evt, Boolean(value) as T);\n } else {\n onCommit(evt, value as T);\n }\n },\n [onCommit, type],\n );\n\n const handleKeyDown = useCallback<KeyboardEventHandler<HTMLInputElement>>(\n (evt) => {\n if (evt.key === \"Enter\") {\n evt.preventDefault();\n evt.stopPropagation();\n const { value } = evt.target as HTMLInputElement;\n commitValue(evt, value);\n }\n onKeyDown?.(evt);\n },\n [commitValue, onKeyDown],\n );\n\n const handleBlur = useCallback<FocusEventHandler<HTMLInputElement>>(\n (evt) => {\n const { value } = evt.target as HTMLInputElement;\n commitValue(evt, value);\n },\n [commitValue],\n );\n\n const endAdornment = TooltipProps?.tooltipContent ? (\n <span\n {...anchorProps}\n className={`${classBase}-errorIcon`}\n data-icon=\"error\"\n />\n ) : undefined;\n\n return (\n <>\n <Input\n {...props}\n endAdornment={endAdornment}\n id={id}\n inputProps={{\n ...constantInputProps,\n ...props.inputProps,\n }}\n className={cx(classBase, className, {\n [`${classBase}-error`]: TooltipProps?.tooltipContent,\n })}\n onBlur={handleBlur}\n ref={forwardedRef}\n onKeyDown={handleKeyDown}\n />\n {tooltipProps ? <Tooltip {...tooltipProps} status=\"error\" /> : null}\n </>\n );\n}) as <T extends VuuRowDataItemType = string>(\n props: VuuInputProps<T> & {\n ref?: ForwardedRef<HTMLDivElement>;\n },\n) => ReactElement<VuuInputProps<T>>;\n"],"names":["forwardRef","VuuInput","useWindow","useComponentCssInjection","vuuInputCss","useId","useTooltip","useCallback","isValidNumber","jsx","jsxs","Fragment","Input","Tooltip"],"mappings":"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"}
1
+ {"version":3,"file":"VuuInput.js","sources":["../../src/vuu-input/VuuInput.tsx"],"sourcesContent":["import { VuuRowDataItemType } from \"@vuu-ui/vuu-protocol-types\";\nimport { CommitHandler, isValidNumber, useId } from \"@vuu-ui/vuu-utils\";\nimport { Input, InputProps, Tooltip } from \"@salt-ds/core\";\nimport { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\nimport cx from \"clsx\";\nimport {\n FocusEventHandler,\n ForwardedRef,\n KeyboardEventHandler,\n ReactElement,\n ReactNode,\n forwardRef,\n useCallback,\n} from \"react\";\n\nimport vuuInputCss from \"./VuuInput.css\";\n\nconst classBase = \"vuuInput\";\n\nexport interface VuuInputProps<T extends VuuRowDataItemType = string>\n extends Omit<InputProps, \"validationStatus\"> {\n errorMessage?: ReactNode;\n onCommit: CommitHandler<HTMLInputElement, T | undefined>;\n type?: T;\n}\n\n/**\n * A variant of Salt Input that provides a commit callback prop,\n * TODO along with cancel behaviour ?\n */\nexport const VuuInput = forwardRef(function VuuInput<\n T extends VuuRowDataItemType = string,\n>(\n {\n className,\n errorMessage,\n id: idProp,\n onCommit,\n onKeyDown,\n type,\n ...props\n }: VuuInputProps<T>,\n forwardedRef: ForwardedRef<HTMLDivElement>,\n) {\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"vuu-input\",\n css: vuuInputCss,\n window: targetWindow,\n });\n\n const id = useId(idProp);\n\n const commitValue = useCallback<CommitHandler>(\n (evt, value) => {\n if (type === \"number\") {\n const numericValue = parseFloat(value);\n if (isValidNumber(numericValue)) {\n onCommit(evt, numericValue as T);\n } else {\n //TODO add validation logic\n throw Error(\"Invalid value\");\n }\n } else if (type === \"boolean\") {\n onCommit(evt, Boolean(value) as T);\n } else {\n onCommit(evt, value as T);\n }\n },\n [onCommit, type],\n );\n\n const handleKeyDown = useCallback<KeyboardEventHandler<HTMLInputElement>>(\n (evt) => {\n if (evt.key === \"Enter\") {\n evt.preventDefault();\n evt.stopPropagation();\n const { value } = evt.target as HTMLInputElement;\n commitValue(evt, value);\n }\n onKeyDown?.(evt);\n },\n [commitValue, onKeyDown],\n );\n\n const handleBlur = useCallback<FocusEventHandler<HTMLInputElement>>(\n (evt) => {\n const { value } = evt.target as HTMLInputElement;\n commitValue(evt, value);\n },\n [commitValue],\n );\n\n const endAdornment = errorMessage ? (\n <Tooltip content={errorMessage} status=\"error\">\n <span className={`${classBase}-errorIcon`} data-icon=\"error\" />\n </Tooltip>\n ) : undefined;\n\n return (\n <>\n <Input\n {...props}\n endAdornment={endAdornment}\n id={id}\n inputProps={{\n autoComplete: \"off\",\n ...props.inputProps,\n }}\n className={cx(classBase, className, {\n [`${classBase}-error`]: errorMessage,\n })}\n onBlur={handleBlur}\n ref={forwardedRef}\n onKeyDown={handleKeyDown}\n />\n </>\n );\n}) as <T extends VuuRowDataItemType = string>(\n props: VuuInputProps<T> & {\n ref?: ForwardedRef<HTMLDivElement>;\n },\n) => ReactElement<VuuInputProps<T>>;\n"],"names":["forwardRef","VuuInput","useWindow","useComponentCssInjection","vuuInputCss","useId","useCallback","isValidNumber","jsx","Tooltip","Fragment","Input"],"mappings":"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"}
@@ -38,7 +38,6 @@ const useDropdownBase = ({
38
38
  }, [onOpenChange, setIsOpen]);
39
39
  const hideDropdown = useCallback(
40
40
  (reason) => {
41
- console.log(`hide dropdown ${reason}`);
42
41
  setIsOpen(false);
43
42
  onOpenChange?.(false, reason);
44
43
  },
@@ -1 +1 @@
1
- {"version":3,"file":"useDropdownBase.js","sources":["../../src/dropdown-base/useDropdownBase.ts"],"sourcesContent":["import { useControlled, useForkRef } from \"@salt-ds/core\";\nimport {\n FocusEventHandler,\n KeyboardEvent,\n useCallback,\n useRef,\n useState,\n} from \"react\";\nimport { measurements, useResizeObserver, WidthOnly } from \"../common-hooks\";\nimport {\n CloseReason,\n DropdownHookProps,\n DropdownHookResult,\n DropdownOpenKey,\n} from \"./dropdownTypes\";\nimport { useClickAway, targetWithinSubPopup } from \"./useClickAway\";\n\nconst NO_OBSERVER: string[] = [];\n\nexport const useDropdownBase = ({\n defaultIsOpen,\n disabled,\n // TODO check how we're using fullWidth, do we need a separate value for the popup component\n fullWidth: fullWidthProp,\n id,\n isOpen: isOpenProp,\n onOpenChange,\n onKeyDown: onKeyDownProp,\n openKeys = [\"Enter\", \"ArrowDown\", \" \"],\n openOnFocus,\n popupComponent,\n popupWidth: popupWidthProp,\n rootRef,\n width,\n}: DropdownHookProps): DropdownHookResult => {\n const justFocused = useRef<number | null>(null);\n const popperRef = useRef<HTMLElement | null>(null);\n\n const [isOpen, setIsOpen] = useControlled({\n controlled: isOpenProp,\n default: Boolean(defaultIsOpen),\n name: \"useDropdown\",\n state: \"isOpen\",\n });\n const [popup, setPopup] = useState<measurements>({\n width: popupWidthProp ?? width ?? 0,\n });\n\n const showDropdown = useCallback(() => {\n setIsOpen(true);\n onOpenChange?.(true);\n }, [onOpenChange, setIsOpen]);\n\n const hideDropdown = useCallback(\n (reason: CloseReason) => {\n console.log(`hide dropdown ${reason}`);\n setIsOpen(false);\n onOpenChange?.(false, reason);\n },\n [onOpenChange, setIsOpen]\n );\n\n // Focus is not usually applied to the popped up component, we\n // manipulate active descendant whilst keeping focus in the\n // trigger. Some component, like Calendar ARE focussed, as they\n // have more complicated navigation. In these cases, we need to\n // listen for focus out.\n const handleComponentFocusOut = useCallback(\n (evt: FocusEvent) => {\n const target = evt.relatedTarget as HTMLElement;\n if (target === null) {\n // if component sets focus on a timeout (as calendar does when\n // transitioning month) wait before testing\n requestAnimationFrame(() => {\n if (!popperRef.current?.contains(document.activeElement)) {\n hideDropdown(\"Tab\");\n }\n });\n } else if (!popperRef.current?.contains(target)) {\n if (!targetWithinSubPopup(popperRef.current, target)) {\n hideDropdown(\"Tab\");\n }\n }\n },\n [hideDropdown]\n );\n\n const popperCallbackRef = useCallback(\n (element: HTMLElement | null) => {\n if (element) {\n element.addEventListener(\"focusout\", handleComponentFocusOut);\n } else if (popperRef.current) {\n popperRef.current.removeEventListener(\n \"focusout\",\n handleComponentFocusOut\n );\n }\n popperRef.current = element;\n },\n [handleComponentFocusOut]\n );\n\n useClickAway({\n popperRef,\n rootRef,\n isOpen,\n onClose: hideDropdown,\n });\n\n const handleTriggerFocus = useCallback(() => {\n if (!disabled) {\n if (openOnFocus) {\n setIsOpen(true);\n onOpenChange?.(true);\n // Suppress response to click if click was the cause of focus\n justFocused.current = window.setTimeout(() => {\n justFocused.current = null;\n }, 1000);\n }\n }\n }, [disabled, onOpenChange, openOnFocus, setIsOpen]);\n\n const handleTriggerToggle = useCallback(\n (e: MouseEvent) => {\n // Do not trigger menu open for 'Enter' and 'SPACE' key as they're handled in `handleKeyDown`\n if (\n [\"Enter\", \" \"].indexOf(\n (e as unknown as KeyboardEvent<HTMLDivElement>).key\n ) === -1\n ) {\n const newIsOpen = !isOpen;\n setIsOpen(newIsOpen);\n onOpenChange?.(newIsOpen);\n }\n },\n [isOpen, setIsOpen, onOpenChange]\n );\n\n const handleKeydown = useCallback(\n (evt: KeyboardEvent<HTMLElement>) => {\n if (/* evt.key === \"Tab\" || */ evt.key === \"Escape\" && isOpen) {\n // No preventDefault for Tab, but if we've handled Escape, we should own it\n if (evt.key === \"Escape\") {\n evt.stopPropagation();\n evt.preventDefault();\n }\n hideDropdown(evt.key);\n } else if (openKeys.includes(evt.key as DropdownOpenKey) && !isOpen) {\n evt.preventDefault();\n showDropdown();\n } else {\n onKeyDownProp?.(evt);\n }\n },\n [hideDropdown, isOpen, onKeyDownProp, openKeys, showDropdown]\n );\n\n const handleBlur = useCallback<FocusEventHandler<HTMLElement>>(\n (evt) => {\n if (isOpen) {\n if (popperRef.current?.contains(evt.relatedTarget)) {\n // ignore\n } else {\n hideDropdown(\"blur\");\n }\n }\n },\n [hideDropdown, isOpen]\n );\n\n const fullWidth = fullWidthProp ?? false;\n const measurements = fullWidth ? WidthOnly : NO_OBSERVER;\n useResizeObserver(rootRef, measurements, setPopup, fullWidth);\n\n const componentId = `${id}-dropdown`;\n\n // TODO do we use aria-popup - valid values are menu, disloag, grid, tree, listbox\n const triggerProps = {\n \"aria-expanded\": isOpen,\n \"aria-owns\": isOpen ? componentId : undefined,\n id: `${id}-control`,\n onClick: disabled || openOnFocus ? undefined : handleTriggerToggle,\n onFocus: handleTriggerFocus,\n role: \"listbox\",\n onBlur: handleBlur,\n onKeyDown: disabled ? undefined : handleKeydown,\n style: { width: fullWidth ? undefined : width },\n };\n\n const dropdownComponentProps = {\n id: componentId,\n width: popup.width,\n };\n\n const popupComponentRef = useForkRef(popperCallbackRef, popupComponent.ref);\n\n return {\n componentProps: dropdownComponentProps,\n popupComponentRef,\n isOpen,\n label: \"Dropdown Button\",\n triggerProps,\n };\n};\n"],"names":["measurements"],"mappings":";;;;;;AAiBA,MAAM,cAAwB,EAAC,CAAA;AAExB,MAAM,kBAAkB,CAAC;AAAA,EAC9B,aAAA;AAAA,EACA,QAAA;AAAA;AAAA,EAEA,SAAW,EAAA,aAAA;AAAA,EACX,EAAA;AAAA,EACA,MAAQ,EAAA,UAAA;AAAA,EACR,YAAA;AAAA,EACA,SAAW,EAAA,aAAA;AAAA,EACX,QAAW,GAAA,CAAC,OAAS,EAAA,WAAA,EAAa,GAAG,CAAA;AAAA,EACrC,WAAA;AAAA,EACA,cAAA;AAAA,EACA,UAAY,EAAA,cAAA;AAAA,EACZ,OAAA;AAAA,EACA,KAAA;AACF,CAA6C,KAAA;AAC3C,EAAM,MAAA,WAAA,GAAc,OAAsB,IAAI,CAAA,CAAA;AAC9C,EAAM,MAAA,SAAA,GAAY,OAA2B,IAAI,CAAA,CAAA;AAEjD,EAAA,MAAM,CAAC,MAAA,EAAQ,SAAS,CAAA,GAAI,aAAc,CAAA;AAAA,IACxC,UAAY,EAAA,UAAA;AAAA,IACZ,OAAA,EAAS,QAAQ,aAAa,CAAA;AAAA,IAC9B,IAAM,EAAA,aAAA;AAAA,IACN,KAAO,EAAA,QAAA;AAAA,GACR,CAAA,CAAA;AACD,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAI,QAAuB,CAAA;AAAA,IAC/C,KAAA,EAAO,kBAAkB,KAAS,IAAA,CAAA;AAAA,GACnC,CAAA,CAAA;AAED,EAAM,MAAA,YAAA,GAAe,YAAY,MAAM;AACrC,IAAA,SAAA,CAAU,IAAI,CAAA,CAAA;AACd,IAAA,YAAA,GAAe,IAAI,CAAA,CAAA;AAAA,GAClB,EAAA,CAAC,YAAc,EAAA,SAAS,CAAC,CAAA,CAAA;AAE5B,EAAA,MAAM,YAAe,GAAA,WAAA;AAAA,IACnB,CAAC,MAAwB,KAAA;AACvB,MAAQ,OAAA,CAAA,GAAA,CAAI,CAAiB,cAAA,EAAA,MAAM,CAAE,CAAA,CAAA,CAAA;AACrC,MAAA,SAAA,CAAU,KAAK,CAAA,CAAA;AACf,MAAA,YAAA,GAAe,OAAO,MAAM,CAAA,CAAA;AAAA,KAC9B;AAAA,IACA,CAAC,cAAc,SAAS,CAAA;AAAA,GAC1B,CAAA;AAOA,EAAA,MAAM,uBAA0B,GAAA,WAAA;AAAA,IAC9B,CAAC,GAAoB,KAAA;AACnB,MAAA,MAAM,SAAS,GAAI,CAAA,aAAA,CAAA;AACnB,MAAA,IAAI,WAAW,IAAM,EAAA;AAGnB,QAAA,qBAAA,CAAsB,MAAM;AAC1B,UAAA,IAAI,CAAC,SAAU,CAAA,OAAA,EAAS,QAAS,CAAA,QAAA,CAAS,aAAa,CAAG,EAAA;AACxD,YAAA,YAAA,CAAa,KAAK,CAAA,CAAA;AAAA,WACpB;AAAA,SACD,CAAA,CAAA;AAAA,iBACQ,CAAC,SAAA,CAAU,OAAS,EAAA,QAAA,CAAS,MAAM,CAAG,EAAA;AAC/C,QAAA,IAAI,CAAC,oBAAA,CAAqB,SAAU,CAAA,OAAA,EAAS,MAAM,CAAG,EAAA;AACpD,UAAA,YAAA,CAAa,KAAK,CAAA,CAAA;AAAA,SACpB;AAAA,OACF;AAAA,KACF;AAAA,IACA,CAAC,YAAY,CAAA;AAAA,GACf,CAAA;AAEA,EAAA,MAAM,iBAAoB,GAAA,WAAA;AAAA,IACxB,CAAC,OAAgC,KAAA;AAC/B,MAAA,IAAI,OAAS,EAAA;AACX,QAAQ,OAAA,CAAA,gBAAA,CAAiB,YAAY,uBAAuB,CAAA,CAAA;AAAA,OAC9D,MAAA,IAAW,UAAU,OAAS,EAAA;AAC5B,QAAA,SAAA,CAAU,OAAQ,CAAA,mBAAA;AAAA,UAChB,UAAA;AAAA,UACA,uBAAA;AAAA,SACF,CAAA;AAAA,OACF;AACA,MAAA,SAAA,CAAU,OAAU,GAAA,OAAA,CAAA;AAAA,KACtB;AAAA,IACA,CAAC,uBAAuB,CAAA;AAAA,GAC1B,CAAA;AAEA,EAAa,YAAA,CAAA;AAAA,IACX,SAAA;AAAA,IACA,OAAA;AAAA,IACA,MAAA;AAAA,IACA,OAAS,EAAA,YAAA;AAAA,GACV,CAAA,CAAA;AAED,EAAM,MAAA,kBAAA,GAAqB,YAAY,MAAM;AAC3C,IAAA,IAAI,CAAC,QAAU,EAAA;AACb,MAAA,IAAI,WAAa,EAAA;AACf,QAAA,SAAA,CAAU,IAAI,CAAA,CAAA;AACd,QAAA,YAAA,GAAe,IAAI,CAAA,CAAA;AAEnB,QAAY,WAAA,CAAA,OAAA,GAAU,MAAO,CAAA,UAAA,CAAW,MAAM;AAC5C,UAAA,WAAA,CAAY,OAAU,GAAA,IAAA,CAAA;AAAA,WACrB,GAAI,CAAA,CAAA;AAAA,OACT;AAAA,KACF;AAAA,KACC,CAAC,QAAA,EAAU,YAAc,EAAA,WAAA,EAAa,SAAS,CAAC,CAAA,CAAA;AAEnD,EAAA,MAAM,mBAAsB,GAAA,WAAA;AAAA,IAC1B,CAAC,CAAkB,KAAA;AAEjB,MACE,IAAA,CAAC,OAAS,EAAA,GAAG,CAAE,CAAA,OAAA;AAAA,QACZ,CAA+C,CAAA,GAAA;AAAA,YAC5C,CACN,CAAA,EAAA;AACA,QAAA,MAAM,YAAY,CAAC,MAAA,CAAA;AACnB,QAAA,SAAA,CAAU,SAAS,CAAA,CAAA;AACnB,QAAA,YAAA,GAAe,SAAS,CAAA,CAAA;AAAA,OAC1B;AAAA,KACF;AAAA,IACA,CAAC,MAAQ,EAAA,SAAA,EAAW,YAAY,CAAA;AAAA,GAClC,CAAA;AAEA,EAAA,MAAM,aAAgB,GAAA,WAAA;AAAA,IACpB,CAAC,GAAoC,KAAA;AACnC,MAAA;AAAA;AAAA,QAA+B,GAAA,CAAI,QAAQ,QAAY,IAAA,MAAA;AAAA,QAAQ;AAE7D,QAAI,IAAA,GAAA,CAAI,QAAQ,QAAU,EAAA;AACxB,UAAA,GAAA,CAAI,eAAgB,EAAA,CAAA;AACpB,UAAA,GAAA,CAAI,cAAe,EAAA,CAAA;AAAA,SACrB;AACA,QAAA,YAAA,CAAa,IAAI,GAAG,CAAA,CAAA;AAAA,iBACX,QAAS,CAAA,QAAA,CAAS,IAAI,GAAsB,CAAA,IAAK,CAAC,MAAQ,EAAA;AACnE,QAAA,GAAA,CAAI,cAAe,EAAA,CAAA;AACnB,QAAa,YAAA,EAAA,CAAA;AAAA,OACR,MAAA;AACL,QAAA,aAAA,GAAgB,GAAG,CAAA,CAAA;AAAA,OACrB;AAAA,KACF;AAAA,IACA,CAAC,YAAA,EAAc,MAAQ,EAAA,aAAA,EAAe,UAAU,YAAY,CAAA;AAAA,GAC9D,CAAA;AAEA,EAAA,MAAM,UAAa,GAAA,WAAA;AAAA,IACjB,CAAC,GAAQ,KAAA;AACP,MAAA,IAAI,MAAQ,EAAA;AACV,QAAA,IAAI,SAAU,CAAA,OAAA,EAAS,QAAS,CAAA,GAAA,CAAI,aAAa,CAAG,EAAA,CAE7C,MAAA;AACL,UAAA,YAAA,CAAa,MAAM,CAAA,CAAA;AAAA,SACrB;AAAA,OACF;AAAA,KACF;AAAA,IACA,CAAC,cAAc,MAAM,CAAA;AAAA,GACvB,CAAA;AAEA,EAAA,MAAM,YAAY,aAAiB,IAAA,KAAA,CAAA;AACnC,EAAMA,MAAAA,aAAAA,GAAe,YAAY,SAAY,GAAA,WAAA,CAAA;AAC7C,EAAkB,iBAAA,CAAA,OAAA,EAASA,aAAc,EAAA,QAAA,EAAU,SAAS,CAAA,CAAA;AAE5D,EAAM,MAAA,WAAA,GAAc,GAAG,EAAE,CAAA,SAAA,CAAA,CAAA;AAGzB,EAAA,MAAM,YAAe,GAAA;AAAA,IACnB,eAAiB,EAAA,MAAA;AAAA,IACjB,WAAA,EAAa,SAAS,WAAc,GAAA,KAAA,CAAA;AAAA,IACpC,EAAA,EAAI,GAAG,EAAE,CAAA,QAAA,CAAA;AAAA,IACT,OAAA,EAAS,QAAY,IAAA,WAAA,GAAc,KAAY,CAAA,GAAA,mBAAA;AAAA,IAC/C,OAAS,EAAA,kBAAA;AAAA,IACT,IAAM,EAAA,SAAA;AAAA,IACN,MAAQ,EAAA,UAAA;AAAA,IACR,SAAA,EAAW,WAAW,KAAY,CAAA,GAAA,aAAA;AAAA,IAClC,KAAO,EAAA,EAAE,KAAO,EAAA,SAAA,GAAY,SAAY,KAAM,EAAA;AAAA,GAChD,CAAA;AAEA,EAAA,MAAM,sBAAyB,GAAA;AAAA,IAC7B,EAAI,EAAA,WAAA;AAAA,IACJ,OAAO,KAAM,CAAA,KAAA;AAAA,GACf,CAAA;AAEA,EAAA,MAAM,iBAAoB,GAAA,UAAA,CAAW,iBAAmB,EAAA,cAAA,CAAe,GAAG,CAAA,CAAA;AAE1E,EAAO,OAAA;AAAA,IACL,cAAgB,EAAA,sBAAA;AAAA,IAChB,iBAAA;AAAA,IACA,MAAA;AAAA,IACA,KAAO,EAAA,iBAAA;AAAA,IACP,YAAA;AAAA,GACF,CAAA;AACF;;;;"}
1
+ {"version":3,"file":"useDropdownBase.js","sources":["../../src/dropdown-base/useDropdownBase.ts"],"sourcesContent":["import { useControlled, useForkRef } from \"@salt-ds/core\";\nimport {\n FocusEventHandler,\n KeyboardEvent,\n useCallback,\n useRef,\n useState,\n} from \"react\";\nimport { measurements, useResizeObserver, WidthOnly } from \"../common-hooks\";\nimport {\n CloseReason,\n DropdownHookProps,\n DropdownHookResult,\n DropdownOpenKey,\n} from \"./dropdownTypes\";\nimport { useClickAway, targetWithinSubPopup } from \"./useClickAway\";\n\nconst NO_OBSERVER: string[] = [];\n\nexport const useDropdownBase = ({\n defaultIsOpen,\n disabled,\n // TODO check how we're using fullWidth, do we need a separate value for the popup component\n fullWidth: fullWidthProp,\n id,\n isOpen: isOpenProp,\n onOpenChange,\n onKeyDown: onKeyDownProp,\n openKeys = [\"Enter\", \"ArrowDown\", \" \"],\n openOnFocus,\n popupComponent,\n popupWidth: popupWidthProp,\n rootRef,\n width,\n}: DropdownHookProps): DropdownHookResult => {\n const justFocused = useRef<number | null>(null);\n const popperRef = useRef<HTMLElement | null>(null);\n\n const [isOpen, setIsOpen] = useControlled({\n controlled: isOpenProp,\n default: Boolean(defaultIsOpen),\n name: \"useDropdown\",\n state: \"isOpen\",\n });\n const [popup, setPopup] = useState<measurements>({\n width: popupWidthProp ?? width ?? 0,\n });\n\n const showDropdown = useCallback(() => {\n setIsOpen(true);\n onOpenChange?.(true);\n }, [onOpenChange, setIsOpen]);\n\n const hideDropdown = useCallback(\n (reason: CloseReason) => {\n setIsOpen(false);\n onOpenChange?.(false, reason);\n },\n [onOpenChange, setIsOpen],\n );\n\n // Focus is not usually applied to the popped up component, we\n // manipulate active descendant whilst keeping focus in the\n // trigger. Some component, like Calendar ARE focussed, as they\n // have more complicated navigation. In these cases, we need to\n // listen for focus out.\n const handleComponentFocusOut = useCallback(\n (evt: FocusEvent) => {\n const target = evt.relatedTarget as HTMLElement;\n if (target === null) {\n // if component sets focus on a timeout (as calendar does when\n // transitioning month) wait before testing\n requestAnimationFrame(() => {\n if (!popperRef.current?.contains(document.activeElement)) {\n hideDropdown(\"Tab\");\n }\n });\n } else if (!popperRef.current?.contains(target)) {\n if (!targetWithinSubPopup(popperRef.current, target)) {\n hideDropdown(\"Tab\");\n }\n }\n },\n [hideDropdown],\n );\n\n const popperCallbackRef = useCallback(\n (element: HTMLElement | null) => {\n if (element) {\n element.addEventListener(\"focusout\", handleComponentFocusOut);\n } else if (popperRef.current) {\n popperRef.current.removeEventListener(\n \"focusout\",\n handleComponentFocusOut,\n );\n }\n popperRef.current = element;\n },\n [handleComponentFocusOut],\n );\n\n useClickAway({\n popperRef,\n rootRef,\n isOpen,\n onClose: hideDropdown,\n });\n\n const handleTriggerFocus = useCallback(() => {\n if (!disabled) {\n if (openOnFocus) {\n setIsOpen(true);\n onOpenChange?.(true);\n // Suppress response to click if click was the cause of focus\n justFocused.current = window.setTimeout(() => {\n justFocused.current = null;\n }, 1000);\n }\n }\n }, [disabled, onOpenChange, openOnFocus, setIsOpen]);\n\n const handleTriggerToggle = useCallback(\n (e: MouseEvent) => {\n // Do not trigger menu open for 'Enter' and 'SPACE' key as they're handled in `handleKeyDown`\n if (\n [\"Enter\", \" \"].indexOf(\n (e as unknown as KeyboardEvent<HTMLDivElement>).key,\n ) === -1\n ) {\n const newIsOpen = !isOpen;\n setIsOpen(newIsOpen);\n onOpenChange?.(newIsOpen);\n }\n },\n [isOpen, setIsOpen, onOpenChange],\n );\n\n const handleKeydown = useCallback(\n (evt: KeyboardEvent<HTMLElement>) => {\n if (/* evt.key === \"Tab\" || */ evt.key === \"Escape\" && isOpen) {\n // No preventDefault for Tab, but if we've handled Escape, we should own it\n if (evt.key === \"Escape\") {\n evt.stopPropagation();\n evt.preventDefault();\n }\n hideDropdown(evt.key);\n } else if (openKeys.includes(evt.key as DropdownOpenKey) && !isOpen) {\n evt.preventDefault();\n showDropdown();\n } else {\n onKeyDownProp?.(evt);\n }\n },\n [hideDropdown, isOpen, onKeyDownProp, openKeys, showDropdown],\n );\n\n const handleBlur = useCallback<FocusEventHandler<HTMLElement>>(\n (evt) => {\n if (isOpen) {\n if (popperRef.current?.contains(evt.relatedTarget)) {\n // ignore\n } else {\n hideDropdown(\"blur\");\n }\n }\n },\n [hideDropdown, isOpen],\n );\n\n const fullWidth = fullWidthProp ?? false;\n const measurements = fullWidth ? WidthOnly : NO_OBSERVER;\n useResizeObserver(rootRef, measurements, setPopup, fullWidth);\n\n const componentId = `${id}-dropdown`;\n\n // TODO do we use aria-popup - valid values are menu, disloag, grid, tree, listbox\n const triggerProps = {\n \"aria-expanded\": isOpen,\n \"aria-owns\": isOpen ? componentId : undefined,\n id: `${id}-control`,\n onClick: disabled || openOnFocus ? undefined : handleTriggerToggle,\n onFocus: handleTriggerFocus,\n role: \"listbox\",\n onBlur: handleBlur,\n onKeyDown: disabled ? undefined : handleKeydown,\n style: { width: fullWidth ? undefined : width },\n };\n\n const dropdownComponentProps = {\n id: componentId,\n width: popup.width,\n };\n\n const popupComponentRef = useForkRef(popperCallbackRef, popupComponent.ref);\n\n return {\n componentProps: dropdownComponentProps,\n popupComponentRef,\n isOpen,\n label: \"Dropdown Button\",\n triggerProps,\n };\n};\n"],"names":["measurements"],"mappings":";;;;;;AAiBA,MAAM,cAAwB,EAAC,CAAA;AAExB,MAAM,kBAAkB,CAAC;AAAA,EAC9B,aAAA;AAAA,EACA,QAAA;AAAA;AAAA,EAEA,SAAW,EAAA,aAAA;AAAA,EACX,EAAA;AAAA,EACA,MAAQ,EAAA,UAAA;AAAA,EACR,YAAA;AAAA,EACA,SAAW,EAAA,aAAA;AAAA,EACX,QAAW,GAAA,CAAC,OAAS,EAAA,WAAA,EAAa,GAAG,CAAA;AAAA,EACrC,WAAA;AAAA,EACA,cAAA;AAAA,EACA,UAAY,EAAA,cAAA;AAAA,EACZ,OAAA;AAAA,EACA,KAAA;AACF,CAA6C,KAAA;AAC3C,EAAM,MAAA,WAAA,GAAc,OAAsB,IAAI,CAAA,CAAA;AAC9C,EAAM,MAAA,SAAA,GAAY,OAA2B,IAAI,CAAA,CAAA;AAEjD,EAAA,MAAM,CAAC,MAAA,EAAQ,SAAS,CAAA,GAAI,aAAc,CAAA;AAAA,IACxC,UAAY,EAAA,UAAA;AAAA,IACZ,OAAA,EAAS,QAAQ,aAAa,CAAA;AAAA,IAC9B,IAAM,EAAA,aAAA;AAAA,IACN,KAAO,EAAA,QAAA;AAAA,GACR,CAAA,CAAA;AACD,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAI,QAAuB,CAAA;AAAA,IAC/C,KAAA,EAAO,kBAAkB,KAAS,IAAA,CAAA;AAAA,GACnC,CAAA,CAAA;AAED,EAAM,MAAA,YAAA,GAAe,YAAY,MAAM;AACrC,IAAA,SAAA,CAAU,IAAI,CAAA,CAAA;AACd,IAAA,YAAA,GAAe,IAAI,CAAA,CAAA;AAAA,GAClB,EAAA,CAAC,YAAc,EAAA,SAAS,CAAC,CAAA,CAAA;AAE5B,EAAA,MAAM,YAAe,GAAA,WAAA;AAAA,IACnB,CAAC,MAAwB,KAAA;AACvB,MAAA,SAAA,CAAU,KAAK,CAAA,CAAA;AACf,MAAA,YAAA,GAAe,OAAO,MAAM,CAAA,CAAA;AAAA,KAC9B;AAAA,IACA,CAAC,cAAc,SAAS,CAAA;AAAA,GAC1B,CAAA;AAOA,EAAA,MAAM,uBAA0B,GAAA,WAAA;AAAA,IAC9B,CAAC,GAAoB,KAAA;AACnB,MAAA,MAAM,SAAS,GAAI,CAAA,aAAA,CAAA;AACnB,MAAA,IAAI,WAAW,IAAM,EAAA;AAGnB,QAAA,qBAAA,CAAsB,MAAM;AAC1B,UAAA,IAAI,CAAC,SAAU,CAAA,OAAA,EAAS,QAAS,CAAA,QAAA,CAAS,aAAa,CAAG,EAAA;AACxD,YAAA,YAAA,CAAa,KAAK,CAAA,CAAA;AAAA,WACpB;AAAA,SACD,CAAA,CAAA;AAAA,iBACQ,CAAC,SAAA,CAAU,OAAS,EAAA,QAAA,CAAS,MAAM,CAAG,EAAA;AAC/C,QAAA,IAAI,CAAC,oBAAA,CAAqB,SAAU,CAAA,OAAA,EAAS,MAAM,CAAG,EAAA;AACpD,UAAA,YAAA,CAAa,KAAK,CAAA,CAAA;AAAA,SACpB;AAAA,OACF;AAAA,KACF;AAAA,IACA,CAAC,YAAY,CAAA;AAAA,GACf,CAAA;AAEA,EAAA,MAAM,iBAAoB,GAAA,WAAA;AAAA,IACxB,CAAC,OAAgC,KAAA;AAC/B,MAAA,IAAI,OAAS,EAAA;AACX,QAAQ,OAAA,CAAA,gBAAA,CAAiB,YAAY,uBAAuB,CAAA,CAAA;AAAA,OAC9D,MAAA,IAAW,UAAU,OAAS,EAAA;AAC5B,QAAA,SAAA,CAAU,OAAQ,CAAA,mBAAA;AAAA,UAChB,UAAA;AAAA,UACA,uBAAA;AAAA,SACF,CAAA;AAAA,OACF;AACA,MAAA,SAAA,CAAU,OAAU,GAAA,OAAA,CAAA;AAAA,KACtB;AAAA,IACA,CAAC,uBAAuB,CAAA;AAAA,GAC1B,CAAA;AAEA,EAAa,YAAA,CAAA;AAAA,IACX,SAAA;AAAA,IACA,OAAA;AAAA,IACA,MAAA;AAAA,IACA,OAAS,EAAA,YAAA;AAAA,GACV,CAAA,CAAA;AAED,EAAM,MAAA,kBAAA,GAAqB,YAAY,MAAM;AAC3C,IAAA,IAAI,CAAC,QAAU,EAAA;AACb,MAAA,IAAI,WAAa,EAAA;AACf,QAAA,SAAA,CAAU,IAAI,CAAA,CAAA;AACd,QAAA,YAAA,GAAe,IAAI,CAAA,CAAA;AAEnB,QAAY,WAAA,CAAA,OAAA,GAAU,MAAO,CAAA,UAAA,CAAW,MAAM;AAC5C,UAAA,WAAA,CAAY,OAAU,GAAA,IAAA,CAAA;AAAA,WACrB,GAAI,CAAA,CAAA;AAAA,OACT;AAAA,KACF;AAAA,KACC,CAAC,QAAA,EAAU,YAAc,EAAA,WAAA,EAAa,SAAS,CAAC,CAAA,CAAA;AAEnD,EAAA,MAAM,mBAAsB,GAAA,WAAA;AAAA,IAC1B,CAAC,CAAkB,KAAA;AAEjB,MACE,IAAA,CAAC,OAAS,EAAA,GAAG,CAAE,CAAA,OAAA;AAAA,QACZ,CAA+C,CAAA,GAAA;AAAA,YAC5C,CACN,CAAA,EAAA;AACA,QAAA,MAAM,YAAY,CAAC,MAAA,CAAA;AACnB,QAAA,SAAA,CAAU,SAAS,CAAA,CAAA;AACnB,QAAA,YAAA,GAAe,SAAS,CAAA,CAAA;AAAA,OAC1B;AAAA,KACF;AAAA,IACA,CAAC,MAAQ,EAAA,SAAA,EAAW,YAAY,CAAA;AAAA,GAClC,CAAA;AAEA,EAAA,MAAM,aAAgB,GAAA,WAAA;AAAA,IACpB,CAAC,GAAoC,KAAA;AACnC,MAAA;AAAA;AAAA,QAA+B,GAAA,CAAI,QAAQ,QAAY,IAAA,MAAA;AAAA,QAAQ;AAE7D,QAAI,IAAA,GAAA,CAAI,QAAQ,QAAU,EAAA;AACxB,UAAA,GAAA,CAAI,eAAgB,EAAA,CAAA;AACpB,UAAA,GAAA,CAAI,cAAe,EAAA,CAAA;AAAA,SACrB;AACA,QAAA,YAAA,CAAa,IAAI,GAAG,CAAA,CAAA;AAAA,iBACX,QAAS,CAAA,QAAA,CAAS,IAAI,GAAsB,CAAA,IAAK,CAAC,MAAQ,EAAA;AACnE,QAAA,GAAA,CAAI,cAAe,EAAA,CAAA;AACnB,QAAa,YAAA,EAAA,CAAA;AAAA,OACR,MAAA;AACL,QAAA,aAAA,GAAgB,GAAG,CAAA,CAAA;AAAA,OACrB;AAAA,KACF;AAAA,IACA,CAAC,YAAA,EAAc,MAAQ,EAAA,aAAA,EAAe,UAAU,YAAY,CAAA;AAAA,GAC9D,CAAA;AAEA,EAAA,MAAM,UAAa,GAAA,WAAA;AAAA,IACjB,CAAC,GAAQ,KAAA;AACP,MAAA,IAAI,MAAQ,EAAA;AACV,QAAA,IAAI,SAAU,CAAA,OAAA,EAAS,QAAS,CAAA,GAAA,CAAI,aAAa,CAAG,EAAA,CAE7C,MAAA;AACL,UAAA,YAAA,CAAa,MAAM,CAAA,CAAA;AAAA,SACrB;AAAA,OACF;AAAA,KACF;AAAA,IACA,CAAC,cAAc,MAAM,CAAA;AAAA,GACvB,CAAA;AAEA,EAAA,MAAM,YAAY,aAAiB,IAAA,KAAA,CAAA;AACnC,EAAMA,MAAAA,aAAAA,GAAe,YAAY,SAAY,GAAA,WAAA,CAAA;AAC7C,EAAkB,iBAAA,CAAA,OAAA,EAASA,aAAc,EAAA,QAAA,EAAU,SAAS,CAAA,CAAA;AAE5D,EAAM,MAAA,WAAA,GAAc,GAAG,EAAE,CAAA,SAAA,CAAA,CAAA;AAGzB,EAAA,MAAM,YAAe,GAAA;AAAA,IACnB,eAAiB,EAAA,MAAA;AAAA,IACjB,WAAA,EAAa,SAAS,WAAc,GAAA,KAAA,CAAA;AAAA,IACpC,EAAA,EAAI,GAAG,EAAE,CAAA,QAAA,CAAA;AAAA,IACT,OAAA,EAAS,QAAY,IAAA,WAAA,GAAc,KAAY,CAAA,GAAA,mBAAA;AAAA,IAC/C,OAAS,EAAA,kBAAA;AAAA,IACT,IAAM,EAAA,SAAA;AAAA,IACN,MAAQ,EAAA,UAAA;AAAA,IACR,SAAA,EAAW,WAAW,KAAY,CAAA,GAAA,aAAA;AAAA,IAClC,KAAO,EAAA,EAAE,KAAO,EAAA,SAAA,GAAY,SAAY,KAAM,EAAA;AAAA,GAChD,CAAA;AAEA,EAAA,MAAM,sBAAyB,GAAA;AAAA,IAC7B,EAAI,EAAA,WAAA;AAAA,IACJ,OAAO,KAAM,CAAA,KAAA;AAAA,GACf,CAAA;AAEA,EAAA,MAAM,iBAAoB,GAAA,UAAA,CAAW,iBAAmB,EAAA,cAAA,CAAe,GAAG,CAAA,CAAA;AAE1E,EAAO,OAAA;AAAA,IACL,cAAgB,EAAA,sBAAA;AAAA,IAChB,iBAAA;AAAA,IACA,MAAA;AAAA,IACA,KAAO,EAAA,iBAAA;AAAA,IACP,YAAA;AAAA,GACF,CAAA;AACF;;;;"}
@@ -25,9 +25,9 @@ const useEditableText = ({
25
25
  (target) => {
26
26
  if (isDirtyRef.current) {
27
27
  hasCommittedRef.current = true;
28
- const warningMessage = clientSideEditValidationCheck?.(value);
29
- if (warningMessage) {
30
- setMessage(warningMessage);
28
+ const result = clientSideEditValidationCheck?.(value);
29
+ if (result?.ok === false) {
30
+ setMessage(result?.messages?.join(","));
31
31
  } else {
32
32
  setMessage(void 0);
33
33
  console.log(`commit value ${value}`);
@@ -80,13 +80,13 @@ const useEditableText = ({
80
80
  isDirtyRef.current = value !== initialValueRef.current;
81
81
  setValue(typedValue);
82
82
  if (hasCommittedRef.current && value !== void 0) {
83
- const warningMessage = clientSideEditValidationCheck?.(value);
84
- if (warningMessage !== message && warningMessage !== false) {
85
- setMessage(warningMessage);
83
+ const result = clientSideEditValidationCheck?.(value);
84
+ if (result?.ok === false) {
85
+ setMessage(result.messages?.join(","));
86
86
  }
87
87
  }
88
88
  },
89
- [clientSideEditValidationCheck, message, type, value]
89
+ [clientSideEditValidationCheck, type, value]
90
90
  );
91
91
  return {
92
92
  inputProps: {
@@ -1 +1 @@
1
- {"version":3,"file":"useEditableText.js","sources":["../../src/editable/useEditableText.ts"],"sourcesContent":["import {\n ClientSideValidationChecker,\n DataItemCommitHandler,\n} from \"@vuu-ui/vuu-table-types\";\nimport { useLayoutEffectSkipFirst } from \"@vuu-ui/vuu-utils\";\nimport { VuuRowDataItemType } from \"@vuu-ui/vuu-protocol-types\";\nimport { dispatchCustomEvent } from \"@vuu-ui/vuu-utils\";\nimport {\n FocusEventHandler,\n FormEventHandler,\n KeyboardEvent,\n useCallback,\n useRef,\n useState,\n} from \"react\";\n\nexport const WarnCommit = (): Promise<true> => {\n console.warn(\n \"onCommit handler has not been provided to InputCell cell renderer\",\n );\n return Promise.resolve(true);\n};\n\nexport interface EditableTextHookProps<\n T extends VuuRowDataItemType = VuuRowDataItemType,\n> {\n clientSideEditValidationCheck?: ClientSideValidationChecker;\n initialValue?: T;\n onCommit: DataItemCommitHandler<T>;\n type?: \"string\" | \"number\" | \"boolean\";\n}\n\nexport const useEditableText = <T extends string | number = string>({\n clientSideEditValidationCheck,\n initialValue,\n onCommit,\n type,\n}: EditableTextHookProps<T>) => {\n const [message, setMessage] = useState<string | undefined>();\n const [value, setValue] = useState<T | undefined>(initialValue);\n const initialValueRef = useRef<T | undefined>(initialValue);\n const isDirtyRef = useRef(false);\n const hasCommittedRef = useRef(false);\n\n useLayoutEffectSkipFirst(() => {\n //TODO this isn't right, review the state we're using\n setValue(initialValue);\n }, [initialValue]);\n\n const commit = useCallback(\n (target: HTMLElement) => {\n if (isDirtyRef.current) {\n hasCommittedRef.current = true;\n const warningMessage = clientSideEditValidationCheck?.(value);\n if (warningMessage) {\n setMessage(warningMessage);\n } else {\n setMessage(undefined);\n console.log(`commit value ${value}`);\n onCommit(value as T).then((response) => {\n if (response === true) {\n isDirtyRef.current = false;\n dispatchCustomEvent(target, \"vuu-commit\");\n } else {\n setMessage(response);\n }\n });\n }\n } else {\n // why, if not dirty ?\n dispatchCustomEvent(target, \"vuu-commit\");\n hasCommittedRef.current = false;\n }\n },\n [clientSideEditValidationCheck, onCommit, value],\n );\n\n const handleKeyDown = useCallback(\n (evt: KeyboardEvent<HTMLElement>) => {\n if (evt.key === \"Enter\") {\n commit(evt.target as HTMLElement);\n } else if (\n evt.key === \"ArrowRight\" ||\n evt.key === \"ArrowLeft\" ||\n evt.key === \"ArrowUp\" ||\n evt.key === \"ArrowDown\"\n ) {\n evt.stopPropagation();\n } else if (evt.key === \"Escape\") {\n if (isDirtyRef.current) {\n isDirtyRef.current = false;\n setMessage(undefined);\n setValue(initialValueRef.current);\n }\n }\n },\n [commit],\n );\n\n const handleBlur = useCallback<FocusEventHandler<HTMLElement>>(\n (evt) => {\n if (isDirtyRef.current) {\n commit(evt.target as HTMLElement);\n }\n },\n [commit],\n );\n\n const handleChange = useCallback<FormEventHandler>(\n (evt) => {\n let typedValue: VuuRowDataItemType = (evt.target as HTMLInputElement)\n .value;\n if (type === \"number\" && !isNaN(parseFloat(typedValue))) {\n typedValue = parseFloat(typedValue);\n }\n isDirtyRef.current = value !== initialValueRef.current;\n setValue(typedValue as T);\n if (hasCommittedRef.current && value !== undefined) {\n const warningMessage = clientSideEditValidationCheck?.(value);\n if (warningMessage !== message && warningMessage !== false) {\n setMessage(warningMessage);\n }\n }\n },\n [clientSideEditValidationCheck, message, type, value],\n );\n\n return {\n inputProps: {\n onBlur: handleBlur,\n onKeyDown: handleKeyDown,\n },\n onChange: handleChange,\n value: value ?? \"\",\n warningMessage: message,\n };\n};\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"useEditableText.js","sources":["../../src/editable/useEditableText.ts"],"sourcesContent":["import { DataValueValidationChecker } from \"@vuu-ui/vuu-data-types\";\nimport { DataItemCommitHandler } from \"@vuu-ui/vuu-table-types\";\nimport { useLayoutEffectSkipFirst } from \"@vuu-ui/vuu-utils\";\nimport { VuuRowDataItemType } from \"@vuu-ui/vuu-protocol-types\";\nimport { dispatchCustomEvent } from \"@vuu-ui/vuu-utils\";\nimport {\n FocusEventHandler,\n FormEventHandler,\n KeyboardEvent,\n useCallback,\n useRef,\n useState,\n} from \"react\";\n\nexport const WarnCommit = (): Promise<true> => {\n console.warn(\n \"onCommit handler has not been provided to InputCell cell renderer\",\n );\n return Promise.resolve(true);\n};\n\nexport interface EditableTextHookProps<\n T extends VuuRowDataItemType = VuuRowDataItemType,\n> {\n clientSideEditValidationCheck?: DataValueValidationChecker;\n initialValue?: T;\n onCommit: DataItemCommitHandler<T>;\n type?: \"string\" | \"number\" | \"boolean\";\n}\n\nexport const useEditableText = <T extends string | number = string>({\n clientSideEditValidationCheck,\n initialValue,\n onCommit,\n type,\n}: EditableTextHookProps<T>) => {\n const [message, setMessage] = useState<string | undefined>();\n const [value, setValue] = useState<T | undefined>(initialValue);\n const initialValueRef = useRef<T | undefined>(initialValue);\n const isDirtyRef = useRef(false);\n const hasCommittedRef = useRef(false);\n\n useLayoutEffectSkipFirst(() => {\n //TODO this isn't right, review the state we're using\n setValue(initialValue);\n }, [initialValue]);\n\n const commit = useCallback(\n (target: HTMLElement) => {\n if (isDirtyRef.current) {\n hasCommittedRef.current = true;\n const result = clientSideEditValidationCheck?.(value);\n if (result?.ok === false) {\n setMessage(result?.messages?.join(\",\"));\n } else {\n setMessage(undefined);\n console.log(`commit value ${value}`);\n onCommit(value as T).then((response) => {\n if (response === true) {\n isDirtyRef.current = false;\n dispatchCustomEvent(target, \"vuu-commit\");\n } else {\n setMessage(response);\n }\n });\n }\n } else {\n // why, if not dirty ?\n dispatchCustomEvent(target, \"vuu-commit\");\n hasCommittedRef.current = false;\n }\n },\n [clientSideEditValidationCheck, onCommit, value],\n );\n\n const handleKeyDown = useCallback(\n (evt: KeyboardEvent<HTMLElement>) => {\n if (evt.key === \"Enter\") {\n commit(evt.target as HTMLElement);\n } else if (\n evt.key === \"ArrowRight\" ||\n evt.key === \"ArrowLeft\" ||\n evt.key === \"ArrowUp\" ||\n evt.key === \"ArrowDown\"\n ) {\n evt.stopPropagation();\n } else if (evt.key === \"Escape\") {\n if (isDirtyRef.current) {\n isDirtyRef.current = false;\n setMessage(undefined);\n setValue(initialValueRef.current);\n }\n }\n },\n [commit],\n );\n\n const handleBlur = useCallback<FocusEventHandler<HTMLElement>>(\n (evt) => {\n if (isDirtyRef.current) {\n commit(evt.target as HTMLElement);\n }\n },\n [commit],\n );\n\n const handleChange = useCallback<FormEventHandler>(\n (evt) => {\n let typedValue: VuuRowDataItemType = (evt.target as HTMLInputElement)\n .value;\n if (type === \"number\" && !isNaN(parseFloat(typedValue))) {\n typedValue = parseFloat(typedValue);\n }\n isDirtyRef.current = value !== initialValueRef.current;\n setValue(typedValue as T);\n if (hasCommittedRef.current && value !== undefined) {\n const result = clientSideEditValidationCheck?.(value);\n if (result?.ok === false) {\n setMessage(result.messages?.join(\",\"));\n }\n }\n },\n [clientSideEditValidationCheck, type, value],\n );\n\n return {\n inputProps: {\n onBlur: handleBlur,\n onKeyDown: handleKeyDown,\n },\n onChange: handleChange,\n value: value ?? \"\",\n warningMessage: message,\n };\n};\n"],"names":[],"mappings":"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"}
@@ -10,7 +10,7 @@ const classBase = "vuuExpandoInput";
10
10
  const noop = () => void 0;
11
11
  const ExpandoInput = forwardRef(function ExpandoInput2({
12
12
  className: classNameProp,
13
- TooltipProps,
13
+ errorMessage,
14
14
  value,
15
15
  inputProps,
16
16
  onCommit = noop,
@@ -26,14 +26,14 @@ const ExpandoInput = forwardRef(function ExpandoInput2({
26
26
  "div",
27
27
  {
28
28
  className: cx(classBase, classNameProp, {
29
- [`${classBase}-error`]: TooltipProps
29
+ [`${classBase}-error`]: errorMessage
30
30
  }),
31
31
  "data-text": value,
32
32
  children: /* @__PURE__ */ jsx(
33
33
  VuuInput,
34
34
  {
35
35
  ...props,
36
- TooltipProps,
36
+ errorMessage,
37
37
  inputProps: { ...inputProps, className: `${classBase}-input` },
38
38
  onCommit,
39
39
  ref: forwardedRef,
@@ -1 +1 @@
1
- {"version":3,"file":"ExpandoInput.js","sources":["../../src/expando-input/ExpandoInput.tsx"],"sourcesContent":["import cx from \"clsx\";\nimport { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\nimport { ForwardedRef, forwardRef } from \"react\";\nimport { VuuInput, VuuInputProps } from \"../vuu-input\";\n\nimport expandoInputCss from \"./ExpandoInput.css\";\n\nconst classBase = \"vuuExpandoInput\";\n\nconst noop = () => undefined;\n\nexport interface ExpandoInputProps extends Omit<VuuInputProps, \"onCommit\"> {\n onCommit?: VuuInputProps[\"onCommit\"];\n}\n\nexport const ExpandoInput = forwardRef(function ExpandoInput(\n {\n className: classNameProp,\n TooltipProps,\n value,\n inputProps,\n onCommit = noop,\n ...props\n }: ExpandoInputProps,\n forwardedRef: ForwardedRef<HTMLDivElement>\n) {\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"vuu-expando-input\",\n css: expandoInputCss,\n window: targetWindow,\n });\n\n return (\n <div\n className={cx(classBase, classNameProp, {\n [`${classBase}-error`]: TooltipProps,\n })}\n data-text={value}\n >\n <VuuInput\n {...props}\n TooltipProps={TooltipProps}\n inputProps={{ ...inputProps, className: `${classBase}-input` }}\n onCommit={onCommit}\n ref={forwardedRef}\n style={{ padding: 0 }}\n textAlign=\"left\"\n value={value}\n variant=\"secondary\"\n />\n </div>\n );\n});\n"],"names":["ExpandoInput"],"mappings":";;;;;;;;AAQA,MAAM,SAAY,GAAA,iBAAA,CAAA;AAElB,MAAM,OAAO,MAAM,KAAA,CAAA,CAAA;AAMN,MAAA,YAAA,GAAe,UAAW,CAAA,SAASA,aAC9C,CAAA;AAAA,EACE,SAAW,EAAA,aAAA;AAAA,EACX,YAAA;AAAA,EACA,KAAA;AAAA,EACA,UAAA;AAAA,EACA,QAAW,GAAA,IAAA;AAAA,EACX,GAAG,KAAA;AACL,CAAA,EACA,YACA,EAAA;AACA,EAAA,MAAM,eAAe,SAAU,EAAA,CAAA;AAC/B,EAAyB,wBAAA,CAAA;AAAA,IACvB,MAAQ,EAAA,mBAAA;AAAA,IACR,GAAK,EAAA,eAAA;AAAA,IACL,MAAQ,EAAA,YAAA;AAAA,GACT,CAAA,CAAA;AAED,EACE,uBAAA,GAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,SAAA,EAAW,EAAG,CAAA,SAAA,EAAW,aAAe,EAAA;AAAA,QACtC,CAAC,CAAA,EAAG,SAAS,CAAA,MAAA,CAAQ,GAAG,YAAA;AAAA,OACzB,CAAA;AAAA,MACD,WAAW,EAAA,KAAA;AAAA,MAEX,QAAA,kBAAA,GAAA;AAAA,QAAC,QAAA;AAAA,QAAA;AAAA,UACE,GAAG,KAAA;AAAA,UACJ,YAAA;AAAA,UACA,YAAY,EAAE,GAAG,YAAY,SAAW,EAAA,CAAA,EAAG,SAAS,CAAS,MAAA,CAAA,EAAA;AAAA,UAC7D,QAAA;AAAA,UACA,GAAK,EAAA,YAAA;AAAA,UACL,KAAA,EAAO,EAAE,OAAA,EAAS,CAAE,EAAA;AAAA,UACpB,SAAU,EAAA,MAAA;AAAA,UACV,KAAA;AAAA,UACA,OAAQ,EAAA,WAAA;AAAA,SAAA;AAAA,OACV;AAAA,KAAA;AAAA,GACF,CAAA;AAEJ,CAAC;;;;"}
1
+ {"version":3,"file":"ExpandoInput.js","sources":["../../src/expando-input/ExpandoInput.tsx"],"sourcesContent":["import cx from \"clsx\";\nimport { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\nimport { ForwardedRef, forwardRef } from \"react\";\nimport { VuuInput, VuuInputProps } from \"../vuu-input\";\n\nimport expandoInputCss from \"./ExpandoInput.css\";\n\nconst classBase = \"vuuExpandoInput\";\n\nconst noop = () => undefined;\n\nexport interface ExpandoInputProps extends Omit<VuuInputProps, \"onCommit\"> {\n onCommit?: VuuInputProps[\"onCommit\"];\n}\n\nexport const ExpandoInput = forwardRef(function ExpandoInput(\n {\n className: classNameProp,\n errorMessage,\n value,\n inputProps,\n onCommit = noop,\n ...props\n }: ExpandoInputProps,\n forwardedRef: ForwardedRef<HTMLDivElement>,\n) {\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"vuu-expando-input\",\n css: expandoInputCss,\n window: targetWindow,\n });\n\n return (\n <div\n className={cx(classBase, classNameProp, {\n [`${classBase}-error`]: errorMessage,\n })}\n data-text={value}\n >\n <VuuInput\n {...props}\n errorMessage={errorMessage}\n inputProps={{ ...inputProps, className: `${classBase}-input` }}\n onCommit={onCommit}\n ref={forwardedRef}\n style={{ padding: 0 }}\n textAlign=\"left\"\n value={value}\n variant=\"secondary\"\n />\n </div>\n );\n});\n"],"names":["ExpandoInput"],"mappings":";;;;;;;;AAQA,MAAM,SAAY,GAAA,iBAAA,CAAA;AAElB,MAAM,OAAO,MAAM,KAAA,CAAA,CAAA;AAMN,MAAA,YAAA,GAAe,UAAW,CAAA,SAASA,aAC9C,CAAA;AAAA,EACE,SAAW,EAAA,aAAA;AAAA,EACX,YAAA;AAAA,EACA,KAAA;AAAA,EACA,UAAA;AAAA,EACA,QAAW,GAAA,IAAA;AAAA,EACX,GAAG,KAAA;AACL,CAAA,EACA,YACA,EAAA;AACA,EAAA,MAAM,eAAe,SAAU,EAAA,CAAA;AAC/B,EAAyB,wBAAA,CAAA;AAAA,IACvB,MAAQ,EAAA,mBAAA;AAAA,IACR,GAAK,EAAA,eAAA;AAAA,IACL,MAAQ,EAAA,YAAA;AAAA,GACT,CAAA,CAAA;AAED,EACE,uBAAA,GAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,SAAA,EAAW,EAAG,CAAA,SAAA,EAAW,aAAe,EAAA;AAAA,QACtC,CAAC,CAAA,EAAG,SAAS,CAAA,MAAA,CAAQ,GAAG,YAAA;AAAA,OACzB,CAAA;AAAA,MACD,WAAW,EAAA,KAAA;AAAA,MAEX,QAAA,kBAAA,GAAA;AAAA,QAAC,QAAA;AAAA,QAAA;AAAA,UACE,GAAG,KAAA;AAAA,UACJ,YAAA;AAAA,UACA,YAAY,EAAE,GAAG,YAAY,SAAW,EAAA,CAAA,EAAG,SAAS,CAAS,MAAA,CAAA,EAAA;AAAA,UAC7D,QAAA;AAAA,UACA,GAAK,EAAA,YAAA;AAAA,UACL,KAAA,EAAO,EAAE,OAAA,EAAS,CAAE,EAAA;AAAA,UACpB,SAAU,EAAA,MAAA;AAAA,UACV,KAAA;AAAA,UACA,OAAQ,EAAA,WAAA;AAAA,SAAA;AAAA,OACV;AAAA,KAAA;AAAA,GACF,CAAA;AAEJ,CAAC;;;;"}
package/esm/index.js CHANGED
@@ -23,7 +23,6 @@ export { useGlobalDragDrop } from './drag-drop/useGlobalDragDrop.js';
23
23
  export { DatePopup } from './date-popup/DatePopup.js';
24
24
  export { DropdownBase } from './dropdown-base/DropdownBase.js';
25
25
  export { useDropdownBase } from './dropdown-base/useDropdownBase.js';
26
- export { buildValidationChecker } from './editable/editable-utils.js';
27
26
  export { WarnCommit, useEditableText } from './editable/useEditableText.js';
28
27
  export { EditableLabel, NullEditAPI } from './editable-label/EditableLabel.js';
29
28
  export { ExpandoInput } from './expando-input/ExpandoInput.js';
package/esm/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -1,24 +1,20 @@
1
- import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
2
- import { useTooltip, Tooltip } from '@vuu-ui/vuu-popups';
1
+ import { jsx, Fragment } from 'react/jsx-runtime';
3
2
  import { useId, isValidNumber } from '@vuu-ui/vuu-utils';
4
- import { Input } from '@salt-ds/core';
5
- import cx from 'clsx';
3
+ import { Input, Tooltip } from '@salt-ds/core';
6
4
  import { useComponentCssInjection } from '@salt-ds/styles';
7
5
  import { useWindow } from '@salt-ds/window';
6
+ import cx from 'clsx';
8
7
  import { forwardRef, useCallback } from 'react';
9
8
  import vuuInputCss from './VuuInput.css.js';
10
9
 
11
10
  const classBase = "vuuInput";
12
- const constantInputProps = {
13
- autoComplete: "off"
14
- };
15
11
  const VuuInput = forwardRef(function VuuInput2({
16
12
  className,
13
+ errorMessage,
17
14
  id: idProp,
18
15
  onCommit,
19
16
  onKeyDown,
20
17
  type,
21
- TooltipProps,
22
18
  ...props
23
19
  }, forwardedRef) {
24
20
  const targetWindow = useWindow();
@@ -28,11 +24,6 @@ const VuuInput = forwardRef(function VuuInput2({
28
24
  window: targetWindow
29
25
  });
30
26
  const id = useId(idProp);
31
- const { anchorProps, tooltipProps } = useTooltip({
32
- id,
33
- placement: TooltipProps?.placement,
34
- tooltipContent: TooltipProps?.tooltipContent
35
- });
36
27
  const commitValue = useCallback(
37
28
  (evt, value) => {
38
29
  if (type === "number") {
@@ -69,35 +60,25 @@ const VuuInput = forwardRef(function VuuInput2({
69
60
  },
70
61
  [commitValue]
71
62
  );
72
- const endAdornment = TooltipProps?.tooltipContent ? /* @__PURE__ */ jsx(
73
- "span",
63
+ const endAdornment = errorMessage ? /* @__PURE__ */ jsx(Tooltip, { content: errorMessage, status: "error", children: /* @__PURE__ */ jsx("span", { className: `${classBase}-errorIcon`, "data-icon": "error" }) }) : void 0;
64
+ return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx(
65
+ Input,
74
66
  {
75
- ...anchorProps,
76
- className: `${classBase}-errorIcon`,
77
- "data-icon": "error"
67
+ ...props,
68
+ endAdornment,
69
+ id,
70
+ inputProps: {
71
+ autoComplete: "off",
72
+ ...props.inputProps
73
+ },
74
+ className: cx(classBase, className, {
75
+ [`${classBase}-error`]: errorMessage
76
+ }),
77
+ onBlur: handleBlur,
78
+ ref: forwardedRef,
79
+ onKeyDown: handleKeyDown
78
80
  }
79
- ) : void 0;
80
- return /* @__PURE__ */ jsxs(Fragment, { children: [
81
- /* @__PURE__ */ jsx(
82
- Input,
83
- {
84
- ...props,
85
- endAdornment,
86
- id,
87
- inputProps: {
88
- ...constantInputProps,
89
- ...props.inputProps
90
- },
91
- className: cx(classBase, className, {
92
- [`${classBase}-error`]: TooltipProps?.tooltipContent
93
- }),
94
- onBlur: handleBlur,
95
- ref: forwardedRef,
96
- onKeyDown: handleKeyDown
97
- }
98
- ),
99
- tooltipProps ? /* @__PURE__ */ jsx(Tooltip, { ...tooltipProps, status: "error" }) : null
100
- ] });
81
+ ) });
101
82
  });
102
83
 
103
84
  export { VuuInput };
@@ -1 +1 @@
1
- {"version":3,"file":"VuuInput.js","sources":["../../src/vuu-input/VuuInput.tsx"],"sourcesContent":["import { Tooltip, TooltipHookProps, useTooltip } from \"@vuu-ui/vuu-popups\";\nimport { VuuRowDataItemType } from \"@vuu-ui/vuu-protocol-types\";\nimport { CommitHandler, isValidNumber, useId } from \"@vuu-ui/vuu-utils\";\nimport { Input, InputProps } from \"@salt-ds/core\";\nimport cx from \"clsx\";\nimport { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\nimport {\n FocusEventHandler,\n ForwardedRef,\n forwardRef,\n KeyboardEventHandler,\n ReactElement,\n useCallback,\n} from \"react\";\n\nimport vuuInputCss from \"./VuuInput.css\";\n\nconst classBase = \"vuuInput\";\n\nconst constantInputProps = {\n autoComplete: \"off\",\n};\n\nexport interface VuuInputProps<T extends VuuRowDataItemType = string>\n extends InputProps {\n onCommit: CommitHandler<HTMLInputElement, T | undefined>;\n type?: T;\n TooltipProps?: Pick<TooltipHookProps, \"placement\" | \"tooltipContent\">;\n}\n\n/**\n * A variant of Salt Input that provides a commit callback prop,\n * TODO along with cancel behaviour ?\n */\nexport const VuuInput = forwardRef(function VuuInput<\n T extends VuuRowDataItemType = string,\n>(\n {\n className,\n id: idProp,\n onCommit,\n onKeyDown,\n type,\n TooltipProps,\n ...props\n }: VuuInputProps<T>,\n forwardedRef: ForwardedRef<HTMLDivElement>,\n) {\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"vuu-input\",\n css: vuuInputCss,\n window: targetWindow,\n });\n\n const id = useId(idProp);\n const { anchorProps, tooltipProps } = useTooltip({\n id,\n placement: TooltipProps?.placement,\n tooltipContent: TooltipProps?.tooltipContent,\n });\n\n const commitValue = useCallback<CommitHandler>(\n (evt, value) => {\n if (type === \"number\") {\n const numericValue = parseFloat(value);\n if (isValidNumber(numericValue)) {\n onCommit(evt, numericValue as T);\n } else {\n //TODO add validation logic\n throw Error(\"Invalid value\");\n }\n } else if (type === \"boolean\") {\n onCommit(evt, Boolean(value) as T);\n } else {\n onCommit(evt, value as T);\n }\n },\n [onCommit, type],\n );\n\n const handleKeyDown = useCallback<KeyboardEventHandler<HTMLInputElement>>(\n (evt) => {\n if (evt.key === \"Enter\") {\n evt.preventDefault();\n evt.stopPropagation();\n const { value } = evt.target as HTMLInputElement;\n commitValue(evt, value);\n }\n onKeyDown?.(evt);\n },\n [commitValue, onKeyDown],\n );\n\n const handleBlur = useCallback<FocusEventHandler<HTMLInputElement>>(\n (evt) => {\n const { value } = evt.target as HTMLInputElement;\n commitValue(evt, value);\n },\n [commitValue],\n );\n\n const endAdornment = TooltipProps?.tooltipContent ? (\n <span\n {...anchorProps}\n className={`${classBase}-errorIcon`}\n data-icon=\"error\"\n />\n ) : undefined;\n\n return (\n <>\n <Input\n {...props}\n endAdornment={endAdornment}\n id={id}\n inputProps={{\n ...constantInputProps,\n ...props.inputProps,\n }}\n className={cx(classBase, className, {\n [`${classBase}-error`]: TooltipProps?.tooltipContent,\n })}\n onBlur={handleBlur}\n ref={forwardedRef}\n onKeyDown={handleKeyDown}\n />\n {tooltipProps ? <Tooltip {...tooltipProps} status=\"error\" /> : null}\n </>\n );\n}) as <T extends VuuRowDataItemType = string>(\n props: VuuInputProps<T> & {\n ref?: ForwardedRef<HTMLDivElement>;\n },\n) => ReactElement<VuuInputProps<T>>;\n"],"names":["VuuInput"],"mappings":"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"}
1
+ {"version":3,"file":"VuuInput.js","sources":["../../src/vuu-input/VuuInput.tsx"],"sourcesContent":["import { VuuRowDataItemType } from \"@vuu-ui/vuu-protocol-types\";\nimport { CommitHandler, isValidNumber, useId } from \"@vuu-ui/vuu-utils\";\nimport { Input, InputProps, Tooltip } from \"@salt-ds/core\";\nimport { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\nimport cx from \"clsx\";\nimport {\n FocusEventHandler,\n ForwardedRef,\n KeyboardEventHandler,\n ReactElement,\n ReactNode,\n forwardRef,\n useCallback,\n} from \"react\";\n\nimport vuuInputCss from \"./VuuInput.css\";\n\nconst classBase = \"vuuInput\";\n\nexport interface VuuInputProps<T extends VuuRowDataItemType = string>\n extends Omit<InputProps, \"validationStatus\"> {\n errorMessage?: ReactNode;\n onCommit: CommitHandler<HTMLInputElement, T | undefined>;\n type?: T;\n}\n\n/**\n * A variant of Salt Input that provides a commit callback prop,\n * TODO along with cancel behaviour ?\n */\nexport const VuuInput = forwardRef(function VuuInput<\n T extends VuuRowDataItemType = string,\n>(\n {\n className,\n errorMessage,\n id: idProp,\n onCommit,\n onKeyDown,\n type,\n ...props\n }: VuuInputProps<T>,\n forwardedRef: ForwardedRef<HTMLDivElement>,\n) {\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"vuu-input\",\n css: vuuInputCss,\n window: targetWindow,\n });\n\n const id = useId(idProp);\n\n const commitValue = useCallback<CommitHandler>(\n (evt, value) => {\n if (type === \"number\") {\n const numericValue = parseFloat(value);\n if (isValidNumber(numericValue)) {\n onCommit(evt, numericValue as T);\n } else {\n //TODO add validation logic\n throw Error(\"Invalid value\");\n }\n } else if (type === \"boolean\") {\n onCommit(evt, Boolean(value) as T);\n } else {\n onCommit(evt, value as T);\n }\n },\n [onCommit, type],\n );\n\n const handleKeyDown = useCallback<KeyboardEventHandler<HTMLInputElement>>(\n (evt) => {\n if (evt.key === \"Enter\") {\n evt.preventDefault();\n evt.stopPropagation();\n const { value } = evt.target as HTMLInputElement;\n commitValue(evt, value);\n }\n onKeyDown?.(evt);\n },\n [commitValue, onKeyDown],\n );\n\n const handleBlur = useCallback<FocusEventHandler<HTMLInputElement>>(\n (evt) => {\n const { value } = evt.target as HTMLInputElement;\n commitValue(evt, value);\n },\n [commitValue],\n );\n\n const endAdornment = errorMessage ? (\n <Tooltip content={errorMessage} status=\"error\">\n <span className={`${classBase}-errorIcon`} data-icon=\"error\" />\n </Tooltip>\n ) : undefined;\n\n return (\n <>\n <Input\n {...props}\n endAdornment={endAdornment}\n id={id}\n inputProps={{\n autoComplete: \"off\",\n ...props.inputProps,\n }}\n className={cx(classBase, className, {\n [`${classBase}-error`]: errorMessage,\n })}\n onBlur={handleBlur}\n ref={forwardedRef}\n onKeyDown={handleKeyDown}\n />\n </>\n );\n}) as <T extends VuuRowDataItemType = string>(\n props: VuuInputProps<T> & {\n ref?: ForwardedRef<HTMLDivElement>;\n },\n) => ReactElement<VuuInputProps<T>>;\n"],"names":["VuuInput"],"mappings":"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"}
package/package.json CHANGED
@@ -1,17 +1,17 @@
1
1
  {
2
- "version": "0.8.91",
2
+ "version": "0.8.92",
3
3
  "description": "VUU UI Controls",
4
4
  "author": "heswell",
5
5
  "license": "Apache-2.0",
6
6
  "devDependencies": {
7
- "@vuu-ui/vuu-data-types": "0.8.91",
8
- "@vuu-ui/vuu-table-types": "0.8.91"
7
+ "@vuu-ui/vuu-data-types": "0.8.92",
8
+ "@vuu-ui/vuu-table-types": "0.8.92"
9
9
  },
10
10
  "dependencies": {
11
- "@vuu-ui/vuu-layout": "0.8.91",
12
- "@vuu-ui/vuu-popups": "0.8.91",
13
- "@vuu-ui/vuu-table": "0.8.91",
14
- "@vuu-ui/vuu-utils": "0.8.91",
11
+ "@vuu-ui/vuu-layout": "0.8.92",
12
+ "@vuu-ui/vuu-popups": "0.8.92",
13
+ "@vuu-ui/vuu-table": "0.8.92",
14
+ "@vuu-ui/vuu-utils": "0.8.92",
15
15
  "@floating-ui/react": "^0.26.5",
16
16
  "@salt-ds/core": "1.34.0",
17
17
  "@salt-ds/icons": "1.12.1",
@@ -1,2 +1 @@
1
- export * from "./editable-utils";
2
1
  export * from "./useEditableText";
@@ -1,9 +1,10 @@
1
- import { ClientSideValidationChecker, DataItemCommitHandler } from "@vuu-ui/vuu-table-types";
1
+ import { DataValueValidationChecker } from "@vuu-ui/vuu-data-types";
2
+ import { DataItemCommitHandler } from "@vuu-ui/vuu-table-types";
2
3
  import { VuuRowDataItemType } from "@vuu-ui/vuu-protocol-types";
3
4
  import { FocusEventHandler, FormEventHandler, KeyboardEvent } from "react";
4
5
  export declare const WarnCommit: () => Promise<true>;
5
6
  export interface EditableTextHookProps<T extends VuuRowDataItemType = VuuRowDataItemType> {
6
- clientSideEditValidationCheck?: ClientSideValidationChecker;
7
+ clientSideEditValidationCheck?: DataValueValidationChecker;
7
8
  initialValue?: T;
8
9
  onCommit: DataItemCommitHandler<T>;
9
10
  type?: "string" | "number" | "boolean";
@@ -1,12 +1,11 @@
1
- import { TooltipHookProps } from "@vuu-ui/vuu-popups";
2
1
  import { VuuRowDataItemType } from "@vuu-ui/vuu-protocol-types";
3
2
  import { CommitHandler } from "@vuu-ui/vuu-utils";
4
3
  import { InputProps } from "@salt-ds/core";
5
- import { ForwardedRef, ReactElement } from "react";
6
- export interface VuuInputProps<T extends VuuRowDataItemType = string> extends InputProps {
4
+ import { ForwardedRef, ReactElement, ReactNode } from "react";
5
+ export interface VuuInputProps<T extends VuuRowDataItemType = string> extends Omit<InputProps, "validationStatus"> {
6
+ errorMessage?: ReactNode;
7
7
  onCommit: CommitHandler<HTMLInputElement, T | undefined>;
8
8
  type?: T;
9
- TooltipProps?: Pick<TooltipHookProps, "placement" | "tooltipContent">;
10
9
  }
11
10
  /**
12
11
  * A variant of Salt Input that provides a commit callback prop,
@@ -1,37 +0,0 @@
1
- 'use strict';
2
-
3
- var vuuUtils = require('@vuu-ui/vuu-utils');
4
-
5
- const buildValidationChecker = (rules) => (value) => applyRules(rules, value);
6
- function applyRules(rules, value) {
7
- let result = void 0;
8
- for (const rule of rules) {
9
- const editRuleValidator = vuuUtils.getEditRuleValidator(rule.name);
10
- if (editRuleValidator) {
11
- const ruleResult = editRuleValidator(rule, value);
12
- switch (ruleResult) {
13
- case true:
14
- break;
15
- case false:
16
- if (result === void 0) {
17
- result = false;
18
- }
19
- break;
20
- default:
21
- if (result === void 0 || result === false) {
22
- result = ruleResult;
23
- } else {
24
- result += `::${ruleResult}`;
25
- }
26
- }
27
- } else {
28
- throw Error(
29
- `editable-utils applyRules, no validator registered for rule '${rule.name}'`
30
- );
31
- }
32
- }
33
- return result;
34
- }
35
-
36
- exports.buildValidationChecker = buildValidationChecker;
37
- //# sourceMappingURL=editable-utils.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"editable-utils.js","sources":["../../src/editable/editable-utils.ts"],"sourcesContent":["import {\n ClientSideValidationChecker,\n EditValidationRule,\n} from \"@vuu-ui/vuu-table-types\";\nimport { VuuRowDataItemType } from \"@vuu-ui/vuu-protocol-types\";\nimport { getEditRuleValidator } from \"@vuu-ui/vuu-utils\";\n\nexport const buildValidationChecker =\n (rules: EditValidationRule[]): ClientSideValidationChecker =>\n (value?: VuuRowDataItemType) =>\n applyRules(rules, value);\n\nfunction applyRules(\n rules: EditValidationRule[],\n value?: VuuRowDataItemType,\n): string | false | undefined {\n let result: false | string | undefined = undefined;\n for (const rule of rules) {\n const editRuleValidator = getEditRuleValidator(rule.name);\n if (editRuleValidator) {\n const ruleResult = editRuleValidator(rule, value);\n switch (ruleResult) {\n case true:\n break;\n case false:\n if (result === undefined) {\n result = false;\n }\n break;\n default:\n if (result === undefined || result === false) {\n result = ruleResult;\n } else {\n result += `::${ruleResult}`;\n }\n }\n } else {\n throw Error(\n `editable-utils applyRules, no validator registered for rule '${rule.name}'`,\n );\n }\n }\n\n return result;\n}\n"],"names":["getEditRuleValidator"],"mappings":";;;;AAOO,MAAM,yBACX,CAAC,KAAA,KACD,CAAC,KACC,KAAA,UAAA,CAAW,OAAO,KAAK,EAAA;AAE3B,SAAS,UAAA,CACP,OACA,KAC4B,EAAA;AAC5B,EAAA,IAAI,MAAqC,GAAA,KAAA,CAAA,CAAA;AACzC,EAAA,KAAA,MAAW,QAAQ,KAAO,EAAA;AACxB,IAAM,MAAA,iBAAA,GAAoBA,6BAAqB,CAAA,IAAA,CAAK,IAAI,CAAA,CAAA;AACxD,IAAA,IAAI,iBAAmB,EAAA;AACrB,MAAM,MAAA,UAAA,GAAa,iBAAkB,CAAA,IAAA,EAAM,KAAK,CAAA,CAAA;AAChD,MAAA,QAAQ,UAAY;AAAA,QAClB,KAAK,IAAA;AACH,UAAA,MAAA;AAAA,QACF,KAAK,KAAA;AACH,UAAA,IAAI,WAAW,KAAW,CAAA,EAAA;AACxB,YAAS,MAAA,GAAA,KAAA,CAAA;AAAA,WACX;AACA,UAAA,MAAA;AAAA,QACF;AACE,UAAI,IAAA,MAAA,KAAW,KAAa,CAAA,IAAA,MAAA,KAAW,KAAO,EAAA;AAC5C,YAAS,MAAA,GAAA,UAAA,CAAA;AAAA,WACJ,MAAA;AACL,YAAA,MAAA,IAAU,KAAK,UAAU,CAAA,CAAA,CAAA;AAAA,WAC3B;AAAA,OACJ;AAAA,KACK,MAAA;AACL,MAAM,MAAA,KAAA;AAAA,QACJ,CAAA,6DAAA,EAAgE,KAAK,IAAI,CAAA,CAAA,CAAA;AAAA,OAC3E,CAAA;AAAA,KACF;AAAA,GACF;AAEA,EAAO,OAAA,MAAA,CAAA;AACT;;;;"}
@@ -1,35 +0,0 @@
1
- import { getEditRuleValidator } from '@vuu-ui/vuu-utils';
2
-
3
- const buildValidationChecker = (rules) => (value) => applyRules(rules, value);
4
- function applyRules(rules, value) {
5
- let result = void 0;
6
- for (const rule of rules) {
7
- const editRuleValidator = getEditRuleValidator(rule.name);
8
- if (editRuleValidator) {
9
- const ruleResult = editRuleValidator(rule, value);
10
- switch (ruleResult) {
11
- case true:
12
- break;
13
- case false:
14
- if (result === void 0) {
15
- result = false;
16
- }
17
- break;
18
- default:
19
- if (result === void 0 || result === false) {
20
- result = ruleResult;
21
- } else {
22
- result += `::${ruleResult}`;
23
- }
24
- }
25
- } else {
26
- throw Error(
27
- `editable-utils applyRules, no validator registered for rule '${rule.name}'`
28
- );
29
- }
30
- }
31
- return result;
32
- }
33
-
34
- export { buildValidationChecker };
35
- //# sourceMappingURL=editable-utils.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"editable-utils.js","sources":["../../src/editable/editable-utils.ts"],"sourcesContent":["import {\n ClientSideValidationChecker,\n EditValidationRule,\n} from \"@vuu-ui/vuu-table-types\";\nimport { VuuRowDataItemType } from \"@vuu-ui/vuu-protocol-types\";\nimport { getEditRuleValidator } from \"@vuu-ui/vuu-utils\";\n\nexport const buildValidationChecker =\n (rules: EditValidationRule[]): ClientSideValidationChecker =>\n (value?: VuuRowDataItemType) =>\n applyRules(rules, value);\n\nfunction applyRules(\n rules: EditValidationRule[],\n value?: VuuRowDataItemType,\n): string | false | undefined {\n let result: false | string | undefined = undefined;\n for (const rule of rules) {\n const editRuleValidator = getEditRuleValidator(rule.name);\n if (editRuleValidator) {\n const ruleResult = editRuleValidator(rule, value);\n switch (ruleResult) {\n case true:\n break;\n case false:\n if (result === undefined) {\n result = false;\n }\n break;\n default:\n if (result === undefined || result === false) {\n result = ruleResult;\n } else {\n result += `::${ruleResult}`;\n }\n }\n } else {\n throw Error(\n `editable-utils applyRules, no validator registered for rule '${rule.name}'`,\n );\n }\n }\n\n return result;\n}\n"],"names":[],"mappings":";;AAOO,MAAM,yBACX,CAAC,KAAA,KACD,CAAC,KACC,KAAA,UAAA,CAAW,OAAO,KAAK,EAAA;AAE3B,SAAS,UAAA,CACP,OACA,KAC4B,EAAA;AAC5B,EAAA,IAAI,MAAqC,GAAA,KAAA,CAAA,CAAA;AACzC,EAAA,KAAA,MAAW,QAAQ,KAAO,EAAA;AACxB,IAAM,MAAA,iBAAA,GAAoB,oBAAqB,CAAA,IAAA,CAAK,IAAI,CAAA,CAAA;AACxD,IAAA,IAAI,iBAAmB,EAAA;AACrB,MAAM,MAAA,UAAA,GAAa,iBAAkB,CAAA,IAAA,EAAM,KAAK,CAAA,CAAA;AAChD,MAAA,QAAQ,UAAY;AAAA,QAClB,KAAK,IAAA;AACH,UAAA,MAAA;AAAA,QACF,KAAK,KAAA;AACH,UAAA,IAAI,WAAW,KAAW,CAAA,EAAA;AACxB,YAAS,MAAA,GAAA,KAAA,CAAA;AAAA,WACX;AACA,UAAA,MAAA;AAAA,QACF;AACE,UAAI,IAAA,MAAA,KAAW,KAAa,CAAA,IAAA,MAAA,KAAW,KAAO,EAAA;AAC5C,YAAS,MAAA,GAAA,UAAA,CAAA;AAAA,WACJ,MAAA;AACL,YAAA,MAAA,IAAU,KAAK,UAAU,CAAA,CAAA,CAAA;AAAA,WAC3B;AAAA,OACJ;AAAA,KACK,MAAA;AACL,MAAM,MAAA,KAAA;AAAA,QACJ,CAAA,6DAAA,EAAgE,KAAK,IAAI,CAAA,CAAA,CAAA;AAAA,OAC3E,CAAA;AAAA,KACF;AAAA,GACF;AAEA,EAAO,OAAA,MAAA,CAAA;AACT;;;;"}
@@ -1,2 +0,0 @@
1
- import { ClientSideValidationChecker, EditValidationRule } from "@vuu-ui/vuu-table-types";
2
- export declare const buildValidationChecker: (rules: EditValidationRule[]) => ClientSideValidationChecker;