{"version":3,"sources":["../src/index.ts","../src/indent.ts"],"sourcesContent":["export * from './indent'\n","import { Extension } from '@tiptap/core'\nimport { TextSelection } from '@tiptap/pm/state'\n\n/**\n * Configuration options for the Indent extension\n */\nexport interface IndentOptions {\n  /**\n   * Character(s) to insert for each indentation\n   * @default '  ' (2 spaces)\n   */\n  indentChars: string\n\n  /**\n   * Whether the extension is enabled\n   * @default true\n   */\n  enabled: boolean\n\n  /**\n   * List of node types that can accept indentation\n   * If not provided or empty, all nodes will be indented\n   * @default ['paragraph', 'listItem', 'orderedList']\n   */\n  allowedNodeTypes?: string[]\n}\n\ndeclare module '@tiptap/core' {\n  interface Commands<ReturnType> {\n    indent: {\n      /**\n       * Add indentation at cursor position or to selected content\n       */\n      indent: () => ReturnType\n      /**\n       * Remove indentation at cursor position or from selected content\n       */\n      outdent: () => ReturnType\n    }\n  }\n}\n\n/**\n * Indent Extension for Tiptap\n *\n * Provides functionality to indent and outdent text in the editor.\n */\nexport const Indent = Extension.create<IndentOptions>({\n  name: 'indent',\n\n  addOptions() {\n    return {\n      indentChars: '  ',\n      enabled: true,\n      allowedNodeTypes: ['paragraph', 'listItem', 'orderedList']\n    }\n  },\n\n  addCommands() {\n    /**\n     * Checks if the current node type is allowed for indentation\n     * @param state - Editor state\n     * @returns boolean indicating if indentation is allowed\n     */\n    const isNodeAllowed = (state: any) => {\n      const { allowedNodeTypes } = this.options\n\n      if (!allowedNodeTypes?.length) return true\n\n      const $pos = state.selection.$from\n      const node = $pos.node()\n\n      return allowedNodeTypes.includes(node.type.name)\n    }\n\n    return {\n      /**\n       * Adds indentation at cursor position or to selected content\n       */\n      indent:\n        () =>\n        ({ tr, state, dispatch }) => {\n          if (!this.options.enabled || !isNodeAllowed(state)) return false\n\n          const { selection } = state\n          const { indentChars } = this.options\n\n          // Handle empty selection (cursor position)\n          if (selection.empty) {\n            if (dispatch) {\n              tr.insertText(indentChars, selection.from, selection.to)\n              dispatch(tr)\n            }\n            return true\n          }\n\n          // Handle multiline selection\n          const lines = state.doc.textBetween(selection.from, selection.to).split('\\n')\n          let pos = selection.from\n\n          if (dispatch) {\n            for (const line of lines) {\n              const lineStart = pos\n              const lineEnd = lineStart + line.length\n\n              tr.insertText(indentChars, lineStart, lineStart)\n              pos = lineEnd + indentChars.length + 1 // +1 for newline\n            }\n\n            dispatch(tr)\n          }\n\n          return true\n        },\n\n      /**\n       * Removes indentation at cursor position or from selected content\n       */\n      outdent:\n        () =>\n        ({ tr, state, dispatch }) => {\n          if (!this.options.enabled || !isNodeAllowed(state)) return false\n\n          const { selection } = state\n          const { indentChars } = this.options\n          let madeChanges = false\n\n          // Handle empty selection (cursor position)\n          if (selection.empty) {\n            const $cursor = (selection as TextSelection).$cursor\n            if (!$cursor) return false\n\n            const cursorPos = $cursor.pos\n            const lineStart = state.doc.resolve(cursorPos).start()\n            const textBeforeCursor = state.doc.textBetween(lineStart, cursorPos)\n            const isAtLineStart = cursorPos === lineStart\n\n            // Check if there are indentation characters to remove\n            if (textBeforeCursor.endsWith(indentChars)) {\n              if (dispatch) {\n                tr.delete(cursorPos - indentChars.length, cursorPos)\n                madeChanges = true\n              }\n            } else if (isAtLineStart && textBeforeCursor.startsWith(indentChars)) {\n              if (dispatch) {\n                tr.delete(lineStart, lineStart + indentChars.length)\n                madeChanges = true\n              }\n            }\n\n            if (dispatch) {\n              if (!madeChanges) {\n                tr.setSelection(TextSelection.create(tr.doc, cursorPos))\n              }\n              dispatch(tr)\n            }\n\n            return true\n          }\n\n          // Handle multiline selection\n          const lines = state.doc.textBetween(selection.from, selection.to).split('\\n')\n          let pos = selection.from\n\n          if (dispatch) {\n            for (const line of lines) {\n              const lineStart = pos\n\n              if (line.startsWith(indentChars)) {\n                tr.delete(lineStart, lineStart + indentChars.length)\n                pos = lineStart + line.length - indentChars.length + 1\n              } else {\n                pos = lineStart + line.length + 1\n              }\n            }\n\n            dispatch(tr)\n          }\n\n          return true\n        }\n    }\n  },\n\n  /**\n   * Add keyboard shortcuts for indent/outdent functionality\n   */\n  addKeyboardShortcuts() {\n    return {\n      Tab: () => (this.options.enabled ? this.editor.commands.indent() : false),\n      'Shift-Tab': () => (this.options.enabled ? this.editor.commands.outdent() : false)\n    }\n  }\n})\n\nexport const indentCSS = null // No CSS needed for this approach\n"],"mappings":"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","names":["src_exports","__export","Indent","indentCSS","__toCommonJS","import_core","import_state","Indent","isNodeAllowed","state","allowedNodeTypes","node","tr","dispatch","selection","indentChars","lines","pos","line","lineStart","lineEnd","madeChanges","$cursor","cursorPos","textBeforeCursor","isAtLineStart","indentCSS"]}