@neo4j-ndl/react 4.16.12 → 4.17.1

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.
Files changed (72) hide show
  1. package/lib/cjs/ai/response/stories/response-full-example.story.js +4 -4
  2. package/lib/cjs/ai/response/stories/response-full-example.story.js.map +1 -1
  3. package/lib/cjs/data-grid/stories/datagrid-search-and-filters.stories.js +3 -4
  4. package/lib/cjs/data-grid/stories/datagrid-search-and-filters.stories.js.map +1 -1
  5. package/lib/cjs/drawer/Drawer.js.map +1 -1
  6. package/lib/cjs/hooks/use-debounce-callback/index.js.map +1 -1
  7. package/lib/cjs/icons/generated/custom/DatabaseCheck.js +30 -0
  8. package/lib/cjs/icons/generated/custom/DatabaseCheck.js.map +1 -0
  9. package/lib/cjs/icons/generated/custom/index.js +5 -3
  10. package/lib/cjs/icons/generated/custom/index.js.map +1 -1
  11. package/lib/cjs/next/tree-view/TreeView.js.map +1 -1
  12. package/lib/cjs/popover/Popover.js.map +1 -1
  13. package/lib/cjs/popover/use-popover.js.map +1 -1
  14. package/lib/cjs/slider/Slider.js.map +1 -1
  15. package/lib/cjs/spotlight/SpotlightTarget.js.map +1 -1
  16. package/lib/cjs/spotlight/use-spotlight.js.map +1 -1
  17. package/lib/cjs/text-input/TextInput.js.map +1 -1
  18. package/lib/cjs/text-overflow/TextOverflow.js +1 -1
  19. package/lib/cjs/text-overflow/TextOverflow.js.map +1 -1
  20. package/lib/cjs/text-overflow/text-overflow-utils.js +3 -3
  21. package/lib/cjs/text-overflow/text-overflow-utils.js.map +1 -1
  22. package/lib/cjs/text-overflow/use-truncate-with-button.js +2 -2
  23. package/lib/cjs/text-overflow/use-truncate-with-button.js.map +1 -1
  24. package/lib/cjs/tooltip/Tooltip.js.map +1 -1
  25. package/lib/cjs/tooltip/use-tooltip.js.map +1 -1
  26. package/lib/cjs/tree-view/TreeViewItem.js.map +1 -1
  27. package/lib/esm/ai/response/stories/response-full-example.story.js +4 -4
  28. package/lib/esm/ai/response/stories/response-full-example.story.js.map +1 -1
  29. package/lib/esm/data-grid/stories/datagrid-search-and-filters.stories.js +3 -4
  30. package/lib/esm/data-grid/stories/datagrid-search-and-filters.stories.js.map +1 -1
  31. package/lib/esm/drawer/Drawer.js.map +1 -1
  32. package/lib/esm/hooks/use-debounce-callback/index.js.map +1 -1
  33. package/lib/esm/icons/generated/custom/DatabaseCheck.js +28 -0
  34. package/lib/esm/icons/generated/custom/DatabaseCheck.js.map +1 -0
  35. package/lib/esm/icons/generated/custom/index.js +1 -0
  36. package/lib/esm/icons/generated/custom/index.js.map +1 -1
  37. package/lib/esm/next/tree-view/TreeView.js.map +1 -1
  38. package/lib/esm/popover/Popover.js.map +1 -1
  39. package/lib/esm/popover/use-popover.js.map +1 -1
  40. package/lib/esm/slider/Slider.js.map +1 -1
  41. package/lib/esm/spotlight/SpotlightTarget.js.map +1 -1
  42. package/lib/esm/spotlight/use-spotlight.js.map +1 -1
  43. package/lib/esm/text-input/TextInput.js.map +1 -1
  44. package/lib/esm/text-overflow/TextOverflow.js +1 -1
  45. package/lib/esm/text-overflow/TextOverflow.js.map +1 -1
  46. package/lib/esm/text-overflow/text-overflow-utils.js +3 -3
  47. package/lib/esm/text-overflow/text-overflow-utils.js.map +1 -1
  48. package/lib/esm/text-overflow/use-truncate-with-button.js +2 -2
  49. package/lib/esm/text-overflow/use-truncate-with-button.js.map +1 -1
  50. package/lib/esm/tooltip/Tooltip.js.map +1 -1
  51. package/lib/esm/tooltip/use-tooltip.js.map +1 -1
  52. package/lib/esm/tree-view/TreeViewItem.js.map +1 -1
  53. package/lib/types/data-grid/stories/datagrid-search-and-filters.stories.d.ts.map +1 -1
  54. package/lib/types/drawer/Drawer.d.ts.map +1 -1
  55. package/lib/types/hooks/use-debounce-callback/index.d.ts.map +1 -1
  56. package/lib/types/icons/generated/custom/DatabaseCheck.d.ts +29 -0
  57. package/lib/types/icons/generated/custom/DatabaseCheck.d.ts.map +1 -0
  58. package/lib/types/icons/generated/custom/index.d.ts +1 -0
  59. package/lib/types/icons/generated/custom/index.d.ts.map +1 -1
  60. package/lib/types/next/tree-view/TreeView.d.ts.map +1 -1
  61. package/lib/types/popover/Popover.d.ts.map +1 -1
  62. package/lib/types/popover/use-popover.d.ts.map +1 -1
  63. package/lib/types/slider/Slider.d.ts.map +1 -1
  64. package/lib/types/spotlight/SpotlightTarget.d.ts.map +1 -1
  65. package/lib/types/spotlight/use-spotlight.d.ts.map +1 -1
  66. package/lib/types/text-input/TextInput.d.ts.map +1 -1
  67. package/lib/types/text-overflow/text-overflow-utils.d.ts +1 -1
  68. package/lib/types/text-overflow/text-overflow-utils.d.ts.map +1 -1
  69. package/lib/types/tooltip/Tooltip.d.ts.map +1 -1
  70. package/lib/types/tooltip/use-tooltip.d.ts.map +1 -1
  71. package/lib/types/tree-view/TreeViewItem.d.ts.map +1 -1
  72. package/package.json +2 -2
@@ -1 +1 @@
1
- {"version":3,"file":"TextInput.js","sourceRoot":"","sources":["../../../src/text-input/TextInput.tsx"],"names":[],"mappings":"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","sourcesContent":["/**\n *\n * Copyright (c) \"Neo4j\"\n * Neo4j Sweden AB [http://neo4j.com]\n *\n * This file is part of Neo4j.\n *\n * Neo4j is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\nimport classNames from 'classnames';\nimport {\n type InputHTMLAttributes,\n type ReactElement,\n type ReactNode,\n useId,\n useMemo,\n} from 'react';\n\nimport { customLabelAndNoAriaLabelWarningMessage } from '../_common/messages';\nimport { type CommonProps, type TooltipObjectProps } from '../_common/types';\nimport { useSemiControlledInput } from '../_common/use-semi-controlled-input';\nimport { needleWarningMessage } from '../_common/utils';\nimport { ExclamationCircleIconSolid } from '../icons/generated/heroIcons/ExclamationCircleIconSolid';\nimport { InformationCircleIconOutline } from '../icons/generated/heroIcons/InformationCircleIconOutline';\nimport { XMarkIconOutline } from '../icons/generated/heroIcons/XMarkIconOutline';\nimport { LoadingSpinner } from '../loading-spinner';\nimport { Skeleton } from '../skeleton';\nimport { Tooltip } from '../tooltip';\nimport { Typography } from '../typography';\n\n/**\n * @remarks\n * When `moreInformationText` is provided, a tooltip is rendered next to the label, and the `tooltipProps` prop is used to configure the tooltip. The `TooltipObjectProps` type is defined as: `{ root?: Partial<React.ComponentProps<typeof Tooltip>>; trigger?: Partial<React.ComponentProps<typeof Tooltip.Trigger>>; content?: Partial<React.ComponentProps<typeof Tooltip.Content>>; }`, see the Tooltip component for more details.\n *\n * @remarks\n * When `isSkeletonLoading` is true, the input is rendered as a loading skeleton and the `skeletonProps` prop is used to configure the skeleton. For more information, see the Skeleton documentation.\n */\ntype TextInputProps = {\n /** Assistive text displayed below the input */\n helpText?: string | ReactNode;\n\n /** Error message displayed below the input. When provided, it overrides `helpText` and shows an error icon */\n errorText?: string | ReactNode;\n\n /** Leading element rendered inside the input */\n leadingElement?: ReactElement;\n\n /** Trailing element rendered inside the input */\n trailingElement?: ReactElement;\n\n /** Size of the input */\n size?: 'small' | 'medium' | 'large';\n\n /** Whether the input is read-only */\n isReadOnly?: boolean;\n\n /**\n * Whether to display the Required/Optional label next to the field label.\n * Shows Required if isRequired is true, otherwise shows Optional.\n * @default false\n */\n showRequiredOrOptionalLabel?: boolean;\n\n /** Whether the input is disabled */\n isDisabled?: boolean;\n\n /** Whether the input is required */\n isRequired?: boolean;\n\n /** The current value of the input */\n value?: React.ComponentPropsWithoutRef<'input'>['value'];\n\n /** Placeholder text displayed when the input is empty */\n placeholder?: React.ComponentPropsWithoutRef<'input'>['placeholder'];\n\n /** Callback function triggered when the input value changes */\n onChange?: React.ComponentPropsWithoutRef<'input'>['onChange'];\n\n /** Whether the input should take the full available width */\n isFluid?: boolean;\n\n /** Text displayed in the information tooltip shown next to the label */\n moreInformationText?: React.ReactNode;\n\n /** The label displayed above the input */\n label?: string | React.ReactNode;\n\n /** Props for the Tooltip component used by the information icon */\n tooltipProps?: TooltipObjectProps;\n\n /** Whether to render skeletons instead of content */\n isSkeletonLoading?: boolean;\n\n /** Additional props forwarded to the underlying Skeleton components */\n skeletonProps?: React.ComponentProps<typeof Skeleton>;\n\n /** Whether to show the clear button */\n isClearable?: boolean;\n\n /** Whether to show the loading spinner */\n isLoading?: boolean;\n};\n\n/**\n *\n *\n * TextInput Component\n *\n *\n */\n\nexport const TextInput = ({\n label,\n isFluid,\n errorText,\n helpText,\n leadingElement,\n trailingElement,\n showRequiredOrOptionalLabel = false,\n moreInformationText,\n size = 'medium',\n placeholder,\n value,\n tooltipProps,\n htmlAttributes,\n isDisabled,\n isReadOnly,\n isRequired,\n onChange,\n isClearable = false,\n className,\n style,\n isSkeletonLoading = false,\n isLoading = false,\n skeletonProps,\n ref,\n ...restProps\n}: CommonProps<'input', TextInputProps>) => {\n const [currentValue, handleChange] = useSemiControlledInput({\n inputType: 'text',\n isControlled: value !== undefined,\n onChange,\n state: value ?? '',\n });\n const hintId = useId();\n const helpTextId = useId();\n const errorTextId = useId();\n\n const containerWrappingClasses = classNames(`ndl-text-input`, className, {\n 'ndl-disabled': isDisabled,\n 'ndl-has-error': errorText,\n 'ndl-has-icon': leadingElement || trailingElement || errorText,\n 'ndl-has-leading-icon': leadingElement,\n 'ndl-has-trailing-icon': trailingElement || errorText,\n 'ndl-large': size === 'large',\n 'ndl-medium': size === 'medium',\n 'ndl-read-only': isReadOnly,\n 'ndl-small': size === 'small',\n });\n\n const hasEmptyLabelValue =\n label === undefined || label === null || label === '';\n\n const labelWrappingClasses = classNames('ndl-form-item-label', {\n 'ndl-fluid': isFluid,\n 'ndl-form-item-no-label': hasEmptyLabelValue,\n });\n\n const combinedHtmlInputAttributes: InputHTMLAttributes<HTMLInputElement> = {\n ...htmlAttributes,\n className: classNames('ndl-input', htmlAttributes?.className),\n };\n const ariaLabel = combinedHtmlInputAttributes['aria-label'];\n const isCustomLabel = Boolean(label) && typeof label !== 'string';\n const hasCustomLabelAndNoAriaLabel =\n isCustomLabel && (ariaLabel === undefined || ariaLabel === '');\n const shouldRenderHint = isClearable || isLoading;\n\n const handleInputKeyDown = (event: React.KeyboardEvent<HTMLInputElement>) => {\n if (isClearable && event.key === 'Escape' && Boolean(currentValue)) {\n event.preventDefault();\n event.stopPropagation();\n handleChange?.({\n target: { value: '' },\n } as React.ChangeEvent<HTMLInputElement>);\n }\n htmlAttributes?.onKeyDown?.(event);\n };\n\n useMemo(() => {\n if (!label && !ariaLabel) {\n needleWarningMessage(\n 'A TextInput without a label does not have an aria label, be sure to include an aria label for screen readers. Link: https://dequeuniversity.com/rules/axe/4.2/label?application=axeAPI',\n );\n }\n\n if (hasCustomLabelAndNoAriaLabel) {\n needleWarningMessage(customLabelAndNoAriaLabelWarningMessage);\n }\n }, [label, ariaLabel, hasCustomLabelAndNoAriaLabel]);\n\n const informationIconClasses = classNames({\n 'ndl-information-icon-large': size === 'large',\n 'ndl-information-icon-small': size === 'small' || size === 'medium',\n });\n\n const combinedAriaDescribedby = useMemo(() => {\n const ariaDescribedby = [];\n\n if (hintId && shouldRenderHint) {\n ariaDescribedby.push(hintId);\n }\n if (helpText && !errorText) {\n ariaDescribedby.push(helpTextId);\n } else if (errorText) {\n ariaDescribedby.push(errorTextId);\n }\n return ariaDescribedby.join(' ');\n }, [hintId, shouldRenderHint, helpText, errorText, helpTextId, errorTextId]);\n\n return (\n <div className={containerWrappingClasses} style={style}>\n {/* We enable implicit label wrapping */}\n {/* Source: https://dequeuniversity.com/rules/axe/4.2/label?application=axeAPI */}\n <label className={labelWrappingClasses}>\n {!hasEmptyLabelValue && (\n <Skeleton\n onBackground=\"weak\"\n shape=\"rectangular\"\n {...skeletonProps}\n isLoading={isSkeletonLoading}\n >\n <div className=\"ndl-label-text-wrapper\">\n <Typography\n variant={size === 'large' ? 'body-large' : 'body-medium'}\n className=\"ndl-label-text\"\n >\n {label}\n </Typography>\n {Boolean(moreInformationText) && (\n <Tooltip {...tooltipProps?.root} type=\"simple\">\n <Tooltip.Trigger\n {...tooltipProps?.trigger}\n className={informationIconClasses}\n hasButtonWrapper\n >\n <div\n tabIndex={0}\n role=\"button\"\n aria-label=\"Information icon\"\n >\n <InformationCircleIconOutline />\n </div>\n </Tooltip.Trigger>\n <Tooltip.Content {...tooltipProps?.content}>\n {moreInformationText}\n </Tooltip.Content>\n </Tooltip>\n )}\n {showRequiredOrOptionalLabel && (\n <Typography\n variant={size === 'large' ? 'body-large' : 'body-medium'}\n className=\"ndl-form-item-optional\"\n >\n {isRequired === true ? 'Required' : 'Optional'}\n </Typography>\n )}\n </div>\n </Skeleton>\n )}\n <Skeleton\n onBackground=\"weak\"\n shape=\"rectangular\"\n {...skeletonProps}\n isLoading={isSkeletonLoading}\n >\n <div className=\"ndl-input-wrapper\">\n {(leadingElement || (isLoading && !trailingElement)) && (\n <div className=\"ndl-element-leading ndl-element\">\n {isLoading ? (\n <LoadingSpinner\n size={size === 'large' ? 'medium' : 'small'}\n className={\n size === 'large'\n ? 'ndl-medium-spinner'\n : 'ndl-small-spinner'\n }\n />\n ) : (\n leadingElement\n )}\n </div>\n )}\n <div\n className={classNames('ndl-input-container', {\n 'ndl-clearable': isClearable,\n })}\n >\n <input\n ref={ref}\n readOnly={isReadOnly}\n disabled={isDisabled}\n required={isRequired}\n value={currentValue}\n placeholder={placeholder}\n type=\"text\"\n onChange={handleChange}\n aria-describedby={combinedAriaDescribedby}\n aria-invalid={Boolean(errorText)}\n {...combinedHtmlInputAttributes}\n onKeyDown={handleInputKeyDown}\n {...restProps}\n />\n {shouldRenderHint && (\n <span\n id={hintId}\n className=\"ndl-text-input-hint\"\n aria-hidden={true}\n >\n {isLoading && 'Loading '}\n {isClearable && 'Press Escape to clear input.'}\n </span>\n )}\n {isClearable && Boolean(currentValue) && (\n <div className=\"ndl-element-clear ndl-element\">\n <button\n tabIndex={-1}\n aria-hidden={true}\n type=\"button\"\n title=\"Clear input (Esc)\"\n onClick={() => {\n handleChange?.({\n target: { value: '' },\n } as React.ChangeEvent<HTMLInputElement>);\n }}\n >\n <XMarkIconOutline className=\"n-size-4\" />\n </button>\n </div>\n )}\n </div>\n {trailingElement && (\n <div className=\"ndl-element-trailing ndl-element\">\n {isLoading && !leadingElement ? (\n <LoadingSpinner\n size={size === 'large' ? 'medium' : 'small'}\n className={\n size === 'large'\n ? 'ndl-medium-spinner'\n : 'ndl-small-spinner'\n }\n />\n ) : (\n trailingElement\n )}\n </div>\n )}\n </div>\n </Skeleton>\n </label>\n {Boolean(helpText) && !errorText && (\n <Skeleton\n onBackground=\"weak\"\n shape=\"rectangular\"\n isLoading={isSkeletonLoading}\n >\n <Typography\n variant={size === 'large' ? 'body-medium' : 'body-small'}\n className=\"ndl-form-message\"\n htmlAttributes={{\n 'aria-live': 'polite',\n id: helpTextId,\n }}\n >\n {helpText}\n </Typography>\n </Skeleton>\n )}\n {Boolean(errorText) && (\n // TODO v4: We might want to have a min width for the container for the messages to help skeleton loading.\n // Currently the message fills 100% of the width while the rest of the text input has a set width.\n <Skeleton\n onBackground=\"weak\"\n shape=\"rectangular\"\n width=\"fit-content\"\n {...skeletonProps}\n isLoading={isSkeletonLoading}\n >\n <div className=\"ndl-form-message\">\n <div className=\"ndl-error-icon\">\n <ExclamationCircleIconSolid />\n </div>\n <Typography\n className=\"ndl-error-text\"\n variant={size === 'large' ? 'body-medium' : 'body-small'}\n htmlAttributes={{\n 'aria-live': 'polite',\n id: errorTextId,\n }}\n >\n {errorText}\n </Typography>\n </div>\n </Skeleton>\n )}\n </div>\n );\n};\n"]}
1
+ {"version":3,"file":"TextInput.js","sourceRoot":"","sources":["../../../src/text-input/TextInput.tsx"],"names":[],"mappings":"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","sourcesContent":["/**\n *\n * Copyright (c) \"Neo4j\"\n * Neo4j Sweden AB [http://neo4j.com]\n *\n * This file is part of Neo4j.\n *\n * Neo4j is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\nimport classNames from 'classnames';\nimport {\n type InputHTMLAttributes,\n type ReactElement,\n type ReactNode,\n useId,\n useMemo,\n} from 'react';\n\nimport { customLabelAndNoAriaLabelWarningMessage } from '../_common/messages';\nimport { type CommonProps, type TooltipObjectProps } from '../_common/types';\nimport { useSemiControlledInput } from '../_common/use-semi-controlled-input';\nimport { needleWarningMessage } from '../_common/utils';\nimport { ExclamationCircleIconSolid } from '../icons/generated/heroIcons/ExclamationCircleIconSolid';\nimport { InformationCircleIconOutline } from '../icons/generated/heroIcons/InformationCircleIconOutline';\nimport { XMarkIconOutline } from '../icons/generated/heroIcons/XMarkIconOutline';\nimport { LoadingSpinner } from '../loading-spinner';\nimport { Skeleton } from '../skeleton';\nimport { Tooltip } from '../tooltip';\nimport { Typography } from '../typography';\n\n/**\n * @remarks\n * When `moreInformationText` is provided, a tooltip is rendered next to the label, and the `tooltipProps` prop is used to configure the tooltip. The `TooltipObjectProps` type is defined as: `{ root?: Partial<React.ComponentProps<typeof Tooltip>>; trigger?: Partial<React.ComponentProps<typeof Tooltip.Trigger>>; content?: Partial<React.ComponentProps<typeof Tooltip.Content>>; }`, see the Tooltip component for more details.\n *\n * @remarks\n * When `isSkeletonLoading` is true, the input is rendered as a loading skeleton and the `skeletonProps` prop is used to configure the skeleton. For more information, see the Skeleton documentation.\n */\ntype TextInputProps = {\n /** Assistive text displayed below the input */\n helpText?: string | ReactNode;\n\n /** Error message displayed below the input. When provided, it overrides `helpText` and shows an error icon */\n errorText?: string | ReactNode;\n\n /** Leading element rendered inside the input */\n leadingElement?: ReactElement;\n\n /** Trailing element rendered inside the input */\n trailingElement?: ReactElement;\n\n /** Size of the input */\n size?: 'small' | 'medium' | 'large';\n\n /** Whether the input is read-only */\n isReadOnly?: boolean;\n\n /**\n * Whether to display the Required/Optional label next to the field label.\n * Shows Required if isRequired is true, otherwise shows Optional.\n * @default false\n */\n // TODO v5: decide if this naming is okay, or change it\n // eslint-disable-next-line @typescript-eslint/naming-convention\n showRequiredOrOptionalLabel?: boolean;\n\n /** Whether the input is disabled */\n isDisabled?: boolean;\n\n /** Whether the input is required */\n isRequired?: boolean;\n\n /** The current value of the input */\n value?: React.ComponentPropsWithoutRef<'input'>['value'];\n\n /** Placeholder text displayed when the input is empty */\n placeholder?: React.ComponentPropsWithoutRef<'input'>['placeholder'];\n\n /** Callback function triggered when the input value changes */\n onChange?: React.ComponentPropsWithoutRef<'input'>['onChange'];\n\n /** Whether the input should take the full available width */\n isFluid?: boolean;\n\n /** Text displayed in the information tooltip shown next to the label */\n moreInformationText?: React.ReactNode;\n\n /** The label displayed above the input */\n label?: string | React.ReactNode;\n\n /** Props for the Tooltip component used by the information icon */\n tooltipProps?: TooltipObjectProps;\n\n /** Whether to render skeletons instead of content */\n isSkeletonLoading?: boolean;\n\n /** Additional props forwarded to the underlying Skeleton components */\n skeletonProps?: React.ComponentProps<typeof Skeleton>;\n\n /** Whether to show the clear button */\n isClearable?: boolean;\n\n /** Whether to show the loading spinner */\n isLoading?: boolean;\n};\n\n/**\n *\n *\n * TextInput Component\n *\n *\n */\n\nexport const TextInput = ({\n label,\n isFluid,\n errorText,\n helpText,\n leadingElement,\n trailingElement,\n showRequiredOrOptionalLabel = false,\n moreInformationText,\n size = 'medium',\n placeholder,\n value,\n tooltipProps,\n htmlAttributes,\n isDisabled,\n isReadOnly,\n isRequired,\n onChange,\n isClearable = false,\n className,\n style,\n isSkeletonLoading = false,\n isLoading = false,\n skeletonProps,\n ref,\n ...restProps\n}: CommonProps<'input', TextInputProps>) => {\n const [currentValue, handleChange] = useSemiControlledInput({\n inputType: 'text',\n isControlled: value !== undefined,\n onChange,\n state: value ?? '',\n });\n const hintId = useId();\n const helpTextId = useId();\n const errorTextId = useId();\n\n const containerWrappingClasses = classNames(`ndl-text-input`, className, {\n 'ndl-disabled': isDisabled,\n 'ndl-has-error': errorText,\n 'ndl-has-icon': leadingElement || trailingElement || errorText,\n 'ndl-has-leading-icon': leadingElement,\n 'ndl-has-trailing-icon': trailingElement || errorText,\n 'ndl-large': size === 'large',\n 'ndl-medium': size === 'medium',\n 'ndl-read-only': isReadOnly,\n 'ndl-small': size === 'small',\n });\n\n const hasEmptyLabelValue =\n label === undefined || label === null || label === '';\n\n const labelWrappingClasses = classNames('ndl-form-item-label', {\n 'ndl-fluid': isFluid,\n 'ndl-form-item-no-label': hasEmptyLabelValue,\n });\n\n const combinedHtmlInputAttributes: InputHTMLAttributes<HTMLInputElement> = {\n ...htmlAttributes,\n className: classNames('ndl-input', htmlAttributes?.className),\n };\n const ariaLabel = combinedHtmlInputAttributes['aria-label'];\n const isCustomLabel = Boolean(label) && typeof label !== 'string';\n const hasCustomLabelAndNoAriaLabel =\n isCustomLabel && (ariaLabel === undefined || ariaLabel === '');\n const shouldRenderHint = isClearable || isLoading;\n\n const handleInputKeyDown = (event: React.KeyboardEvent<HTMLInputElement>) => {\n if (isClearable && event.key === 'Escape' && Boolean(currentValue)) {\n event.preventDefault();\n event.stopPropagation();\n handleChange?.({\n target: { value: '' },\n } as React.ChangeEvent<HTMLInputElement>);\n }\n htmlAttributes?.onKeyDown?.(event);\n };\n\n useMemo(() => {\n if (!label && !ariaLabel) {\n needleWarningMessage(\n 'A TextInput without a label does not have an aria label, be sure to include an aria label for screen readers. Link: https://dequeuniversity.com/rules/axe/4.2/label?application=axeAPI',\n );\n }\n\n if (hasCustomLabelAndNoAriaLabel) {\n needleWarningMessage(customLabelAndNoAriaLabelWarningMessage);\n }\n }, [label, ariaLabel, hasCustomLabelAndNoAriaLabel]);\n\n const informationIconClasses = classNames({\n 'ndl-information-icon-large': size === 'large',\n 'ndl-information-icon-small': size === 'small' || size === 'medium',\n });\n\n const combinedAriaDescribedby = useMemo(() => {\n const ariaDescribedby = [];\n\n if (hintId && shouldRenderHint) {\n ariaDescribedby.push(hintId);\n }\n if (helpText && !errorText) {\n ariaDescribedby.push(helpTextId);\n } else if (errorText) {\n ariaDescribedby.push(errorTextId);\n }\n return ariaDescribedby.join(' ');\n }, [hintId, shouldRenderHint, helpText, errorText, helpTextId, errorTextId]);\n\n return (\n <div className={containerWrappingClasses} style={style}>\n {/* We enable implicit label wrapping */}\n {/* Source: https://dequeuniversity.com/rules/axe/4.2/label?application=axeAPI */}\n <label className={labelWrappingClasses}>\n {!hasEmptyLabelValue && (\n <Skeleton\n onBackground=\"weak\"\n shape=\"rectangular\"\n {...skeletonProps}\n isLoading={isSkeletonLoading}\n >\n <div className=\"ndl-label-text-wrapper\">\n <Typography\n variant={size === 'large' ? 'body-large' : 'body-medium'}\n className=\"ndl-label-text\"\n >\n {label}\n </Typography>\n {Boolean(moreInformationText) && (\n <Tooltip {...tooltipProps?.root} type=\"simple\">\n <Tooltip.Trigger\n {...tooltipProps?.trigger}\n className={informationIconClasses}\n hasButtonWrapper\n >\n <div\n tabIndex={0}\n role=\"button\"\n aria-label=\"Information icon\"\n >\n <InformationCircleIconOutline />\n </div>\n </Tooltip.Trigger>\n <Tooltip.Content {...tooltipProps?.content}>\n {moreInformationText}\n </Tooltip.Content>\n </Tooltip>\n )}\n {showRequiredOrOptionalLabel && (\n <Typography\n variant={size === 'large' ? 'body-large' : 'body-medium'}\n className=\"ndl-form-item-optional\"\n >\n {isRequired === true ? 'Required' : 'Optional'}\n </Typography>\n )}\n </div>\n </Skeleton>\n )}\n <Skeleton\n onBackground=\"weak\"\n shape=\"rectangular\"\n {...skeletonProps}\n isLoading={isSkeletonLoading}\n >\n <div className=\"ndl-input-wrapper\">\n {(leadingElement || (isLoading && !trailingElement)) && (\n <div className=\"ndl-element-leading ndl-element\">\n {isLoading ? (\n <LoadingSpinner\n size={size === 'large' ? 'medium' : 'small'}\n className={\n size === 'large'\n ? 'ndl-medium-spinner'\n : 'ndl-small-spinner'\n }\n />\n ) : (\n leadingElement\n )}\n </div>\n )}\n <div\n className={classNames('ndl-input-container', {\n 'ndl-clearable': isClearable,\n })}\n >\n <input\n ref={ref}\n readOnly={isReadOnly}\n disabled={isDisabled}\n required={isRequired}\n value={currentValue}\n placeholder={placeholder}\n type=\"text\"\n onChange={handleChange}\n aria-describedby={combinedAriaDescribedby}\n aria-invalid={Boolean(errorText)}\n {...combinedHtmlInputAttributes}\n onKeyDown={handleInputKeyDown}\n {...restProps}\n />\n {shouldRenderHint && (\n <span\n id={hintId}\n className=\"ndl-text-input-hint\"\n aria-hidden={true}\n >\n {isLoading && 'Loading '}\n {isClearable && 'Press Escape to clear input.'}\n </span>\n )}\n {isClearable && Boolean(currentValue) && (\n <div className=\"ndl-element-clear ndl-element\">\n <button\n tabIndex={-1}\n aria-hidden={true}\n type=\"button\"\n title=\"Clear input (Esc)\"\n onClick={() => {\n handleChange?.({\n target: { value: '' },\n } as React.ChangeEvent<HTMLInputElement>);\n }}\n >\n <XMarkIconOutline className=\"n-size-4\" />\n </button>\n </div>\n )}\n </div>\n {trailingElement && (\n <div className=\"ndl-element-trailing ndl-element\">\n {isLoading && !leadingElement ? (\n <LoadingSpinner\n size={size === 'large' ? 'medium' : 'small'}\n className={\n size === 'large'\n ? 'ndl-medium-spinner'\n : 'ndl-small-spinner'\n }\n />\n ) : (\n trailingElement\n )}\n </div>\n )}\n </div>\n </Skeleton>\n </label>\n {Boolean(helpText) && !errorText && (\n <Skeleton\n onBackground=\"weak\"\n shape=\"rectangular\"\n isLoading={isSkeletonLoading}\n >\n <Typography\n variant={size === 'large' ? 'body-medium' : 'body-small'}\n className=\"ndl-form-message\"\n htmlAttributes={{\n 'aria-live': 'polite',\n id: helpTextId,\n }}\n >\n {helpText}\n </Typography>\n </Skeleton>\n )}\n {Boolean(errorText) && (\n // TODO v4: We might want to have a min width for the container for the messages to help skeleton loading.\n // Currently the message fills 100% of the width while the rest of the text input has a set width.\n <Skeleton\n onBackground=\"weak\"\n shape=\"rectangular\"\n width=\"fit-content\"\n {...skeletonProps}\n isLoading={isSkeletonLoading}\n >\n <div className=\"ndl-form-message\">\n <div className=\"ndl-error-icon\">\n <ExclamationCircleIconSolid />\n </div>\n <Typography\n className=\"ndl-error-text\"\n variant={size === 'large' ? 'body-medium' : 'body-small'}\n htmlAttributes={{\n 'aria-live': 'polite',\n id: errorTextId,\n }}\n >\n {errorText}\n </Typography>\n </div>\n </Skeleton>\n )}\n </div>\n );\n};\n"]}
@@ -71,7 +71,7 @@ const TextOverflow = (_a) => {
71
71
  const characterTruncatedContent = (0, react_1.useMemo)(() => {
72
72
  if (maxCharacters !== undefined && expandButton === undefined) {
73
73
  const result = (0, text_overflow_utils_1.truncateReactNodeByCharacters)(children, maxCharacters);
74
- return result.needsTruncation ? result.truncatedContent : null;
74
+ return result.shouldTruncation ? result.truncatedContent : null;
75
75
  }
76
76
  return null;
77
77
  }, [maxCharacters, expandButton, children]);
@@ -1 +1 @@
1
- {"version":3,"file":"TextOverflow.js","sourceRoot":"","sources":["../../../src/text-overflow/TextOverflow.tsx"],"names":[],"mappings":"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","sourcesContent":["/**\n *\n * Copyright (c) \"Neo4j\"\n * Neo4j Sweden AB [http://neo4j.com]\n *\n * This file is part of Neo4j.\n *\n * Neo4j is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\nimport classNames from 'classnames';\nimport type React from 'react';\nimport { useCallback, useMemo, useRef, useState } from 'react';\n\nimport type {\n PolymorphicCommonProps,\n TooltipObjectProps,\n} from '../_common/types';\nimport { TextLink } from '../text-link';\nimport { Tooltip } from '../tooltip';\nimport { Typography } from '../typography';\nimport { COLLAPSE_BUTTON_TEXT, ELLIPSIS_CHAR } from './constants';\nimport {\n getTextContent,\n truncateReactNodeByCharacters,\n} from './text-overflow-utils';\nimport { useTruncateWithButton } from './use-truncate-with-button';\n\ntype TextOverflowProps = {\n /** The content to be truncated. Can be text, Typography components, or complex JSX. */\n children: React.ReactNode;\n\n /**\n * Controls the expand/collapse UI.\n * - string: show expand/collapse button with custom text (e.g., \"View more\")\n * - undefined: content is not expandable, only truncated with ellipsis\n * @default undefined\n */\n expandButton?: 'view-more' | 'ellipsis';\n\n /**\n * Maximum number of characters to display. Takes precedence over line-based truncation when set.\n */\n maxCharacters?: number;\n\n /**\n * Number of lines to show before truncation.\n * Uses CSS line-clamp for non-expandable content.\n * Uses DOM measurement for expandable content.\n * **Note**: Ignored if `maxCharacters` is explicitly set to a custom value.\n */\n lines?: number;\n\n /**\n * Whether to show tooltip with full text on hover when content is truncated.\n * @default true\n */\n shouldShowTooltip?: boolean;\n\n /** Props to pass to tooltip component */\n tooltipProps?: TooltipObjectProps;\n\n /** Callback function called when content is expanded or collapsed */\n onExpandedToggle?: (isExpanded: boolean) => void;\n\n /**\n * The typography variant to use for the text.\n * @default 'body-medium'\n */\n typographyVariant?: React.ComponentProps<typeof Typography>['variant'];\n};\n\nconst expandButtonTexts = {\n ellipsis: ELLIPSIS_CHAR,\n 'view-more': 'View more',\n};\n\nexport const TextOverflow = <T extends React.ElementType = 'div'>({\n as,\n children,\n className,\n htmlAttributes,\n lines,\n tooltipProps,\n onExpandedToggle,\n expandButton,\n maxCharacters,\n shouldShowTooltip = true,\n typographyVariant = 'body-medium',\n ref,\n ...restProps\n}: PolymorphicCommonProps<T, TextOverflowProps>) => {\n const contentRef = useRef<HTMLDivElement>(null);\n const textElementRef = useRef<HTMLSpanElement>(null);\n const [isTooltipOpen, setIsTooltipOpen] = useState(false);\n\n // Use truncate with button hook when expandButton is provided\n const shouldUseTruncateWithButton = expandButton !== undefined;\n const truncateWithButtonResult = useTruncateWithButton({\n button: expandButtonTexts[expandButton!] || 'View more',\n buttonType: expandButton,\n closeTooltip: () => setIsTooltipOpen(false),\n content: children,\n // Disable expensive calculations when no expand button is needed\n isDisabled: !shouldUseTruncateWithButton,\n lineClamp: lines ?? 1,\n maxCharacters,\n onExpandedToggle,\n });\n\n // Handle character-based truncation when no expand button is used\n const characterTruncatedContent = useMemo(() => {\n if (maxCharacters !== undefined && expandButton === undefined) {\n const result = truncateReactNodeByCharacters(children, maxCharacters);\n return result.needsTruncation ? result.truncatedContent : null;\n }\n return null;\n }, [maxCharacters, expandButton, children]);\n\n // Memoize text content extraction to avoid repeated traversals\n const textContent = useMemo(() => getTextContent(children), [children]);\n\n // Memoize tooltip truncation detection logic\n const checkTruncationForTooltip = useCallback(() => {\n if (shouldUseTruncateWithButton) {\n return truncateWithButtonResult.isTruncated;\n }\n\n // Character based truncation\n if (maxCharacters !== undefined) {\n return characterTruncatedContent !== null;\n }\n\n const element = textElementRef.current;\n if (element === null) {\n return false;\n }\n\n // Regular multiline truncation\n if (lines !== undefined && lines > 1) {\n return element.scrollHeight > element.clientHeight;\n }\n\n // Regular single line truncation\n return element.scrollWidth > element.clientWidth;\n }, [\n shouldUseTruncateWithButton,\n truncateWithButtonResult.isTruncated,\n maxCharacters,\n characterTruncatedContent,\n lines,\n ]);\n\n const renderContent = () => {\n const isMultiline = typeof lines === 'number' && lines > 1;\n\n const textStyle = {\n '--ndl-line-clamp': isMultiline ? lines.toString() : undefined,\n } as React.CSSProperties;\n\n const textClasses = classNames({\n 'ndl-text-overflow-multi-line': isMultiline,\n 'ndl-text-overflow-single-line':\n !isMultiline && maxCharacters === undefined,\n });\n\n if (shouldUseTruncateWithButton) {\n return (\n <div ref={truncateWithButtonResult.containerRef}>\n <div\n className={truncateWithButtonResult.isExpanded ? '' : textClasses}\n style={textStyle}\n >\n {truncateWithButtonResult.contentToRender}\n {truncateWithButtonResult.isTruncated && (\n <TextLink\n as=\"button\"\n className={classNames('ndl-text-overflow-toggle', {\n 'ndl-text-overflow-toggle-margin-left':\n expandButton !== 'ellipsis' ||\n truncateWithButtonResult.isExpanded,\n })}\n htmlAttributes={{\n onClick: truncateWithButtonResult.toggleExpand,\n }}\n >\n {truncateWithButtonResult.isExpanded\n ? COLLAPSE_BUTTON_TEXT\n : expandButtonTexts[expandButton!]}\n </TextLink>\n )}\n </div>\n <div\n ref={truncateWithButtonResult.measureRef}\n style={{\n position: 'absolute',\n top: '-9999px',\n visibility: 'hidden',\n }}\n />\n </div>\n );\n }\n\n return (\n <span ref={textElementRef} className={textClasses} style={textStyle}>\n {characterTruncatedContent ?? children}\n </span>\n );\n };\n\n const isTooltipDisabled =\n !shouldShowTooltip ||\n (expandButton !== undefined && truncateWithButtonResult.isExpanded);\n\n return (\n <Tooltip\n {...tooltipProps?.root}\n type=\"simple\"\n isDisabled={isTooltipDisabled}\n isOpen={isTooltipOpen}\n onOpenChange={(open) => {\n if (open) {\n setIsTooltipOpen(checkTruncationForTooltip());\n } else {\n setIsTooltipOpen(false);\n }\n }}\n >\n <Tooltip.Trigger {...tooltipProps?.trigger} hasButtonWrapper>\n <Typography\n as={as ?? 'div'}\n ref={ref}\n variant={typographyVariant}\n className={classNames('ndl-text-overflow', className)}\n htmlAttributes={{\n ...htmlAttributes,\n }}\n {...restProps}\n {...(!isTooltipDisabled &&\n expandButton === undefined && {\n tabIndex: 0,\n })}\n >\n <div className=\"ndl-text-overflow-content\" ref={contentRef}>\n {renderContent()}\n </div>\n </Typography>\n </Tooltip.Trigger>\n <Tooltip.Content\n className={classNames(\n 'ndl-text-overflow-tooltip-content',\n tooltipProps?.content?.className,\n )}\n {...tooltipProps?.content}\n >\n {textContent}\n </Tooltip.Content>\n </Tooltip>\n );\n};\n"]}
1
+ {"version":3,"file":"TextOverflow.js","sourceRoot":"","sources":["../../../src/text-overflow/TextOverflow.tsx"],"names":[],"mappings":"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","sourcesContent":["/**\n *\n * Copyright (c) \"Neo4j\"\n * Neo4j Sweden AB [http://neo4j.com]\n *\n * This file is part of Neo4j.\n *\n * Neo4j is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\nimport classNames from 'classnames';\nimport type React from 'react';\nimport { useCallback, useMemo, useRef, useState } from 'react';\n\nimport type {\n PolymorphicCommonProps,\n TooltipObjectProps,\n} from '../_common/types';\nimport { TextLink } from '../text-link';\nimport { Tooltip } from '../tooltip';\nimport { Typography } from '../typography';\nimport { COLLAPSE_BUTTON_TEXT, ELLIPSIS_CHAR } from './constants';\nimport {\n getTextContent,\n truncateReactNodeByCharacters,\n} from './text-overflow-utils';\nimport { useTruncateWithButton } from './use-truncate-with-button';\n\ntype TextOverflowProps = {\n /** The content to be truncated. Can be text, Typography components, or complex JSX. */\n children: React.ReactNode;\n\n /**\n * Controls the expand/collapse UI.\n * - string: show expand/collapse button with custom text (e.g., \"View more\")\n * - undefined: content is not expandable, only truncated with ellipsis\n * @default undefined\n */\n expandButton?: 'view-more' | 'ellipsis';\n\n /**\n * Maximum number of characters to display. Takes precedence over line-based truncation when set.\n */\n maxCharacters?: number;\n\n /**\n * Number of lines to show before truncation.\n * Uses CSS line-clamp for non-expandable content.\n * Uses DOM measurement for expandable content.\n * **Note**: Ignored if `maxCharacters` is explicitly set to a custom value.\n */\n lines?: number;\n\n /**\n * Whether to show tooltip with full text on hover when content is truncated.\n * @default true\n */\n shouldShowTooltip?: boolean;\n\n /** Props to pass to tooltip component */\n tooltipProps?: TooltipObjectProps;\n\n /** Callback function called when content is expanded or collapsed */\n onExpandedToggle?: (isExpanded: boolean) => void;\n\n /**\n * The typography variant to use for the text.\n * @default 'body-medium'\n */\n typographyVariant?: React.ComponentProps<typeof Typography>['variant'];\n};\n\nconst expandButtonTexts = {\n ellipsis: ELLIPSIS_CHAR,\n 'view-more': 'View more',\n};\n\nexport const TextOverflow = <T extends React.ElementType = 'div'>({\n as,\n children,\n className,\n htmlAttributes,\n lines,\n tooltipProps,\n onExpandedToggle,\n expandButton,\n maxCharacters,\n shouldShowTooltip = true,\n typographyVariant = 'body-medium',\n ref,\n ...restProps\n}: PolymorphicCommonProps<T, TextOverflowProps>) => {\n const contentRef = useRef<HTMLDivElement>(null);\n const textElementRef = useRef<HTMLSpanElement>(null);\n const [isTooltipOpen, setIsTooltipOpen] = useState(false);\n\n // Use truncate with button hook when expandButton is provided\n const shouldUseTruncateWithButton = expandButton !== undefined;\n const truncateWithButtonResult = useTruncateWithButton({\n button: expandButtonTexts[expandButton!] || 'View more',\n buttonType: expandButton,\n closeTooltip: () => setIsTooltipOpen(false),\n content: children,\n // Disable expensive calculations when no expand button is needed\n isDisabled: !shouldUseTruncateWithButton,\n lineClamp: lines ?? 1,\n maxCharacters,\n onExpandedToggle,\n });\n\n // Handle character-based truncation when no expand button is used\n const characterTruncatedContent = useMemo(() => {\n if (maxCharacters !== undefined && expandButton === undefined) {\n const result = truncateReactNodeByCharacters(children, maxCharacters);\n return result.shouldTruncation ? result.truncatedContent : null;\n }\n return null;\n }, [maxCharacters, expandButton, children]);\n\n // Memoize text content extraction to avoid repeated traversals\n const textContent = useMemo(() => getTextContent(children), [children]);\n\n // Memoize tooltip truncation detection logic\n const checkTruncationForTooltip = useCallback(() => {\n if (shouldUseTruncateWithButton) {\n return truncateWithButtonResult.isTruncated;\n }\n\n // Character based truncation\n if (maxCharacters !== undefined) {\n return characterTruncatedContent !== null;\n }\n\n const element = textElementRef.current;\n if (element === null) {\n return false;\n }\n\n // Regular multiline truncation\n if (lines !== undefined && lines > 1) {\n return element.scrollHeight > element.clientHeight;\n }\n\n // Regular single line truncation\n return element.scrollWidth > element.clientWidth;\n }, [\n shouldUseTruncateWithButton,\n truncateWithButtonResult.isTruncated,\n maxCharacters,\n characterTruncatedContent,\n lines,\n ]);\n\n const renderContent = () => {\n const isMultiline = typeof lines === 'number' && lines > 1;\n\n const textStyle = {\n '--ndl-line-clamp': isMultiline ? lines.toString() : undefined,\n } as React.CSSProperties;\n\n const textClasses = classNames({\n 'ndl-text-overflow-multi-line': isMultiline,\n 'ndl-text-overflow-single-line':\n !isMultiline && maxCharacters === undefined,\n });\n\n if (shouldUseTruncateWithButton) {\n return (\n <div ref={truncateWithButtonResult.containerRef}>\n <div\n className={truncateWithButtonResult.isExpanded ? '' : textClasses}\n style={textStyle}\n >\n {truncateWithButtonResult.contentToRender}\n {truncateWithButtonResult.isTruncated && (\n <TextLink\n as=\"button\"\n className={classNames('ndl-text-overflow-toggle', {\n 'ndl-text-overflow-toggle-margin-left':\n expandButton !== 'ellipsis' ||\n truncateWithButtonResult.isExpanded,\n })}\n htmlAttributes={{\n onClick: truncateWithButtonResult.toggleExpand,\n }}\n >\n {truncateWithButtonResult.isExpanded\n ? COLLAPSE_BUTTON_TEXT\n : expandButtonTexts[expandButton!]}\n </TextLink>\n )}\n </div>\n <div\n ref={truncateWithButtonResult.measureRef}\n style={{\n position: 'absolute',\n top: '-9999px',\n visibility: 'hidden',\n }}\n />\n </div>\n );\n }\n\n return (\n <span ref={textElementRef} className={textClasses} style={textStyle}>\n {characterTruncatedContent ?? children}\n </span>\n );\n };\n\n const isTooltipDisabled =\n !shouldShowTooltip ||\n (expandButton !== undefined && truncateWithButtonResult.isExpanded);\n\n return (\n <Tooltip\n {...tooltipProps?.root}\n type=\"simple\"\n isDisabled={isTooltipDisabled}\n isOpen={isTooltipOpen}\n onOpenChange={(open) => {\n if (open) {\n setIsTooltipOpen(checkTruncationForTooltip());\n } else {\n setIsTooltipOpen(false);\n }\n }}\n >\n <Tooltip.Trigger {...tooltipProps?.trigger} hasButtonWrapper>\n <Typography\n as={as ?? 'div'}\n ref={ref}\n variant={typographyVariant}\n className={classNames('ndl-text-overflow', className)}\n htmlAttributes={{\n ...htmlAttributes,\n }}\n {...restProps}\n {...(!isTooltipDisabled &&\n expandButton === undefined && {\n tabIndex: 0,\n })}\n >\n <div className=\"ndl-text-overflow-content\" ref={contentRef}>\n {renderContent()}\n </div>\n </Typography>\n </Tooltip.Trigger>\n <Tooltip.Content\n className={classNames(\n 'ndl-text-overflow-tooltip-content',\n tooltipProps?.content?.className,\n )}\n {...tooltipProps?.content}\n >\n {textContent}\n </Tooltip.Content>\n </Tooltip>\n );\n};\n"]}
@@ -58,7 +58,7 @@ const truncateReactNodeByCharacters = (node, maxCharacters, shouldAddEllipsis =
58
58
  // Get the total character count first to determine if truncation is needed
59
59
  const totalLength = (0, exports.getTextContent)(normalizedNode).length;
60
60
  if (totalLength <= maxCharacters) {
61
- return { needsTruncation: false, truncatedContent: null };
61
+ return { shouldTruncation: false, truncatedContent: null };
62
62
  }
63
63
  let charCount = 0;
64
64
  let hasReachedLimit = false;
@@ -156,10 +156,10 @@ const truncateReactNodeByCharacters = (node, maxCharacters, shouldAddEllipsis =
156
156
  // Add ellipsis if needed
157
157
  if (shouldAddEllipsis && finalResult !== null) {
158
158
  const withEllipsis = react_1.default.createElement(react_1.default.Fragment, null, finalResult, constants_1.ELLIPSIS_CHAR);
159
- return { needsTruncation: true, truncatedContent: withEllipsis };
159
+ return { shouldTruncation: true, truncatedContent: withEllipsis };
160
160
  }
161
161
  return {
162
- needsTruncation: true,
162
+ shouldTruncation: true,
163
163
  truncatedContent: finalResult,
164
164
  };
165
165
  };
@@ -1 +1 @@
1
- {"version":3,"file":"text-overflow-utils.js","sourceRoot":"","sources":["../../../src/text-overflow/text-overflow-utils.ts"],"names":[],"mappings":";;;;;;AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,kDAA8C;AAE9C,2CAAgE;AAOhE;;GAEG;AACI,MAAM,cAAc,GAAG,CAAC,IAAqB,EAAU,EAAE;IAC9D,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC7B,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC7B,OAAO,IAAI,CAAC,QAAQ,EAAE,CAAC;IACzB,CAAC;IACD,IAAI,eAAK,CAAC,cAAc,CAAC,IAAI,CAAC,EAAE,CAAC;QAC/B,wCAAwC;QACxC,MAAM,OAAO,GAAG,IAAoD,CAAC;QACrE,OAAO,IAAA,sBAAc,EAAC,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IAChD,CAAC;IACD,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;QACxB,OAAO,IAAI,CAAC,GAAG,CAAC,sBAAc,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC3C,CAAC;IACD,OAAO,EAAE,CAAC;AACZ,CAAC,CAAC;AAhBW,QAAA,cAAc,kBAgBzB;AAEF;;GAEG;AACI,MAAM,6BAA6B,GAAG,CAC3C,IAAqB,EACrB,aAAqB,EACrB,iBAAiB,GAAG,IAAI,EACG,EAAE;IAC7B,0DAA0D;IAC1D,MAAM,cAAc,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC;QACxC,CAAC,CAAC,eAAK,CAAC,aAAa,CAAC,eAAK,CAAC,QAAQ,EAAE,IAAI,EAAE,GAAG,IAAI,CAAC;QACpD,CAAC,CAAC,IAAI,CAAC;IAET,2EAA2E;IAC3E,MAAM,WAAW,GAAG,IAAA,sBAAc,EAAC,cAAc,CAAC,CAAC,MAAM,CAAC;IAE1D,IAAI,WAAW,IAAI,aAAa,EAAE,CAAC;QACjC,OAAO,EAAE,eAAe,EAAE,KAAK,EAAE,gBAAgB,EAAE,IAAI,EAAE,CAAC;IAC5D,CAAC;IAED,IAAI,SAAS,GAAG,CAAC,CAAC;IAClB,IAAI,eAAe,GAAG,KAAK,CAAC;IAE5B,MAAM,YAAY,GAAG,CAAC,WAA4B,EAAmB,EAAE;QACrE,gDAAgD;QAChD,IAAI,eAAe,IAAI,SAAS,IAAI,aAAa,EAAE,CAAC;YAClD,eAAe,GAAG,IAAI,CAAC;YACvB,OAAO,IAAI,CAAC;QACd,CAAC;QAED,iDAAiD;QACjD,IAAI,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE,CAAC;YAC/B,MAAM,iBAAiB,GAAsB,EAAE,CAAC;YAEhD,KAAK,MAAM,KAAK,IAAI,WAAW,EAAE,CAAC;gBAChC,IAAI,eAAe,IAAI,SAAS,IAAI,aAAa,EAAE,CAAC;oBAClD,MAAM;gBACR,CAAC;gBAED,MAAM,cAAc,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;gBAC3C,IAAI,cAAc,KAAK,IAAI,EAAE,CAAC;oBAC5B,iBAAiB,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;gBACzC,CAAC;YACH,CAAC;YAED,OAAO,iBAAiB,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,IAAI,CAAC;QACjE,CAAC;QAED,IAAI,OAAO,WAAW,KAAK,QAAQ,EAAE,CAAC;YACpC,MAAM,cAAc,GAAG,aAAa,GAAG,SAAS,CAAC;YAEjD,IAAI,WAAW,CAAC,MAAM,IAAI,cAAc,EAAE,CAAC;gBACzC,SAAS,IAAI,WAAW,CAAC,MAAM,CAAC;gBAChC,OAAO,WAAW,CAAC;YACrB,CAAC;YAED,0DAA0D;YAC1D,IAAI,SAAS,GAAG,WAAW,CAAC,SAAS,CAAC,CAAC,EAAE,cAAc,CAAC,CAAC;YACzD,MAAM,cAAc,GAAG,SAAS,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;YAElD,IAAI,cAAc,GAAG,cAAc,GAAG,8BAAkB,CAAC,aAAa,EAAE,CAAC;gBACvE,SAAS,GAAG,SAAS,CAAC,SAAS,CAAC,CAAC,EAAE,cAAc,CAAC,CAAC;YACrD,CAAC;YAED,SAAS,GAAG,SAAS,CAAC,IAAI,EAAE,CAAC;YAC7B,SAAS,IAAI,SAAS,CAAC,MAAM,CAAC;YAC9B,eAAe,GAAG,IAAI,CAAC;YACvB,OAAO,SAAS,CAAC;QACnB,CAAC;QAED,IAAI,OAAO,WAAW,KAAK,QAAQ,EAAE,CAAC;YACpC,MAAM,GAAG,GAAG,WAAW,CAAC,QAAQ,EAAE,CAAC;YACnC,MAAM,cAAc,GAAG,aAAa,GAAG,SAAS,CAAC;YAEjD,IAAI,GAAG,CAAC,MAAM,IAAI,cAAc,EAAE,CAAC;gBACjC,SAAS,IAAI,GAAG,CAAC,MAAM,CAAC;gBACxB,OAAO,WAAW,CAAC;YACrB,CAAC;YAED,MAAM,SAAS,GAAG,GAAG,CAAC,SAAS,CAAC,CAAC,EAAE,cAAc,CAAC,CAAC;YACnD,SAAS,IAAI,SAAS,CAAC,MAAM,CAAC;YAC9B,eAAe,GAAG,IAAI,CAAC;YACvB,OAAO,SAAS,CAAC;QACnB,CAAC;QAED,IAAI,CAAC,eAAK,CAAC,cAAc,CAAC,WAAW,CAAC,EAAE,CAAC;YACvC,OAAO,WAAW,CAAC;QACrB,CAAC;QAED,MAAM,EAAE,QAAQ,EAAE,GAAG,WAAW,CAAC,KAAiC,CAAC;QACnE,IAAI,QAAQ,KAAK,IAAI,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;YAChD,OAAO,WAAW,CAAC;QACrB,CAAC;QAED,IAAI,OAAO,QAAQ,KAAK,QAAQ,EAAE,CAAC;YACjC,MAAM,cAAc,GAAG,YAAY,CAAC,QAAQ,CAAC,CAAC;YAC9C,IAAI,cAAc,KAAK,IAAI,EAAE,CAAC;gBAC5B,OAAO,IAAI,CAAC;YACd,CAAC;YACD,OAAO,eAAK,CAAC,YAAY,CAAC,WAAW,EAAE,EAAE,EAAE,cAAc,CAAC,CAAC;QAC7D,CAAC;QAED,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC5B,MAAM,iBAAiB,GAAsB,EAAE,CAAC;YAChD,KAAK,MAAM,KAAK,IAAI,QAAQ,EAAE,CAAC;gBAC7B,IAAI,eAAe,IAAI,SAAS,IAAI,aAAa,EAAE,CAAC;oBAClD,MAAM;gBACR,CAAC;gBAED,MAAM,cAAc,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;gBAC3C,IAAI,cAAc,KAAK,IAAI,EAAE,CAAC;oBAC5B,iBAAiB,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;gBACzC,CAAC;YACH,CAAC;YAED,IAAI,iBAAiB,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACnC,OAAO,IAAI,CAAC;YACd,CAAC;YACD,OAAO,eAAK,CAAC,YAAY,CAAC,WAAW,EAAE,EAAE,EAAE,GAAG,iBAAiB,CAAC,CAAC;QACnE,CAAC;QAED,6BAA6B;QAC7B,MAAM,cAAc,GAAG,YAAY,CAAC,QAAQ,CAAC,CAAC;QAC9C,IAAI,cAAc,KAAK,IAAI,EAAE,CAAC;YAC5B,OAAO,IAAI,CAAC;QACd,CAAC;QACD,OAAO,eAAK,CAAC,YAAY,CAAC,WAAW,EAAE,EAAE,EAAE,cAAc,CAAC,CAAC;IAC7D,CAAC,CAAC;IAEF,MAAM,eAAe,GAAG,YAAY,CAAC,cAAc,CAAC,CAAC;IAErD,iDAAiD;IACjD,MAAM,WAAW,GAAG,KAAK,CAAC,OAAO,CAAC,eAAe,CAAC;QAChD,CAAC,CAAC,eAAK,CAAC,aAAa,CAAC,eAAK,CAAC,QAAQ,EAAE,IAAI,EAAE,GAAG,eAAe,CAAC;QAC/D,CAAC,CAAC,eAAe,CAAC;IAEpB,yBAAyB;IACzB,IAAI,iBAAiB,IAAI,WAAW,KAAK,IAAI,EAAE,CAAC;QAC9C,MAAM,YAAY,GAAG,eAAK,CAAC,aAAa,CACtC,eAAK,CAAC,QAAQ,EACd,IAAI,EACJ,WAAW,EACX,yBAAa,CACd,CAAC;QACF,OAAO,EAAE,eAAe,EAAE,IAAI,EAAE,gBAAgB,EAAE,YAAY,EAAE,CAAC;IACnE,CAAC;IAED,OAAO;QACL,eAAe,EAAE,IAAI;QACrB,gBAAgB,EAAE,WAAW;KAC9B,CAAC;AACJ,CAAC,CAAC;AApJW,QAAA,6BAA6B,iCAoJxC","sourcesContent":["/**\n *\n * Copyright (c) \"Neo4j\"\n * Neo4j Sweden AB [http://neo4j.com]\n *\n * This file is part of Neo4j.\n *\n * Neo4j is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\nimport React, { type ReactNode } from 'react';\n\nimport { ELLIPSIS_CHAR, ESTIMATION_FACTORS } from './constants';\n\ntype ReactNodeTruncationResult = {\n needsTruncation: boolean;\n truncatedContent: React.ReactNode | null;\n};\n\n/**\n * Recursively extracts plain text from React nodes\n */\nexport const getTextContent = (node: React.ReactNode): string => {\n if (typeof node === 'string') {\n return node;\n }\n if (typeof node === 'number') {\n return node.toString();\n }\n if (React.isValidElement(node)) {\n // Type assertion to access props safely\n const element = node as React.ReactElement<{ children?: ReactNode }>;\n return getTextContent(element.props.children);\n }\n if (Array.isArray(node)) {\n return node.map(getTextContent).join('');\n }\n return '';\n};\n\n/**\n * Truncates React node content by character count while preserving element structure.\n */\nexport const truncateReactNodeByCharacters = (\n node: React.ReactNode,\n maxCharacters: number,\n shouldAddEllipsis = true,\n): ReactNodeTruncationResult => {\n // Handle the case where node is an array (React children)\n const normalizedNode = Array.isArray(node)\n ? React.createElement(React.Fragment, null, ...node)\n : node;\n\n // Get the total character count first to determine if truncation is needed\n const totalLength = getTextContent(normalizedNode).length;\n\n if (totalLength <= maxCharacters) {\n return { needsTruncation: false, truncatedContent: null };\n }\n\n let charCount = 0;\n let hasReachedLimit = false;\n\n const truncateNode = (currentNode: React.ReactNode): React.ReactNode => {\n // Stop processing if character limit is reached\n if (hasReachedLimit || charCount >= maxCharacters) {\n hasReachedLimit = true;\n return null;\n }\n\n // Handle arrays of children (mixed content case)\n if (Array.isArray(currentNode)) {\n const truncatedChildren: React.ReactNode[] = [];\n\n for (const child of currentNode) {\n if (hasReachedLimit || charCount >= maxCharacters) {\n break;\n }\n\n const truncatedChild = truncateNode(child);\n if (truncatedChild !== null) {\n truncatedChildren.push(truncatedChild);\n }\n }\n\n return truncatedChildren.length > 0 ? truncatedChildren : null;\n }\n\n if (typeof currentNode === 'string') {\n const availableChars = maxCharacters - charCount;\n\n if (currentNode.length <= availableChars) {\n charCount += currentNode.length;\n return currentNode;\n }\n\n // Truncate at character limit, preferring word boundaries\n let truncated = currentNode.substring(0, availableChars);\n const lastSpaceIndex = truncated.lastIndexOf(' ');\n\n if (lastSpaceIndex > availableChars * ESTIMATION_FACTORS.WORD_BOUNDARY) {\n truncated = truncated.substring(0, lastSpaceIndex);\n }\n\n truncated = truncated.trim();\n charCount += truncated.length;\n hasReachedLimit = true;\n return truncated;\n }\n\n if (typeof currentNode === 'number') {\n const str = currentNode.toString();\n const availableChars = maxCharacters - charCount;\n\n if (str.length <= availableChars) {\n charCount += str.length;\n return currentNode;\n }\n\n const truncated = str.substring(0, availableChars);\n charCount += truncated.length;\n hasReachedLimit = true;\n return truncated;\n }\n\n if (!React.isValidElement(currentNode)) {\n return currentNode;\n }\n\n const { children } = currentNode.props as { children?: ReactNode };\n if (children === null || children === undefined) {\n return currentNode;\n }\n\n if (typeof children === 'string') {\n const truncatedChild = truncateNode(children);\n if (truncatedChild === null) {\n return null;\n }\n return React.cloneElement(currentNode, {}, truncatedChild);\n }\n\n if (Array.isArray(children)) {\n const truncatedChildren: React.ReactNode[] = [];\n for (const child of children) {\n if (hasReachedLimit || charCount >= maxCharacters) {\n break;\n }\n\n const truncatedChild = truncateNode(child);\n if (truncatedChild !== null) {\n truncatedChildren.push(truncatedChild);\n }\n }\n\n if (truncatedChildren.length === 0) {\n return null;\n }\n return React.cloneElement(currentNode, {}, ...truncatedChildren);\n }\n\n // Single React element child\n const truncatedChild = truncateNode(children);\n if (truncatedChild === null) {\n return null;\n }\n return React.cloneElement(currentNode, {}, truncatedChild);\n };\n\n const truncatedResult = truncateNode(normalizedNode);\n\n // Convert array results to proper React elements\n const finalResult = Array.isArray(truncatedResult)\n ? React.createElement(React.Fragment, null, ...truncatedResult)\n : truncatedResult;\n\n // Add ellipsis if needed\n if (shouldAddEllipsis && finalResult !== null) {\n const withEllipsis = React.createElement(\n React.Fragment,\n null,\n finalResult,\n ELLIPSIS_CHAR,\n );\n return { needsTruncation: true, truncatedContent: withEllipsis };\n }\n\n return {\n needsTruncation: true,\n truncatedContent: finalResult,\n };\n};\n"]}
1
+ {"version":3,"file":"text-overflow-utils.js","sourceRoot":"","sources":["../../../src/text-overflow/text-overflow-utils.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n *\n * Copyright (c) \"Neo4j\"\n * Neo4j Sweden AB [http://neo4j.com]\n *\n * This file is part of Neo4j.\n *\n * Neo4j is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\nimport React, { type ReactNode } from 'react';\n\nimport { ELLIPSIS_CHAR, ESTIMATION_FACTORS } from './constants';\n\ntype ReactNodeTruncationResult = {\n shouldTruncation: boolean;\n truncatedContent: React.ReactNode | null;\n};\n\n/**\n * Recursively extracts plain text from React nodes\n */\nexport const getTextContent = (node: React.ReactNode): string => {\n if (typeof node === 'string') {\n return node;\n }\n if (typeof node === 'number') {\n return node.toString();\n }\n if (React.isValidElement(node)) {\n // Type assertion to access props safely\n const element = node as React.ReactElement<{ children?: ReactNode }>;\n return getTextContent(element.props.children);\n }\n if (Array.isArray(node)) {\n return node.map(getTextContent).join('');\n }\n return '';\n};\n\n/**\n * Truncates React node content by character count while preserving element structure.\n */\nexport const truncateReactNodeByCharacters = (\n node: React.ReactNode,\n maxCharacters: number,\n shouldAddEllipsis = true,\n): ReactNodeTruncationResult => {\n // Handle the case where node is an array (React children)\n const normalizedNode = Array.isArray(node)\n ? React.createElement(React.Fragment, null, ...node)\n : node;\n\n // Get the total character count first to determine if truncation is needed\n const totalLength = getTextContent(normalizedNode).length;\n\n if (totalLength <= maxCharacters) {\n return { shouldTruncation: false, truncatedContent: null };\n }\n\n let charCount = 0;\n let hasReachedLimit = false;\n\n const truncateNode = (currentNode: React.ReactNode): React.ReactNode => {\n // Stop processing if character limit is reached\n if (hasReachedLimit || charCount >= maxCharacters) {\n hasReachedLimit = true;\n return null;\n }\n\n // Handle arrays of children (mixed content case)\n if (Array.isArray(currentNode)) {\n const truncatedChildren: React.ReactNode[] = [];\n\n for (const child of currentNode) {\n if (hasReachedLimit || charCount >= maxCharacters) {\n break;\n }\n\n const truncatedChild = truncateNode(child);\n if (truncatedChild !== null) {\n truncatedChildren.push(truncatedChild);\n }\n }\n\n return truncatedChildren.length > 0 ? truncatedChildren : null;\n }\n\n if (typeof currentNode === 'string') {\n const availableChars = maxCharacters - charCount;\n\n if (currentNode.length <= availableChars) {\n charCount += currentNode.length;\n return currentNode;\n }\n\n // Truncate at character limit, preferring word boundaries\n let truncated = currentNode.substring(0, availableChars);\n const lastSpaceIndex = truncated.lastIndexOf(' ');\n\n if (lastSpaceIndex > availableChars * ESTIMATION_FACTORS.WORD_BOUNDARY) {\n truncated = truncated.substring(0, lastSpaceIndex);\n }\n\n truncated = truncated.trim();\n charCount += truncated.length;\n hasReachedLimit = true;\n return truncated;\n }\n\n if (typeof currentNode === 'number') {\n const str = currentNode.toString();\n const availableChars = maxCharacters - charCount;\n\n if (str.length <= availableChars) {\n charCount += str.length;\n return currentNode;\n }\n\n const truncated = str.substring(0, availableChars);\n charCount += truncated.length;\n hasReachedLimit = true;\n return truncated;\n }\n\n if (!React.isValidElement(currentNode)) {\n return currentNode;\n }\n\n const { children } = currentNode.props as { children?: ReactNode };\n if (children === null || children === undefined) {\n return currentNode;\n }\n\n if (typeof children === 'string') {\n const truncatedChild = truncateNode(children);\n if (truncatedChild === null) {\n return null;\n }\n return React.cloneElement(currentNode, {}, truncatedChild);\n }\n\n if (Array.isArray(children)) {\n const truncatedChildren: React.ReactNode[] = [];\n for (const child of children) {\n if (hasReachedLimit || charCount >= maxCharacters) {\n break;\n }\n\n const truncatedChild = truncateNode(child);\n if (truncatedChild !== null) {\n truncatedChildren.push(truncatedChild);\n }\n }\n\n if (truncatedChildren.length === 0) {\n return null;\n }\n return React.cloneElement(currentNode, {}, ...truncatedChildren);\n }\n\n // Single React element child\n const truncatedChild = truncateNode(children);\n if (truncatedChild === null) {\n return null;\n }\n return React.cloneElement(currentNode, {}, truncatedChild);\n };\n\n const truncatedResult = truncateNode(normalizedNode);\n\n // Convert array results to proper React elements\n const finalResult = Array.isArray(truncatedResult)\n ? React.createElement(React.Fragment, null, ...truncatedResult)\n : truncatedResult;\n\n // Add ellipsis if needed\n if (shouldAddEllipsis && finalResult !== null) {\n const withEllipsis = React.createElement(\n React.Fragment,\n null,\n finalResult,\n ELLIPSIS_CHAR,\n );\n return { shouldTruncation: true, truncatedContent: withEllipsis };\n }\n\n return {\n shouldTruncation: true,\n truncatedContent: finalResult,\n };\n};\n"]}
@@ -114,8 +114,8 @@ function useTruncateWithButton({ content, lineClamp, button, onExpandedToggle, m
114
114
  // Character-based truncation takes precedence
115
115
  if (typeof maxCharacters === 'number') {
116
116
  const result = (0, text_overflow_utils_1.truncateReactNodeByCharacters)(content, maxCharacters);
117
- setIsTruncated(result.needsTruncation);
118
- setTruncatedContent(result.needsTruncation ? result.truncatedContent : content);
117
+ setIsTruncated(result.shouldTruncation);
118
+ setTruncatedContent(result.shouldTruncation ? result.truncatedContent : content);
119
119
  return;
120
120
  }
121
121
  // Fallback to line-based truncation
@@ -1 +1 @@
1
- {"version":3,"file":"use-truncate-with-button.js","sourceRoot":"","sources":["../../../src/text-overflow/use-truncate-with-button.tsx"],"names":[],"mappings":"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","sourcesContent":["/**\n *\n * Copyright (c) \"Neo4j\"\n * Neo4j Sweden AB [http://neo4j.com]\n *\n * This file is part of Neo4j.\n *\n * Neo4j is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\nimport { tokens } from '@neo4j-ndl/base';\nimport {\n type ReactNode,\n useCallback,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\n\nimport { useDebounceCallback } from '../hooks';\nimport {\n getTextContent,\n truncateReactNodeByCharacters,\n} from './text-overflow-utils';\n\n// Cache for computed styles to avoid repeated getComputedStyle calls\nconst styleCache = new WeakMap<HTMLElement, CSSStyleDeclaration>();\n\n// Helper function to copy relevant styles for measurement\nconst copyStylesForMeasurement = (\n measureElement: HTMLElement,\n sourceElement: HTMLElement,\n) => {\n // Use cached styles if available\n let sourceStyles = styleCache.get(sourceElement);\n if (sourceStyles === undefined) {\n sourceStyles = window.getComputedStyle(sourceElement);\n styleCache.set(sourceElement, sourceStyles);\n }\n\n measureElement.style.position = 'absolute';\n measureElement.style.visibility = 'hidden';\n measureElement.style.top = '-9999px';\n measureElement.style.left = '-9999px';\n measureElement.style.width = sourceStyles.width;\n measureElement.style.fontFamily = sourceStyles.fontFamily;\n measureElement.style.fontSize = sourceStyles.fontSize;\n measureElement.style.fontWeight = sourceStyles.fontWeight;\n measureElement.style.lineHeight = sourceStyles.lineHeight;\n measureElement.style.letterSpacing = sourceStyles.letterSpacing;\n measureElement.style.wordSpacing = sourceStyles.wordSpacing;\n measureElement.style.overflow = 'hidden';\n measureElement.style.wordBreak = 'break-word';\n};\n\n// Helper function to find the optimal truncation point using optimized binary search\nconst findTruncationPoint = (\n content: ReactNode,\n allText: string,\n measureElement: HTMLElement,\n maxHeight: number,\n button: ReactNode,\n buttonType?: 'view-more' | 'ellipsis',\n) => {\n let low = 0;\n let high = allText.length;\n let bestFitContent: ReactNode = null;\n\n // Pre-calculate button text to avoid repeated string operations\n const buttonText = typeof button === 'string' ? button : 'View more';\n const buttonMargin = buttonType !== 'ellipsis' ? tokens.space[4] : '0';\n\n // Create reusable DOM elements to avoid repeated creation\n const tempSpan = document.createElement('span');\n const btnSpan = document.createElement('span');\n btnSpan.style.display = 'inline-block';\n btnSpan.style.marginLeft = buttonMargin;\n\n while (low <= high) {\n const mid = Math.floor((low + high) / 2);\n const testText = allText.slice(0, mid);\n\n measureElement.innerHTML = '';\n\n // Reuse span elements\n tempSpan.textContent =\n buttonType === 'ellipsis' ? testText : `${testText}\\u2026`;\n measureElement.appendChild(tempSpan);\n\n btnSpan.textContent = buttonText;\n measureElement.appendChild(btnSpan);\n\n if (measureElement.scrollHeight <= maxHeight) {\n bestFitContent = truncateReactNodeByCharacters(\n content,\n mid,\n buttonType !== 'ellipsis',\n ).truncatedContent;\n low = mid + 1;\n } else {\n high = mid - 1;\n }\n }\n\n return bestFitContent;\n};\n\ninterface UseTruncateOptions {\n button: ReactNode;\n content: ReactNode;\n lineClamp: number;\n onExpandedToggle?: (isExpanded: boolean) => void;\n maxCharacters?: number;\n buttonType?: 'view-more' | 'ellipsis';\n closeTooltip?: () => void;\n /**\n * When true, skips all expensive DOM calculations and measurements.\n * Useful for performance optimization when the hook functionality isn't needed.\n */\n isDisabled?: boolean;\n}\n\nexport function useTruncateWithButton({\n content,\n lineClamp,\n button,\n onExpandedToggle,\n maxCharacters,\n buttonType,\n closeTooltip,\n isDisabled,\n}: UseTruncateOptions) {\n const containerRef = useRef<HTMLDivElement>(null);\n const measureRef = useRef<HTMLDivElement>(null);\n\n const [isExpanded, setIsExpanded] = useState(false);\n const [isTruncated, setIsTruncated] = useState(false);\n const [truncatedContent, setTruncatedContent] = useState<ReactNode>(content);\n\n // Memoize text content to avoid repeated traversals\n const textContent = useMemo(() => getTextContent(content), [content]);\n\n const toggleExpand = useCallback(() => {\n if (isDisabled === true) {\n return;\n }\n\n const shouldExpand = !isExpanded;\n setIsExpanded(shouldExpand);\n\n if (shouldExpand) {\n onExpandedToggle?.(true);\n closeTooltip?.();\n } else {\n onExpandedToggle?.(false);\n }\n }, [isExpanded, onExpandedToggle, closeTooltip, isDisabled]);\n\n const recalculateTruncation = useCallback(() => {\n // If disabled, don't perform any calculations\n if (isDisabled === true) {\n setIsTruncated(false);\n setTruncatedContent(content);\n return;\n }\n\n // Character-based truncation takes precedence\n if (typeof maxCharacters === 'number') {\n const result = truncateReactNodeByCharacters(content, maxCharacters);\n setIsTruncated(result.needsTruncation);\n setTruncatedContent(\n result.needsTruncation ? result.truncatedContent : content,\n );\n return;\n }\n\n // Fallback to line-based truncation\n if (!measureRef.current || !containerRef.current) {\n return;\n }\n\n const measure = measureRef.current;\n const container = containerRef.current;\n\n copyStylesForMeasurement(measure, container);\n const containerStyles = window.getComputedStyle(container);\n const lineHeight = parseFloat(containerStyles.lineHeight);\n const maxHeight = lineHeight * lineClamp;\n\n const allText = textContent;\n\n // Early exit if no text content\n if (allText.length === 0) {\n setIsTruncated(false);\n setTruncatedContent(content);\n return;\n }\n\n // First, check if truncation is needed at all\n measure.innerHTML = '';\n const fullTextSpan = document.createElement('span');\n fullTextSpan.textContent = allText;\n measure.appendChild(fullTextSpan);\n\n const isTruncationNeeded = measure.scrollHeight > maxHeight;\n\n if (!isTruncationNeeded) {\n setIsTruncated(false);\n setTruncatedContent(content);\n return;\n }\n\n // Binary search for truncation point\n const bestFitContent = findTruncationPoint(\n content,\n allText,\n measure,\n maxHeight,\n button,\n buttonType,\n );\n\n setIsTruncated(true);\n setTruncatedContent(bestFitContent);\n }, [\n content,\n button,\n lineClamp,\n maxCharacters,\n buttonType,\n isDisabled,\n textContent,\n ]);\n\n // Create debounced version of recalculateTruncation for resize events\n const debouncedRecalculateTruncation = useDebounceCallback(\n recalculateTruncation,\n 100,\n );\n\n // Initial calculation and resize handling\n useLayoutEffect(() => {\n // If disabled, don't set up any observers or event listeners\n if (isDisabled === true) {\n return;\n }\n\n recalculateTruncation();\n\n // Set up resize observer for container size changes\n const container = containerRef.current;\n if (!container) {\n return;\n }\n\n const resizeObserver = new ResizeObserver(() => {\n debouncedRecalculateTruncation();\n });\n\n resizeObserver.observe(container);\n\n // Also observe parent element to catch container size changes\n if (container.parentElement) {\n resizeObserver.observe(container.parentElement);\n }\n\n // Handle window resize events\n const handleWindowResize = () => {\n debouncedRecalculateTruncation();\n };\n\n window.addEventListener('resize', handleWindowResize);\n\n return () => {\n resizeObserver.disconnect();\n window.removeEventListener('resize', handleWindowResize);\n };\n }, [recalculateTruncation, debouncedRecalculateTruncation, isDisabled]);\n\n // Compute the final content to render based on expanded state\n const contentToRender = isExpanded ? content : truncatedContent;\n\n return {\n containerRef,\n contentToRender,\n isExpanded,\n isTruncated,\n measureRef,\n toggleExpand,\n };\n}\n"]}
1
+ {"version":3,"file":"use-truncate-with-button.js","sourceRoot":"","sources":["../../../src/text-overflow/use-truncate-with-button.tsx"],"names":[],"mappings":"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","sourcesContent":["/**\n *\n * Copyright (c) \"Neo4j\"\n * Neo4j Sweden AB [http://neo4j.com]\n *\n * This file is part of Neo4j.\n *\n * Neo4j is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\nimport { tokens } from '@neo4j-ndl/base';\nimport {\n type ReactNode,\n useCallback,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\n\nimport { useDebounceCallback } from '../hooks';\nimport {\n getTextContent,\n truncateReactNodeByCharacters,\n} from './text-overflow-utils';\n\n// Cache for computed styles to avoid repeated getComputedStyle calls\nconst styleCache = new WeakMap<HTMLElement, CSSStyleDeclaration>();\n\n// Helper function to copy relevant styles for measurement\nconst copyStylesForMeasurement = (\n measureElement: HTMLElement,\n sourceElement: HTMLElement,\n) => {\n // Use cached styles if available\n let sourceStyles = styleCache.get(sourceElement);\n if (sourceStyles === undefined) {\n sourceStyles = window.getComputedStyle(sourceElement);\n styleCache.set(sourceElement, sourceStyles);\n }\n\n measureElement.style.position = 'absolute';\n measureElement.style.visibility = 'hidden';\n measureElement.style.top = '-9999px';\n measureElement.style.left = '-9999px';\n measureElement.style.width = sourceStyles.width;\n measureElement.style.fontFamily = sourceStyles.fontFamily;\n measureElement.style.fontSize = sourceStyles.fontSize;\n measureElement.style.fontWeight = sourceStyles.fontWeight;\n measureElement.style.lineHeight = sourceStyles.lineHeight;\n measureElement.style.letterSpacing = sourceStyles.letterSpacing;\n measureElement.style.wordSpacing = sourceStyles.wordSpacing;\n measureElement.style.overflow = 'hidden';\n measureElement.style.wordBreak = 'break-word';\n};\n\n// Helper function to find the optimal truncation point using optimized binary search\nconst findTruncationPoint = (\n content: ReactNode,\n allText: string,\n measureElement: HTMLElement,\n maxHeight: number,\n button: ReactNode,\n buttonType?: 'view-more' | 'ellipsis',\n) => {\n let low = 0;\n let high = allText.length;\n let bestFitContent: ReactNode = null;\n\n // Pre-calculate button text to avoid repeated string operations\n const buttonText = typeof button === 'string' ? button : 'View more';\n const buttonMargin = buttonType !== 'ellipsis' ? tokens.space[4] : '0';\n\n // Create reusable DOM elements to avoid repeated creation\n const tempSpan = document.createElement('span');\n const btnSpan = document.createElement('span');\n btnSpan.style.display = 'inline-block';\n btnSpan.style.marginLeft = buttonMargin;\n\n while (low <= high) {\n const mid = Math.floor((low + high) / 2);\n const testText = allText.slice(0, mid);\n\n measureElement.innerHTML = '';\n\n // Reuse span elements\n tempSpan.textContent =\n buttonType === 'ellipsis' ? testText : `${testText}\\u2026`;\n measureElement.appendChild(tempSpan);\n\n btnSpan.textContent = buttonText;\n measureElement.appendChild(btnSpan);\n\n if (measureElement.scrollHeight <= maxHeight) {\n bestFitContent = truncateReactNodeByCharacters(\n content,\n mid,\n buttonType !== 'ellipsis',\n ).truncatedContent;\n low = mid + 1;\n } else {\n high = mid - 1;\n }\n }\n\n return bestFitContent;\n};\n\ninterface UseTruncateOptions {\n button: ReactNode;\n content: ReactNode;\n lineClamp: number;\n onExpandedToggle?: (isExpanded: boolean) => void;\n maxCharacters?: number;\n buttonType?: 'view-more' | 'ellipsis';\n closeTooltip?: () => void;\n /**\n * When true, skips all expensive DOM calculations and measurements.\n * Useful for performance optimization when the hook functionality isn't needed.\n */\n isDisabled?: boolean;\n}\n\nexport function useTruncateWithButton({\n content,\n lineClamp,\n button,\n onExpandedToggle,\n maxCharacters,\n buttonType,\n closeTooltip,\n isDisabled,\n}: UseTruncateOptions) {\n const containerRef = useRef<HTMLDivElement>(null);\n const measureRef = useRef<HTMLDivElement>(null);\n\n const [isExpanded, setIsExpanded] = useState(false);\n const [isTruncated, setIsTruncated] = useState(false);\n const [truncatedContent, setTruncatedContent] = useState<ReactNode>(content);\n\n // Memoize text content to avoid repeated traversals\n const textContent = useMemo(() => getTextContent(content), [content]);\n\n const toggleExpand = useCallback(() => {\n if (isDisabled === true) {\n return;\n }\n\n const shouldExpand = !isExpanded;\n setIsExpanded(shouldExpand);\n\n if (shouldExpand) {\n onExpandedToggle?.(true);\n closeTooltip?.();\n } else {\n onExpandedToggle?.(false);\n }\n }, [isExpanded, onExpandedToggle, closeTooltip, isDisabled]);\n\n const recalculateTruncation = useCallback(() => {\n // If disabled, don't perform any calculations\n if (isDisabled === true) {\n setIsTruncated(false);\n setTruncatedContent(content);\n return;\n }\n\n // Character-based truncation takes precedence\n if (typeof maxCharacters === 'number') {\n const result = truncateReactNodeByCharacters(content, maxCharacters);\n setIsTruncated(result.shouldTruncation);\n setTruncatedContent(\n result.shouldTruncation ? result.truncatedContent : content,\n );\n return;\n }\n\n // Fallback to line-based truncation\n if (!measureRef.current || !containerRef.current) {\n return;\n }\n\n const measure = measureRef.current;\n const container = containerRef.current;\n\n copyStylesForMeasurement(measure, container);\n const containerStyles = window.getComputedStyle(container);\n const lineHeight = parseFloat(containerStyles.lineHeight);\n const maxHeight = lineHeight * lineClamp;\n\n const allText = textContent;\n\n // Early exit if no text content\n if (allText.length === 0) {\n setIsTruncated(false);\n setTruncatedContent(content);\n return;\n }\n\n // First, check if truncation is needed at all\n measure.innerHTML = '';\n const fullTextSpan = document.createElement('span');\n fullTextSpan.textContent = allText;\n measure.appendChild(fullTextSpan);\n\n const isTruncationNeeded = measure.scrollHeight > maxHeight;\n\n if (!isTruncationNeeded) {\n setIsTruncated(false);\n setTruncatedContent(content);\n return;\n }\n\n // Binary search for truncation point\n const bestFitContent = findTruncationPoint(\n content,\n allText,\n measure,\n maxHeight,\n button,\n buttonType,\n );\n\n setIsTruncated(true);\n setTruncatedContent(bestFitContent);\n }, [\n content,\n button,\n lineClamp,\n maxCharacters,\n buttonType,\n isDisabled,\n textContent,\n ]);\n\n // Create debounced version of recalculateTruncation for resize events\n const debouncedRecalculateTruncation = useDebounceCallback(\n recalculateTruncation,\n 100,\n );\n\n // Initial calculation and resize handling\n useLayoutEffect(() => {\n // If disabled, don't set up any observers or event listeners\n if (isDisabled === true) {\n return;\n }\n\n recalculateTruncation();\n\n // Set up resize observer for container size changes\n const container = containerRef.current;\n if (!container) {\n return;\n }\n\n const resizeObserver = new ResizeObserver(() => {\n debouncedRecalculateTruncation();\n });\n\n resizeObserver.observe(container);\n\n // Also observe parent element to catch container size changes\n if (container.parentElement) {\n resizeObserver.observe(container.parentElement);\n }\n\n // Handle window resize events\n const handleWindowResize = () => {\n debouncedRecalculateTruncation();\n };\n\n window.addEventListener('resize', handleWindowResize);\n\n return () => {\n resizeObserver.disconnect();\n window.removeEventListener('resize', handleWindowResize);\n };\n }, [recalculateTruncation, debouncedRecalculateTruncation, isDisabled]);\n\n // Compute the final content to render based on expanded state\n const contentToRender = isExpanded ? content : truncatedContent;\n\n return {\n containerRef,\n contentToRender,\n isExpanded,\n isTruncated,\n measureRef,\n toggleExpand,\n };\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"Tooltip.js","sourceRoot":"","sources":["../../../src/tooltip/Tooltip.tsx"],"names":[],"mappings":"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","sourcesContent":["/**\n *\n * Copyright (c) \"Neo4j\"\n * Neo4j Sweden AB [http://neo4j.com]\n *\n * This file is part of Neo4j.\n *\n * Neo4j is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\nimport {\n type AutoUpdateOptions,\n FloatingFocusManager,\n FloatingPortal,\n type Placement,\n type UseFloatingOptions,\n useMergeRefs,\n} from '@floating-ui/react';\nimport classNames from 'classnames';\nimport React, { useEffect } from 'react';\n\nimport { type CommonProps } from '../_common/types';\nimport { ConditionalWrap } from '../conditional-wrap';\nimport { useIsInsideDialog } from '../dialog/dialog-context';\nimport { useNeedleTheme } from '../theme';\nimport { Typography, type TypographyVariants } from '../typography';\nimport { TooltipContext, useTooltip, useTooltipContext } from './use-tooltip';\n\nexport type TooltipProps = {\n /** Content displayed inside the tooltip. Wraps `Tooltip.Trigger`, `Tooltip.Content`, and optional parts */\n children: React.ReactNode;\n /** Whether the tooltip is disabled */\n isDisabled?: boolean;\n /** Whether the tooltip should be open on first render */\n isInitialOpen?: boolean;\n /** Placement of the tooltip content relative to the trigger */\n placement?: Placement;\n /** Controls the open state . If omitted, the tooltip manages its own state */\n isOpen?: boolean;\n // TODO v5: deprecate this prop\n /**\n * Visual style of the tooltip content. `simple` renders plain text, `rich` renders a composable panel\n * @deprecated rich type will be removed in v5, use simple type instead.\n */\n type: 'simple' | 'rich';\n /** Whether the content is rendered in a portal. */\n isPortaled?: boolean;\n /** Callback fired when the open state changes, if omitted, the tooltip manages its own state using internal hooks */\n onOpenChange?: UseFloatingOptions['onOpenChange'];\n /** Positioning strategy of the tooltip. Defaults to `fixed` when inside a dialog, otherwise `absolute` */\n floatingStrategy?: 'absolute' | 'fixed';\n /** Hover open/close delays in milliseconds */\n hoverDelay?: {\n open: number;\n close: number;\n };\n /** Whether the tooltip should close when the reference element is clicked. Useful when the trigger moves after click. */\n shouldCloseOnReferenceClick?: boolean;\n autoUpdateOptions?: AutoUpdateOptions;\n /** Whether the tooltip should follow the mouse cursor. Only applies to 'simple' tooltips with mouse hover. */\n followCursor?: boolean;\n};\n\nconst TooltipComponent = ({\n children,\n isDisabled = false,\n type,\n isInitialOpen,\n placement,\n isOpen,\n onOpenChange,\n isPortaled: isPortaledProp,\n floatingStrategy: strategyProp,\n hoverDelay,\n shouldCloseOnReferenceClick,\n autoUpdateOptions,\n followCursor,\n}: TooltipProps) => {\n const isInsideDialog = useIsInsideDialog();\n const strategy = isInsideDialog ? 'fixed' : 'absolute';\n const isPortaled = !isInsideDialog;\n\n const tooltip = useTooltip({\n autoUpdateOptions,\n followCursor,\n hoverDelay,\n isDisabled,\n isInitialOpen,\n // if isDisabled is true tooltip will not open otherwise either controlled or uncontrolled depending on if isOpen is passed\n isOpen: isDisabled === true ? false : isOpen,\n isPortaled: isPortaledProp ?? isPortaled,\n onOpenChange,\n placement,\n shouldCloseOnReferenceClick,\n strategy: strategyProp ?? strategy,\n type,\n });\n\n return (\n <TooltipContext.Provider value={tooltip}>\n {children}\n </TooltipContext.Provider>\n );\n};\n\nTooltipComponent.displayName = 'Tooltip';\n\ntype TooltipTriggerProps = {\n /** Content displayed inside the trigger element */\n children: React.ReactNode;\n /** Whether the trigger element can be any element without an extra button wrapper. The child element will be cloned with the necessary trigger props and merged refs */\n hasButtonWrapper?: boolean;\n};\n\nconst TooltipTrigger = ({\n children,\n hasButtonWrapper = false,\n htmlAttributes,\n className,\n style,\n ref,\n ...restProps\n}: CommonProps<'button', TooltipTriggerProps>) => {\n const context = useTooltipContext();\n\n // Example from floating-ui\n // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n const childrenProps = (children as any).props;\n const mergedRefs = useMergeRefs([\n context.refs.setReference,\n ref,\n childrenProps?.ref,\n ]);\n\n const triggerClasses = classNames(\n {\n 'ndl-closed': !context.isOpen,\n 'ndl-open': context.isOpen,\n },\n 'ndl-tooltip-trigger',\n className,\n );\n\n // `hasButtonWrapper=true` allows the user to pass any element as the anchor\n if (hasButtonWrapper && React.isValidElement(children)) {\n const props: Record<string, unknown> = {\n className: triggerClasses,\n ...htmlAttributes,\n ...childrenProps,\n ref: mergedRefs,\n };\n\n return React.cloneElement(children, context.getReferenceProps(props));\n }\n\n return (\n <button\n type=\"button\"\n className={triggerClasses}\n style={style}\n ref={mergedRefs}\n {...context.getReferenceProps(htmlAttributes)}\n {...restProps}\n >\n {children}\n </button>\n );\n};\n\ntype TooltipContentProps = {\n /** Content displayed inside the tooltip */\n children: React.ReactNode;\n};\n\nconst TooltipContent = ({\n children,\n style,\n htmlAttributes,\n className,\n ref,\n ...restProps\n}: CommonProps<'div', TooltipContentProps>) => {\n const context = useTooltipContext();\n const mergedRef = useMergeRefs([context.refs.setFloating, ref]);\n const { themeClassName } = useNeedleTheme();\n\n const hasHeaderChild = React.useMemo(() => {\n if (context.type !== 'rich') {\n return false;\n }\n const childrenArray = React.Children.toArray(children);\n return childrenArray.some(\n (child) => React.isValidElement(child) && child.type === TooltipHeader,\n );\n }, [children, context.type]);\n\n if (!context.isOpen) {\n return null;\n }\n\n const classes = classNames('ndl-tooltip-content', themeClassName, className, {\n 'ndl-tooltip-content-rich': context.type === 'rich',\n 'ndl-tooltip-content-simple': context.type === 'simple',\n });\n\n if (context.type === 'simple') {\n return (\n <ConditionalWrap\n shouldWrap={context.isPortaled}\n wrap={(wrapChildren) => <FloatingPortal>{wrapChildren}</FloatingPortal>}\n >\n <div\n ref={mergedRef}\n className={classes}\n style={{\n ...context.floatingStyles,\n ...style,\n }}\n {...restProps}\n {...context.getFloatingProps(htmlAttributes)}\n >\n <Typography variant=\"body-medium\">{children}</Typography>\n </div>\n </ConditionalWrap>\n );\n }\n\n const ariaLabelledBy =\n htmlAttributes?.['aria-labelledby'] ??\n (hasHeaderChild ? context.headerId : undefined);\n\n if (htmlAttributes?.['aria-label'] === undefined && !ariaLabelledBy) {\n console.warn(\n 'The rich Tooltip is missing aria-label and Header. Please add one of them for accessibility.',\n );\n }\n\n return (\n <ConditionalWrap\n shouldWrap={context.isPortaled}\n wrap={(wrapChildren) => <FloatingPortal>{wrapChildren}</FloatingPortal>}\n >\n <FloatingFocusManager\n context={context.context}\n returnFocus={true}\n modal={false}\n initialFocus={0}\n closeOnFocusOut\n >\n <div\n ref={mergedRef}\n className={classes}\n style={{\n ...context.floatingStyles,\n ...style,\n }}\n {...restProps}\n {...context.getFloatingProps({\n ...htmlAttributes,\n 'aria-labelledby': ariaLabelledBy,\n })}\n >\n {children}\n </div>\n </FloatingFocusManager>\n </ConditionalWrap>\n );\n};\n\ntype TooltipHeaderProps = {\n /** Content displayed inside the header */\n children: React.ReactNode;\n /** @deprecated Use `typographyVariant` instead */\n passThroughProps?: Partial<React.ComponentPropsWithoutRef<typeof Typography>>;\n typographyVariant?: TypographyVariants;\n};\n\nconst TooltipHeader = ({\n children,\n passThroughProps,\n typographyVariant = 'subheading-medium',\n className,\n style,\n htmlAttributes,\n ref,\n ...restProps\n}: CommonProps<'span', TooltipHeaderProps>) => {\n const context = useTooltipContext();\n\n const classes = classNames('ndl-tooltip-header', className);\n\n useEffect(() => {\n if (Boolean(htmlAttributes?.id) === true) {\n context.setHeaderId?.(htmlAttributes?.id);\n }\n }, [context, htmlAttributes?.id]);\n\n if (!context.isOpen) {\n return null;\n }\n\n return (\n <Typography\n ref={ref}\n variant={typographyVariant}\n className={classes}\n style={style}\n htmlAttributes={{ ...htmlAttributes, id: context.headerId }}\n {...passThroughProps}\n {...restProps}\n >\n {children}\n </Typography>\n );\n};\n\nexport type TooltipBodyProps = {\n /** Content displayed inside the body */\n children: React.ReactNode;\n /** Additional props to pass to the Typography component */\n // TODO v5: Deprecate passThroughProps and use restProps instead\n passThroughProps?: Partial<React.ComponentPropsWithoutRef<typeof Typography>>;\n};\n\nconst TooltipBody = ({\n children,\n className,\n style,\n htmlAttributes,\n passThroughProps,\n ref,\n ...restProps\n}: CommonProps<'span', TooltipBodyProps>) => {\n const context = useTooltipContext();\n\n const classes = classNames('ndl-tooltip-body', className);\n if (!context.isOpen) {\n return null;\n }\n\n return (\n <Typography\n ref={ref}\n variant=\"body-medium\"\n className={classes}\n style={style}\n htmlAttributes={htmlAttributes}\n {...passThroughProps}\n {...restProps}\n >\n {children}\n </Typography>\n );\n};\n\ntype ToolTipActionsProps = {\n /** Content displayed inside the actions container */\n children: React.ReactNode;\n};\n\nconst Actions = ({\n children,\n className,\n style,\n htmlAttributes,\n ref,\n ...restProps\n}: CommonProps<'div', ToolTipActionsProps>) => {\n const context = useTooltipContext();\n const mergedRefs = useMergeRefs([context.refs.setFloating, ref]);\n\n if (!context.isOpen) {\n return null;\n }\n\n const classes = classNames('ndl-tooltip-actions', className);\n\n return (\n <div\n className={classes}\n ref={mergedRefs}\n style={style}\n {...restProps}\n {...htmlAttributes}\n >\n {children}\n </div>\n );\n};\n\nActions.displayName = 'Tooltip.Actions';\n\nconst Tooltip = Object.assign(TooltipComponent, {\n Actions: Actions,\n Body: TooltipBody,\n Content: TooltipContent,\n Header: TooltipHeader,\n Trigger: TooltipTrigger,\n});\n\nexport { Tooltip };\n"]}
1
+ {"version":3,"file":"Tooltip.js","sourceRoot":"","sources":["../../../src/tooltip/Tooltip.tsx"],"names":[],"mappings":"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","sourcesContent":["/**\n *\n * Copyright (c) \"Neo4j\"\n * Neo4j Sweden AB [http://neo4j.com]\n *\n * This file is part of Neo4j.\n *\n * Neo4j is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\nimport {\n type AutoUpdateOptions,\n FloatingFocusManager,\n FloatingPortal,\n type Placement,\n type UseFloatingOptions,\n useMergeRefs,\n} from '@floating-ui/react';\nimport classNames from 'classnames';\nimport React, { useEffect } from 'react';\n\nimport { type CommonProps } from '../_common/types';\nimport { ConditionalWrap } from '../conditional-wrap';\nimport { useIsInsideDialog } from '../dialog/dialog-context';\nimport { useNeedleTheme } from '../theme';\nimport { Typography, type TypographyVariants } from '../typography';\nimport { TooltipContext, useTooltip, useTooltipContext } from './use-tooltip';\n\nexport type TooltipProps = {\n /** Content displayed inside the tooltip. Wraps `Tooltip.Trigger`, `Tooltip.Content`, and optional parts */\n children: React.ReactNode;\n /** Whether the tooltip is disabled */\n isDisabled?: boolean;\n /** Whether the tooltip should be open on first render */\n isInitialOpen?: boolean;\n /** Placement of the tooltip content relative to the trigger */\n placement?: Placement;\n /** Controls the open state . If omitted, the tooltip manages its own state */\n isOpen?: boolean;\n // TODO v5: deprecate this prop\n /**\n * Visual style of the tooltip content. `simple` renders plain text, `rich` renders a composable panel\n * @deprecated rich type will be removed in v5, use simple type instead.\n */\n type: 'simple' | 'rich';\n /** Whether the content is rendered in a portal. */\n isPortaled?: boolean;\n /** Callback fired when the open state changes, if omitted, the tooltip manages its own state using internal hooks */\n onOpenChange?: UseFloatingOptions['onOpenChange'];\n /** Positioning strategy of the tooltip. Defaults to `fixed` when inside a dialog, otherwise `absolute` */\n floatingStrategy?: 'absolute' | 'fixed';\n /** Hover open/close delays in milliseconds */\n hoverDelay?: {\n open: number;\n close: number;\n };\n /** Whether the tooltip should close when the reference element is clicked. Useful when the trigger moves after click. */\n shouldCloseOnReferenceClick?: boolean;\n autoUpdateOptions?: AutoUpdateOptions;\n /** Whether the tooltip should follow the mouse cursor. Only applies to 'simple' tooltips with mouse hover. */\n // TODO v5: rename this prop to follow lint rule\n // eslint-disable-next-line @typescript-eslint/naming-convention\n followCursor?: boolean;\n};\n\nconst TooltipComponent = ({\n children,\n isDisabled = false,\n type,\n isInitialOpen,\n placement,\n isOpen,\n onOpenChange,\n isPortaled: isPortaledProp,\n floatingStrategy: strategyProp,\n hoverDelay,\n shouldCloseOnReferenceClick,\n autoUpdateOptions,\n followCursor,\n}: TooltipProps) => {\n const isInsideDialog = useIsInsideDialog();\n const strategy = isInsideDialog ? 'fixed' : 'absolute';\n const isPortaled = !isInsideDialog;\n\n const tooltip = useTooltip({\n autoUpdateOptions,\n followCursor,\n hoverDelay,\n isDisabled,\n isInitialOpen,\n // if isDisabled is true tooltip will not open otherwise either controlled or uncontrolled depending on if isOpen is passed\n isOpen: isDisabled === true ? false : isOpen,\n isPortaled: isPortaledProp ?? isPortaled,\n onOpenChange,\n placement,\n shouldCloseOnReferenceClick,\n strategy: strategyProp ?? strategy,\n type,\n });\n\n return (\n <TooltipContext.Provider value={tooltip}>\n {children}\n </TooltipContext.Provider>\n );\n};\n\nTooltipComponent.displayName = 'Tooltip';\n\ntype TooltipTriggerProps = {\n /** Content displayed inside the trigger element */\n children: React.ReactNode;\n /** Whether the trigger element can be any element without an extra button wrapper. The child element will be cloned with the necessary trigger props and merged refs */\n hasButtonWrapper?: boolean;\n};\n\nconst TooltipTrigger = ({\n children,\n hasButtonWrapper = false,\n htmlAttributes,\n className,\n style,\n ref,\n ...restProps\n}: CommonProps<'button', TooltipTriggerProps>) => {\n const context = useTooltipContext();\n\n // Example from floating-ui\n // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n const childrenProps = (children as any).props;\n const mergedRefs = useMergeRefs([\n context.refs.setReference,\n ref,\n childrenProps?.ref,\n ]);\n\n const triggerClasses = classNames(\n {\n 'ndl-closed': !context.isOpen,\n 'ndl-open': context.isOpen,\n },\n 'ndl-tooltip-trigger',\n className,\n );\n\n // `hasButtonWrapper=true` allows the user to pass any element as the anchor\n if (hasButtonWrapper && React.isValidElement(children)) {\n const props: Record<string, unknown> = {\n className: triggerClasses,\n ...htmlAttributes,\n ...childrenProps,\n ref: mergedRefs,\n };\n\n return React.cloneElement(children, context.getReferenceProps(props));\n }\n\n return (\n <button\n type=\"button\"\n className={triggerClasses}\n style={style}\n ref={mergedRefs}\n {...context.getReferenceProps(htmlAttributes)}\n {...restProps}\n >\n {children}\n </button>\n );\n};\n\ntype TooltipContentProps = {\n /** Content displayed inside the tooltip */\n children: React.ReactNode;\n};\n\nconst TooltipContent = ({\n children,\n style,\n htmlAttributes,\n className,\n ref,\n ...restProps\n}: CommonProps<'div', TooltipContentProps>) => {\n const context = useTooltipContext();\n const mergedRef = useMergeRefs([context.refs.setFloating, ref]);\n const { themeClassName } = useNeedleTheme();\n\n const hasHeaderChild = React.useMemo(() => {\n if (context.type !== 'rich') {\n return false;\n }\n const childrenArray = React.Children.toArray(children);\n return childrenArray.some(\n (child) => React.isValidElement(child) && child.type === TooltipHeader,\n );\n }, [children, context.type]);\n\n if (!context.isOpen) {\n return null;\n }\n\n const classes = classNames('ndl-tooltip-content', themeClassName, className, {\n 'ndl-tooltip-content-rich': context.type === 'rich',\n 'ndl-tooltip-content-simple': context.type === 'simple',\n });\n\n if (context.type === 'simple') {\n return (\n <ConditionalWrap\n shouldWrap={context.isPortaled}\n wrap={(wrapChildren) => <FloatingPortal>{wrapChildren}</FloatingPortal>}\n >\n <div\n ref={mergedRef}\n className={classes}\n style={{\n ...context.floatingStyles,\n ...style,\n }}\n {...restProps}\n {...context.getFloatingProps(htmlAttributes)}\n >\n <Typography variant=\"body-medium\">{children}</Typography>\n </div>\n </ConditionalWrap>\n );\n }\n\n const ariaLabelledBy =\n htmlAttributes?.['aria-labelledby'] ??\n (hasHeaderChild ? context.headerId : undefined);\n\n if (htmlAttributes?.['aria-label'] === undefined && !ariaLabelledBy) {\n console.warn(\n 'The rich Tooltip is missing aria-label and Header. Please add one of them for accessibility.',\n );\n }\n\n return (\n <ConditionalWrap\n shouldWrap={context.isPortaled}\n wrap={(wrapChildren) => <FloatingPortal>{wrapChildren}</FloatingPortal>}\n >\n <FloatingFocusManager\n context={context.context}\n returnFocus={true}\n modal={false}\n initialFocus={0}\n closeOnFocusOut\n >\n <div\n ref={mergedRef}\n className={classes}\n style={{\n ...context.floatingStyles,\n ...style,\n }}\n {...restProps}\n {...context.getFloatingProps({\n ...htmlAttributes,\n 'aria-labelledby': ariaLabelledBy,\n })}\n >\n {children}\n </div>\n </FloatingFocusManager>\n </ConditionalWrap>\n );\n};\n\ntype TooltipHeaderProps = {\n /** Content displayed inside the header */\n children: React.ReactNode;\n /** @deprecated Use `typographyVariant` instead */\n passThroughProps?: Partial<React.ComponentPropsWithoutRef<typeof Typography>>;\n typographyVariant?: TypographyVariants;\n};\n\nconst TooltipHeader = ({\n children,\n passThroughProps,\n typographyVariant = 'subheading-medium',\n className,\n style,\n htmlAttributes,\n ref,\n ...restProps\n}: CommonProps<'span', TooltipHeaderProps>) => {\n const context = useTooltipContext();\n\n const classes = classNames('ndl-tooltip-header', className);\n\n useEffect(() => {\n if (Boolean(htmlAttributes?.id) === true) {\n context.setHeaderId?.(htmlAttributes?.id);\n }\n }, [context, htmlAttributes?.id]);\n\n if (!context.isOpen) {\n return null;\n }\n\n return (\n <Typography\n ref={ref}\n variant={typographyVariant}\n className={classes}\n style={style}\n htmlAttributes={{ ...htmlAttributes, id: context.headerId }}\n {...passThroughProps}\n {...restProps}\n >\n {children}\n </Typography>\n );\n};\n\nexport type TooltipBodyProps = {\n /** Content displayed inside the body */\n children: React.ReactNode;\n /** Additional props to pass to the Typography component */\n // TODO v5: Deprecate passThroughProps and use restProps instead\n passThroughProps?: Partial<React.ComponentPropsWithoutRef<typeof Typography>>;\n};\n\nconst TooltipBody = ({\n children,\n className,\n style,\n htmlAttributes,\n passThroughProps,\n ref,\n ...restProps\n}: CommonProps<'span', TooltipBodyProps>) => {\n const context = useTooltipContext();\n\n const classes = classNames('ndl-tooltip-body', className);\n if (!context.isOpen) {\n return null;\n }\n\n return (\n <Typography\n ref={ref}\n variant=\"body-medium\"\n className={classes}\n style={style}\n htmlAttributes={htmlAttributes}\n {...passThroughProps}\n {...restProps}\n >\n {children}\n </Typography>\n );\n};\n\ntype ToolTipActionsProps = {\n /** Content displayed inside the actions container */\n children: React.ReactNode;\n};\n\nconst Actions = ({\n children,\n className,\n style,\n htmlAttributes,\n ref,\n ...restProps\n}: CommonProps<'div', ToolTipActionsProps>) => {\n const context = useTooltipContext();\n const mergedRefs = useMergeRefs([context.refs.setFloating, ref]);\n\n if (!context.isOpen) {\n return null;\n }\n\n const classes = classNames('ndl-tooltip-actions', className);\n\n return (\n <div\n className={classes}\n ref={mergedRefs}\n style={style}\n {...restProps}\n {...htmlAttributes}\n >\n {children}\n </div>\n );\n};\n\nActions.displayName = 'Tooltip.Actions';\n\nconst Tooltip = Object.assign(TooltipComponent, {\n Actions: Actions,\n Body: TooltipBody,\n Content: TooltipContent,\n Header: TooltipHeader,\n Trigger: TooltipTrigger,\n});\n\nexport { Tooltip };\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"use-tooltip.js","sourceRoot":"","sources":["../../../src/tooltip/use-tooltip.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n *\n * Copyright (c) \"Neo4j\"\n * Neo4j Sweden AB [http://neo4j.com]\n *\n * This file is part of Neo4j.\n *\n * Neo4j is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\nimport {\n autoUpdate,\n type AutoUpdateOptions,\n flip,\n offset,\n type Placement,\n type ReferenceType,\n safePolygon,\n shift,\n useClick,\n useClientPoint,\n useDismiss,\n useFloating,\n type UseFloatingOptions,\n type UseFloatingReturn,\n useFocus,\n useHover,\n useInteractions,\n type UseInteractionsReturn,\n useRole,\n} from '@floating-ui/react';\nimport { createContext, useContext, useId, useMemo, useState } from 'react';\n\nexport interface TooltipOptions {\n isInitialOpen?: boolean;\n placement?: Placement;\n isOpen?: boolean;\n onOpenChange?: UseFloatingOptions['onOpenChange'];\n type?: 'simple' | 'rich';\n isPortaled?: boolean;\n strategy?: 'fixed' | 'absolute';\n hoverDelay?: {\n open: number;\n close: number;\n };\n shouldCloseOnReferenceClick?: boolean;\n autoUpdateOptions?: AutoUpdateOptions;\n isDisabled?: boolean;\n /** Whether the tooltip should follow the mouse cursor. Only applies to 'simple' tooltips with mouse hover. */\n followCursor?: boolean;\n}\n\nexport function useTooltip({\n isInitialOpen = false,\n placement = 'top',\n isOpen: controlledOpen,\n onOpenChange: setControlledOpen,\n type = 'simple',\n isPortaled = true,\n strategy = 'absolute',\n hoverDelay = undefined,\n shouldCloseOnReferenceClick = false,\n autoUpdateOptions,\n isDisabled = false,\n followCursor = false,\n}: TooltipOptions = {}): {\n headerId?: string;\n setHeaderId?: (id: string | undefined) => void;\n isOpen: boolean;\n setOpen: (open: boolean) => void;\n type: 'simple' | 'rich';\n isPortaled: boolean;\n} & UseInteractionsReturn &\n UseFloatingReturn<ReferenceType> {\n const id = useId();\n const [headerId, setHeaderId] = useState<string | undefined>(id);\n const [isUncontrolledOpen, setIsUncontrolledOpen] = useState(isInitialOpen);\n const isOpen = controlledOpen ?? isUncontrolledOpen;\n const setOpen = setControlledOpen ?? setIsUncontrolledOpen;\n\n const data = useFloating({\n middleware: [\n offset(5),\n flip({\n crossAxis: placement.includes('-'),\n fallbackAxisSideDirection: 'start',\n padding: 5,\n }),\n shift({ padding: 5 }),\n ],\n onOpenChange: setOpen,\n open: isOpen,\n placement,\n strategy,\n whileElementsMounted(referenceEl, floatingEl, update) {\n const cleanup = autoUpdate(referenceEl, floatingEl, update, {\n ...autoUpdateOptions,\n });\n return cleanup;\n },\n });\n\n const context = data.context;\n\n const hover = useHover(context, {\n delay: hoverDelay,\n enabled: type === 'simple' && !isDisabled,\n handleClose: safePolygon(),\n move: false,\n });\n const click = useClick(context, {\n enabled: type === 'rich' && !isDisabled,\n });\n const focus = useFocus(context, {\n enabled: type === 'simple' && !isDisabled,\n visibleOnly: true,\n });\n const dismiss = useDismiss(context, {\n escapeKey: true,\n outsidePress: true,\n referencePress: shouldCloseOnReferenceClick,\n });\n const role = useRole(context, {\n role: type === 'simple' ? 'tooltip' : 'dialog',\n });\n const followAxis =\n placement.startsWith('left') || placement.startsWith('right') ? 'y' : 'x';\n const clientPoint = useClientPoint(context, {\n axis: followAxis,\n enabled: followCursor && type === 'simple' && !isDisabled,\n });\n\n const interactions = useInteractions([\n hover,\n focus,\n dismiss,\n role,\n click,\n clientPoint,\n ]);\n\n return useMemo(\n () => ({\n headerId: type === 'rich' ? headerId : undefined,\n isOpen,\n isPortaled,\n setHeaderId: type === 'rich' ? setHeaderId : undefined,\n setOpen,\n type,\n ...interactions,\n ...data,\n }),\n [headerId, isOpen, isPortaled, setOpen, type, interactions, data],\n );\n}\n\ntype ContextType = ReturnType<typeof useTooltip> | null;\n\nexport const TooltipContext = createContext<ContextType>(null);\n\nexport const useTooltipContext = (): ReturnType<typeof useTooltip> => {\n const context = useContext(TooltipContext);\n\n if (context === null) {\n throw new Error('Tooltip components must be wrapped in <Tooltip />');\n }\n\n return context;\n};\n"]}
1
+ {"version":3,"file":"use-tooltip.js","sourceRoot":"","sources":["../../../src/tooltip/use-tooltip.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n *\n * Copyright (c) \"Neo4j\"\n * Neo4j Sweden AB [http://neo4j.com]\n *\n * This file is part of Neo4j.\n *\n * Neo4j is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\nimport {\n autoUpdate,\n type AutoUpdateOptions,\n flip,\n offset,\n type Placement,\n type ReferenceType,\n safePolygon,\n shift,\n useClick,\n useClientPoint,\n useDismiss,\n useFloating,\n type UseFloatingOptions,\n type UseFloatingReturn,\n useFocus,\n useHover,\n useInteractions,\n type UseInteractionsReturn,\n useRole,\n} from '@floating-ui/react';\nimport { createContext, useContext, useId, useMemo, useState } from 'react';\n\nexport interface TooltipOptions {\n isInitialOpen?: boolean;\n placement?: Placement;\n isOpen?: boolean;\n onOpenChange?: UseFloatingOptions['onOpenChange'];\n type?: 'simple' | 'rich';\n isPortaled?: boolean;\n strategy?: 'fixed' | 'absolute';\n hoverDelay?: {\n open: number;\n close: number;\n };\n shouldCloseOnReferenceClick?: boolean;\n autoUpdateOptions?: AutoUpdateOptions;\n isDisabled?: boolean;\n // TODO v5: rename this prop to follow lint rule\n /** Whether the tooltip should follow the mouse cursor. Only applies to 'simple' tooltips with mouse hover. */\n // eslint-disable-next-line @typescript-eslint/naming-convention\n followCursor?: boolean;\n}\n\nexport function useTooltip({\n isInitialOpen = false,\n placement = 'top',\n isOpen: controlledOpen,\n onOpenChange: setControlledOpen,\n type = 'simple',\n isPortaled = true,\n strategy = 'absolute',\n hoverDelay = undefined,\n shouldCloseOnReferenceClick = false,\n autoUpdateOptions,\n isDisabled = false,\n followCursor = false,\n}: TooltipOptions = {}): {\n headerId?: string;\n setHeaderId?: (id: string | undefined) => void;\n isOpen: boolean;\n setOpen: (open: boolean) => void;\n type: 'simple' | 'rich';\n isPortaled: boolean;\n} & UseInteractionsReturn &\n UseFloatingReturn<ReferenceType> {\n const id = useId();\n const [headerId, setHeaderId] = useState<string | undefined>(id);\n const [isUncontrolledOpen, setIsUncontrolledOpen] = useState(isInitialOpen);\n const isOpen = controlledOpen ?? isUncontrolledOpen;\n const setOpen = setControlledOpen ?? setIsUncontrolledOpen;\n\n const data = useFloating({\n middleware: [\n offset(5),\n flip({\n crossAxis: placement.includes('-'),\n fallbackAxisSideDirection: 'start',\n padding: 5,\n }),\n shift({ padding: 5 }),\n ],\n onOpenChange: setOpen,\n open: isOpen,\n placement,\n strategy,\n whileElementsMounted(referenceEl, floatingEl, update) {\n const cleanup = autoUpdate(referenceEl, floatingEl, update, {\n ...autoUpdateOptions,\n });\n return cleanup;\n },\n });\n\n const context = data.context;\n\n const hover = useHover(context, {\n delay: hoverDelay,\n enabled: type === 'simple' && !isDisabled,\n handleClose: safePolygon(),\n move: false,\n });\n const click = useClick(context, {\n enabled: type === 'rich' && !isDisabled,\n });\n const focus = useFocus(context, {\n enabled: type === 'simple' && !isDisabled,\n visibleOnly: true,\n });\n const dismiss = useDismiss(context, {\n escapeKey: true,\n outsidePress: true,\n referencePress: shouldCloseOnReferenceClick,\n });\n const role = useRole(context, {\n role: type === 'simple' ? 'tooltip' : 'dialog',\n });\n const followAxis =\n placement.startsWith('left') || placement.startsWith('right') ? 'y' : 'x';\n const clientPoint = useClientPoint(context, {\n axis: followAxis,\n enabled: followCursor && type === 'simple' && !isDisabled,\n });\n\n const interactions = useInteractions([\n hover,\n focus,\n dismiss,\n role,\n click,\n clientPoint,\n ]);\n\n return useMemo(\n () => ({\n headerId: type === 'rich' ? headerId : undefined,\n isOpen,\n isPortaled,\n setHeaderId: type === 'rich' ? setHeaderId : undefined,\n setOpen,\n type,\n ...interactions,\n ...data,\n }),\n [headerId, isOpen, isPortaled, setOpen, type, interactions, data],\n );\n}\n\ntype ContextType = ReturnType<typeof useTooltip> | null;\n\nexport const TooltipContext = createContext<ContextType>(null);\n\nexport const useTooltipContext = (): ReturnType<typeof useTooltip> => {\n const context = useContext(TooltipContext);\n\n if (context === null) {\n throw new Error('Tooltip components must be wrapped in <Tooltip />');\n }\n\n return context;\n};\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"TreeViewItem.js","sourceRoot":"","sources":["../../../src/tree-view/TreeViewItem.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAqBA,gDAI2B;AAC3B,+CAA2D;AAO3D,uDAAsD;AA+BtD,MAAM,oBAAoB,GAAyB,CAAC,EAClD,SAAS,EACT,UAAU,GACX,EAAE,EAAE,CAAC,CAAC,SAAS,IAAI,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;AAgC/C,MAAM,+BAA+B,GAAG,SAAS,oBAAoB,CAGnE,EAsB4B;QAtB5B,EACA,EAAE,EACF,KAAK,EACL,MAAM,EACN,iBAAiB,EACjB,MAAM,EACN,oBAAoB;IACpB,wDAAwD;IACxD,0CAA0C;IAC1C,aAAa,EACb,gBAAgB,EAChB,IAAI,EACJ,UAAU,EACV,MAAM,EACN,cAAc,EACd,KAAK,EACL,SAAS,EACT,YAAY,EACZ,WAAW,EACX,QAAQ,EACR,OAAO,OAEqB,EADzB,SAAS,cArBZ,mPAsBD,CADa;IAEZ,MAAM,EACJ,UAAU,EACV,SAAS,EACT,UAAU,EACV,SAAS,EACT,mBAAmB,EACnB,UAAU,EACV,UAAU,EACV,SAAS,EACT,MAAM,GACP,GAAG,IAAA,sBAAW,EAAC;QACd,oBAAoB;QACpB,EAAE,EAAE,EAAE;QACN,UAAU,EAAE;YACV,QAAQ,EAAE,GAAG,EAAE,eAAe;YAC9B,MAAM,EAAE,+BAA+B;SACxC;KACF,CAAC,CAAC;IAEH,MAAM,KAAK,GAAkB;QAC3B,SAAS,EAAE,SAAS,CAAC,CAAC,CAAC,IAAA,mCAAiB,EAAC,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS;QAC/D,UAAU,EAAE,UAAU,aAAV,UAAU,cAAV,UAAU,GAAI,SAAS;KACpC,CAAC;IACF,MAAM,aAAa,GAAG,IAAA,eAAO,EAAC,GAAG,EAAE;QACjC,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,OAAO,SAAS,CAAC;QACnB,CAAC;QACD,OAAO,GAAG,EAAE,CAAC,UAAU,aAAV,UAAU,uBAAV,UAAU,CAAG,IAAI,CAAC,EAAE,CAAC,CAAC;IACrC,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,EAAE,UAAU,CAAC,CAAC,CAAC;IAE1B,OAAO,CACL,uBAAC,iBAAiB,kBAChB,IAAI,EAAE,IAAI,EACV,YAAY,EAAE,KAAK,IACf,SAAS,IACb,mBAAmB,EAAE,mBAAmB,EACxC,UAAU,EAAE,UAAU,EACtB,KAAK,EAAE,KAAK,EACZ,KAAK,EAAE,KAAK,EACZ,OAAO,EAAE,gBAAgB,EACzB,wBAAwB,EAAE,SAAS,EACnC,cAAc,EAAE,MAAM,EACtB,MAAM,EAAE,MAAM,EACd,eAAe,kCACV,UAAU,GACV,SAAS,GAEd,WAAW,EAAE,UAAU,EACvB,UAAU,EAAE,aAAa,EACzB,cAAc,EAAE,cAAc,EAC9B,KAAK,EAAE,KAAK,EACZ,SAAS,EAAE,SAAS,EACpB,YAAY,EAAE,YAAY,EAC1B,WAAW,EAAE,WAAW,EACxB,oBAAoB,EAAE,oBAAoB,EAC1C,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,QAAQ,EAClB,OAAO,EAAE,OAAO,IAChB,CACH,CAAC;AACJ,CAAC,CAAC;AAEW,QAAA,oBAAoB,GAAG,eAAK,CAAC,IAAI,CAC5C,+BAA+B,CACU,CAAC","sourcesContent":["/**\n *\n * Copyright (c) \"Neo4j\"\n * Neo4j Sweden AB [http://neo4j.com]\n *\n * This file is part of Neo4j.\n *\n * Neo4j is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\nimport { type UniqueIdentifier } from '@dnd-kit/core';\nimport {\n type AnimateLayoutChanges,\n useSortable,\n type UseSortableArguments,\n} from '@dnd-kit/sortable';\nimport React, { type CSSProperties, useMemo } from 'react';\n\nimport {\n type FlattenedTreeItem,\n type ItemChangedReason,\n type TreeItemComponent,\n} from './tree-view-types';\nimport { transformToString } from './tree-view-utils';\n\nexport interface TreeItemProps<T> {\n /** Number of child items */\n childCount?: number;\n /** Whether this is a clone item */\n clone?: boolean;\n /** Whether the item is collapsed */\n collapsed?: boolean;\n /** Depth of the item in the tree */\n depth: number;\n /** Whether interaction should be disabled */\n shouldDisableInteraction?: boolean;\n /** Whether this is an indicator item */\n indicator?: boolean;\n /** Width of the indentation */\n indentationWidth: number;\n /** The tree item data */\n item: FlattenedTreeItem<T>;\n /** Whether this is the last item in its parent */\n isLast: boolean;\n /** Parent item of this item */\n parent: FlattenedTreeItem<T> | null;\n /** Function to call when item is collapsed */\n onCollapse?(id: UniqueIdentifier): void;\n /** Function to call when item is removed */\n onRemove?(id: UniqueIdentifier): void;\n /** Function to set the wrapper ref */\n wrapperRef?(node: HTMLLIElement): void;\n}\n\nconst animateLayoutChanges: AnimateLayoutChanges = ({\n isSorting,\n isDragging,\n}) => (isSorting || isDragging ? false : true);\n\ntype SortableTreeItemProps<\n T extends Record<string, unknown>,\n E extends HTMLElement,\n> = TreeItemProps<T> & {\n id: UniqueIdentifier;\n /** The component to use for rendering the tree item */\n TreeItemComponent: TreeItemComponent<T, E>;\n /** Whether sorting should be disabled for this item */\n shouldDisableSorting?: boolean;\n /** Props for the sortable functionality */\n sortableProps?: Omit<UseSortableArguments, 'id'>;\n /** Whether to keep the ghost item in place while dragging */\n keepGhostInPlace?: boolean;\n /** A list of trails to render before the item */\n trails: ('none' | 'straight' | 'straight-curved' | 'curved')[];\n /** Function to call when the item has changed */\n onItemsChanged: (\n newItems: FlattenedTreeItem<T>[],\n itemChangedReason: ItemChangedReason<T>,\n ) => void;\n /** All items in the tree */\n items: FlattenedTreeItem<T>[];\n ariaLevel?: number;\n ariaPosInSet?: number;\n ariaSetSize?: number;\n tabIndex?: number;\n /** Function to call when the item receives focus */\n onFocus?: () => void;\n};\n\nconst SortableTreeViewItemNotMemoized = function SortableTreeViewItem<\n T extends Record<string, unknown>,\n E extends HTMLElement,\n>({\n id,\n depth,\n isLast,\n TreeItemComponent,\n parent,\n shouldDisableSorting,\n // need to destruct to avoid passing it to the component\n // oxlint-disable-next-line no-unused-vars\n sortableProps,\n keepGhostInPlace,\n item,\n onCollapse,\n trails,\n onItemsChanged,\n items,\n ariaLevel,\n ariaPosInSet,\n ariaSetSize,\n tabIndex,\n onFocus,\n ...restProps\n}: SortableTreeItemProps<T, E>) {\n const {\n attributes,\n listeners,\n setNodeRef,\n transform,\n setActivatorNodeRef,\n transition,\n isDragging,\n isSorting,\n isOver,\n } = useSortable({\n animateLayoutChanges,\n id: id,\n transition: {\n duration: 150, // milliseconds\n easing: 'cubic-bezier(0.25, 1, 0.5, 1)',\n },\n });\n\n const style: CSSProperties = {\n transform: transform ? transformToString(transform) : undefined,\n transition: transition ?? undefined,\n };\n const localCollapse = useMemo(() => {\n if (!onCollapse) {\n return undefined;\n }\n return () => onCollapse?.(item.id);\n }, [item.id, onCollapse]);\n\n return (\n <TreeItemComponent\n item={item}\n isOverParent={false}\n {...restProps}\n setActivatorNodeRef={setActivatorNodeRef}\n setNodeRef={setNodeRef}\n style={style}\n depth={depth}\n isGhost={keepGhostInPlace}\n shouldDisableInteraction={isSorting}\n isLastInParent={isLast}\n parent={parent}\n dragHandleProps={{\n ...attributes,\n ...listeners,\n }}\n isIndicator={isDragging}\n onCollapse={localCollapse}\n onItemsChanged={onItemsChanged}\n items={items}\n ariaLevel={ariaLevel}\n ariaPosInSet={ariaPosInSet}\n ariaSetSize={ariaSetSize}\n shouldDisableSorting={shouldDisableSorting}\n isOver={isOver}\n trails={trails}\n tabIndex={tabIndex}\n onFocus={onFocus}\n />\n );\n};\n\nexport const SortableTreeViewItem = React.memo(\n SortableTreeViewItemNotMemoized,\n) as typeof SortableTreeViewItemNotMemoized;\n"]}
1
+ {"version":3,"file":"TreeViewItem.js","sourceRoot":"","sources":["../../../src/tree-view/TreeViewItem.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAqBA,gDAI2B;AAC3B,+CAA2D;AAO3D,uDAAsD;AAqCtD,MAAM,oBAAoB,GAAyB,CAAC,EAClD,SAAS,EACT,UAAU,GACX,EAAE,EAAE,CAAC,CAAC,SAAS,IAAI,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;AAkC/C,MAAM,+BAA+B,GAAG,SAAS,oBAAoB,CAGnE,EAsB4B;QAtB5B,EACA,EAAE,EACF,KAAK,EACL,MAAM,EACN,iBAAiB,EACjB,MAAM,EACN,oBAAoB;IACpB,wDAAwD;IACxD,0CAA0C;IAC1C,aAAa,EACb,gBAAgB,EAChB,IAAI,EACJ,UAAU,EACV,MAAM,EACN,cAAc,EACd,KAAK,EACL,SAAS,EACT,YAAY,EACZ,WAAW,EACX,QAAQ,EACR,OAAO,OAEqB,EADzB,SAAS,cArBZ,mPAsBD,CADa;IAEZ,MAAM,EACJ,UAAU,EACV,SAAS,EACT,UAAU,EACV,SAAS,EACT,mBAAmB,EACnB,UAAU,EACV,UAAU,EACV,SAAS,EACT,MAAM,GACP,GAAG,IAAA,sBAAW,EAAC;QACd,oBAAoB;QACpB,EAAE,EAAE,EAAE;QACN,UAAU,EAAE;YACV,QAAQ,EAAE,GAAG,EAAE,eAAe;YAC9B,MAAM,EAAE,+BAA+B;SACxC;KACF,CAAC,CAAC;IAEH,MAAM,KAAK,GAAkB;QAC3B,SAAS,EAAE,SAAS,CAAC,CAAC,CAAC,IAAA,mCAAiB,EAAC,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS;QAC/D,UAAU,EAAE,UAAU,aAAV,UAAU,cAAV,UAAU,GAAI,SAAS;KACpC,CAAC;IACF,MAAM,aAAa,GAAG,IAAA,eAAO,EAAC,GAAG,EAAE;QACjC,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,OAAO,SAAS,CAAC;QACnB,CAAC;QACD,OAAO,GAAG,EAAE,CAAC,UAAU,aAAV,UAAU,uBAAV,UAAU,CAAG,IAAI,CAAC,EAAE,CAAC,CAAC;IACrC,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,EAAE,UAAU,CAAC,CAAC,CAAC;IAE1B,OAAO,CACL,uBAAC,iBAAiB,kBAChB,IAAI,EAAE,IAAI,EACV,YAAY,EAAE,KAAK,IACf,SAAS,IACb,mBAAmB,EAAE,mBAAmB,EACxC,UAAU,EAAE,UAAU,EACtB,KAAK,EAAE,KAAK,EACZ,KAAK,EAAE,KAAK,EACZ,OAAO,EAAE,gBAAgB,EACzB,wBAAwB,EAAE,SAAS,EACnC,cAAc,EAAE,MAAM,EACtB,MAAM,EAAE,MAAM,EACd,eAAe,kCACV,UAAU,GACV,SAAS,GAEd,WAAW,EAAE,UAAU,EACvB,UAAU,EAAE,aAAa,EACzB,cAAc,EAAE,cAAc,EAC9B,KAAK,EAAE,KAAK,EACZ,SAAS,EAAE,SAAS,EACpB,YAAY,EAAE,YAAY,EAC1B,WAAW,EAAE,WAAW,EACxB,oBAAoB,EAAE,oBAAoB,EAC1C,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,QAAQ,EAClB,OAAO,EAAE,OAAO,IAChB,CACH,CAAC;AACJ,CAAC,CAAC;AAEW,QAAA,oBAAoB,GAAG,eAAK,CAAC,IAAI,CAC5C,+BAA+B,CACU,CAAC","sourcesContent":["/**\n *\n * Copyright (c) \"Neo4j\"\n * Neo4j Sweden AB [http://neo4j.com]\n *\n * This file is part of Neo4j.\n *\n * Neo4j is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\nimport { type UniqueIdentifier } from '@dnd-kit/core';\nimport {\n type AnimateLayoutChanges,\n useSortable,\n type UseSortableArguments,\n} from '@dnd-kit/sortable';\nimport React, { type CSSProperties, useMemo } from 'react';\n\nimport {\n type FlattenedTreeItem,\n type ItemChangedReason,\n type TreeItemComponent,\n} from './tree-view-types';\nimport { transformToString } from './tree-view-utils';\n\nexport interface TreeItemProps<T> {\n /** Number of child items */\n childCount?: number;\n /** Whether this is a clone item */\n // TODO v5: fix boolean naming convention\n // eslint-disable-next-line @typescript-eslint/naming-convention\n clone?: boolean;\n /** Whether the item is collapsed */\n // TODO v5: fix boolean naming convention\n // eslint-disable-next-line @typescript-eslint/naming-convention\n collapsed?: boolean;\n /** Depth of the item in the tree */\n depth: number;\n /** Whether interaction should be disabled */\n shouldDisableInteraction?: boolean;\n /** Whether this is an indicator item */\n // TODO v5: fix boolean naming convention\n // eslint-disable-next-line @typescript-eslint/naming-convention\n indicator?: boolean;\n /** Width of the indentation */\n indentationWidth: number;\n /** The tree item data */\n item: FlattenedTreeItem<T>;\n /** Whether this is the last item in its parent */\n isLast: boolean;\n /** Parent item of this item */\n parent: FlattenedTreeItem<T> | null;\n /** Function to call when item is collapsed */\n onCollapse?(id: UniqueIdentifier): void;\n /** Function to call when item is removed */\n onRemove?(id: UniqueIdentifier): void;\n /** Function to set the wrapper ref */\n wrapperRef?(node: HTMLLIElement): void;\n}\n\nconst animateLayoutChanges: AnimateLayoutChanges = ({\n isSorting,\n isDragging,\n}) => (isSorting || isDragging ? false : true);\n\ntype SortableTreeItemProps<\n T extends Record<string, unknown>,\n E extends HTMLElement,\n> = TreeItemProps<T> & {\n id: UniqueIdentifier;\n /** The component to use for rendering the tree item */\n TreeItemComponent: TreeItemComponent<T, E>;\n /** Whether sorting should be disabled for this item */\n shouldDisableSorting?: boolean;\n /** Props for the sortable functionality */\n sortableProps?: Omit<UseSortableArguments, 'id'>;\n /** Whether to keep the ghost item in place while dragging */\n // TODO v5: fix boolean naming convention\n // eslint-disable-next-line @typescript-eslint/naming-convention\n keepGhostInPlace?: boolean;\n /** A list of trails to render before the item */\n trails: ('none' | 'straight' | 'straight-curved' | 'curved')[];\n /** Function to call when the item has changed */\n onItemsChanged: (\n newItems: FlattenedTreeItem<T>[],\n itemChangedReason: ItemChangedReason<T>,\n ) => void;\n /** All items in the tree */\n items: FlattenedTreeItem<T>[];\n ariaLevel?: number;\n ariaPosInSet?: number;\n ariaSetSize?: number;\n tabIndex?: number;\n /** Function to call when the item receives focus */\n onFocus?: () => void;\n};\n\nconst SortableTreeViewItemNotMemoized = function SortableTreeViewItem<\n T extends Record<string, unknown>,\n E extends HTMLElement,\n>({\n id,\n depth,\n isLast,\n TreeItemComponent,\n parent,\n shouldDisableSorting,\n // need to destruct to avoid passing it to the component\n // oxlint-disable-next-line no-unused-vars\n sortableProps,\n keepGhostInPlace,\n item,\n onCollapse,\n trails,\n onItemsChanged,\n items,\n ariaLevel,\n ariaPosInSet,\n ariaSetSize,\n tabIndex,\n onFocus,\n ...restProps\n}: SortableTreeItemProps<T, E>) {\n const {\n attributes,\n listeners,\n setNodeRef,\n transform,\n setActivatorNodeRef,\n transition,\n isDragging,\n isSorting,\n isOver,\n } = useSortable({\n animateLayoutChanges,\n id: id,\n transition: {\n duration: 150, // milliseconds\n easing: 'cubic-bezier(0.25, 1, 0.5, 1)',\n },\n });\n\n const style: CSSProperties = {\n transform: transform ? transformToString(transform) : undefined,\n transition: transition ?? undefined,\n };\n const localCollapse = useMemo(() => {\n if (!onCollapse) {\n return undefined;\n }\n return () => onCollapse?.(item.id);\n }, [item.id, onCollapse]);\n\n return (\n <TreeItemComponent\n item={item}\n isOverParent={false}\n {...restProps}\n setActivatorNodeRef={setActivatorNodeRef}\n setNodeRef={setNodeRef}\n style={style}\n depth={depth}\n isGhost={keepGhostInPlace}\n shouldDisableInteraction={isSorting}\n isLastInParent={isLast}\n parent={parent}\n dragHandleProps={{\n ...attributes,\n ...listeners,\n }}\n isIndicator={isDragging}\n onCollapse={localCollapse}\n onItemsChanged={onItemsChanged}\n items={items}\n ariaLevel={ariaLevel}\n ariaPosInSet={ariaPosInSet}\n ariaSetSize={ariaSetSize}\n shouldDisableSorting={shouldDisableSorting}\n isOver={isOver}\n trails={trails}\n tabIndex={tabIndex}\n onFocus={onFocus}\n />\n );\n};\n\nexport const SortableTreeViewItem = React.memo(\n SortableTreeViewItemNotMemoized,\n) as typeof SortableTreeViewItemNotMemoized;\n"]}
@@ -78,7 +78,7 @@ export const Component = () => {
78
78
  const newMessages = [...prev];
79
79
  const lastMessage = newMessages[newMessages.length - 1];
80
80
  if ((lastMessage === null || lastMessage === void 0 ? void 0 : lastMessage.role) === 'assistant') {
81
- lastMessage.done = true;
81
+ lastMessage.isDone = true;
82
82
  }
83
83
  return newMessages;
84
84
  });
@@ -103,7 +103,7 @@ export const Component = () => {
103
103
  let currentText = '';
104
104
  setMessages((prev) => [
105
105
  ...prev,
106
- { content: '', done: false, role: 'assistant', thinkingTime },
106
+ { content: '', isDone: false, role: 'assistant', thinkingTime },
107
107
  ]);
108
108
  // Simulate streaming
109
109
  intervalRef.current = setInterval(() => {
@@ -131,7 +131,7 @@ export const Component = () => {
131
131
  const newMessages = [...prev];
132
132
  const lastMessage = newMessages[newMessages.length - 1];
133
133
  if (lastMessage.role === 'assistant') {
134
- lastMessage.done = true;
134
+ lastMessage.isDone = true;
135
135
  }
136
136
  return newMessages;
137
137
  });
@@ -150,7 +150,7 @@ export const Component = () => {
150
150
  }, children: "Generate a report" })] }), _jsxs(Typography, { variant: "body-medium", children: ["You can also drag and drop files here, or", ' ', _jsx(TextLink, { as: "button", type: "internal-underline", children: "browse" }), ". Supports CVG, MOV, PDF"] })] }) })) : (_jsxs("div", { className: "n-flex n-flex-col n-gap-4 n-pb-4", children: [messages.map((msg, idx) => (_jsx("div", { className: `n-flex ${msg.role === 'user' ? 'n-justify-end' : 'n-justify-start'}`, children: msg.role === 'user' ? (_jsx("div", { className: "n-max-w-[85%]", children: _jsx(UserBubble, { avatarProps: {
151
151
  name: 'NM',
152
152
  type: 'letters',
153
- }, children: msg.content }) })) : (_jsxs("div", { className: "n-w-full n-flex n-flex-col n-gap-2", children: [msg.thinkingTime !== undefined && (_jsx(Thinking, { isThinking: false, thinkingMs: msg.thinkingTime })), _jsxs("div", { className: "n-flex n-flex-col n-gap-2", children: [_jsx(Response, { children: msg.content }), msg.done === true && (_jsxs("div", { className: "n-flex n-flex-row n-gap-1.5", children: [_jsx(CleanIconButton, { size: "small", description: "Dislike", children: _jsx(HandThumbDownIconOutline, {}) }), _jsx(CleanIconButton, { size: "small", description: "Re-run", children: _jsx(ArrowPathIconOutline, {}) }), _jsx(CleanIconButton, { size: "small", description: "Copy", children: _jsx(Square2StackIconOutline, {}) })] }))] })] })) }, idx))), isThinking && _jsx(Thinking, { isThinking: true }), _jsx("div", { ref: messagesEndRef })] })) }), _jsx("div", { className: "n-px-4 n-pt-4 n-pb-1 n-mt-auto", children: _jsx(Prompt, { value: prompt, onChange: (e) => setPrompt(e.target.value), onSubmitPrompt: () => handleSend(), onCancelPrompt: handleCancel, isRunningPrompt: isThinking || isStreaming, isSubmitDisabled: prompt.length === 0 && !(isThinking || isStreaming), bottomContent: _jsx(CleanIconButton, { description: "Add files", size: "small", children: _jsx(PlusIconOutline, {}) }) }) })] }) }));
153
+ }, children: msg.content }) })) : (_jsxs("div", { className: "n-w-full n-flex n-flex-col n-gap-2", children: [msg.thinkingTime !== undefined && (_jsx(Thinking, { isThinking: false, thinkingMs: msg.thinkingTime })), _jsxs("div", { className: "n-flex n-flex-col n-gap-2", children: [_jsx(Response, { children: msg.content }), msg.isDone === true && (_jsxs("div", { className: "n-flex n-flex-row n-gap-1.5", children: [_jsx(CleanIconButton, { size: "small", description: "Dislike", children: _jsx(HandThumbDownIconOutline, {}) }), _jsx(CleanIconButton, { size: "small", description: "Re-run", children: _jsx(ArrowPathIconOutline, {}) }), _jsx(CleanIconButton, { size: "small", description: "Copy", children: _jsx(Square2StackIconOutline, {}) })] }))] })] })) }, idx))), isThinking && _jsx(Thinking, { isThinking: true }), _jsx("div", { ref: messagesEndRef })] })) }), _jsx("div", { className: "n-px-4 n-pt-4 n-pb-1 n-mt-auto", children: _jsx(Prompt, { value: prompt, onChange: (e) => setPrompt(e.target.value), onSubmitPrompt: () => handleSend(), onCancelPrompt: handleCancel, isRunningPrompt: isThinking || isStreaming, isSubmitDisabled: prompt.length === 0 && !(isThinking || isStreaming), bottomContent: _jsx(CleanIconButton, { description: "Add files", size: "small", children: _jsx(PlusIconOutline, {}) }) }) })] }) }));
154
154
  };
155
155
  export default Component;
156
156
  //# sourceMappingURL=response-full-example.story.js.map