@atelier-ui/react 0.0.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.
- package/package.json +28 -0
- package/src/index.d.ts +24 -0
- package/src/index.d.ts.map +1 -0
- package/src/index.js +24 -0
- package/src/index.js.map +1 -0
- package/src/lib/accordion/llm-accordion.d.ts +59 -0
- package/src/lib/accordion/llm-accordion.d.ts.map +1 -0
- package/src/lib/accordion/llm-accordion.js +122 -0
- package/src/lib/accordion/llm-accordion.js.map +1 -0
- package/src/lib/alert/llm-alert.d.ts +29 -0
- package/src/lib/alert/llm-alert.d.ts.map +1 -0
- package/src/lib/alert/llm-alert.js +11 -0
- package/src/lib/alert/llm-alert.js.map +1 -0
- package/src/lib/avatar/llm-avatar.d.ts +58 -0
- package/src/lib/avatar/llm-avatar.d.ts.map +1 -0
- package/src/lib/avatar/llm-avatar.js +39 -0
- package/src/lib/avatar/llm-avatar.js.map +1 -0
- package/src/lib/badge/llm-badge.d.ts +25 -0
- package/src/lib/badge/llm-badge.d.ts.map +1 -0
- package/src/lib/badge/llm-badge.js +11 -0
- package/src/lib/badge/llm-badge.js.map +1 -0
- package/src/lib/breadcrumbs/llm-breadcrumbs.d.ts +38 -0
- package/src/lib/breadcrumbs/llm-breadcrumbs.d.ts.map +1 -0
- package/src/lib/breadcrumbs/llm-breadcrumbs.js +28 -0
- package/src/lib/breadcrumbs/llm-breadcrumbs.js.map +1 -0
- package/src/lib/button/llm-button.d.ts +17 -0
- package/src/lib/button/llm-button.d.ts.map +1 -0
- package/src/lib/button/llm-button.js +21 -0
- package/src/lib/button/llm-button.js.map +1 -0
- package/src/lib/card/llm-card.d.ts +52 -0
- package/src/lib/card/llm-card.d.ts.map +1 -0
- package/src/lib/card/llm-card.js +30 -0
- package/src/lib/card/llm-card.js.map +1 -0
- package/src/lib/checkbox/llm-checkbox.d.ts +41 -0
- package/src/lib/checkbox/llm-checkbox.d.ts.map +1 -0
- package/src/lib/checkbox/llm-checkbox.js +29 -0
- package/src/lib/checkbox/llm-checkbox.js.map +1 -0
- package/src/lib/dialog/llm-dialog.d.ts +68 -0
- package/src/lib/dialog/llm-dialog.d.ts.map +1 -0
- package/src/lib/dialog/llm-dialog.js +76 -0
- package/src/lib/dialog/llm-dialog.js.map +1 -0
- package/src/lib/drawer/llm-drawer.d.ts +64 -0
- package/src/lib/drawer/llm-drawer.d.ts.map +1 -0
- package/src/lib/drawer/llm-drawer.js +83 -0
- package/src/lib/drawer/llm-drawer.js.map +1 -0
- package/src/lib/input/llm-input.d.ts +41 -0
- package/src/lib/input/llm-input.d.ts.map +1 -0
- package/src/lib/input/llm-input.js +25 -0
- package/src/lib/input/llm-input.js.map +1 -0
- package/src/lib/menu/llm-menu.d.ts +66 -0
- package/src/lib/menu/llm-menu.d.ts.map +1 -0
- package/src/lib/menu/llm-menu.js +64 -0
- package/src/lib/menu/llm-menu.js.map +1 -0
- package/src/lib/pagination/llm-pagination.d.ts +33 -0
- package/src/lib/pagination/llm-pagination.d.ts.map +1 -0
- package/src/lib/pagination/llm-pagination.js +54 -0
- package/src/lib/pagination/llm-pagination.js.map +1 -0
- package/src/lib/progress/llm-progress.d.ts +33 -0
- package/src/lib/progress/llm-progress.d.ts.map +1 -0
- package/src/lib/progress/llm-progress.js +18 -0
- package/src/lib/progress/llm-progress.js.map +1 -0
- package/src/lib/radio/llm-radio.d.ts +25 -0
- package/src/lib/radio/llm-radio.d.ts.map +1 -0
- package/src/lib/radio/llm-radio.js +23 -0
- package/src/lib/radio/llm-radio.js.map +1 -0
- package/src/lib/radio-group/llm-radio-group.d.ts +84 -0
- package/src/lib/radio-group/llm-radio-group.d.ts.map +1 -0
- package/src/lib/radio-group/llm-radio-group.js +40 -0
- package/src/lib/radio-group/llm-radio-group.js.map +1 -0
- package/src/lib/select/llm-select.d.ts +58 -0
- package/src/lib/select/llm-select.d.ts.map +1 -0
- package/src/lib/select/llm-select.js +26 -0
- package/src/lib/select/llm-select.js.map +1 -0
- package/src/lib/skeleton/llm-skeleton.d.ts +29 -0
- package/src/lib/skeleton/llm-skeleton.d.ts.map +1 -0
- package/src/lib/skeleton/llm-skeleton.js +27 -0
- package/src/lib/skeleton/llm-skeleton.js.map +1 -0
- package/src/lib/tabs/llm-tabs.d.ts +53 -0
- package/src/lib/tabs/llm-tabs.d.ts.map +1 -0
- package/src/lib/tabs/llm-tabs.js +75 -0
- package/src/lib/tabs/llm-tabs.js.map +1 -0
- package/src/lib/textarea/llm-textarea.d.ts +33 -0
- package/src/lib/textarea/llm-textarea.d.ts.map +1 -0
- package/src/lib/textarea/llm-textarea.js +39 -0
- package/src/lib/textarea/llm-textarea.js.map +1 -0
- package/src/lib/toast/llm-toast.d.ts +54 -0
- package/src/lib/toast/llm-toast.d.ts.map +1 -0
- package/src/lib/toast/llm-toast.js +70 -0
- package/src/lib/toast/llm-toast.js.map +1 -0
- package/src/lib/toggle/llm-toggle.d.ts +29 -0
- package/src/lib/toggle/llm-toggle.d.ts.map +1 -0
- package/src/lib/toggle/llm-toggle.js +23 -0
- package/src/lib/toggle/llm-toggle.js.map +1 -0
- package/src/lib/tooltip/llm-tooltip.d.ts +17 -0
- package/src/lib/tooltip/llm-tooltip.d.ts.map +1 -0
- package/src/lib/tooltip/llm-tooltip.js +68 -0
- package/src/lib/tooltip/llm-tooltip.js.map +1 -0
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useId } from 'react';
|
|
3
|
+
import './llm-toggle.css';
|
|
4
|
+
/**
|
|
5
|
+
* A toggle switch component for binary choices, supporting validation and custom labels.
|
|
6
|
+
*/
|
|
7
|
+
export function LlmToggle({ checked = false, onCheckedChange, invalid = false, errors = [], disabled = false, readOnly: reactReadOnly, readonly: specReadOnly, required = false, children, className, id, name, ...rest }) {
|
|
8
|
+
const readOnly = reactReadOnly ?? specReadOnly ?? false;
|
|
9
|
+
const generatedId = useId();
|
|
10
|
+
const inputId = id || `toggle-${generatedId}`;
|
|
11
|
+
const errorId = `${inputId}-errors`;
|
|
12
|
+
const classes = [
|
|
13
|
+
'llm-toggle',
|
|
14
|
+
checked && 'is-checked',
|
|
15
|
+
invalid && 'is-invalid',
|
|
16
|
+
disabled && 'is-disabled',
|
|
17
|
+
className,
|
|
18
|
+
]
|
|
19
|
+
.filter(Boolean)
|
|
20
|
+
.join(' ');
|
|
21
|
+
return (_jsxs("div", { className: classes, children: [_jsxs("label", { htmlFor: inputId, children: [_jsx("input", { type: "checkbox", role: "switch", id: inputId, checked: checked, onChange: (e) => onCheckedChange?.(e.target.checked), disabled: disabled, readOnly: readOnly, required: required, "aria-checked": checked, "aria-invalid": invalid || undefined, "aria-required": required || undefined, "aria-describedby": errors.length > 0 ? errorId : undefined, name: name, ...rest }), _jsx("span", { className: "track", "aria-hidden": "true", children: _jsx("span", { className: "thumb" }) }), children] }), errors.length > 0 && (_jsx("div", { className: "errors", id: errorId, "aria-live": "polite", children: errors.map((err, i) => (_jsx("p", { className: "error-message", children: err }, i))) }))] }));
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=llm-toggle.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"llm-toggle.js","sourceRoot":"","sources":["../../../../../../libs/react/src/lib/toggle/llm-toggle.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAkC,KAAK,EAAE,MAAM,OAAO,CAAC;AAE9D,OAAO,kBAAkB,CAAC;AA0B1B;;GAEG;AACH,MAAM,UAAU,SAAS,CAAC,EACxB,OAAO,GAAG,KAAK,EACf,eAAe,EACf,OAAO,GAAG,KAAK,EACf,MAAM,GAAG,EAAE,EACX,QAAQ,GAAG,KAAK,EAChB,QAAQ,EAAE,aAAa,EACvB,QAAQ,EAAE,YAAY,EACtB,QAAQ,GAAG,KAAK,EAChB,QAAQ,EACR,SAAS,EACT,EAAE,EACF,IAAI,EACJ,GAAG,IAAI,EACQ;IACf,MAAM,QAAQ,GAAG,aAAa,IAAI,YAAY,IAAI,KAAK,CAAC;IACxD,MAAM,WAAW,GAAG,KAAK,EAAE,CAAC;IAC5B,MAAM,OAAO,GAAG,EAAE,IAAI,UAAU,WAAW,EAAE,CAAC;IAC9C,MAAM,OAAO,GAAG,GAAG,OAAO,SAAS,CAAC;IAEpC,MAAM,OAAO,GAAG;QACd,YAAY;QACZ,OAAO,IAAI,YAAY;QACvB,OAAO,IAAI,YAAY;QACvB,QAAQ,IAAI,aAAa;QACzB,SAAS;KACV;SACE,MAAM,CAAC,OAAO,CAAC;SACf,IAAI,CAAC,GAAG,CAAC,CAAC;IAEb,OAAO,CACL,eAAK,SAAS,EAAE,OAAO,aACrB,iBAAO,OAAO,EAAE,OAAO,aACrB,gBACE,IAAI,EAAC,UAAU,EACf,IAAI,EAAC,QAAQ,EACb,EAAE,EAAE,OAAO,EACX,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,eAAe,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,EACpD,QAAQ,EAAE,QAAQ,EAClB,QAAQ,EAAE,QAAQ,EAClB,QAAQ,EAAE,QAAQ,kBACJ,OAAO,kBACP,OAAO,IAAI,SAAS,mBACnB,QAAQ,IAAI,SAAS,sBAClB,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,EACzD,IAAI,EAAE,IAAI,KACN,IAAI,GACR,EACF,eAAM,SAAS,EAAC,OAAO,iBAAa,MAAM,YACxC,eAAM,SAAS,EAAC,OAAO,GAAG,GACrB,EACN,QAAQ,IACH,EACP,MAAM,CAAC,MAAM,GAAG,CAAC,IAAI,CACpB,cAAK,SAAS,EAAC,QAAQ,EAAC,EAAE,EAAE,OAAO,eAAY,QAAQ,YACpD,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,CACtB,YAAW,SAAS,EAAC,eAAe,YACjC,GAAG,IADE,CAAC,CAEL,CACL,CAAC,GACE,CACP,IACG,CACP,CAAC;AACJ,CAAC","sourcesContent":["import { InputHTMLAttributes, ReactNode, useId } from 'react';\nimport type { LlmToggleSpec } from '@atelier-ui/spec';\nimport './llm-toggle.css';\n\n/**\n * Properties for the LlmToggle component.\n */\nexport interface LlmToggleProps\n extends Omit<InputHTMLAttributes<HTMLInputElement>, 'type' | 'checked' | 'onChange' | 'readOnly'>,\n LlmToggleSpec {\n /**\n * Whether the toggle is read-only.\n */\n readOnly?: boolean;\n /**\n * Callback fired when the checked state changes.\n */\n onCheckedChange?: (checked: boolean) => void;\n /**\n * List of error messages to display.\n */\n errors?: string[];\n /**\n * Optional content to display alongside the toggle.\n */\n children?: ReactNode;\n}\n\n/**\n * A toggle switch component for binary choices, supporting validation and custom labels.\n */\nexport function LlmToggle({\n checked = false,\n onCheckedChange,\n invalid = false,\n errors = [],\n disabled = false,\n readOnly: reactReadOnly,\n readonly: specReadOnly,\n required = false,\n children,\n className,\n id,\n name,\n ...rest\n}: LlmToggleProps) {\n const readOnly = reactReadOnly ?? specReadOnly ?? false;\n const generatedId = useId();\n const inputId = id || `toggle-${generatedId}`;\n const errorId = `${inputId}-errors`;\n\n const classes = [\n 'llm-toggle',\n checked && 'is-checked',\n invalid && 'is-invalid',\n disabled && 'is-disabled',\n className,\n ]\n .filter(Boolean)\n .join(' ');\n\n return (\n <div className={classes}>\n <label htmlFor={inputId}>\n <input\n type=\"checkbox\"\n role=\"switch\"\n id={inputId}\n checked={checked}\n onChange={(e) => onCheckedChange?.(e.target.checked)}\n disabled={disabled}\n readOnly={readOnly}\n required={required}\n aria-checked={checked}\n aria-invalid={invalid || undefined}\n aria-required={required || undefined}\n aria-describedby={errors.length > 0 ? errorId : undefined}\n name={name}\n {...rest}\n />\n <span className=\"track\" aria-hidden=\"true\">\n <span className=\"thumb\" />\n </span>\n {children}\n </label>\n {errors.length > 0 && (\n <div className=\"errors\" id={errorId} aria-live=\"polite\">\n {errors.map((err, i) => (\n <p key={i} className=\"error-message\">\n {err}\n </p>\n ))}\n </div>\n )}\n </div>\n );\n}\n"]}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
import type { LlmTooltipSpec } from '@atelier-ui/spec';
|
|
3
|
+
import './llm-tooltip.css';
|
|
4
|
+
/**
|
|
5
|
+
* Properties for the LlmTooltip component.
|
|
6
|
+
*/
|
|
7
|
+
export interface LlmTooltipProps extends LlmTooltipSpec {
|
|
8
|
+
/**
|
|
9
|
+
* The content to trigger the tooltip.
|
|
10
|
+
*/
|
|
11
|
+
children: ReactNode;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* A tooltip component that displays additional information when the trigger is hovered or focused.
|
|
15
|
+
*/
|
|
16
|
+
export declare function LlmTooltip({ llmTooltip, llmTooltipPosition, llmTooltipDisabled, llmTooltipShowDelay, llmTooltipHideDelay, children, }: LlmTooltipProps): import("react/jsx-runtime").JSX.Element;
|
|
17
|
+
//# sourceMappingURL=llm-tooltip.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"llm-tooltip.d.ts","sourceRoot":"","sources":["../../../../../../libs/react/src/lib/tooltip/llm-tooltip.tsx"],"names":[],"mappings":"AAAA,OAAO,EAA+B,SAAS,EAAS,MAAM,OAAO,CAAC;AACtE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,mBAAmB,CAAC;AAE3B;;GAEG;AACH,MAAM,WAAW,eAAgB,SAAQ,cAAc;IACrD;;OAEG;IACH,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,EACzB,UAAU,EACV,kBAA4B,EAC5B,kBAA0B,EAC1B,mBAAyB,EACzB,mBAAuB,EACvB,QAAQ,GACT,EAAE,eAAe,2CAiFjB"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useState, useRef, useEffect, useId } from 'react';
|
|
3
|
+
import './llm-tooltip.css';
|
|
4
|
+
/**
|
|
5
|
+
* A tooltip component that displays additional information when the trigger is hovered or focused.
|
|
6
|
+
*/
|
|
7
|
+
export function LlmTooltip({ llmTooltip, llmTooltipPosition = 'above', llmTooltipDisabled = false, llmTooltipShowDelay = 300, llmTooltipHideDelay = 0, children, }) {
|
|
8
|
+
const [visible, setVisible] = useState(false);
|
|
9
|
+
const showTimer = useRef(null);
|
|
10
|
+
const hideTimer = useRef(null);
|
|
11
|
+
const wrapperRef = useRef(null);
|
|
12
|
+
const id = useId();
|
|
13
|
+
const tooltipId = `tooltip-${id}`;
|
|
14
|
+
const show = () => {
|
|
15
|
+
if (llmTooltipDisabled || !llmTooltip)
|
|
16
|
+
return;
|
|
17
|
+
if (hideTimer.current) {
|
|
18
|
+
clearTimeout(hideTimer.current);
|
|
19
|
+
hideTimer.current = null;
|
|
20
|
+
}
|
|
21
|
+
if (!visible) {
|
|
22
|
+
showTimer.current = setTimeout(() => {
|
|
23
|
+
showTimer.current = null;
|
|
24
|
+
setVisible(true);
|
|
25
|
+
}, llmTooltipShowDelay);
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
const hide = () => {
|
|
29
|
+
if (showTimer.current) {
|
|
30
|
+
clearTimeout(showTimer.current);
|
|
31
|
+
showTimer.current = null;
|
|
32
|
+
}
|
|
33
|
+
hideTimer.current = setTimeout(() => {
|
|
34
|
+
hideTimer.current = null;
|
|
35
|
+
setVisible(false);
|
|
36
|
+
}, llmTooltipHideDelay);
|
|
37
|
+
};
|
|
38
|
+
// Set aria-describedby on the child element
|
|
39
|
+
useEffect(() => {
|
|
40
|
+
const el = wrapperRef.current?.firstElementChild;
|
|
41
|
+
if (el && visible) {
|
|
42
|
+
el.setAttribute('aria-describedby', tooltipId);
|
|
43
|
+
}
|
|
44
|
+
else if (el) {
|
|
45
|
+
el.removeAttribute('aria-describedby');
|
|
46
|
+
}
|
|
47
|
+
}, [visible, tooltipId]);
|
|
48
|
+
// Handle Escape key to dismiss
|
|
49
|
+
useEffect(() => {
|
|
50
|
+
const keyHandler = (e) => {
|
|
51
|
+
if (e.key === 'Escape')
|
|
52
|
+
setVisible(false);
|
|
53
|
+
};
|
|
54
|
+
document.addEventListener('keydown', keyHandler);
|
|
55
|
+
return () => document.removeEventListener('keydown', keyHandler);
|
|
56
|
+
}, []);
|
|
57
|
+
// Cleanup timers on unmount
|
|
58
|
+
useEffect(() => {
|
|
59
|
+
return () => {
|
|
60
|
+
if (showTimer.current)
|
|
61
|
+
clearTimeout(showTimer.current);
|
|
62
|
+
if (hideTimer.current)
|
|
63
|
+
clearTimeout(hideTimer.current);
|
|
64
|
+
};
|
|
65
|
+
}, []);
|
|
66
|
+
return (_jsxs("span", { ref: wrapperRef, className: "llm-tooltip-wrapper", onMouseEnter: show, onMouseLeave: hide, onFocus: show, onBlur: hide, children: [children, visible && !llmTooltipDisabled && llmTooltip && (_jsx("div", { id: tooltipId, role: "tooltip", className: `llm-tooltip position-${llmTooltipPosition}`, children: llmTooltip }))] }));
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=llm-tooltip.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"llm-tooltip.js","sourceRoot":"","sources":["../../../../../../libs/react/src/lib/tooltip/llm-tooltip.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useState, useRef, useEffect, ReactNode, useId } from 'react';\nimport type { LlmTooltipSpec } from '@atelier-ui/spec';\nimport './llm-tooltip.css';\n\n/**\n * Properties for the LlmTooltip component.\n */\nexport interface LlmTooltipProps extends LlmTooltipSpec {\n /**\n * The content to trigger the tooltip.\n */\n children: ReactNode;\n}\n\n/**\n * A tooltip component that displays additional information when the trigger is hovered or focused.\n */\nexport function LlmTooltip({\n llmTooltip,\n llmTooltipPosition = 'above',\n llmTooltipDisabled = false,\n llmTooltipShowDelay = 300,\n llmTooltipHideDelay = 0,\n children,\n}: LlmTooltipProps) {\n const [visible, setVisible] = useState(false);\n const showTimer = useRef<ReturnType<typeof setTimeout> | null>(null);\n const hideTimer = useRef<ReturnType<typeof setTimeout> | null>(null);\n const wrapperRef = useRef<HTMLSpanElement>(null);\n const id = useId();\n const tooltipId = `tooltip-${id}`;\n\n const show = () => {\n if (llmTooltipDisabled || !llmTooltip) return;\n if (hideTimer.current) {\n clearTimeout(hideTimer.current);\n hideTimer.current = null;\n }\n if (!visible) {\n showTimer.current = setTimeout(() => {\n showTimer.current = null;\n setVisible(true);\n }, llmTooltipShowDelay);\n }\n };\n\n const hide = () => {\n if (showTimer.current) {\n clearTimeout(showTimer.current);\n showTimer.current = null;\n }\n hideTimer.current = setTimeout(() => {\n hideTimer.current = null;\n setVisible(false);\n }, llmTooltipHideDelay);\n };\n\n // Set aria-describedby on the child element\n useEffect(() => {\n const el = wrapperRef.current?.firstElementChild as HTMLElement | null;\n if (el && visible) {\n el.setAttribute('aria-describedby', tooltipId);\n } else if (el) {\n el.removeAttribute('aria-describedby');\n }\n }, [visible, tooltipId]);\n\n // Handle Escape key to dismiss\n useEffect(() => {\n const keyHandler = (e: globalThis.KeyboardEvent) => {\n if (e.key === 'Escape') setVisible(false);\n };\n document.addEventListener('keydown', keyHandler);\n return () => document.removeEventListener('keydown', keyHandler);\n }, []);\n\n // Cleanup timers on unmount\n useEffect(() => {\n return () => {\n if (showTimer.current) clearTimeout(showTimer.current);\n if (hideTimer.current) clearTimeout(hideTimer.current);\n };\n }, []);\n\n return (\n <span\n ref={wrapperRef}\n className=\"llm-tooltip-wrapper\"\n onMouseEnter={show}\n onMouseLeave={hide}\n onFocus={show}\n onBlur={hide}\n >\n {children}\n {visible && !llmTooltipDisabled && llmTooltip && (\n <div\n id={tooltipId}\n role=\"tooltip\"\n className={`llm-tooltip position-${llmTooltipPosition}`}\n >\n {llmTooltip}\n </div>\n )}\n </span>\n );\n}\n"]}
|