{
  "version": 3,
  "sources": ["../../../../src/lib/ui/hooks/useActionState.ts"],
  "sourcesContent": ["import { Editor, useComputed, useMaybeEditor, useValue } from '@tldraw/editor'\nimport { TLUiActionItem, useActions } from '../context/actions'\n\n/** @internal */\nexport interface TLUiActionState {\n\t/** False hides the item in every menu except the keyboard shortcuts dialog. */\n\tavailable: boolean\n\tenabled: boolean\n\tchecked: boolean | undefined\n}\n\nconst MISSING: TLUiActionState = { available: false, enabled: false, checked: undefined }\nconst NO_EDITOR: TLUiActionState = { available: true, enabled: true, checked: undefined }\n\nfunction isActionAvailable(editor: Editor, action: TLUiActionItem) {\n\tif (editor.getIsReadonly() && !action.readonlyOk) return false\n\treturn !action.isAvailable || action.isAvailable(editor)\n}\n\nfunction isActionEnabled(editor: Editor, action: TLUiActionItem) {\n\treturn !action.isEnabled || action.isEnabled(editor)\n}\n\n/** @internal */\nexport function getActionState(\n\teditor: Editor | null,\n\taction: TLUiActionItem | undefined\n): TLUiActionState {\n\tif (!action) return MISSING\n\tif (!editor) return NO_EDITOR\n\treturn readActionState(editor, action)\n}\n\nfunction readActionState(editor: Editor, action: TLUiActionItem): TLUiActionState {\n\t// These run from always-mounted menus, so a throw would take down the whole editor rather than\n\t// one menu item. A throw disables the item instead; it stays visible unless readonly hides it.\n\tlet threw = false\n\tfunction tryPredicate<T>(name: string, run: () => T, fallback: T): T {\n\t\ttry {\n\t\t\treturn run()\n\t\t} catch (error) {\n\t\t\tthrew = true\n\t\t\treportThrowingPredicate(action, name, error)\n\t\t\treturn fallback\n\t\t}\n\t}\n\tconst available = tryPredicate(\n\t\t'isAvailable',\n\t\t() => isActionAvailable(editor, action),\n\t\t!editor.getIsReadonly() || !!action.readonlyOk\n\t)\n\tconst enabled =\n\t\tavailable && tryPredicate('isEnabled', () => isActionEnabled(editor, action), false)\n\tconst checked = tryPredicate('isChecked', () => action.isChecked?.(editor), undefined)\n\treturn { available, enabled: enabled && !threw, checked }\n}\n\nconst reportedPredicates = new Set<string>()\n\nfunction reportThrowingPredicate(action: TLUiActionItem, name: string, error: unknown) {\n\tconst key = `${action.id}:${name}`\n\tif (reportedPredicates.has(key)) return\n\treportedPredicates.add(key)\n\tconsole.error(`The \"${action.id}\" action's ${name} threw`, error)\n}\n\nfunction isSameState(a: TLUiActionState, b: TLUiActionState) {\n\treturn a.available === b.available && a.enabled === b.enabled && a.checked === b.checked\n}\n\n/**\n * The one place menus read an action's visibility, enablement and checked state from.\n *\n * @internal\n */\nexport function useActionState(action: TLUiActionItem | undefined): TLUiActionState {\n\tconst editor = useMaybeEditor()\n\tconst $state = useComputed(\n\t\t'action state',\n\t\t() => getActionState(editor, action),\n\t\t{ isEqual: isSameState },\n\t\t[editor, action]\n\t)\n\treturn useValue($state)\n}\n\nfunction useSomeActions(\n\tname: string,\n\tactionIds: readonly string[],\n\ttest: (state: TLUiActionState) => boolean\n) {\n\tconst editor = useMaybeEditor()\n\tconst actions = useActions()\n\tconst key = actionIds.join('\\n')\n\treturn useValue(\n\t\tname,\n\t\t() => actionIds.some((id) => test(getActionState(editor, actions[id]))),\n\t\t// eslint-disable-next-line react-hooks/exhaustive-deps\n\t\t[editor, actions, key]\n\t)\n}\n\n/**\n * Whether any of the given actions is available and enabled. Unknown ids, unavailable actions,\n * and actions that aren't `readonlyOk` while the editor is readonly count as not enabled. Use it to\n * hide a submenu when none of its items can run; a closed submenu doesn't mount its items, so it\n * can't ask them.\n *\n * @public\n */\nexport function useSomeActionsEnabled(actionIds: readonly string[]): boolean {\n\treturn useSomeActions('some actions enabled', actionIds, (state) => state.enabled)\n}\n\n/**\n * Like {@link useSomeActionsEnabled}, but for a submenu that shows disabled items: true when any\n * of the actions would show at all.\n *\n * @internal\n */\nexport function useSomeActionsAvailable(actionIds: readonly string[]): boolean {\n\treturn useSomeActions('some actions available', actionIds, (state) => state.available)\n}\n"],
  "mappings": "AAAA,SAAiB,aAAa,gBAAgB,gBAAgB;AAC9D,SAAyB,kBAAkB;AAU3C,MAAM,UAA2B,EAAE,WAAW,OAAO,SAAS,OAAO,SAAS,OAAU;AACxF,MAAM,YAA6B,EAAE,WAAW,MAAM,SAAS,MAAM,SAAS,OAAU;AAExF,SAAS,kBAAkB,QAAgB,QAAwB;AAClE,MAAI,OAAO,cAAc,KAAK,CAAC,OAAO,WAAY,QAAO;AACzD,SAAO,CAAC,OAAO,eAAe,OAAO,YAAY,MAAM;AACxD;AAEA,SAAS,gBAAgB,QAAgB,QAAwB;AAChE,SAAO,CAAC,OAAO,aAAa,OAAO,UAAU,MAAM;AACpD;AAGO,SAAS,eACf,QACA,QACkB;AAClB,MAAI,CAAC,OAAQ,QAAO;AACpB,MAAI,CAAC,OAAQ,QAAO;AACpB,SAAO,gBAAgB,QAAQ,MAAM;AACtC;AAEA,SAAS,gBAAgB,QAAgB,QAAyC;AAGjF,MAAI,QAAQ;AACZ,WAAS,aAAgB,MAAc,KAAc,UAAgB;AACpE,QAAI;AACH,aAAO,IAAI;AAAA,IACZ,SAAS,OAAO;AACf,cAAQ;AACR,8BAAwB,QAAQ,MAAM,KAAK;AAC3C,aAAO;AAAA,IACR;AAAA,EACD;AACA,QAAM,YAAY;AAAA,IACjB;AAAA,IACA,MAAM,kBAAkB,QAAQ,MAAM;AAAA,IACtC,CAAC,OAAO,cAAc,KAAK,CAAC,CAAC,OAAO;AAAA,EACrC;AACA,QAAM,UACL,aAAa,aAAa,aAAa,MAAM,gBAAgB,QAAQ,MAAM,GAAG,KAAK;AACpF,QAAM,UAAU,aAAa,aAAa,MAAM,OAAO,YAAY,MAAM,GAAG,MAAS;AACrF,SAAO,EAAE,WAAW,SAAS,WAAW,CAAC,OAAO,QAAQ;AACzD;AAEA,MAAM,qBAAqB,oBAAI,IAAY;AAE3C,SAAS,wBAAwB,QAAwB,MAAc,OAAgB;AACtF,QAAM,MAAM,GAAG,OAAO,EAAE,IAAI,IAAI;AAChC,MAAI,mBAAmB,IAAI,GAAG,EAAG;AACjC,qBAAmB,IAAI,GAAG;AAC1B,UAAQ,MAAM,QAAQ,OAAO,EAAE,cAAc,IAAI,UAAU,KAAK;AACjE;AAEA,SAAS,YAAY,GAAoB,GAAoB;AAC5D,SAAO,EAAE,cAAc,EAAE,aAAa,EAAE,YAAY,EAAE,WAAW,EAAE,YAAY,EAAE;AAClF;AAOO,SAAS,eAAe,QAAqD;AACnF,QAAM,SAAS,eAAe;AAC9B,QAAM,SAAS;AAAA,IACd;AAAA,IACA,MAAM,eAAe,QAAQ,MAAM;AAAA,IACnC,EAAE,SAAS,YAAY;AAAA,IACvB,CAAC,QAAQ,MAAM;AAAA,EAChB;AACA,SAAO,SAAS,MAAM;AACvB;AAEA,SAAS,eACR,MACA,WACA,MACC;AACD,QAAM,SAAS,eAAe;AAC9B,QAAM,UAAU,WAAW;AAC3B,QAAM,MAAM,UAAU,KAAK,IAAI;AAC/B,SAAO;AAAA,IACN;AAAA,IACA,MAAM,UAAU,KAAK,CAAC,OAAO,KAAK,eAAe,QAAQ,QAAQ,EAAE,CAAC,CAAC,CAAC;AAAA;AAAA,IAEtE,CAAC,QAAQ,SAAS,GAAG;AAAA,EACtB;AACD;AAUO,SAAS,sBAAsB,WAAuC;AAC5E,SAAO,eAAe,wBAAwB,WAAW,CAAC,UAAU,MAAM,OAAO;AAClF;AAQO,SAAS,wBAAwB,WAAuC;AAC9E,SAAO,eAAe,0BAA0B,WAAW,CAAC,UAAU,MAAM,SAAS;AACtF;",
  "names": []
}
