@capillarytech/blaze-ui 6.1.5 → 6.1.6

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 (50) hide show
  1. package/CapEmojiPicker/Picker/index.d.ts +6 -0
  2. package/CapEmojiPicker/Picker/index.d.ts.map +1 -0
  3. package/CapEmojiPicker/Picker/index.js +114 -0
  4. package/CapEmojiPicker/Picker/messages.d.ts +21 -0
  5. package/CapEmojiPicker/Picker/messages.d.ts.map +1 -0
  6. package/CapEmojiPicker/Picker/messages.js +24 -0
  7. package/CapEmojiPicker/TriggerButton/_triggerButton.scss +45 -0
  8. package/CapEmojiPicker/TriggerButton/index.d.ts +9 -0
  9. package/CapEmojiPicker/TriggerButton/index.d.ts.map +1 -0
  10. package/CapEmojiPicker/TriggerButton/index.js +35 -0
  11. package/CapEmojiPicker/Wrapper/index.d.ts +4 -0
  12. package/CapEmojiPicker/Wrapper/index.d.ts.map +1 -0
  13. package/CapEmojiPicker/Wrapper/index.js +166 -0
  14. package/CapEmojiPicker/Wrapper/messages.d.ts +13 -0
  15. package/CapEmojiPicker/Wrapper/messages.d.ts.map +1 -0
  16. package/CapEmojiPicker/Wrapper/messages.js +16 -0
  17. package/CapEmojiPicker/Wrapper/useEmojiTriggerPosition.d.ts +18 -0
  18. package/CapEmojiPicker/Wrapper/useEmojiTriggerPosition.d.ts.map +1 -0
  19. package/CapEmojiPicker/Wrapper/useEmojiTriggerPosition.js +108 -0
  20. package/CapEmojiPicker/_capEmojiPicker.css +231 -0
  21. package/CapEmojiPicker/_capEmojiPicker.scss +281 -0
  22. package/CapEmojiPicker/_config.scss +7 -0
  23. package/CapEmojiPicker/assets/sentiment-satsified.svg +3 -0
  24. package/CapEmojiPicker/assets/sentiment-satsified.svg.js +4 -0
  25. package/CapEmojiPicker/constants.d.ts +34 -0
  26. package/CapEmojiPicker/constants.d.ts.map +1 -0
  27. package/CapEmojiPicker/constants.js +18 -0
  28. package/CapEmojiPicker/index.d.ts +4 -0
  29. package/CapEmojiPicker/index.d.ts.map +1 -0
  30. package/CapEmojiPicker/index.js +11 -0
  31. package/CapEmojiPicker/utils.d.ts +20 -0
  32. package/CapEmojiPicker/utils.d.ts.map +1 -0
  33. package/CapEmojiPicker/utils.js +24 -0
  34. package/assets/icons/blocks.svg +9 -0
  35. package/assets/icons/closed-lock.svg +1 -0
  36. package/assets/icons/csv.svg +21 -0
  37. package/assets/icons/databricks.svg +7 -0
  38. package/assets/icons/four-join.svg +19 -0
  39. package/assets/icons/http.svg +18 -0
  40. package/assets/icons/kafka.svg +9 -0
  41. package/assets/icons/open-lock.svg +1 -0
  42. package/assets/icons/s3.svg +3 -0
  43. package/assets/icons/sftp.svg +32 -0
  44. package/assets/icons/split-json.svg +9 -0
  45. package/assets/icons/three-join.svg +17 -0
  46. package/assets/icons/two-join.svg +15 -0
  47. package/assets/icons/xml.svg +12 -0
  48. package/package.json +2 -1
  49. package/utils/getCapThemeConfig.d.ts +1 -1
  50. package/utils/getCapThemeConfig.d.ts.map +1 -1
@@ -0,0 +1,6 @@
1
+ import React from 'react';
2
+ import '../_capEmojiPicker.scss';
3
+ export declare const importEmojiPicker: () => Promise<typeof import("emoji-picker-react")>;
4
+ declare const _default: React.ComponentType<Omit<import("react-intl").WrappedComponentProps, "intl">>;
5
+ export default _default;
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../components/CapEmojiPicker/Picker/index.tsx"],"names":[],"mappings":"AAEA,OAAO,KAA4D,MAAM,OAAO,CAAC;AAKjF,OAAO,yBAAyB,CAAC;AAMjC,eAAO,MAAM,iBAAiB,oDAAqC,CAAC;;AAuJpE,wBAAkC"}
@@ -0,0 +1,114 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import classNames from "classnames";
3
+ import PropTypes from "prop-types";
4
+ import { useState, useRef, useCallback, useEffect, useMemo } from "react";
5
+ import { intlShape, injectIntl } from "react-intl";
6
+ import CapButton from "../../CapButton/index.js";
7
+ import CapLabelWithStatic from "../../CapLabel/index.js";
8
+ import '../_capEmojiPicker.css';/* empty css */
9
+ import { CLS_PREFIX, PICKER_HEIGHT, PICKER_WIDTH } from "../constants.js";
10
+ import messages from "./messages.js";
11
+ const importEmojiPicker = () => import("emoji-picker-react");
12
+ const Picker = ({
13
+ intl: { formatMessage },
14
+ onEmojiSelect,
15
+ className = "",
16
+ importFunction = importEmojiPicker
17
+ }) => {
18
+ const [EmojiPickerComponent, setEmojiPickerComponent] = useState(null);
19
+ const [EmojiPickerEnums, setEmojiPickerEnums] = useState(null);
20
+ const [isLoading, setIsLoading] = useState(true);
21
+ const [hasError, setHasError] = useState(false);
22
+ const isMountedRef = useRef(true);
23
+ const loadEmojiPicker = useCallback(() => {
24
+ importFunction().then((module) => {
25
+ if (isMountedRef.current) {
26
+ const { Theme, EmojiStyle, SuggestionMode, SkinTonePickerLocation } = module;
27
+ setEmojiPickerComponent(() => module.default);
28
+ setEmojiPickerEnums({
29
+ Theme,
30
+ EmojiStyle,
31
+ SuggestionMode,
32
+ SkinTonePickerLocation
33
+ });
34
+ setIsLoading(false);
35
+ setHasError(false);
36
+ }
37
+ }).catch((error) => {
38
+ console.error("Failed to load emoji-picker-react:", error);
39
+ if (isMountedRef.current) {
40
+ setIsLoading(false);
41
+ setHasError(true);
42
+ }
43
+ });
44
+ }, [importFunction]);
45
+ useEffect(() => {
46
+ isMountedRef.current = true;
47
+ loadEmojiPicker();
48
+ return () => {
49
+ isMountedRef.current = false;
50
+ };
51
+ }, [loadEmojiPicker]);
52
+ const handleRetry = useCallback(() => {
53
+ setHasError(false);
54
+ setIsLoading(true);
55
+ loadEmojiPicker();
56
+ }, [loadEmojiPicker]);
57
+ const handleEmojiClick = useCallback(
58
+ ({
59
+ emoji,
60
+ names,
61
+ originalUnified
62
+ }) => {
63
+ const mappedData = {
64
+ emoji,
65
+ label: (names == null ? void 0 : names[0]) || originalUnified || ""
66
+ };
67
+ onEmojiSelect(mappedData);
68
+ },
69
+ [onEmojiSelect]
70
+ );
71
+ const previewConfig = useMemo(
72
+ () => ({
73
+ showPreview: true,
74
+ defaultCaption: formatMessage(messages.defaultCaption)
75
+ }),
76
+ [formatMessage]
77
+ );
78
+ if (hasError) {
79
+ return /* @__PURE__ */ jsx("div", { className: classNames(`${CLS_PREFIX}-panel`, className), children: /* @__PURE__ */ jsxs("div", { className: `${CLS_PREFIX}-error-container`, children: [
80
+ /* @__PURE__ */ jsx(CapLabelWithStatic, { className: `${CLS_PREFIX}-error-message`, children: formatMessage(messages.errorMessage) }),
81
+ /* @__PURE__ */ jsx(CapButton, { onClick: handleRetry, className: `${CLS_PREFIX}-retry-button`, children: formatMessage(messages.retryButton) })
82
+ ] }) });
83
+ }
84
+ if (isLoading || !EmojiPickerComponent || !EmojiPickerEnums) {
85
+ return /* @__PURE__ */ jsx("div", { className: classNames(`${CLS_PREFIX}-panel`, className), children: /* @__PURE__ */ jsx("div", { className: `${CLS_PREFIX}-loading-container`, children: /* @__PURE__ */ jsx(CapLabelWithStatic, { children: formatMessage(messages.loadingMessage) }) }) });
86
+ }
87
+ return /* @__PURE__ */ jsx("div", { className: classNames(`${CLS_PREFIX}-panel`, className), children: /* @__PURE__ */ jsx(
88
+ EmojiPickerComponent,
89
+ {
90
+ onEmojiClick: handleEmojiClick,
91
+ width: PICKER_WIDTH,
92
+ height: PICKER_HEIGHT,
93
+ theme: EmojiPickerEnums.Theme.LIGHT,
94
+ emojiStyle: EmojiPickerEnums.EmojiStyle.NATIVE,
95
+ suggestedEmojisMode: EmojiPickerEnums.SuggestionMode.RECENT,
96
+ skinTonePickerLocation: EmojiPickerEnums.SkinTonePickerLocation.SEARCH,
97
+ skinTonesDisabled: false,
98
+ searchDisabled: false,
99
+ previewConfig,
100
+ lazyLoadEmojis: true
101
+ }
102
+ ) });
103
+ };
104
+ Picker.propTypes = {
105
+ intl: intlShape.isRequired,
106
+ onEmojiSelect: PropTypes.func.isRequired,
107
+ className: PropTypes.string,
108
+ importFunction: PropTypes.func
109
+ };
110
+ const Picker$1 = injectIntl(Picker);
111
+ export {
112
+ Picker$1 as default,
113
+ importEmojiPicker
114
+ };
@@ -0,0 +1,21 @@
1
+ export declare const scope = "app.commonUtils.capUiLibrary.CapEmojiPicker.Picker";
2
+ declare const _default: {
3
+ defaultCaption: {
4
+ id: string;
5
+ defaultMessage: string;
6
+ };
7
+ errorMessage: {
8
+ id: string;
9
+ defaultMessage: string;
10
+ };
11
+ retryButton: {
12
+ id: string;
13
+ defaultMessage: string;
14
+ };
15
+ loadingMessage: {
16
+ id: string;
17
+ defaultMessage: string;
18
+ };
19
+ };
20
+ export default _default;
21
+ //# sourceMappingURL=messages.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"messages.d.ts","sourceRoot":"","sources":["../../../components/CapEmojiPicker/Picker/messages.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,KAAK,uDAAuD,CAAC;;;;;;;;;;;;;;;;;;;AAE1E,wBAiBG"}
@@ -0,0 +1,24 @@
1
+ import { defineMessages } from "react-intl";
2
+ const scope = "app.commonUtils.capUiLibrary.CapEmojiPicker.Picker";
3
+ const messages = defineMessages({
4
+ defaultCaption: {
5
+ id: `${scope}.defaultCaption`,
6
+ defaultMessage: "Choose an emoji"
7
+ },
8
+ errorMessage: {
9
+ id: `${scope}.errorMessage`,
10
+ defaultMessage: "Failed to load emoji picker"
11
+ },
12
+ retryButton: {
13
+ id: `${scope}.retryButton`,
14
+ defaultMessage: "Retry"
15
+ },
16
+ loadingMessage: {
17
+ id: `${scope}.loadingMessage`,
18
+ defaultMessage: "Loading emoji picker..."
19
+ }
20
+ });
21
+ export {
22
+ messages as default,
23
+ scope
24
+ };
@@ -0,0 +1,45 @@
1
+ @import '../../styles/_variables.scss';
2
+ @import '../_config.scss';
3
+
4
+ .#{$clsPrefix}-trigger-button {
5
+ position: absolute;
6
+ bottom: $CAP_SPACE_02;
7
+ right: $CAP_SPACE_02;
8
+ display: flex;
9
+ align-items: center;
10
+ justify-content: center;
11
+ width: $CAP_SPACE_28;
12
+ height: $CAP_SPACE_28;
13
+ padding: 0;
14
+ border: none;
15
+ background: transparent;
16
+ cursor: pointer;
17
+ border-radius: 50%;
18
+ transition:
19
+ background-color 0.2s ease,
20
+ transform 0.2s ease;
21
+ z-index: 10;
22
+
23
+ &:hover {
24
+ background-color: rgba($FONT_COLOR_02, 0.1); // Light background on hover (rounded)
25
+ transform: scale(1.05);
26
+ }
27
+
28
+ &:active {
29
+ background-color: rgba($FONT_COLOR_02, 0.15);
30
+ transform: scale(0.95);
31
+ }
32
+
33
+ &:focus {
34
+ outline: $CAP_SPACE_02 solid $FONT_COLOR_05;
35
+ outline-offset: $CAP_SPACE_02;
36
+ background-color: rgba($FONT_COLOR_02, 0.1);
37
+ }
38
+
39
+ .#{$clsPrefix}-trigger-button-icon {
40
+ width: 1rem;
41
+ height: 1rem;
42
+ display: block;
43
+ pointer-events: none;
44
+ }
45
+ }
@@ -0,0 +1,9 @@
1
+ import React from 'react';
2
+ declare const TriggerButton: React.ForwardRefExoticComponent<{
3
+ onClick?: () => void;
4
+ className?: string;
5
+ disabled?: boolean;
6
+ ariaLabel?: string;
7
+ } & React.RefAttributes<HTMLButtonElement>>;
8
+ export default TriggerButton;
9
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../components/CapEmojiPicker/TriggerButton/index.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,MAAM,OAAO,CAAC;AAK1B,QAAA,MAAM,aAAa;cAGL,MAAM,IAAI;gBACR,MAAM;eACP,OAAO;gBACN,MAAM;2CAapB,CAAC;AAkBH,eAAe,aAAa,CAAC"}
@@ -0,0 +1,35 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import classNames from "classnames";
3
+ import PropTypes from "prop-types";
4
+ import React from "react";
5
+ import emojiIcon from "../assets/sentiment-satsified.svg.js";
6
+ import { CLS_PREFIX } from "../constants.js";
7
+ const TriggerButton = React.forwardRef(({ onClick, className, disabled, ariaLabel }, ref) => /* @__PURE__ */ jsx(
8
+ "button",
9
+ {
10
+ type: "button",
11
+ className: classNames(`${CLS_PREFIX}-trigger`, className),
12
+ onClick,
13
+ disabled,
14
+ "aria-label": ariaLabel,
15
+ ref,
16
+ children: /* @__PURE__ */ jsx("img", { src: emojiIcon, alt: "emoji picker" })
17
+ }
18
+ ));
19
+ TriggerButton.displayName = "CapEmojiPickerTriggerButton";
20
+ TriggerButton.propTypes = {
21
+ onClick: PropTypes.func,
22
+ className: PropTypes.string,
23
+ disabled: PropTypes.bool,
24
+ ariaLabel: PropTypes.string
25
+ };
26
+ TriggerButton.defaultProps = {
27
+ onClick: () => {
28
+ },
29
+ className: "",
30
+ disabled: false,
31
+ ariaLabel: "Insert emoji"
32
+ };
33
+ export {
34
+ TriggerButton as default
35
+ };
@@ -0,0 +1,4 @@
1
+ import React from 'react';
2
+ declare const _default: React.ComponentType<Omit<import("react-intl").WrappedComponentProps, "intl">>;
3
+ export default _default;
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../components/CapEmojiPicker/Wrapper/index.tsx"],"names":[],"mappings":"AAEA,OAAO,KAA4E,MAAM,OAAO,CAAC;;AAsOjG,wBAAmC"}
@@ -0,0 +1,166 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import classNames from "classnames";
3
+ import PropTypes from "prop-types";
4
+ import { lazy, useState, useRef, useEffect, useCallback, useMemo, Suspense } from "react";
5
+ import { intlShape, injectIntl } from "react-intl";
6
+ import CapLabelWithStatic from "../../CapLabel/index.js";
7
+ import CapPopover from "../../CapPopover/index.js";
8
+ import { INPUT_TEXTAREA_SELECTOR, LOADING_FALLBACK_COLOR, PICKER_HEIGHT, PICKER_WIDTH, CLS_PREFIX, DEFAULT_POPOVER_PLACEMENT } from "../constants.js";
9
+ import TriggerButton from "../TriggerButton/index.js";
10
+ import { resolveInputElement } from "../utils.js";
11
+ import messages from "./messages.js";
12
+ import useEmojiTriggerPosition from "./useEmojiTriggerPosition.js";
13
+ const Picker = lazy(() => import("../Picker/index.js"));
14
+ const Wrapper = ({
15
+ intl: { formatMessage },
16
+ children,
17
+ value,
18
+ onChange,
19
+ textAreaRef,
20
+ // Deprecated: kept for backward compatibility
21
+ inputRef,
22
+ // New preferred prop name
23
+ popoverPlacement,
24
+ disabled,
25
+ onEmojiSelect,
26
+ triggerAriaLabel,
27
+ className,
28
+ popoverClassName,
29
+ pickerClassName
30
+ }) => {
31
+ const [visible, setVisible] = useState(false);
32
+ const wrapperRef = useRef(null);
33
+ const extractedInputRef = useRef(null);
34
+ const inputElementRef = inputRef || textAreaRef;
35
+ useEffect(() => {
36
+ if (!wrapperRef.current) return;
37
+ const rafId = requestAnimationFrame(() => {
38
+ const inputElement = wrapperRef.current.querySelector(INPUT_TEXTAREA_SELECTOR);
39
+ if (inputElement) {
40
+ extractedInputRef.current = inputElement;
41
+ if (inputElementRef) {
42
+ if (typeof inputElementRef === "object" && "current" in inputElementRef) {
43
+ inputElementRef.current = inputElement;
44
+ } else if (typeof inputElementRef === "function") {
45
+ inputElementRef(
46
+ inputElement
47
+ );
48
+ }
49
+ }
50
+ }
51
+ });
52
+ return () => {
53
+ cancelAnimationFrame(rafId);
54
+ if (inputElementRef && typeof inputElementRef === "function") {
55
+ inputElementRef(null);
56
+ }
57
+ };
58
+ }, [inputElementRef]);
59
+ const { triggerPositionClass } = useEmojiTriggerPosition(
60
+ wrapperRef,
61
+ inputElementRef,
62
+ value,
63
+ extractedInputRef
64
+ );
65
+ const handleEmojiSelect = useCallback(
66
+ (emojiData) => {
67
+ const emoji = (emojiData == null ? void 0 : emojiData.emoji) || "";
68
+ const target = extractedInputRef.current || resolveInputElement(inputElementRef);
69
+ const currentValue = value || "";
70
+ let nextValue = `${currentValue}${emoji}`;
71
+ if (target && typeof target.selectionStart === "number" && typeof target.selectionEnd === "number") {
72
+ const { selectionStart, selectionEnd } = target;
73
+ nextValue = currentValue.slice(0, selectionStart) + emoji + currentValue.slice(selectionEnd);
74
+ requestAnimationFrame(() => {
75
+ const caret = selectionStart + emoji.length;
76
+ target.focus();
77
+ target.setSelectionRange(caret, caret);
78
+ });
79
+ }
80
+ onChange(nextValue);
81
+ if (onEmojiSelect) {
82
+ onEmojiSelect(emojiData);
83
+ }
84
+ setVisible(false);
85
+ },
86
+ [onChange, onEmojiSelect, inputElementRef, value]
87
+ );
88
+ const content = useMemo(
89
+ () => /* @__PURE__ */ jsx(
90
+ Suspense,
91
+ {
92
+ fallback: /* @__PURE__ */ jsx("div", { className: classNames(`${CLS_PREFIX}-panel`, pickerClassName), children: /* @__PURE__ */ jsx(
93
+ "div",
94
+ {
95
+ style: {
96
+ width: PICKER_WIDTH,
97
+ height: PICKER_HEIGHT,
98
+ display: "flex",
99
+ alignItems: "center",
100
+ justifyContent: "center",
101
+ color: LOADING_FALLBACK_COLOR
102
+ },
103
+ children: /* @__PURE__ */ jsx(CapLabelWithStatic, { children: formatMessage(messages.loadingMessage) })
104
+ }
105
+ ) }),
106
+ children: /* @__PURE__ */ jsx(Picker, { onEmojiSelect: handleEmojiSelect, className: pickerClassName })
107
+ }
108
+ ),
109
+ [handleEmojiSelect, pickerClassName, formatMessage]
110
+ );
111
+ return /* @__PURE__ */ jsxs("div", { ref: wrapperRef, className: classNames(`${CLS_PREFIX}-wrapper`, className), children: [
112
+ children,
113
+ !disabled && /* @__PURE__ */ jsx("div", { className: classNames(`${CLS_PREFIX}-trigger-container`, triggerPositionClass), children: /* @__PURE__ */ jsx(
114
+ CapPopover,
115
+ {
116
+ content,
117
+ trigger: "click",
118
+ placement: popoverPlacement,
119
+ overlayClassName: classNames(`${CLS_PREFIX}-popover`, popoverClassName),
120
+ visible,
121
+ onVisibleChange: (nextVisible) => setVisible(nextVisible),
122
+ children: /* @__PURE__ */ jsx(
123
+ TriggerButton,
124
+ {
125
+ ariaLabel: triggerAriaLabel || formatMessage(messages.defaultTriggerAriaLabel)
126
+ }
127
+ )
128
+ }
129
+ ) })
130
+ ] });
131
+ };
132
+ Wrapper.propTypes = {
133
+ intl: intlShape.isRequired,
134
+ children: PropTypes.node.isRequired,
135
+ value: PropTypes.string,
136
+ onChange: PropTypes.func.isRequired,
137
+ textAreaRef: PropTypes.oneOfType([PropTypes.shape({ current: PropTypes.any }), PropTypes.any]),
138
+ // Deprecated: use inputRef instead
139
+ inputRef: PropTypes.oneOfType([PropTypes.shape({ current: PropTypes.any }), PropTypes.any]),
140
+ // Ref to the input/textarea element for inserting emoji at cursor position
141
+ popoverPlacement: PropTypes.string,
142
+ disabled: PropTypes.bool,
143
+ onEmojiSelect: PropTypes.func,
144
+ triggerAriaLabel: PropTypes.string,
145
+ className: PropTypes.string,
146
+ popoverClassName: PropTypes.string,
147
+ pickerClassName: PropTypes.string
148
+ };
149
+ Wrapper.defaultProps = {
150
+ value: "",
151
+ textAreaRef: null,
152
+ // Deprecated
153
+ inputRef: null,
154
+ popoverPlacement: DEFAULT_POPOVER_PLACEMENT,
155
+ disabled: false,
156
+ onEmojiSelect: null,
157
+ triggerAriaLabel: null,
158
+ // Will use translated default if not provided
159
+ className: "",
160
+ popoverClassName: "",
161
+ pickerClassName: ""
162
+ };
163
+ const Wrapper$1 = injectIntl(Wrapper);
164
+ export {
165
+ Wrapper$1 as default
166
+ };
@@ -0,0 +1,13 @@
1
+ export declare const scope = "app.commonUtils.capUiLibrary.CapEmojiPicker.Wrapper";
2
+ declare const _default: {
3
+ loadingMessage: {
4
+ id: string;
5
+ defaultMessage: string;
6
+ };
7
+ defaultTriggerAriaLabel: {
8
+ id: string;
9
+ defaultMessage: string;
10
+ };
11
+ };
12
+ export default _default;
13
+ //# sourceMappingURL=messages.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"messages.d.ts","sourceRoot":"","sources":["../../../components/CapEmojiPicker/Wrapper/messages.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,KAAK,wDAAwD,CAAC;;;;;;;;;;;AAE3E,wBASG"}
@@ -0,0 +1,16 @@
1
+ import { defineMessages } from "react-intl";
2
+ const scope = "app.commonUtils.capUiLibrary.CapEmojiPicker.Wrapper";
3
+ const messages = defineMessages({
4
+ loadingMessage: {
5
+ id: `${scope}.loadingMessage`,
6
+ defaultMessage: "Loading emoji picker..."
7
+ },
8
+ defaultTriggerAriaLabel: {
9
+ id: `${scope}.defaultTriggerAriaLabel`,
10
+ defaultMessage: "Insert emoji"
11
+ }
12
+ });
13
+ export {
14
+ messages as default,
15
+ scope
16
+ };
@@ -0,0 +1,18 @@
1
+ import React from 'react';
2
+ type InputElementRef = React.RefObject<HTMLInputElement | HTMLTextAreaElement | null> | ((el: HTMLInputElement | HTMLTextAreaElement | null) => void) | null;
3
+ /**
4
+ * Custom hook to calculate and apply emoji trigger positioning
5
+ * Optimizes DOM queries and style mutations while maintaining backward compatibility
6
+ *
7
+ * @param {React.RefObject} wrapperRef - Ref to the wrapper container
8
+ * @param {React.RefObject|Function} inputElementRef - Ref to the input element (for backward compat)
9
+ * @param {string} value - Current input value
10
+ * @param {React.RefObject} extractedInputRef - Ref to the extracted input element from DOM
11
+ * @returns {Object} { triggerPositionClass, triggerContainerRef } - Position class and ref to container
12
+ */
13
+ declare const useEmojiTriggerPosition: (wrapperRef: React.RefObject<HTMLDivElement | null>, inputElementRef: InputElementRef, value: string, extractedInputRef: React.RefObject<HTMLInputElement | HTMLTextAreaElement | null>) => {
14
+ triggerPositionClass: string;
15
+ triggerContainerRef: React.MutableRefObject<HTMLDivElement>;
16
+ };
17
+ export default useEmojiTriggerPosition;
18
+ //# sourceMappingURL=useEmojiTriggerPosition.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useEmojiTriggerPosition.d.ts","sourceRoot":"","sources":["../../../components/CapEmojiPicker/Wrapper/useEmojiTriggerPosition.ts"],"names":[],"mappings":"AAAA,OAAO,KAAsC,MAAM,OAAO,CAAC;AAK3D,KAAK,eAAe,GAChB,KAAK,CAAC,SAAS,CAAC,gBAAgB,GAAG,mBAAmB,GAAG,IAAI,CAAC,GAC9D,CAAC,CAAC,EAAE,EAAE,gBAAgB,GAAG,mBAAmB,GAAG,IAAI,KAAK,IAAI,CAAC,GAC7D,IAAI,CAAC;AAET;;;;;;;;;GASG;AACH,QAAA,MAAM,uBAAuB,GAC3B,YAAY,KAAK,CAAC,SAAS,CAAC,cAAc,GAAG,IAAI,CAAC,EAClD,iBAAiB,eAAe,EAChC,OAAO,MAAM,EACb,mBAAmB,KAAK,CAAC,SAAS,CAAC,gBAAgB,GAAG,mBAAmB,GAAG,IAAI,CAAC;;;CAkKlF,CAAC;AAEF,eAAe,uBAAuB,CAAC"}
@@ -0,0 +1,108 @@
1
+ import { useState, useRef, useEffect } from "react";
2
+ import { CLS_PREFIX, TEXTAREA_TAG, INPUT_TAG } from "../constants.js";
3
+ import { resolveInputElement } from "../utils.js";
4
+ const useEmojiTriggerPosition = (wrapperRef, inputElementRef, value, extractedInputRef) => {
5
+ const [triggerPositionClass, setTriggerPositionClass] = useState("");
6
+ const triggerContainerRef = useRef(null);
7
+ const resizeObserverRef = useRef(null);
8
+ const rafIdRef = useRef(null);
9
+ useEffect(() => {
10
+ if (!wrapperRef.current) {
11
+ setTriggerPositionClass("");
12
+ return;
13
+ }
14
+ const updatePosition = () => {
15
+ if (rafIdRef.current) {
16
+ cancelAnimationFrame(rafIdRef.current);
17
+ }
18
+ rafIdRef.current = requestAnimationFrame(() => {
19
+ const target = extractedInputRef.current || resolveInputElement(inputElementRef);
20
+ if (!target || !wrapperRef.current) {
21
+ setTriggerPositionClass("");
22
+ if (triggerContainerRef.current) {
23
+ triggerContainerRef.current.style.setProperty("--emoji-trigger-bottom", "");
24
+ }
25
+ return;
26
+ }
27
+ if (!triggerContainerRef.current) {
28
+ triggerContainerRef.current = wrapperRef.current.querySelector(
29
+ `.${CLS_PREFIX}-trigger-container`
30
+ );
31
+ }
32
+ const tagName = target.tagName;
33
+ const hasValue = (value == null ? void 0 : value.trim().length) > 0;
34
+ const componentWithLabel = wrapperRef.current.querySelector(".component-with-label");
35
+ const inputWrapper = target.closest(".component-with-label-wrapper") || target.closest(".ant-input-affix-wrapper") || target.parentElement;
36
+ const errorMessage = componentWithLabel == null ? void 0 : componentWithLabel.querySelector(".error-message");
37
+ let bottomOffset = null;
38
+ if (errorMessage && inputWrapper && triggerContainerRef.current) {
39
+ const inputWrapperRect = inputWrapper.getBoundingClientRect();
40
+ const wrapperRect = wrapperRef.current.getBoundingClientRect();
41
+ const inputWrapperBottomFromWrapperTop = inputWrapperRect.bottom - wrapperRect.top;
42
+ const distanceFromWrapperBottomToInputWrapperBottom = wrapperRect.height - inputWrapperBottomFromWrapperTop;
43
+ bottomOffset = tagName === TEXTAREA_TAG ? `${distanceFromWrapperBottomToInputWrapperBottom + 4}px` : `${distanceFromWrapperBottomToInputWrapperBottom + 2}px`;
44
+ }
45
+ if (triggerContainerRef.current) {
46
+ if (bottomOffset !== null) {
47
+ triggerContainerRef.current.style.setProperty("--emoji-trigger-bottom", bottomOffset);
48
+ } else {
49
+ triggerContainerRef.current.style.setProperty("--emoji-trigger-bottom", "");
50
+ }
51
+ }
52
+ if (tagName === TEXTAREA_TAG) {
53
+ setTriggerPositionClass(`${CLS_PREFIX}-trigger-textarea`);
54
+ } else if (tagName === INPUT_TAG) {
55
+ let isSearch = false;
56
+ let hasClearIcon = false;
57
+ const parentElement = target.parentElement;
58
+ const prefixArea = parentElement == null ? void 0 : parentElement.querySelector(".ant-input-prefix");
59
+ const suffixArea = parentElement == null ? void 0 : parentElement.querySelector(".ant-input-suffix");
60
+ if (prefixArea) {
61
+ const hasSearchIcon = prefixArea.querySelector('[class*="search"], [class*="Search"]');
62
+ isSearch = hasSearchIcon !== null;
63
+ }
64
+ if (suffixArea) {
65
+ hasClearIcon = suffixArea.querySelector('.anticon-close, [class*="close"], [class*="Close"]') !== null;
66
+ }
67
+ if (isSearch && hasValue && hasClearIcon) {
68
+ setTriggerPositionClass(`${CLS_PREFIX}-trigger-search-with-value`);
69
+ } else {
70
+ setTriggerPositionClass(`${CLS_PREFIX}-trigger-input`);
71
+ }
72
+ } else {
73
+ setTriggerPositionClass("");
74
+ }
75
+ });
76
+ };
77
+ updatePosition();
78
+ let observeInputTimeout = null;
79
+ if (window.ResizeObserver && wrapperRef.current) {
80
+ resizeObserverRef.current = new ResizeObserver(() => {
81
+ updatePosition();
82
+ });
83
+ resizeObserverRef.current.observe(wrapperRef.current);
84
+ observeInputTimeout = setTimeout(() => {
85
+ const target = extractedInputRef.current || resolveInputElement(inputElementRef);
86
+ if (target && resizeObserverRef.current) {
87
+ resizeObserverRef.current.observe(target);
88
+ }
89
+ }, 0);
90
+ }
91
+ return () => {
92
+ if (rafIdRef.current) {
93
+ cancelAnimationFrame(rafIdRef.current);
94
+ }
95
+ if (resizeObserverRef.current) {
96
+ resizeObserverRef.current.disconnect();
97
+ }
98
+ if (observeInputTimeout) {
99
+ clearTimeout(observeInputTimeout);
100
+ }
101
+ triggerContainerRef.current = null;
102
+ };
103
+ }, [value]);
104
+ return { triggerPositionClass, triggerContainerRef };
105
+ };
106
+ export {
107
+ useEmojiTriggerPosition as default
108
+ };