@intlayer/design-system 8.7.0-canary.0 → 8.7.0

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 (77) hide show
  1. package/dist/esm/components/Browser/Browser.mjs.map +1 -1
  2. package/dist/esm/components/ContentEditor/ContentEditorTextArea.mjs +1 -1
  3. package/dist/esm/components/DictionaryFieldEditor/ContentEditor.mjs +1 -1
  4. package/dist/esm/components/DictionaryFieldEditor/ContentEditor.mjs.map +1 -1
  5. package/dist/esm/components/DictionaryFieldEditor/ContentEditorView/TextEditor.mjs +2 -2
  6. package/dist/esm/components/DictionaryFieldEditor/DictionaryCreationForm/DictionaryCreationForm.mjs +2 -2
  7. package/dist/esm/components/DictionaryFieldEditor/DictionaryCreationForm/DictionaryCreationForm.mjs.map +1 -1
  8. package/dist/esm/components/DictionaryFieldEditor/DictionaryDetails/DictionaryDetailsForm.mjs +3 -3
  9. package/dist/esm/components/DictionaryFieldEditor/DictionaryFieldEditor.mjs +1 -1
  10. package/dist/esm/components/DictionaryFieldEditor/NavigationView/NavigationViewNode.mjs +1 -1
  11. package/dist/esm/components/DictionaryFieldEditor/SaveForm/SaveForm.mjs +2 -2
  12. package/dist/esm/components/DictionaryFieldEditor/StructureView/StructureView.mjs +1 -1
  13. package/dist/esm/components/Form/elements/FormElement.mjs +2 -1
  14. package/dist/esm/components/Form/elements/FormElement.mjs.map +1 -1
  15. package/dist/esm/components/Form/elements/FormElementWrapper.mjs.map +1 -1
  16. package/dist/esm/components/Form/elements/OTPElement.mjs +1 -1
  17. package/dist/esm/components/Form/layout/FormItemLayout.mjs +3 -2
  18. package/dist/esm/components/Form/layout/FormItemLayout.mjs.map +1 -1
  19. package/dist/esm/components/IDE/MonacoCode.mjs +1 -0
  20. package/dist/esm/components/IDE/MonacoCode.mjs.map +1 -1
  21. package/dist/esm/components/Link/Link.mjs.map +1 -1
  22. package/dist/esm/components/LocaleSwitcherContentDropDown/LocaleSwitcherContent.mjs +1 -1
  23. package/dist/esm/components/MarkDownRender/MarkDownRender.mjs +2 -2
  24. package/dist/esm/components/MarkDownRender/MarkDownRender.mjs.map +1 -1
  25. package/dist/esm/components/Modal/Modal.mjs +2 -2
  26. package/dist/esm/components/Navbar/MobileNavbar.mjs +1 -1
  27. package/dist/esm/components/Navbar/index.mjs +2 -57
  28. package/dist/esm/components/Navbar/index.mjs.map +1 -1
  29. package/dist/esm/components/Pagination/Pagination.mjs +1 -1
  30. package/dist/esm/components/RightDrawer/RightDrawer.mjs +3 -3
  31. package/dist/esm/components/Table/SmartTable.mjs +222 -0
  32. package/dist/esm/components/Table/SmartTable.mjs.map +1 -0
  33. package/dist/esm/components/Table/Table.mjs +7 -212
  34. package/dist/esm/components/Table/Table.mjs.map +1 -1
  35. package/dist/esm/components/Table/index.mjs +2 -1
  36. package/dist/esm/components/TextArea/ContentEditableTextArea.mjs +1 -1
  37. package/dist/esm/components/TextArea/ContentEditableTextArea.mjs.map +1 -1
  38. package/dist/esm/components/index.mjs +5 -1
  39. package/dist/esm/hooks/index.mjs +9 -9
  40. package/dist/esm/hooks/reactQuery.mjs +1 -3
  41. package/dist/esm/hooks/reactQuery.mjs.map +1 -1
  42. package/dist/esm/hooks/useAuth/useOAuth2.mjs +1 -1
  43. package/dist/esm/hooks/useAuth/useSession.mjs +1 -1
  44. package/dist/esm/libs/auth.mjs +7 -3
  45. package/dist/esm/libs/auth.mjs.map +1 -1
  46. package/dist/esm/routes.mjs +1 -1
  47. package/dist/esm/routes.mjs.map +1 -1
  48. package/dist/types/components/Button/Button.d.ts +1 -1
  49. package/dist/types/components/CollapsibleTable/CollapsibleTable.d.ts +1 -1
  50. package/dist/types/components/Command/index.d.ts +1 -1
  51. package/dist/types/components/Container/index.d.ts +3 -3
  52. package/dist/types/components/Form/elements/FormElement.d.ts +1 -0
  53. package/dist/types/components/Form/elements/FormElement.d.ts.map +1 -1
  54. package/dist/types/components/Form/layout/FormItemLayout.d.ts +1 -0
  55. package/dist/types/components/Form/layout/FormItemLayout.d.ts.map +1 -1
  56. package/dist/types/components/Input/Checkbox.d.ts +1 -1
  57. package/dist/types/components/Link/Link.d.ts +1 -1
  58. package/dist/types/components/Link/Link.d.ts.map +1 -1
  59. package/dist/types/components/MarkDownRender/MarkDownRender.d.ts +3 -3
  60. package/dist/types/components/MarkDownRender/MarkDownRender.d.ts.map +1 -1
  61. package/dist/types/components/Navbar/index.d.ts +4 -1
  62. package/dist/types/components/Navbar/index.d.ts.map +1 -1
  63. package/dist/types/components/Pagination/Pagination.d.ts +1 -1
  64. package/dist/types/components/TabSelector/TabSelector.d.ts +1 -1
  65. package/dist/types/components/Table/SmartTable.d.ts +158 -0
  66. package/dist/types/components/Table/SmartTable.d.ts.map +1 -0
  67. package/dist/types/components/Table/Table.d.ts +8 -191
  68. package/dist/types/components/Table/Table.d.ts.map +1 -1
  69. package/dist/types/components/Table/index.d.ts +3 -2
  70. package/dist/types/components/TextArea/ContentEditableTextArea.d.ts +2 -2
  71. package/dist/types/components/TextArea/ContentEditableTextArea.d.ts.map +1 -1
  72. package/dist/types/components/Toaster/Toast.d.ts +1 -1
  73. package/dist/types/components/index.d.ts +6 -2
  74. package/dist/types/hooks/reactQuery.d.ts.map +1 -1
  75. package/dist/types/routes.d.ts +1 -1
  76. package/dist/types/routes.d.ts.map +1 -1
  77. package/package.json +22 -22
@@ -1 +1 @@
1
- {"version":3,"file":"Table.mjs","names":[],"sources":["../../../../src/components/Table/Table.tsx"],"sourcesContent":["'use client';\n\nimport { cn } from '@utils/cn';\n\nimport {\n type FC,\n type HTMLAttributes,\n useEffect,\n useRef,\n useState,\n} from 'react';\nimport { ExpandCollapse } from '../ExpandCollapse';\nimport { Modal, ModalSize } from '../Modal';\nimport { ExpandButton } from './ExpandButton';\nimport { useTableWidths } from './useTableWidths';\n\n/**\n * Properties for the Table component that extends standard HTML table attributes\n *\n * @interface TableProps\n * @extends {HTMLAttributes<HTMLTableElement>}\n *\n * @property {boolean} [isRollable] - Whether the table content can be collapsed/expanded using the ExpandCollapse wrapper\n * @property {string} [className] - Additional CSS classes for custom styling\n * @property {ReactNode} children - The table content including thead, tbody, tfoot elements\n *\n * @example\n * ```tsx\n * // Basic table usage\n * <Table>\n * <thead>\n * <tr>\n * <th>Name</th>\n * <th>Email</th>\n * </tr>\n * </thead>\n * <tbody>\n * <tr>\n * <td>John Doe</td>\n * <td>john@example.com</td>\n * </tr>\n * </tbody>\n * </Table>\n *\n * // Collapsible table with custom styling\n * <Table isRollable className=\"border border-gray-300 rounded-lg\">\n * <thead>\n * <tr>\n * <th>Product</th>\n * <th>Price</th>\n * <th>Stock</th>\n * </tr>\n * </thead>\n * <tbody>\n * <tr>\n * <td>Laptop</td>\n * <td>$999</td>\n * <td>15</td>\n * </tr>\n * </tbody>\n * </Table>\n * ```\n */\ntype TableProps = HTMLAttributes<HTMLTableElement> & {\n isRollable?: boolean;\n displayModal?: boolean;\n};\n\n/**\n * Table component that provides an enhanced table experience with modal expansion and collapsible content\n *\n * The Table component wraps a standard HTML table element with additional functionality:\n * - **Modal Expansion**: Click the diagonal arrow button to view the table in a full-screen modal\n * - **Collapsible Content**: Optionally wrap content in an ExpandCollapse component for space-saving\n * - **Responsive Design**: Handles large tables gracefully with modal overflow\n * - **Sticky Controls**: Table controls remain accessible even when scrolling\n *\n * ## Features\n * - **Modal View**: Full-screen modal for better viewing of large tables\n * - **Expand/Collapse**: Optional collapsible wrapper to save space\n * - **Responsive**: Handles overflow and responsive behavior automatically\n * - **Accessibility**: Maintains proper table semantics and keyboard navigation\n * - **Customizable**: Supports all standard HTML table attributes and styling\n *\n * ## Best Practices\n * - Use semantic HTML table structure (thead, tbody, tfoot)\n * - Provide proper column headers with scope attributes\n * - Use the isRollable prop for large tables that might need space management\n * - Apply consistent styling through the className prop\n * - Consider pagination for very large datasets\n *\n * @param {TableProps} props - The properties for the Table component\n * @returns {JSX.Element} The rendered table with enhanced functionality\n *\n * @example\n * ```tsx\n * // Simple data table\n * <Table>\n * <thead>\n * <tr>\n * <th scope=\"col\">Name</th>\n * <th scope=\"col\">Email</th>\n * <th scope=\"col\">Status</th>\n * </tr>\n * </thead>\n * <tbody>\n * <tr>\n * <td>John Doe</td>\n * <td>john@example.com</td>\n * <td>\n * <span className=\"px-2 py-1 bg-green-100 text-green-800 rounded-full text-xs\">\n * Active\n * </span>\n * </td>\n * </tr>\n * <tr>\n * <td>Jane Smith</td>\n * <td>jane@example.com</td>\n * <td>\n * <span className=\"px-2 py-1 bg-yellow-100 text-yellow-800 rounded-full text-xs\">\n * Pending\n * </span>\n * </td>\n * </tr>\n * </tbody>\n * </Table>\n *\n * // Large collapsible table with custom styling\n * <Table\n * isRollable\n * className=\"border border-gray-200 rounded-lg overflow-hidden\"\n * >\n * <thead className=\"bg-gray-50\">\n * <tr>\n * <th scope=\"col\" className=\"px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase\">\n * Product ID\n * </th>\n * <th scope=\"col\" className=\"px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase\">\n * Name\n * </th>\n * <th scope=\"col\" className=\"px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase\">\n * Category\n * </th>\n * <th scope=\"col\" className=\"px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase\">\n * Price\n * </th>\n * <th scope=\"col\" className=\"px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase\">\n * Stock\n * </th>\n * </tr>\n * </thead>\n * <tbody className=\"bg-white divide-y divide-gray-200\">\n * {products.map((product) => (\n * <tr key={product.id} className=\"hover:bg-gray-50\">\n * <td className=\"px-6 py-4 whitespace-nowrap text-sm text-gray-900\">\n * #{product.id}\n * </td>\n * <td className=\"px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900\">\n * {product.name}\n * </td>\n * <td className=\"px-6 py-4 whitespace-nowrap text-sm text-gray-500\">\n * {product.category}\n * </td>\n * <td className=\"px-6 py-4 whitespace-nowrap text-sm text-gray-900\">\n * ${product.price.toFixed(2)}\n * </td>\n * <td className=\"px-6 py-4 whitespace-nowrap text-sm text-gray-500\">\n * {product.stock} units\n * </td>\n * </tr>\n * ))}\n * </tbody>\n * </Table>\n *\n * // Financial data table with formatted numbers\n * <Table className=\"w-full border-collapse\">\n * <thead>\n * <tr className=\"border-b-2 border-gray-300\">\n * <th scope=\"col\" className=\"text-left py-3 px-4\">Quarter</th>\n * <th scope=\"col\" className=\"text-right py-3 px-4\">Revenue</th>\n * <th scope=\"col\" className=\"text-right py-3 px-4\">Profit</th>\n * <th scope=\"col\" className=\"text-right py-3 px-4\">Growth</th>\n * </tr>\n * </thead>\n * <tbody>\n * <tr className=\"border-b border-gray-200\">\n * <td className=\"py-3 px-4 font-medium\">Q1 2024</td>\n * <td className=\"py-3 px-4 text-right\">$2,450,000</td>\n * <td className=\"py-3 px-4 text-right text-green-600\">$345,000</td>\n * <td className=\"py-3 px-4 text-right text-green-600\">+12.5%</td>\n * </tr>\n * <tr className=\"border-b border-gray-200\">\n * <td className=\"py-3 px-4 font-medium\">Q2 2024</td>\n * <td className=\"py-3 px-4 text-right\">$2,780,000</td>\n * <td className=\"py-3 px-4 text-right text-green-600\">$398,000</td>\n * <td className=\"py-3 px-4 text-right text-green-600\">+13.5%</td>\n * </tr>\n * </tbody>\n * </Table>\n * ```\n *\n * @see {@link ExpandCollapse} - Component used for collapsible table content\n * @see {@link Modal} - Component used for full-screen table view\n * @see {@link Button} - Component used for the modal trigger button\n */\nexport const Table: FC<TableProps> = ({\n className,\n isRollable = false,\n displayModal,\n onClick,\n ...props\n}) => {\n const [isModalOpen, setIsModalOpen] = useState(false);\n const [highlightedRowIndex, setHighlightedRowIndex] = useState<number | null>(\n null\n );\n\n const tableRef = useRef<HTMLTableElement>(null);\n const modalTableRef = useRef<HTMLTableElement>(null);\n\n useTableWidths(tableRef, modalTableRef, [props.children, isModalOpen]);\n\n useEffect(() => {\n if (isModalOpen && highlightedRowIndex !== null && modalTableRef.current) {\n const row = modalTableRef.current.rows[highlightedRowIndex];\n\n if (row) {\n row.scrollIntoView({ behavior: 'smooth', block: 'center' });\n\n row.classList.add('bg-neutral/40', 'dark:bg-neutral-dark/40');\n row.style.transition = 'background-color 0.3s ease-in-out';\n }\n }\n }, [isModalOpen, highlightedRowIndex]);\n\n useEffect(() => {\n if (!isModalOpen) {\n setHighlightedRowIndex(null);\n }\n }, [isModalOpen]);\n\n const handleTableClick = (e: React.MouseEvent<HTMLTableElement>) => {\n if (displayModal) {\n const target = e.target as HTMLElement;\n const tr = target.closest('tr');\n\n if (tr?.closest('tbody')) {\n setHighlightedRowIndex(tr.rowIndex);\n setIsModalOpen(true);\n }\n }\n onClick?.(e);\n };\n\n return (\n <div className=\"group relative\">\n {displayModal && <ExpandButton setIsModalOpen={setIsModalOpen} />}\n\n <ExpandCollapse\n isRollable={isRollable}\n className=\"max-w-full overflow-x-auto rounded-2xl bg-background text-left [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-3xl\"\n >\n <table\n ref={tableRef}\n className={cn(\n 'w-full table-auto overflow-hidden',\n displayModal &&\n '[&_tbody_tr:hover]:bg-neutral/40 [&_tbody_tr:hover]:dark:bg-neutral-dark/40 [&_tbody_tr]:cursor-pointer [&_tbody_tr]:transition-colors',\n className\n )}\n onClick={handleTableClick}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n handleTableClick(\n e as unknown as React.MouseEvent<HTMLTableElement>\n );\n }\n }}\n {...props}\n />\n </ExpandCollapse>\n\n <Modal\n isOpen={isModalOpen}\n onClose={() => setIsModalOpen(false)}\n size={ModalSize.XL}\n hasCloseButton\n isScrollable\n >\n {isModalOpen ? (\n <div className=\"grid\">\n <table\n ref={modalTableRef}\n className={cn(\n 'min-w-full max-w-full table-auto text-left',\n className\n )}\n {...props}\n />\n </div>\n ) : (\n <></>\n )}\n </Modal>\n </div>\n );\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6MA,MAAa,SAAyB,EACpC,WACA,aAAa,OACb,cACA,SACA,GAAG,YACC;CACJ,MAAM,CAAC,aAAa,kBAAkB,SAAS,MAAM;CACrD,MAAM,CAAC,qBAAqB,0BAA0B,SACpD,KACD;CAED,MAAM,WAAW,OAAyB,KAAK;CAC/C,MAAM,gBAAgB,OAAyB,KAAK;AAEpD,gBAAe,UAAU,eAAe,CAAC,MAAM,UAAU,YAAY,CAAC;AAEtE,iBAAgB;AACd,MAAI,eAAe,wBAAwB,QAAQ,cAAc,SAAS;GACxE,MAAM,MAAM,cAAc,QAAQ,KAAK;AAEvC,OAAI,KAAK;AACP,QAAI,eAAe;KAAE,UAAU;KAAU,OAAO;KAAU,CAAC;AAE3D,QAAI,UAAU,IAAI,iBAAiB,0BAA0B;AAC7D,QAAI,MAAM,aAAa;;;IAG1B,CAAC,aAAa,oBAAoB,CAAC;AAEtC,iBAAgB;AACd,MAAI,CAAC,YACH,wBAAuB,KAAK;IAE7B,CAAC,YAAY,CAAC;CAEjB,MAAM,oBAAoB,MAA0C;AAClE,MAAI,cAAc;GAEhB,MAAM,KADS,EAAE,OACC,QAAQ,KAAK;AAE/B,OAAI,IAAI,QAAQ,QAAQ,EAAE;AACxB,2BAAuB,GAAG,SAAS;AACnC,mBAAe,KAAK;;;AAGxB,YAAU,EAAE;;AAGd,QACE,qBAAC,OAAD;EAAK,WAAU;YAAf;GACG,gBAAgB,oBAAC,cAAD,EAA8B,gBAAkB;GAEjE,oBAAC,gBAAD;IACc;IACZ,WAAU;cAEV,oBAAC,SAAD;KACE,KAAK;KACL,WAAW,GACT,qCACA,gBACE,0IACF,UACD;KACD,SAAS;KACT,YAAY,MAAM;AAChB,UAAI,EAAE,QAAQ,WAAW,EAAE,QAAQ,IACjC,kBACE,EACD;;KAGL,GAAI;KACJ;IACa;GAEjB,oBAAC,OAAD;IACE,QAAQ;IACR,eAAe,eAAe,MAAM;IACpC,MAAM,UAAU;IAChB;IACA;cAEC,cACC,oBAAC,OAAD;KAAK,WAAU;eACb,oBAAC,SAAD;MACE,KAAK;MACL,WAAW,GACT,8CACA,UACD;MACD,GAAI;MACJ;KACE,IAEN,kCAAK;IAED;GACJ"}
1
+ {"version":3,"file":"Table.mjs","names":[],"sources":["../../../../src/components/Table/Table.tsx"],"sourcesContent":["import { cn } from '@utils/cn';\nimport { forwardRef, type HTMLAttributes } from 'react';\n\nexport interface TableProps extends HTMLAttributes<HTMLTableElement> {\n /** Enables hover states and cursor changes for interactive rows */\n isInteractive?: boolean;\n}\n\nexport const Table = forwardRef<HTMLTableElement, TableProps>(\n ({ className, isInteractive, ...props }, ref) => (\n <table\n ref={ref}\n className={cn(\n 'w-full table-auto overflow-hidden text-left',\n isInteractive &&\n '[&_tbody_tr:hover]:bg-neutral/40 [&_tbody_tr:hover]:dark:bg-neutral-dark/40 [&_tbody_tr]:cursor-pointer [&_tbody_tr]:transition-colors',\n className\n )}\n {...props}\n />\n )\n);\n"],"mappings":";;;;;AAQA,MAAa,QAAQ,YAClB,EAAE,WAAW,eAAe,GAAG,SAAS,QACvC,oBAAC,SAAD;CACO;CACL,WAAW,GACT,+CACA,iBACE,0IACF,UACD;CACD,GAAI;CACJ,EAEL"}
@@ -1,3 +1,4 @@
1
1
  import { Table } from "./Table.mjs";
2
+ import { SmartTable } from "./SmartTable.mjs";
2
3
 
3
- export { Table };
4
+ export { SmartTable, Table };
@@ -259,7 +259,7 @@ const useContentEditable = ({ value, defaultValue, onChange, disabled = false })
259
259
  }
260
260
  e.preventDefault();
261
261
  const selInfo = getSelectionOffsets();
262
- if (!selInfo || !selInfo.hasSelection) return;
262
+ if (!selInfo?.hasSelection) return;
263
263
  const currentText = linesRef.current.join("\n");
264
264
  const selectedText = currentText.slice(selInfo.start, selInfo.end);
265
265
  e.clipboardData.setData("text/plain", selectedText);
@@ -1 +1 @@
1
- {"version":3,"file":"ContentEditableTextArea.mjs","names":[],"sources":["../../../../src/components/TextArea/ContentEditableTextArea.tsx"],"sourcesContent":["'use client';\n\nimport { cn } from '@utils/cn';\nimport type { VariantProps } from 'class-variance-authority';\nimport {\n type ClipboardEvent,\n type DragEvent,\n type FC,\n type FormEvent,\n type HTMLAttributes,\n type KeyboardEvent,\n type MutableRefObject,\n type Ref,\n useEffect,\n useImperativeHandle,\n useRef,\n useState,\n} from 'react';\nimport { type InputVariant, inputVariants } from '../Input';\n\ntype CaretPosition = {\n line: number;\n offset: number;\n};\n\ntype UseContentEditableOptions = {\n value?: string;\n defaultValue?: string;\n onChange?: (value: string) => void;\n disabled?: boolean;\n};\n\nconst ZERO_WIDTH_SPACE = '\\u200B';\n\nconst getTextFromContainer = (container: HTMLDivElement): string => {\n const lineEls = container.querySelectorAll('[data-line]');\n if (lineEls.length === 0) {\n return (container.textContent ?? '').split(ZERO_WIDTH_SPACE).join('');\n }\n\n return Array.from(lineEls)\n .map((el) => {\n const editable = el.querySelector('[data-editable]');\n const raw = editable?.textContent ?? el.textContent ?? '';\n return raw === ZERO_WIDTH_SPACE\n ? ''\n : raw.split(ZERO_WIDTH_SPACE).join('');\n })\n .join('\\n');\n};\n\nconst splitLines = (text: string): string[] => {\n const lines = text.split('\\n');\n return lines.length === 0 ? [''] : lines;\n};\n\n// Cached Intl.Segmenter for grapheme-aware deletion (emoji, CJK, etc.)\n// Intl.Segmenter is ES2022+ but we feature-detect at runtime.\ntype GraphemeSegmenter = {\n segment: (input: string) => Iterable<{ segment: string }>;\n};\n\nconst createGraphemeSegmenter = (): GraphemeSegmenter | null => {\n if (typeof Intl === 'undefined' || !('Segmenter' in Intl)) return null;\n const SegmenterCtor = (\n Intl as unknown as Record<\n string,\n new (\n ...args: unknown[]\n ) => GraphemeSegmenter\n >\n ).Segmenter;\n return new SegmenterCtor(undefined, { granularity: 'grapheme' });\n};\n\nconst graphemeSegmenter = createGraphemeSegmenter();\n\n/**\n * Find the previous grapheme cluster boundary for safe deletion.\n * Falls back to code-point-aware deletion if Intl.Segmenter is unavailable.\n */\nconst prevGraphemeBoundary = (text: string, offset: number): number => {\n if (offset <= 0) return 0;\n\n if (graphemeSegmenter) {\n const segments = [...graphemeSegmenter.segment(text.slice(0, offset))];\n const last = segments[segments.length - 1];\n return last ? offset - last.segment.length : offset - 1;\n }\n\n // Fallback: handle surrogate pairs\n const code = text.charCodeAt(offset - 1);\n if (code >= 0xdc00 && code <= 0xdfff && offset >= 2) {\n return offset - 2;\n }\n return offset - 1;\n};\n\n/**\n * Find the next grapheme cluster boundary for safe forward deletion.\n */\nconst nextGraphemeBoundary = (text: string, offset: number): number => {\n if (offset >= text.length) return text.length;\n\n if (graphemeSegmenter) {\n const segments = [...graphemeSegmenter.segment(text.slice(offset))];\n const first = segments[0];\n return first ? offset + first.segment.length : offset + 1;\n }\n\n // Fallback: handle surrogate pairs\n const code = text.charCodeAt(offset);\n if (code >= 0xd800 && code <= 0xdbff && offset + 1 < text.length) {\n return offset + 2;\n }\n return offset + 1;\n};\n\n/**\n * Find the previous word boundary for Option+Backspace.\n */\nconst prevWordBoundary = (text: string, offset: number): number => {\n if (offset <= 0) return 0;\n let i = offset - 1;\n // Skip whitespace\n while (i > 0 && /\\s/.test(text[i - 1])) i--;\n // Skip word characters\n while (i > 0 && /\\S/.test(text[i - 1])) i--;\n return i;\n};\n\n/**\n * Find the next word boundary for Option+Delete.\n */\nconst nextWordBoundary = (text: string, offset: number): number => {\n if (offset >= text.length) return text.length;\n let i = offset;\n // Skip word characters\n while (i < text.length && /\\S/.test(text[i])) i++;\n // Skip whitespace\n while (i < text.length && /\\s/.test(text[i])) i++;\n return i;\n};\n\n/**\n * Find the start of the current line (for Cmd+Backspace).\n */\nconst lineStart = (text: string, offset: number): number => {\n const before = text.slice(0, offset);\n const lastNewline = before.lastIndexOf('\\n');\n return lastNewline + 1;\n};\n\n/**\n * Find the end of the current line (for Cmd+Delete).\n */\nconst lineEnd = (text: string, offset: number): number => {\n const nextNewline = text.indexOf('\\n', offset);\n return nextNewline === -1 ? text.length : nextNewline;\n};\n\nexport const useContentEditable = ({\n value,\n defaultValue,\n onChange,\n disabled = false,\n}: UseContentEditableOptions) => {\n const initialValue = value ?? defaultValue ?? '';\n const [lines, setLines] = useState<string[]>(() => splitLines(initialValue));\n const containerRef = useRef<HTMLDivElement | null>(null);\n const pendingCaretRef = useRef<CaretPosition | null>(null);\n const isControlled = value !== undefined;\n\n // Keep a ref to the latest lines to avoid stale closures in rapid typing\n const linesRef = useRef(lines);\n linesRef.current = lines;\n\n useEffect(() => {\n if (isControlled && value !== undefined) {\n setLines(splitLines(value));\n }\n }, [value, isControlled]);\n\n const getText = () => linesRef.current.join('\\n');\n\n const getCaretPosition = (): CaretPosition | null => {\n const sel = window.getSelection();\n if (!sel?.rangeCount || !containerRef.current) return null;\n\n const range = sel.getRangeAt(0);\n const lineEls = containerRef.current.querySelectorAll('[data-line]');\n\n for (let i = 0; i < lineEls.length; i++) {\n if (lineEls[i].contains(range.startContainer)) {\n return { line: i, offset: range.startOffset };\n }\n }\n return null;\n };\n\n const getSelectionOffsets = (): {\n start: number;\n end: number;\n hasSelection: boolean;\n } | null => {\n const sel = window.getSelection();\n if (!sel?.rangeCount || !containerRef.current) return null;\n\n const range = sel.getRangeAt(0);\n const lineEls = containerRef.current.querySelectorAll('[data-line]');\n const currentLines = linesRef.current;\n\n const findOffset = (node: Node, nodeOffset: number): number => {\n for (let i = 0; i < lineEls.length; i++) {\n if (lineEls[i].contains(node)) {\n let flat = 0;\n for (let j = 0; j < i; j++) {\n flat += currentLines[j].length + 1;\n }\n return flat + Math.min(nodeOffset, currentLines[i]?.length ?? 0);\n }\n }\n // Selection is on the root container (e.g. select-all)\n if (node === containerRef.current) {\n if (nodeOffset === 0) return 0;\n return currentLines.join('\\n').length;\n }\n return 0;\n };\n\n const start = findOffset(range.startContainer, range.startOffset);\n const end = findOffset(range.endContainer, range.endOffset);\n\n return {\n start: Math.min(start, end),\n end: Math.max(start, end),\n hasSelection: !range.collapsed,\n };\n };\n\n const setCaretPosition = (pos: CaretPosition) => {\n if (!containerRef.current) return;\n\n const lineEls = containerRef.current.querySelectorAll('[data-line]');\n const lineEl = lineEls[pos.line];\n if (!lineEl) return;\n\n const editable = lineEl.querySelector('[data-editable]');\n const node =\n editable?.firstChild ?? editable ?? lineEl.firstChild ?? lineEl;\n\n const sel = window.getSelection();\n if (!sel) return;\n\n const range = document.createRange();\n const maxOff = Math.min(pos.offset, node.textContent?.length ?? 0);\n\n try {\n range.setStart(node, maxOff);\n range.collapse(true);\n sel.removeAllRanges();\n sel.addRange(range);\n } catch {\n range.selectNodeContents(node);\n range.collapse(false);\n sel.removeAllRanges();\n sel.addRange(range);\n }\n };\n\n useEffect(() => {\n if (pendingCaretRef.current && containerRef.current) {\n setCaretPosition(pendingCaretRef.current);\n pendingCaretRef.current = null;\n }\n });\n\n const flatOffsetFromCaret = (pos: CaretPosition): number => {\n const currentLines = linesRef.current;\n let offset = 0;\n for (let i = 0; i < pos.line; i++) {\n offset += currentLines[i].length + 1;\n }\n return offset + pos.offset;\n };\n\n const caretFromFlatOffset = (\n flat: number,\n targetLines: string[]\n ): CaretPosition => {\n let rem = flat;\n for (let i = 0; i < targetLines.length; i++) {\n if (rem <= targetLines[i].length) {\n return { line: i, offset: rem };\n }\n rem -= targetLines[i].length + 1;\n }\n return {\n line: targetLines.length - 1,\n offset: targetLines[targetLines.length - 1]?.length ?? 0,\n };\n };\n\n const getCursorOffset = (): number => {\n const pos = getCaretPosition();\n if (!pos) return 0;\n return flatOffsetFromCaret(pos);\n };\n\n /**\n * Applies a text mutation: computes new lines, sets pending caret, updates state.\n */\n const applyTextChange = (newText: string, caretOffset: number) => {\n const newLines = splitLines(newText);\n pendingCaretRef.current = caretFromFlatOffset(caretOffset, newLines);\n setLines(newLines);\n onChange?.(newText);\n };\n\n const handleInput = () => {\n if (pendingCaretRef.current !== null) return;\n if (disabled || !containerRef.current) return;\n\n const caretPos = getCaretPosition();\n const newText = getTextFromContainer(containerRef.current);\n const newLines = splitLines(newText);\n\n pendingCaretRef.current = caretPos;\n setLines(newLines);\n onChange?.(newText);\n };\n\n const handleKeyDown = (e: KeyboardEvent<HTMLDivElement>) => {\n if (disabled) {\n e.preventDefault();\n return;\n }\n\n // Don't intercept during IME composition (CJK input)\n if (e.nativeEvent.isComposing) return;\n\n // Block undo/redo - browser would mutate DOM out of sync with React\n if ((e.metaKey || e.ctrlKey) && e.key === 'z') {\n e.preventDefault();\n return;\n }\n\n const selInfo = getSelectionOffsets();\n if (!selInfo) return;\n\n const currentText = linesRef.current.join('\\n');\n\n if (e.key === 'Enter') {\n e.preventDefault();\n const newText =\n currentText.slice(0, selInfo.start) +\n '\\n' +\n currentText.slice(selInfo.end);\n applyTextChange(newText, selInfo.start + 1);\n return;\n }\n\n if (e.key === 'Backspace') {\n e.preventDefault();\n\n if (selInfo.hasSelection) {\n const newText =\n currentText.slice(0, selInfo.start) + currentText.slice(selInfo.end);\n applyTextChange(newText, selInfo.start);\n } else {\n if (selInfo.start === 0) return;\n\n let deleteFrom: number;\n if (e.metaKey) {\n // Cmd+Backspace: delete to start of line\n deleteFrom = lineStart(currentText, selInfo.start);\n } else if (e.altKey) {\n // Option+Backspace: delete previous word\n deleteFrom = prevWordBoundary(currentText, selInfo.start);\n } else {\n // Regular backspace: delete one grapheme\n deleteFrom = prevGraphemeBoundary(currentText, selInfo.start);\n }\n\n const newText =\n currentText.slice(0, deleteFrom) + currentText.slice(selInfo.start);\n applyTextChange(newText, deleteFrom);\n }\n return;\n }\n\n if (e.key === 'Delete') {\n e.preventDefault();\n\n if (selInfo.hasSelection) {\n const newText =\n currentText.slice(0, selInfo.start) + currentText.slice(selInfo.end);\n applyTextChange(newText, selInfo.start);\n } else {\n if (selInfo.start >= currentText.length) return;\n\n let deleteTo: number;\n if (e.metaKey) {\n // Cmd+Delete: delete to end of line\n deleteTo = lineEnd(currentText, selInfo.start);\n } else if (e.altKey) {\n // Option+Delete: delete next word\n deleteTo = nextWordBoundary(currentText, selInfo.start);\n } else {\n // Regular delete: delete one grapheme\n deleteTo = nextGraphemeBoundary(currentText, selInfo.start);\n }\n\n const newText =\n currentText.slice(0, selInfo.start) + currentText.slice(deleteTo);\n applyTextChange(newText, selInfo.start);\n }\n return;\n }\n };\n\n const handleCut = (e: ClipboardEvent<HTMLDivElement>) => {\n if (disabled) {\n e.preventDefault();\n return;\n }\n\n e.preventDefault();\n const selInfo = getSelectionOffsets();\n if (!selInfo || !selInfo.hasSelection) return;\n\n const currentText = linesRef.current.join('\\n');\n const selectedText = currentText.slice(selInfo.start, selInfo.end);\n\n // Write selected text to clipboard\n e.clipboardData.setData('text/plain', selectedText);\n\n // Delete the selected text\n const newText =\n currentText.slice(0, selInfo.start) + currentText.slice(selInfo.end);\n applyTextChange(newText, selInfo.start);\n };\n\n const handlePaste = (e: ClipboardEvent<HTMLDivElement>) => {\n if (disabled) {\n e.preventDefault();\n return;\n }\n\n e.preventDefault();\n const pastedText = e.clipboardData.getData('text/plain');\n if (!pastedText) return;\n\n const selInfo = getSelectionOffsets();\n if (!selInfo) return;\n\n const currentText = linesRef.current.join('\\n');\n const newText =\n currentText.slice(0, selInfo.start) +\n pastedText +\n currentText.slice(selInfo.end);\n applyTextChange(newText, selInfo.start + pastedText.length);\n };\n\n const handleBeforeInput = (e: FormEvent<HTMLDivElement>) => {\n if (disabled) return;\n\n const inputEvent = e.nativeEvent as InputEvent;\n\n // Don't intercept during IME composition (CJK input)\n if (inputEvent.isComposing) return;\n\n const inputType = inputEvent.inputType;\n\n // Skip types handled by handleKeyDown (when keydown fires)\n if (inputType === 'insertParagraph' || inputType === 'insertLineBreak') {\n return;\n }\n\n // Handle deletions as fallback for mobile keyboards that don't fire keydown\n if (\n inputType === 'deleteContentBackward' ||\n inputType === 'deleteContentForward'\n ) {\n e.preventDefault();\n const selInfo = getSelectionOffsets();\n if (!selInfo) return;\n\n const currentText = linesRef.current.join('\\n');\n\n if (selInfo.hasSelection) {\n const newText =\n currentText.slice(0, selInfo.start) + currentText.slice(selInfo.end);\n applyTextChange(newText, selInfo.start);\n } else if (inputType === 'deleteContentBackward') {\n if (selInfo.start === 0) return;\n const deleteFrom = prevGraphemeBoundary(currentText, selInfo.start);\n const newText =\n currentText.slice(0, deleteFrom) + currentText.slice(selInfo.start);\n applyTextChange(newText, deleteFrom);\n } else {\n if (selInfo.start >= currentText.length) return;\n const deleteTo = nextGraphemeBoundary(currentText, selInfo.start);\n const newText =\n currentText.slice(0, selInfo.start) + currentText.slice(deleteTo);\n applyTextChange(newText, selInfo.start);\n }\n return;\n }\n\n // Handle spell-check replacements\n if (inputType === 'insertReplacementText') {\n e.preventDefault();\n const selInfo = getSelectionOffsets();\n if (!selInfo) return;\n\n const currentText = linesRef.current.join('\\n');\n const replacement =\n inputEvent.data ?? inputEvent.dataTransfer?.getData('text/plain') ?? '';\n const newText =\n currentText.slice(0, selInfo.start) +\n replacement +\n currentText.slice(selInfo.end);\n applyTextChange(newText, selInfo.start + replacement.length);\n return;\n }\n\n if (inputType === 'insertText' && inputEvent.data) {\n e.preventDefault();\n\n const selInfo = getSelectionOffsets();\n if (!selInfo) return;\n\n const currentText = linesRef.current.join('\\n');\n const inserted = inputEvent.data;\n const newText =\n currentText.slice(0, selInfo.start) +\n inserted +\n currentText.slice(selInfo.end);\n applyTextChange(newText, selInfo.start + inserted.length);\n }\n };\n\n const handleDrop = (e: DragEvent<HTMLDivElement>) => {\n // Block drag-and-drop to prevent uncontrolled DOM mutations\n e.preventDefault();\n };\n\n const handleDragOver = (e: DragEvent<HTMLDivElement>) => {\n e.preventDefault();\n };\n\n return {\n lines,\n containerRef,\n getText,\n handleInput,\n handleBeforeInput,\n handleKeyDown,\n handleCut,\n handlePaste,\n handleDrop,\n handleDragOver,\n getCaretPosition,\n setCaretPosition,\n getCursorOffset,\n caretFromFlatOffset,\n };\n};\n\ntype LineProps = {\n index: number;\n text: string;\n isLast: boolean;\n ghostText?: string;\n};\n\nconst Line: FC<LineProps> = ({ index, text, isLast, ghostText }) => (\n <span data-line={index} className=\"block min-h-[1.5rem]\">\n <span data-editable>{text || '\\u200B'}</span>\n {ghostText && (\n <span\n data-ghost\n className=\"pointer-events-none select-none text-neutral\"\n aria-hidden=\"true\"\n >\n {ghostText}\n </span>\n )}\n {!isLast && <br />}\n </span>\n);\n\nexport type ContentEditableTextAreaHandle = {\n getContainer: () => HTMLDivElement | null;\n getText: () => string;\n focus: () => void;\n getCursorOffset: () => number;\n setCursorAtOffset: (offset: number) => void;\n};\n\nexport type ContentEditableTextAreaProps = Omit<\n HTMLAttributes<HTMLDivElement>,\n 'onChange' | 'defaultValue'\n> & {\n value?: string;\n defaultValue?: string;\n onChange?: (value: string) => void;\n placeholder?: string;\n disabled?: boolean;\n minRows?: number;\n maxRows?: number;\n autoSize?: boolean;\n validationStyleEnabled?: boolean;\n variant?: InputVariant | `${InputVariant}`;\n ghostText?: string;\n ghostLine?: number;\n ghostOffset?: number;\n ref?: Ref<ContentEditableTextAreaHandle>;\n dir?: 'ltr' | 'rtl' | 'auto';\n} & Omit<\n VariantProps<typeof inputVariants>,\n 'validationStyleEnabled' | 'variant'\n >;\n\nconst LINE_HEIGHT = 24;\nconst LINE_PADDING = 12;\n\nexport const ContentEditableTextArea: FC<ContentEditableTextAreaProps> = ({\n value,\n defaultValue,\n onChange,\n placeholder,\n disabled = false,\n minRows = 1,\n maxRows = 999,\n autoSize = true,\n validationStyleEnabled = false,\n variant,\n ghostText,\n ghostLine,\n ghostOffset,\n onClick,\n className,\n dir = 'auto',\n ref,\n ...rest\n}) => {\n const {\n lines,\n containerRef,\n getText,\n handleInput,\n handleBeforeInput,\n handleKeyDown,\n handleCut,\n handlePaste,\n handleDrop,\n handleDragOver,\n getCursorOffset,\n setCaretPosition,\n caretFromFlatOffset,\n } = useContentEditable({ value, defaultValue, onChange, disabled });\n\n const elRef = useRef<HTMLDivElement | null>(null);\n\n const setRef = (el: HTMLDivElement | null) => {\n elRef.current = el;\n (containerRef as MutableRefObject<HTMLDivElement | null>).current = el;\n };\n\n useImperativeHandle(ref, () => ({\n getContainer: () => elRef.current,\n getText,\n focus: () => elRef.current?.focus(),\n getCursorOffset,\n setCursorAtOffset: (offset: number) => {\n setCaretPosition(caretFromFlatOffset(offset, lines));\n },\n }));\n\n useEffect(() => {\n if (!autoSize || !elRef.current) return;\n\n const el = elRef.current;\n const max = LINE_HEIGHT * maxRows + LINE_PADDING;\n const min = LINE_HEIGHT * minRows + LINE_PADDING;\n\n el.style.height = 'auto';\n const sh = el.scrollHeight;\n el.style.height = `${Math.max(Math.min(sh, max), min)}px`;\n el.style.overflowY = sh > max ? 'auto' : 'hidden';\n }, [lines, autoSize, maxRows, minRows]);\n\n const isEmpty = lines.length === 1 && lines[0] === '';\n const hasGhost =\n ghostText && ghostLine !== undefined && ghostOffset !== undefined;\n\n return (\n <div className=\"relative w-full\">\n {isEmpty && placeholder && (\n <div\n className=\"pointer-events-none absolute inset-0 select-none px-2 py-3 text-base text-neutral-400 leading-[1.5rem] md:py-2 md:text-sm\"\n aria-hidden=\"true\"\n >\n {placeholder}\n </div>\n )}\n\n <div\n {...rest}\n ref={setRef}\n role=\"textbox\"\n aria-multiline=\"true\"\n aria-placeholder={placeholder}\n aria-disabled={disabled}\n aria-autocomplete={hasGhost ? 'inline' : undefined}\n tabIndex={disabled ? -1 : 0}\n contentEditable={!disabled}\n suppressContentEditableWarning\n dir={dir}\n onInput={handleInput}\n onBeforeInput={handleBeforeInput}\n onKeyDown={handleKeyDown}\n onCut={handleCut}\n onPaste={handlePaste}\n onDrop={handleDrop}\n onDragOver={handleDragOver}\n onClick={onClick}\n className={cn(\n 'resize-none whitespace-pre-wrap break-words outline-none',\n inputVariants({\n variant,\n validationStyleEnabled: validationStyleEnabled\n ? 'enabled'\n : 'disabled',\n }),\n autoSize && 'overflow-y-auto',\n className\n )}\n >\n {lines.map((text, i) => (\n <Line\n key={i}\n index={i}\n text={text}\n isLast={i === lines.length - 1}\n ghostText={hasGhost && ghostLine === i ? ghostText : undefined}\n />\n ))}\n </div>\n </div>\n );\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"ContentEditableTextArea.mjs","names":[],"sources":["../../../../src/components/TextArea/ContentEditableTextArea.tsx"],"sourcesContent":["'use client';\n\nimport { cn } from '@utils/cn';\nimport type { VariantProps } from 'class-variance-authority';\nimport {\n type ClipboardEvent,\n type DragEvent,\n type FC,\n type HTMLAttributes,\n type InputEvent,\n type KeyboardEvent,\n type MutableRefObject,\n type Ref,\n useEffect,\n useImperativeHandle,\n useRef,\n useState,\n} from 'react';\nimport { type InputVariant, inputVariants } from '../Input';\n\ntype CaretPosition = {\n line: number;\n offset: number;\n};\n\ntype UseContentEditableOptions = {\n value?: string;\n defaultValue?: string;\n onChange?: (value: string) => void;\n disabled?: boolean;\n};\n\nconst ZERO_WIDTH_SPACE = '\\u200B';\n\nconst getTextFromContainer = (container: HTMLDivElement): string => {\n const lineEls = container.querySelectorAll('[data-line]');\n if (lineEls.length === 0) {\n return (container.textContent ?? '').split(ZERO_WIDTH_SPACE).join('');\n }\n\n return Array.from(lineEls)\n .map((el) => {\n const editable = el.querySelector('[data-editable]');\n const raw = editable?.textContent ?? el.textContent ?? '';\n return raw === ZERO_WIDTH_SPACE\n ? ''\n : raw.split(ZERO_WIDTH_SPACE).join('');\n })\n .join('\\n');\n};\n\nconst splitLines = (text: string): string[] => {\n const lines = text.split('\\n');\n return lines.length === 0 ? [''] : lines;\n};\n\n// Cached Intl.Segmenter for grapheme-aware deletion (emoji, CJK, etc.)\n// Intl.Segmenter is ES2022+ but we feature-detect at runtime.\ntype GraphemeSegmenter = {\n segment: (input: string) => Iterable<{ segment: string }>;\n};\n\nconst createGraphemeSegmenter = (): GraphemeSegmenter | null => {\n if (typeof Intl === 'undefined' || !('Segmenter' in Intl)) return null;\n const SegmenterCtor = (\n Intl as unknown as Record<\n string,\n new (\n ...args: unknown[]\n ) => GraphemeSegmenter\n >\n ).Segmenter;\n return new SegmenterCtor(undefined, { granularity: 'grapheme' });\n};\n\nconst graphemeSegmenter = createGraphemeSegmenter();\n\n/**\n * Find the previous grapheme cluster boundary for safe deletion.\n * Falls back to code-point-aware deletion if Intl.Segmenter is unavailable.\n */\nconst prevGraphemeBoundary = (text: string, offset: number): number => {\n if (offset <= 0) return 0;\n\n if (graphemeSegmenter) {\n const segments = [...graphemeSegmenter.segment(text.slice(0, offset))];\n const last = segments[segments.length - 1];\n return last ? offset - last.segment.length : offset - 1;\n }\n\n // Fallback: handle surrogate pairs\n const code = text.charCodeAt(offset - 1);\n if (code >= 0xdc00 && code <= 0xdfff && offset >= 2) {\n return offset - 2;\n }\n return offset - 1;\n};\n\n/**\n * Find the next grapheme cluster boundary for safe forward deletion.\n */\nconst nextGraphemeBoundary = (text: string, offset: number): number => {\n if (offset >= text.length) return text.length;\n\n if (graphemeSegmenter) {\n const segments = [...graphemeSegmenter.segment(text.slice(offset))];\n const first = segments[0];\n return first ? offset + first.segment.length : offset + 1;\n }\n\n // Fallback: handle surrogate pairs\n const code = text.charCodeAt(offset);\n if (code >= 0xd800 && code <= 0xdbff && offset + 1 < text.length) {\n return offset + 2;\n }\n return offset + 1;\n};\n\n/**\n * Find the previous word boundary for Option+Backspace.\n */\nconst prevWordBoundary = (text: string, offset: number): number => {\n if (offset <= 0) return 0;\n let i = offset - 1;\n // Skip whitespace\n while (i > 0 && /\\s/.test(text[i - 1])) i--;\n // Skip word characters\n while (i > 0 && /\\S/.test(text[i - 1])) i--;\n return i;\n};\n\n/**\n * Find the next word boundary for Option+Delete.\n */\nconst nextWordBoundary = (text: string, offset: number): number => {\n if (offset >= text.length) return text.length;\n let i = offset;\n // Skip word characters\n while (i < text.length && /\\S/.test(text[i])) i++;\n // Skip whitespace\n while (i < text.length && /\\s/.test(text[i])) i++;\n return i;\n};\n\n/**\n * Find the start of the current line (for Cmd+Backspace).\n */\nconst lineStart = (text: string, offset: number): number => {\n const before = text.slice(0, offset);\n const lastNewline = before.lastIndexOf('\\n');\n return lastNewline + 1;\n};\n\n/**\n * Find the end of the current line (for Cmd+Delete).\n */\nconst lineEnd = (text: string, offset: number): number => {\n const nextNewline = text.indexOf('\\n', offset);\n return nextNewline === -1 ? text.length : nextNewline;\n};\n\nexport const useContentEditable = ({\n value,\n defaultValue,\n onChange,\n disabled = false,\n}: UseContentEditableOptions) => {\n const initialValue = value ?? defaultValue ?? '';\n const [lines, setLines] = useState<string[]>(() => splitLines(initialValue));\n const containerRef = useRef<HTMLDivElement | null>(null);\n const pendingCaretRef = useRef<CaretPosition | null>(null);\n const isControlled = value !== undefined;\n\n // Keep a ref to the latest lines to avoid stale closures in rapid typing\n const linesRef = useRef(lines);\n linesRef.current = lines;\n\n useEffect(() => {\n if (isControlled && value !== undefined) {\n setLines(splitLines(value));\n }\n }, [value, isControlled]);\n\n const getText = () => linesRef.current.join('\\n');\n\n const getCaretPosition = (): CaretPosition | null => {\n const sel = window.getSelection();\n if (!sel?.rangeCount || !containerRef.current) return null;\n\n const range = sel.getRangeAt(0);\n const lineEls = containerRef.current.querySelectorAll('[data-line]');\n\n for (let i = 0; i < lineEls.length; i++) {\n if (lineEls[i].contains(range.startContainer)) {\n return { line: i, offset: range.startOffset };\n }\n }\n return null;\n };\n\n const getSelectionOffsets = (): {\n start: number;\n end: number;\n hasSelection: boolean;\n } | null => {\n const sel = window.getSelection();\n if (!sel?.rangeCount || !containerRef.current) return null;\n\n const range = sel.getRangeAt(0);\n const lineEls = containerRef.current.querySelectorAll('[data-line]');\n const currentLines = linesRef.current;\n\n const findOffset = (node: Node, nodeOffset: number): number => {\n for (let i = 0; i < lineEls.length; i++) {\n if (lineEls[i].contains(node)) {\n let flat = 0;\n for (let j = 0; j < i; j++) {\n flat += currentLines[j].length + 1;\n }\n return flat + Math.min(nodeOffset, currentLines[i]?.length ?? 0);\n }\n }\n // Selection is on the root container (e.g. select-all)\n if (node === containerRef.current) {\n if (nodeOffset === 0) return 0;\n return currentLines.join('\\n').length;\n }\n return 0;\n };\n\n const start = findOffset(range.startContainer, range.startOffset);\n const end = findOffset(range.endContainer, range.endOffset);\n\n return {\n start: Math.min(start, end),\n end: Math.max(start, end),\n hasSelection: !range.collapsed,\n };\n };\n\n const setCaretPosition = (pos: CaretPosition) => {\n if (!containerRef.current) return;\n\n const lineEls = containerRef.current.querySelectorAll('[data-line]');\n const lineEl = lineEls[pos.line];\n if (!lineEl) return;\n\n const editable = lineEl.querySelector('[data-editable]');\n const node =\n editable?.firstChild ?? editable ?? lineEl.firstChild ?? lineEl;\n\n const sel = window.getSelection();\n if (!sel) return;\n\n const range = document.createRange();\n const maxOff = Math.min(pos.offset, node.textContent?.length ?? 0);\n\n try {\n range.setStart(node, maxOff);\n range.collapse(true);\n sel.removeAllRanges();\n sel.addRange(range);\n } catch {\n range.selectNodeContents(node);\n range.collapse(false);\n sel.removeAllRanges();\n sel.addRange(range);\n }\n };\n\n useEffect(() => {\n if (pendingCaretRef.current && containerRef.current) {\n setCaretPosition(pendingCaretRef.current);\n pendingCaretRef.current = null;\n }\n });\n\n const flatOffsetFromCaret = (pos: CaretPosition): number => {\n const currentLines = linesRef.current;\n let offset = 0;\n for (let i = 0; i < pos.line; i++) {\n offset += currentLines[i].length + 1;\n }\n return offset + pos.offset;\n };\n\n const caretFromFlatOffset = (\n flat: number,\n targetLines: string[]\n ): CaretPosition => {\n let rem = flat;\n for (let i = 0; i < targetLines.length; i++) {\n if (rem <= targetLines[i].length) {\n return { line: i, offset: rem };\n }\n rem -= targetLines[i].length + 1;\n }\n return {\n line: targetLines.length - 1,\n offset: targetLines[targetLines.length - 1]?.length ?? 0,\n };\n };\n\n const getCursorOffset = (): number => {\n const pos = getCaretPosition();\n if (!pos) return 0;\n return flatOffsetFromCaret(pos);\n };\n\n /**\n * Applies a text mutation: computes new lines, sets pending caret, updates state.\n */\n const applyTextChange = (newText: string, caretOffset: number) => {\n const newLines = splitLines(newText);\n pendingCaretRef.current = caretFromFlatOffset(caretOffset, newLines);\n setLines(newLines);\n onChange?.(newText);\n };\n\n const handleInput = () => {\n if (pendingCaretRef.current !== null) return;\n if (disabled || !containerRef.current) return;\n\n const caretPos = getCaretPosition();\n const newText = getTextFromContainer(containerRef.current);\n const newLines = splitLines(newText);\n\n pendingCaretRef.current = caretPos;\n setLines(newLines);\n onChange?.(newText);\n };\n\n const handleKeyDown = (e: KeyboardEvent<HTMLDivElement>) => {\n if (disabled) {\n e.preventDefault();\n return;\n }\n\n // Don't intercept during IME composition (CJK input)\n if (e.nativeEvent.isComposing) return;\n\n // Block undo/redo - browser would mutate DOM out of sync with React\n if ((e.metaKey || e.ctrlKey) && e.key === 'z') {\n e.preventDefault();\n return;\n }\n\n const selInfo = getSelectionOffsets();\n if (!selInfo) return;\n\n const currentText = linesRef.current.join('\\n');\n\n if (e.key === 'Enter') {\n e.preventDefault();\n const newText =\n currentText.slice(0, selInfo.start) +\n '\\n' +\n currentText.slice(selInfo.end);\n applyTextChange(newText, selInfo.start + 1);\n return;\n }\n\n if (e.key === 'Backspace') {\n e.preventDefault();\n\n if (selInfo.hasSelection) {\n const newText =\n currentText.slice(0, selInfo.start) + currentText.slice(selInfo.end);\n applyTextChange(newText, selInfo.start);\n } else {\n if (selInfo.start === 0) return;\n\n let deleteFrom: number;\n if (e.metaKey) {\n // Cmd+Backspace: delete to start of line\n deleteFrom = lineStart(currentText, selInfo.start);\n } else if (e.altKey) {\n // Option+Backspace: delete previous word\n deleteFrom = prevWordBoundary(currentText, selInfo.start);\n } else {\n // Regular backspace: delete one grapheme\n deleteFrom = prevGraphemeBoundary(currentText, selInfo.start);\n }\n\n const newText =\n currentText.slice(0, deleteFrom) + currentText.slice(selInfo.start);\n applyTextChange(newText, deleteFrom);\n }\n return;\n }\n\n if (e.key === 'Delete') {\n e.preventDefault();\n\n if (selInfo.hasSelection) {\n const newText =\n currentText.slice(0, selInfo.start) + currentText.slice(selInfo.end);\n applyTextChange(newText, selInfo.start);\n } else {\n if (selInfo.start >= currentText.length) return;\n\n let deleteTo: number;\n if (e.metaKey) {\n // Cmd+Delete: delete to end of line\n deleteTo = lineEnd(currentText, selInfo.start);\n } else if (e.altKey) {\n // Option+Delete: delete next word\n deleteTo = nextWordBoundary(currentText, selInfo.start);\n } else {\n // Regular delete: delete one grapheme\n deleteTo = nextGraphemeBoundary(currentText, selInfo.start);\n }\n\n const newText =\n currentText.slice(0, selInfo.start) + currentText.slice(deleteTo);\n applyTextChange(newText, selInfo.start);\n }\n return;\n }\n };\n\n const handleCut = (e: ClipboardEvent<HTMLDivElement>) => {\n if (disabled) {\n e.preventDefault();\n return;\n }\n\n e.preventDefault();\n const selInfo = getSelectionOffsets();\n if (!selInfo?.hasSelection) return;\n\n const currentText = linesRef.current.join('\\n');\n const selectedText = currentText.slice(selInfo.start, selInfo.end);\n\n // Write selected text to clipboard\n e.clipboardData.setData('text/plain', selectedText);\n\n // Delete the selected text\n const newText =\n currentText.slice(0, selInfo.start) + currentText.slice(selInfo.end);\n applyTextChange(newText, selInfo.start);\n };\n\n const handlePaste = (e: ClipboardEvent<HTMLDivElement>) => {\n if (disabled) {\n e.preventDefault();\n return;\n }\n\n e.preventDefault();\n const pastedText = e.clipboardData.getData('text/plain');\n if (!pastedText) return;\n\n const selInfo = getSelectionOffsets();\n if (!selInfo) return;\n\n const currentText = linesRef.current.join('\\n');\n const newText =\n currentText.slice(0, selInfo.start) +\n pastedText +\n currentText.slice(selInfo.end);\n applyTextChange(newText, selInfo.start + pastedText.length);\n };\n\n const handleBeforeInput = (e: InputEvent<HTMLDivElement>) => {\n if (disabled) return;\n\n const inputEvent = e.nativeEvent as InputEvent;\n\n // Don't intercept during IME composition (CJK input)\n if (inputEvent.isComposing) return;\n\n const inputType = inputEvent.inputType;\n\n // Skip types handled by handleKeyDown (when keydown fires)\n if (inputType === 'insertParagraph' || inputType === 'insertLineBreak') {\n return;\n }\n\n // Handle deletions as fallback for mobile keyboards that don't fire keydown\n if (\n inputType === 'deleteContentBackward' ||\n inputType === 'deleteContentForward'\n ) {\n e.preventDefault();\n const selInfo = getSelectionOffsets();\n if (!selInfo) return;\n\n const currentText = linesRef.current.join('\\n');\n\n if (selInfo.hasSelection) {\n const newText =\n currentText.slice(0, selInfo.start) + currentText.slice(selInfo.end);\n applyTextChange(newText, selInfo.start);\n } else if (inputType === 'deleteContentBackward') {\n if (selInfo.start === 0) return;\n const deleteFrom = prevGraphemeBoundary(currentText, selInfo.start);\n const newText =\n currentText.slice(0, deleteFrom) + currentText.slice(selInfo.start);\n applyTextChange(newText, deleteFrom);\n } else {\n if (selInfo.start >= currentText.length) return;\n const deleteTo = nextGraphemeBoundary(currentText, selInfo.start);\n const newText =\n currentText.slice(0, selInfo.start) + currentText.slice(deleteTo);\n applyTextChange(newText, selInfo.start);\n }\n return;\n }\n\n // Handle spell-check replacements\n if (inputType === 'insertReplacementText') {\n e.preventDefault();\n const selInfo = getSelectionOffsets();\n if (!selInfo) return;\n\n const currentText = linesRef.current.join('\\n');\n const replacement =\n inputEvent.data ?? inputEvent.dataTransfer?.getData('text/plain') ?? '';\n const newText =\n currentText.slice(0, selInfo.start) +\n replacement +\n currentText.slice(selInfo.end);\n applyTextChange(newText, selInfo.start + replacement.length);\n return;\n }\n\n if (inputType === 'insertText' && inputEvent.data) {\n e.preventDefault();\n\n const selInfo = getSelectionOffsets();\n if (!selInfo) return;\n\n const currentText = linesRef.current.join('\\n');\n const inserted = inputEvent.data;\n const newText =\n currentText.slice(0, selInfo.start) +\n inserted +\n currentText.slice(selInfo.end);\n applyTextChange(newText, selInfo.start + inserted.length);\n }\n };\n\n const handleDrop = (e: DragEvent<HTMLDivElement>) => {\n // Block drag-and-drop to prevent uncontrolled DOM mutations\n e.preventDefault();\n };\n\n const handleDragOver = (e: DragEvent<HTMLDivElement>) => {\n e.preventDefault();\n };\n\n return {\n lines,\n containerRef,\n getText,\n handleInput,\n handleBeforeInput,\n handleKeyDown,\n handleCut,\n handlePaste,\n handleDrop,\n handleDragOver,\n getCaretPosition,\n setCaretPosition,\n getCursorOffset,\n caretFromFlatOffset,\n };\n};\n\ntype LineProps = {\n index: number;\n text: string;\n isLast: boolean;\n ghostText?: string;\n};\n\nconst Line: FC<LineProps> = ({ index, text, isLast, ghostText }) => (\n <span data-line={index} className=\"block min-h-[1.5rem]\">\n <span data-editable>{text || '\\u200B'}</span>\n {ghostText && (\n <span\n data-ghost\n className=\"pointer-events-none select-none text-neutral\"\n aria-hidden=\"true\"\n >\n {ghostText}\n </span>\n )}\n {!isLast && <br />}\n </span>\n);\n\nexport type ContentEditableTextAreaHandle = {\n getContainer: () => HTMLDivElement | null;\n getText: () => string;\n focus: () => void;\n getCursorOffset: () => number;\n setCursorAtOffset: (offset: number) => void;\n};\n\nexport type ContentEditableTextAreaProps = Omit<\n HTMLAttributes<HTMLDivElement>,\n 'onChange' | 'defaultValue'\n> & {\n value?: string;\n defaultValue?: string;\n onChange?: (value: string) => void;\n placeholder?: string;\n disabled?: boolean;\n minRows?: number;\n maxRows?: number;\n autoSize?: boolean;\n validationStyleEnabled?: boolean;\n variant?: InputVariant | `${InputVariant}`;\n ghostText?: string;\n ghostLine?: number;\n ghostOffset?: number;\n ref?: Ref<ContentEditableTextAreaHandle>;\n dir?: 'ltr' | 'rtl' | 'auto';\n} & Omit<\n VariantProps<typeof inputVariants>,\n 'validationStyleEnabled' | 'variant'\n >;\n\nconst LINE_HEIGHT = 24;\nconst LINE_PADDING = 12;\n\nexport const ContentEditableTextArea: FC<ContentEditableTextAreaProps> = ({\n value,\n defaultValue,\n onChange,\n placeholder,\n disabled = false,\n minRows = 1,\n maxRows = 999,\n autoSize = true,\n validationStyleEnabled = false,\n variant,\n ghostText,\n ghostLine,\n ghostOffset,\n onClick,\n className,\n dir = 'auto',\n ref,\n ...rest\n}) => {\n const {\n lines,\n containerRef,\n getText,\n handleInput,\n handleBeforeInput,\n handleKeyDown,\n handleCut,\n handlePaste,\n handleDrop,\n handleDragOver,\n getCursorOffset,\n setCaretPosition,\n caretFromFlatOffset,\n } = useContentEditable({ value, defaultValue, onChange, disabled });\n\n const elRef = useRef<HTMLDivElement | null>(null);\n\n const setRef = (el: HTMLDivElement | null) => {\n elRef.current = el;\n (containerRef as MutableRefObject<HTMLDivElement | null>).current = el;\n };\n\n useImperativeHandle(ref, () => ({\n getContainer: () => elRef.current,\n getText,\n focus: () => elRef.current?.focus(),\n getCursorOffset,\n setCursorAtOffset: (offset: number) => {\n setCaretPosition(caretFromFlatOffset(offset, lines));\n },\n }));\n\n useEffect(() => {\n if (!autoSize || !elRef.current) return;\n\n const el = elRef.current;\n const max = LINE_HEIGHT * maxRows + LINE_PADDING;\n const min = LINE_HEIGHT * minRows + LINE_PADDING;\n\n el.style.height = 'auto';\n const sh = el.scrollHeight;\n el.style.height = `${Math.max(Math.min(sh, max), min)}px`;\n el.style.overflowY = sh > max ? 'auto' : 'hidden';\n }, [lines, autoSize, maxRows, minRows]);\n\n const isEmpty = lines.length === 1 && lines[0] === '';\n const hasGhost =\n ghostText && ghostLine !== undefined && ghostOffset !== undefined;\n\n return (\n <div className=\"relative w-full\">\n {isEmpty && placeholder && (\n <div\n className=\"pointer-events-none absolute inset-0 select-none px-2 py-3 text-base text-neutral-400 leading-[1.5rem] md:py-2 md:text-sm\"\n aria-hidden=\"true\"\n >\n {placeholder}\n </div>\n )}\n\n <div\n {...rest}\n ref={setRef}\n role=\"textbox\"\n aria-multiline=\"true\"\n aria-placeholder={placeholder}\n aria-disabled={disabled}\n aria-autocomplete={hasGhost ? 'inline' : undefined}\n tabIndex={disabled ? -1 : 0}\n contentEditable={!disabled}\n suppressContentEditableWarning\n dir={dir}\n onInput={handleInput}\n onBeforeInput={handleBeforeInput}\n onKeyDown={handleKeyDown}\n onCut={handleCut}\n onPaste={handlePaste}\n onDrop={handleDrop}\n onDragOver={handleDragOver}\n onClick={onClick}\n className={cn(\n 'resize-none whitespace-pre-wrap break-words outline-none',\n inputVariants({\n variant,\n validationStyleEnabled: validationStyleEnabled\n ? 'enabled'\n : 'disabled',\n }),\n autoSize && 'overflow-y-auto',\n className\n )}\n >\n {lines.map((text, i) => (\n <Line\n key={i}\n index={i}\n text={text}\n isLast={i === lines.length - 1}\n ghostText={hasGhost && ghostLine === i ? ghostText : undefined}\n />\n ))}\n </div>\n </div>\n );\n};\n"],"mappings":"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"}
@@ -49,6 +49,7 @@ import { TabSelector, TabSelectorColor } from "./TabSelector/TabSelector.mjs";
49
49
  import { Tab } from "./Tab/Tab.mjs";
50
50
  import { Modal, ModalSize } from "./Modal/Modal.mjs";
51
51
  import { Table } from "./Table/Table.mjs";
52
+ import { SmartTable } from "./Table/SmartTable.mjs";
52
53
  import { MarkdownRenderer, baseMarkdownComponents, getIntlayerMarkdownOptions } from "./MarkDownRender/MarkDownRender.mjs";
53
54
  import { TextEditor, TextEditorContainer, traceKeys } from "./DictionaryFieldEditor/ContentEditorView/TextEditor.mjs";
54
55
  import { KeyPathBreadcrumb } from "./DictionaryFieldEditor/KeyPathBreadcrumb.mjs";
@@ -92,6 +93,9 @@ import { KeyboardScreenAdapter } from "./KeyboardScreenAdapter/index.mjs";
92
93
  import { LanguageBackground, LanguageSection } from "./LanguageBackground/index.mjs";
93
94
  import { LocaleSwitcher } from "./LocaleSwitcherDropDown/LocaleSwitcher.mjs";
94
95
  import { MaxWidthSmoother } from "./MaxWidthSmoother/index.mjs";
96
+ import { DesktopNavbar } from "./Navbar/DesktopNavbar.mjs";
97
+ import { Burger } from "./Navbar/Burger.mjs";
98
+ import { MobileNavbar } from "./Navbar/MobileNavbar.mjs";
95
99
  import { Navbar } from "./Navbar/index.mjs";
96
100
  import { NumberItemsSelector } from "./Pagination/NumberItemsSelector.mjs";
97
101
  import { Pagination, PaginationSize, PaginationVariant, paginationVariants } from "./Pagination/Pagination.mjs";
@@ -110,4 +114,4 @@ import { Modes } from "./ThemeSwitcherDropDown/types.mjs";
110
114
  import { DesktopThemeSwitcher } from "./ThemeSwitcherDropDown/DesktopThemeSwitcher.mjs";
111
115
  import { MobileThemeSwitcher } from "./ThemeSwitcherDropDown/MobileThemeSwitcher.mjs";
112
116
 
113
- export { Accordion, AutoCompleteTextarea, AutoSizedTextArea, Avatar, Badge, BadgeColor, BadgeSize, BadgeVariant, BitbucketLogo, Breadcrumb, Browser, Button, ButtonColor, ButtonSize, ButtonTextAlign, ButtonVariant, Carousel, Checkbox, CheckboxColor, CheckboxSize, ClickOutsideDiv, Code, CodeBlock, CodeDefault, CollapsibleTable, Command, CommandRoot, Container, ContainerBackground, ContainerBorderColor, ContainerGap, ContainerPadding, ContainerRoundedSize, ContainerSeparator, ContainerTransparency, ContentEditableTextArea, ContentEditor, ContentSelector, CopyButton, CopyToClipboard, DesktopThemeSwitcher, Detail, DictionaryCreationForm, DictionaryEditor, DictionaryFieldEditor, DiscordLogo, DotPattern, DropDown, DropDownAlign, DropDownYAlign, EditableFieldInput, EditableFieldTextArea, ExpandCollapse, FacebookLogo, FileList, Flag, flags_exports as Flags, Footer, Form, GitHubLogo, GitLabLogo, GoogleLogo, GridPattern, H1, H2, H3, H4, H5, H6, HTMLRenderer, HeightResizer, HideShow, IDE, InformationTag, Input, InputIndicator, InputOTP, InputOTPGroup, InputOTPSeparator, InputOTPSlot, InputPassword, InputSize, InputVariant, InstagramLogo, KeyList, KeyPathBreadcrumb, KeyboardScreenAdapter, KeyboardShortcut, Label, LanguageBackground, LanguageSection, Link, LinkColor, LinkRoundedSize, LinkSize, LinkUnderlined, LinkVariant, LinkedInLogo, Loader, LocaleSwitcher, LocaleSwitcherContent, LocaleSwitcherContentProvider, Logo, LogoTextOnly, LogoWithText, LogoWithTextBelow, MarkdownRenderer, MaxHeightSmoother, MaxWidthSmoother, MobileThemeSwitcher, Modal, ModalSize, Modes, MultiSelect, Navbar, NumberItemsSelector, OTPInput, OTPInputContext, Pagination, PaginationSize, PaginationVariant, Popover, PopoverStatic, PopoverXAlign, PopoverYAlign, PressableSpan, ProductHuntLogo, RightDrawer, SaveForm, SearchInput, Select, SelectContent, SelectContentPosition, SelectLabel, SelectSeparator, ShowingResultsNumberItems, SocialNetworks, Spotlight, SwitchSelector, SwitchSelectorColor, SwitchSelectorSize, Tab, TabSelector, TabSelectorColor, Table, Tag, TagBackground, TagBorder, TagColor, TagRoundedSize, TagSize, TechLogo, TechLogoName, techLogos_exports as TechLogos, Terminal, TextArea, TextEditor, TextEditorContainer, TiktokLogo, Toast, ToastAction, ToastClose, ToastDescription, ToastProvider, ToastTitle, ToastViewport, Toaster, VersionSwitcher, VersionSwitcherProvider, WithResizer, XLogo, YoutubeLogo, badgeVariants, baseMarkdownComponents, buttonVariants, checkIsExternalLink, checkboxVariants, containerVariants, drawerManager, getCapitals, getIntlayerHTMLOptions, getIntlayerMarkdownOptions, inputSlotVariants, inputVariants, isTextChildren, linkVariants, paginationVariants, reducer, toast, traceKeys, useContentEditable, useCopyToClipboard, useForm, useFormField, useLocaleSwitcherContent, usePasswordManagerBadge, usePrevious, useRightDrawer, useToast, useVersionSwitcher };
117
+ export { Accordion, AutoCompleteTextarea, AutoSizedTextArea, Avatar, Badge, BadgeColor, BadgeSize, BadgeVariant, BitbucketLogo, Breadcrumb, Browser, Burger, Button, ButtonColor, ButtonSize, ButtonTextAlign, ButtonVariant, Carousel, Checkbox, CheckboxColor, CheckboxSize, ClickOutsideDiv, Code, CodeBlock, CodeDefault, CollapsibleTable, Command, CommandRoot, Container, ContainerBackground, ContainerBorderColor, ContainerGap, ContainerPadding, ContainerRoundedSize, ContainerSeparator, ContainerTransparency, ContentEditableTextArea, ContentEditor, ContentSelector, CopyButton, CopyToClipboard, DesktopNavbar, DesktopThemeSwitcher, Detail, DictionaryCreationForm, DictionaryEditor, DictionaryFieldEditor, DiscordLogo, DotPattern, DropDown, DropDownAlign, DropDownYAlign, EditableFieldInput, EditableFieldTextArea, ExpandCollapse, FacebookLogo, FileList, Flag, flags_exports as Flags, Footer, Form, GitHubLogo, GitLabLogo, GoogleLogo, GridPattern, H1, H2, H3, H4, H5, H6, HTMLRenderer, HeightResizer, HideShow, IDE, InformationTag, Input, InputIndicator, InputOTP, InputOTPGroup, InputOTPSeparator, InputOTPSlot, InputPassword, InputSize, InputVariant, InstagramLogo, KeyList, KeyPathBreadcrumb, KeyboardScreenAdapter, KeyboardShortcut, Label, LanguageBackground, LanguageSection, Link, LinkColor, LinkRoundedSize, LinkSize, LinkUnderlined, LinkVariant, LinkedInLogo, Loader, LocaleSwitcher, LocaleSwitcherContent, LocaleSwitcherContentProvider, Logo, LogoTextOnly, LogoWithText, LogoWithTextBelow, MarkdownRenderer, MaxHeightSmoother, MaxWidthSmoother, MobileNavbar, MobileThemeSwitcher, Modal, ModalSize, Modes, MultiSelect, Navbar, NumberItemsSelector, OTPInput, OTPInputContext, Pagination, PaginationSize, PaginationVariant, Popover, PopoverStatic, PopoverXAlign, PopoverYAlign, PressableSpan, ProductHuntLogo, RightDrawer, SaveForm, SearchInput, Select, SelectContent, SelectContentPosition, SelectLabel, SelectSeparator, ShowingResultsNumberItems, SmartTable, SocialNetworks, Spotlight, SwitchSelector, SwitchSelectorColor, SwitchSelectorSize, Tab, TabSelector, TabSelectorColor, Table, Tag, TagBackground, TagBorder, TagColor, TagRoundedSize, TagSize, TechLogo, TechLogoName, techLogos_exports as TechLogos, Terminal, TextArea, TextEditor, TextEditorContainer, TiktokLogo, Toast, ToastAction, ToastClose, ToastDescription, ToastProvider, ToastTitle, ToastViewport, Toaster, VersionSwitcher, VersionSwitcherProvider, WithResizer, XLogo, YoutubeLogo, badgeVariants, baseMarkdownComponents, buttonVariants, checkIsExternalLink, checkboxVariants, containerVariants, drawerManager, getCapitals, getIntlayerHTMLOptions, getIntlayerMarkdownOptions, inputSlotVariants, inputVariants, isTextChildren, linkVariants, paginationVariants, reducer, toast, traceKeys, useContentEditable, useCopyToClipboard, useForm, useFormField, useLocaleSwitcherContent, usePasswordManagerBadge, usePrevious, useRightDrawer, useToast, useVersionSwitcher };
@@ -1,22 +1,22 @@
1
- import { useKeyboardDetector } from "./useKeyboardDetector.mjs";
2
- import { useGetElementOrWindow } from "./useGetElementOrWindow.mjs";
3
- import { useScrollY } from "./useScrollY.mjs";
4
- import { usePersistedStore } from "./usePersistedStore.mjs";
5
- import { useHorizontalSwipe } from "./useHorizontalSwipe.mjs";
6
- import { useItemSelector } from "./useItemSelector.mjs";
7
1
  import { calculateIsMobile, checkIsIOS, checkIsIphoneOrSafariDevice, checkIsMac, checkIsMobileScreen, checkIsMobileUserAgent, getBreakpointFromSize, useDevice } from "./useDevice.mjs";
2
+ import { useItemSelector } from "./useItemSelector.mjs";
3
+ import { usePersistedStore } from "./usePersistedStore.mjs";
8
4
  import { useOAuth2 } from "./useAuth/useOAuth2.mjs";
9
5
  import { useSession } from "./useAuth/useSession.mjs";
10
6
  import { useAuth } from "./useAuth/useAuth.mjs";
11
7
  import { useIntlayerAuth, useIntlayerOAuth } from "./useIntlayerAPI.mjs";
12
8
  import { useAddDictionary, useAddNewAccessKey, useAddOrganization, useAddOrganizationMember, useAddPasskey, useAddProject, useAddTag, useAppQuery, useAskDocQuestion, useAskResetPassword, useAuditContentDeclaration, useAuditContentDeclarationField, useAuditContentDeclarationMetadata, useAuditScan, useAuditTag, useAutocomplete, useBitbucketAuth, useBitbucketCheckConfig, useBitbucketGetConfigFile, useBitbucketRepos, useCancelSubscription, useChangePassword, useCreateUser, useDeleteAccessKey, useDeleteDictionary, useDeleteOrganization, useDeletePasskey, useDeleteProject, useDeleteSSOProvider, useDeleteShowcaseProject, useDeleteTag, useDeleteUser, useDisableTwoFactor, useEnableTwoFactor, useGetCIConfig, useGetDictionaries, useGetDictionariesKeys, useGetDictionary, useGetDiscussions, useGetDiscussionsData, useGetEditorDictionaries, useGetNewsletterStatus, useGetOrganizations, useGetOtherShowcaseProjects, useGetPricing, useGetProjects, useGetRecursiveAuditStatus, useGetShowcaseProjectById, useGetShowcaseProjects, useGetSubscription, useGetTags, useGetUserByAccount, useGetUserById, useGetUsers, useGetVerifyEmailStatus, useGithubAuth, useGithubCheckConfig, useGithubGetAuthUrl, useGithubGetConfigFile, useGithubRepos, useGitlabAuth, useGitlabCheckConfig, useGitlabGetConfigFile, useGitlabProjects, useInfiniteGetDictionaries, useListPasskeys, useListSSOProviders, useLogin, useLogout, usePushCIConfig, usePushDictionaries, useQueryClient, useRefreshAccessKey, useRegister, useRegisterSSO, useResetPassword, useSearchDoc, useSelectOrganization, useSelectProject, useSignInMagicLink, useSignInPasskey, useSignInSSO, useStartRecursiveAudit, useSubmitShowcaseProject, useSubscribeToNewsletter, useToggleShowcaseDownvote, useToggleShowcaseUpvote, useTranslateJSONDeclaration, useTriggerBuild, useTriggerWebhook, useUnselectOrganization, useUnselectProject, useUnsubscribeFromNewsletter, useUpdateDictionary, useUpdateOrganization, useUpdateOrganizationMembers, useUpdateOrganizationMembersById, useUpdateProject, useUpdateProjectMembers, useUpdateShowcaseProject, useUpdateTag, useUpdateUser, useVerifyBackupCode, useVerifyEmail, useVerifyTotp, useWriteDictionary } from "./reactQuery.mjs";
13
- import { useSearch } from "./useSearch.mjs";
14
- import { useIsMounted } from "./useIsMounted.mjs";
9
+ import { useUser } from "./useUser/index.mjs";
10
+ import { useHorizontalSwipe } from "./useHorizontalSwipe.mjs";
15
11
  import { useGetElementById } from "./useGetElementById.mjs";
12
+ import { useGetElementOrWindow } from "./useGetElementOrWindow.mjs";
16
13
  import { useIsDarkMode } from "./useIsDarkMode.mjs";
14
+ import { useIsMounted } from "./useIsMounted.mjs";
15
+ import { useKeyboardDetector } from "./useKeyboardDetector.mjs";
17
16
  import { useScreenWidth } from "./useScreenWidth.mjs";
18
17
  import { useScrollBlockage } from "./useScrollBlockage/index.mjs";
19
18
  import { useScrollDetection } from "./useScrollDetection.mjs";
20
- import { useUser } from "./useUser/index.mjs";
19
+ import { useScrollY } from "./useScrollY.mjs";
20
+ import { useSearch } from "./useSearch.mjs";
21
21
 
22
22
  export { calculateIsMobile, checkIsIOS, checkIsIphoneOrSafariDevice, checkIsMac, checkIsMobileScreen, checkIsMobileUserAgent, getBreakpointFromSize, useAddDictionary, useAddNewAccessKey, useAddOrganization, useAddOrganizationMember, useAddPasskey, useAddProject, useAddTag, useAppQuery, useAskDocQuestion, useAskResetPassword, useAuditContentDeclaration, useAuditContentDeclarationField, useAuditContentDeclarationMetadata, useAuditScan, useAuditTag, useAuth, useAutocomplete, useBitbucketAuth, useBitbucketCheckConfig, useBitbucketGetConfigFile, useBitbucketRepos, useCancelSubscription, useChangePassword, useCreateUser, useDeleteAccessKey, useDeleteDictionary, useDeleteOrganization, useDeletePasskey, useDeleteProject, useDeleteSSOProvider, useDeleteShowcaseProject, useDeleteTag, useDeleteUser, useDevice, useDisableTwoFactor, useEnableTwoFactor, useGetCIConfig, useGetDictionaries, useGetDictionariesKeys, useGetDictionary, useGetDiscussions, useGetDiscussionsData, useGetEditorDictionaries, useGetElementById, useGetElementOrWindow, useGetNewsletterStatus, useGetOrganizations, useGetOtherShowcaseProjects, useGetPricing, useGetProjects, useGetRecursiveAuditStatus, useGetShowcaseProjectById, useGetShowcaseProjects, useGetSubscription, useGetTags, useGetUserByAccount, useGetUserById, useGetUsers, useGetVerifyEmailStatus, useGithubAuth, useGithubCheckConfig, useGithubGetAuthUrl, useGithubGetConfigFile, useGithubRepos, useGitlabAuth, useGitlabCheckConfig, useGitlabGetConfigFile, useGitlabProjects, useHorizontalSwipe, useInfiniteGetDictionaries, useIntlayerAuth, useIntlayerOAuth, useIsDarkMode, useIsMounted, useItemSelector, useKeyboardDetector, useListPasskeys, useListSSOProviders, useLogin, useLogout, useOAuth2, usePersistedStore, usePushCIConfig, usePushDictionaries, useQueryClient, useRefreshAccessKey, useRegister, useRegisterSSO, useResetPassword, useScreenWidth, useScrollBlockage, useScrollDetection, useScrollY, useSearch, useSearchDoc, useSelectOrganization, useSelectProject, useSession, useSignInMagicLink, useSignInPasskey, useSignInSSO, useStartRecursiveAudit, useSubmitShowcaseProject, useSubscribeToNewsletter, useToggleShowcaseDownvote, useToggleShowcaseUpvote, useTranslateJSONDeclaration, useTriggerBuild, useTriggerWebhook, useUnselectOrganization, useUnselectProject, useUnsubscribeFromNewsletter, useUpdateDictionary, useUpdateOrganization, useUpdateOrganizationMembers, useUpdateOrganizationMembersById, useUpdateProject, useUpdateProjectMembers, useUpdateShowcaseProject, useUpdateTag, useUpdateUser, useUser, useVerifyBackupCode, useVerifyEmail, useVerifyTotp, useWriteDictionary };
@@ -57,8 +57,7 @@ const useRegister = () => {
57
57
  const intlayerAuth = useIntlayerAuth();
58
58
  return useMutation({
59
59
  mutationKey: ["register"],
60
- mutationFn: (args) => intlayerAuth.signUpEmail(args),
61
- meta: { resetQueries: [["session"]] }
60
+ mutationFn: (args) => intlayerAuth.signUpEmail(args)
62
61
  });
63
62
  };
64
63
  const useLogout = () => {
@@ -612,7 +611,6 @@ const useGetTags = (filters, options) => {
612
611
  queryFn: ({ signal }) => intlayerOAuth.tag.getTags(filters, { signal }),
613
612
  requireUser: true,
614
613
  requireOrganization: true,
615
- requireProject: true,
616
614
  ...options
617
615
  });
618
616
  };