@jimka/typescript-ui 0.4.1 → 0.5.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 (194) hide show
  1. package/dist/lib/{AbstractBooleanInput-DE5NNJT0.js → AbstractBooleanInput-CbW7ZrDT.js} +2 -2
  2. package/dist/lib/{AbstractBooleanInput-DE5NNJT0.js.map → AbstractBooleanInput-CbW7ZrDT.js.map} +1 -1
  3. package/dist/lib/{AbstractInput-BxfrmD2W.js → AbstractInput-B10DfLOf.js} +2 -2
  4. package/dist/lib/{AbstractInput-BxfrmD2W.js.map → AbstractInput-B10DfLOf.js.map} +1 -1
  5. package/dist/lib/Anchor-BsblS5it.js +2 -0
  6. package/dist/lib/Anchor-BsblS5it.js.map +1 -0
  7. package/dist/lib/AnchorConstraints-Bfkt8019.js +2 -0
  8. package/dist/lib/AnchorConstraints-Bfkt8019.js.map +1 -0
  9. package/dist/lib/{AnimatedDropdown-QLNasu_Y.js → AnimatedDropdown-kL47HPGP.js} +2 -2
  10. package/dist/lib/{AnimatedDropdown-QLNasu_Y.js.map → AnimatedDropdown-kL47HPGP.js.map} +1 -1
  11. package/dist/lib/Border-CNS6aEXB.js +2 -0
  12. package/dist/lib/{Border-CKKUk5G9.js.map → Border-CNS6aEXB.js.map} +1 -1
  13. package/dist/lib/Button-T16zSZip.js +2 -0
  14. package/dist/lib/Button-T16zSZip.js.map +1 -0
  15. package/dist/lib/{Card-a4dzYrbX.js → Card-CD3jxshU.js} +2 -2
  16. package/dist/lib/{Card-a4dzYrbX.js.map → Card-CD3jxshU.js.map} +1 -1
  17. package/dist/lib/CodeEditor-BGlB232h.js +2 -0
  18. package/dist/lib/CodeEditor-BGlB232h.js.map +1 -0
  19. package/dist/lib/ComboBox-C9FYMuLv.js +2 -0
  20. package/dist/lib/ComboBox-C9FYMuLv.js.map +1 -0
  21. package/dist/lib/Component-w65rPK75.js +2 -0
  22. package/dist/lib/Component-w65rPK75.js.map +1 -0
  23. package/dist/lib/Container-C7RPLQEc.js +2 -0
  24. package/dist/lib/{Container-0bsG2Q8Z.js.map → Container-C7RPLQEc.js.map} +1 -1
  25. package/dist/lib/DOM-Ba8YRVel.js +2 -0
  26. package/dist/lib/{DOM-67StIm5G.js.map → DOM-Ba8YRVel.js.map} +1 -1
  27. package/dist/lib/DragManager-UvPHSoRm.js +2 -0
  28. package/dist/lib/{DragManager-DRor_-1x.js.map → DragManager-UvPHSoRm.js.map} +1 -1
  29. package/dist/lib/{FieldDecorator-Bpx8J8n9.js → FieldDecorator-HG65hEtk.js} +2 -2
  30. package/dist/lib/{FieldDecorator-Bpx8J8n9.js.map → FieldDecorator-HG65hEtk.js.map} +1 -1
  31. package/dist/lib/{Fit-CL1m1nIZ.js → Fit-Cg3dPyZg.js} +2 -2
  32. package/dist/lib/{Fit-CL1m1nIZ.js.map → Fit-Cg3dPyZg.js.map} +1 -1
  33. package/dist/lib/FloatingPanel-D5buuVrQ.js +2 -0
  34. package/dist/lib/FloatingPanel-D5buuVrQ.js.map +1 -0
  35. package/dist/lib/{Glyph-wN7bk7mg.js → Glyph-DeJF_zsR.js} +2 -2
  36. package/dist/lib/{Glyph-wN7bk7mg.js.map → Glyph-DeJF_zsR.js.map} +1 -1
  37. package/dist/lib/{Grid-DHHmaB-Y.js → Grid-BYBohJIA.js} +2 -2
  38. package/dist/lib/{Grid-DHHmaB-Y.js.map → Grid-BYBohJIA.js.map} +1 -1
  39. package/dist/lib/{GridConstraints-DVc1BmlP.js → GridConstraints-Bts284FI.js} +2 -2
  40. package/dist/lib/{GridConstraints-DVc1BmlP.js.map → GridConstraints-Bts284FI.js.map} +1 -1
  41. package/dist/lib/{Header-2hKwQo_u.js → Header-BIFJK9nR.js} +2 -2
  42. package/dist/lib/{Header-2hKwQo_u.js.map → Header-BIFJK9nR.js.map} +1 -1
  43. package/dist/lib/{IconText-DC7Xe34b.js → IconText-Dsb1xS-E.js} +2 -2
  44. package/dist/lib/{IconText-DC7Xe34b.js.map → IconText-Dsb1xS-E.js.map} +1 -1
  45. package/dist/lib/LanguageRegistry-CcVnbKuh.js +2 -0
  46. package/dist/lib/LanguageRegistry-CcVnbKuh.js.map +1 -0
  47. package/dist/lib/LayoutSerialization-ySzY1h2l.js +2 -0
  48. package/dist/lib/{LayoutSerialization-D5bBas4W.js.map → LayoutSerialization-ySzY1h2l.js.map} +1 -1
  49. package/dist/lib/LayoutSizes-DKDK1Cle.js +2 -0
  50. package/dist/lib/LayoutSizes-DKDK1Cle.js.map +1 -0
  51. package/dist/lib/List-BPd-IXZR.js +2 -0
  52. package/dist/lib/{List-CG4NvwuV.js.map → List-BPd-IXZR.js.map} +1 -1
  53. package/dist/lib/MemoryStore-BgP7-Uzn.js +2 -0
  54. package/dist/lib/{MemoryStore-DT6iWWco.js.map → MemoryStore-BgP7-Uzn.js.map} +1 -1
  55. package/dist/lib/Menu-C0roOCY7.js +2 -0
  56. package/dist/lib/Menu-C0roOCY7.js.map +1 -0
  57. package/dist/lib/{MenuButton-wy_0RskC.js → MenuButton-BR4KOFld.js} +2 -2
  58. package/dist/lib/{MenuButton-wy_0RskC.js.map → MenuButton-BR4KOFld.js.map} +1 -1
  59. package/dist/lib/Panel-CpNQTLNF.js +2 -0
  60. package/dist/lib/{Panel-Rd9zkNXx.js.map → Panel-CpNQTLNF.js.map} +1 -1
  61. package/dist/lib/{Position-Ck_KD4cR.js → Position-PBVBW1JS.js} +2 -2
  62. package/dist/lib/{Position-Ck_KD4cR.js.map → Position-PBVBW1JS.js.map} +1 -1
  63. package/dist/lib/{ProgressSpinner-yt-VXyCb.js → ProgressSpinner-lAsK26C-.js} +2 -2
  64. package/dist/lib/{ProgressSpinner-yt-VXyCb.js.map → ProgressSpinner-lAsK26C-.js.map} +1 -1
  65. package/dist/lib/RadioButton-CCcIaL54.js +2 -0
  66. package/dist/lib/RadioButton-CCcIaL54.js.map +1 -0
  67. package/dist/lib/{RovingTabIndex-DFJyoveq.js → RovingTabIndex-C2Vzq0IX.js} +2 -2
  68. package/dist/lib/{RovingTabIndex-DFJyoveq.js.map → RovingTabIndex-C2Vzq0IX.js.map} +1 -1
  69. package/dist/lib/Scrollbar-C3ZZyZ1e.js +2 -0
  70. package/dist/lib/Scrollbar-C3ZZyZ1e.js.map +1 -0
  71. package/dist/lib/Slider-DZ9drUxn.js +2 -0
  72. package/dist/lib/Slider-DZ9drUxn.js.map +1 -0
  73. package/dist/lib/{Spacer-qalSEJ5i.js → Spacer-SDhOMp2g.js} +2 -2
  74. package/dist/lib/{Spacer-qalSEJ5i.js.map → Spacer-SDhOMp2g.js.map} +1 -1
  75. package/dist/lib/TabButton-DNo4ZgV8.js +2 -0
  76. package/dist/lib/TabButton-DNo4ZgV8.js.map +1 -0
  77. package/dist/lib/Text-CdHf3B-1.js +2 -0
  78. package/dist/lib/Text-CdHf3B-1.js.map +1 -0
  79. package/dist/lib/{Tooltip-Dro4DOZs.js → Tooltip-B_UF5bXD.js} +2 -2
  80. package/dist/lib/{Tooltip-Dro4DOZs.js.map → Tooltip-B_UF5bXD.js.map} +1 -1
  81. package/dist/lib/Tree-C7qLbIYH.js +2 -0
  82. package/dist/lib/Tree-C7qLbIYH.js.map +1 -0
  83. package/dist/lib/VBox-32fxpkDl.js +2 -0
  84. package/dist/lib/VBox-32fxpkDl.js.map +1 -0
  85. package/dist/lib/{Validator-Du8PqS5i.js → Validator-Cjs1EU5Q.js} +2 -2
  86. package/dist/lib/{Validator-Du8PqS5i.js.map → Validator-Cjs1EU5Q.js.map} +1 -1
  87. package/dist/lib/{VirtualScroller-Bv4KXGKW.js → VirtualScroller-cvFNMS7U.js} +2 -2
  88. package/dist/lib/{VirtualScroller-Bv4KXGKW.js.map → VirtualScroller-cvFNMS7U.js.map} +1 -1
  89. package/dist/lib/component/button.es.js +1 -1
  90. package/dist/lib/component/chart.es.js +1 -1
  91. package/dist/lib/component/chart.es.js.map +1 -1
  92. package/dist/lib/component/container.es.js +1 -1
  93. package/dist/lib/component/container.es.js.map +1 -1
  94. package/dist/lib/component/diagram.es.js +1 -1
  95. package/dist/lib/component/diagram.es.js.map +1 -1
  96. package/dist/lib/component/display.es.js +1 -1
  97. package/dist/lib/component/display.es.js.map +1 -1
  98. package/dist/lib/component/editor.es.js +3 -3
  99. package/dist/lib/component/editor.es.js.map +1 -1
  100. package/dist/lib/component/input.es.js +1 -1
  101. package/dist/lib/component/input.es.js.map +1 -1
  102. package/dist/lib/component/list.es.js +1 -1
  103. package/dist/lib/component/list.es.js.map +1 -1
  104. package/dist/lib/component/menubar.es.js +1 -1
  105. package/dist/lib/component/menubar.es.js.map +1 -1
  106. package/dist/lib/component/table.es.js +2 -2
  107. package/dist/lib/component/table.es.js.map +1 -1
  108. package/dist/lib/component/tree.es.js +1 -1
  109. package/dist/lib/component/tree.es.js.map +1 -1
  110. package/dist/lib/core.es.js +1 -1
  111. package/dist/lib/core.es.js.map +1 -1
  112. package/dist/lib/data.es.js +1 -1
  113. package/dist/lib/glyphs/solid/index.es.js +1 -1
  114. package/dist/lib/languages-Dl8qdL8a.js +2 -0
  115. package/dist/lib/languages-Dl8qdL8a.js.map +1 -0
  116. package/dist/lib/layout.es.js +1 -1
  117. package/dist/lib/layout.es.js.map +1 -1
  118. package/dist/lib/overlay.es.js +1 -1
  119. package/dist/lib/overlay.es.js.map +1 -1
  120. package/dist/lib/primitive.es.js +1 -1
  121. package/dist/lib/router.es.js +1 -1
  122. package/dist/lib/router.es.js.map +1 -1
  123. package/dist/lib/selectionsEqual-BrTxPMmK.js +2 -0
  124. package/dist/lib/{selectionsEqual-Ci3_uflt.js.map → selectionsEqual-BrTxPMmK.js.map} +1 -1
  125. package/dist/lib/types/component/button/TabButton.d.ts +1 -1
  126. package/dist/lib/types/component/button/ToggleButton.d.ts +1 -1
  127. package/dist/lib/types/component/chart/ChartLegend.d.ts +1 -1
  128. package/dist/lib/types/component/container/FloatingPanel.d.ts +23 -0
  129. package/dist/lib/types/component/container/ScrollStrip.d.ts +1 -1
  130. package/dist/lib/types/component/container/Scrollbar.d.ts +1 -3
  131. package/dist/lib/types/component/container/TabBar.d.ts +1 -1
  132. package/dist/lib/types/component/container/index.d.ts +2 -0
  133. package/dist/lib/types/component/diagram/DiagramGroupNode.d.ts +1 -1
  134. package/dist/lib/types/component/display/Markdown.d.ts +42 -1
  135. package/dist/lib/types/component/display/MarkdownMinimap.d.ts +38 -0
  136. package/dist/lib/types/component/display/MarkdownViewer.d.ts +60 -0
  137. package/dist/lib/types/component/display/index.d.ts +6 -0
  138. package/dist/lib/types/component/editor/CodeEditor.d.ts +13 -0
  139. package/dist/lib/types/component/editor/index.d.ts +1 -1
  140. package/dist/lib/types/component/input/Checkbox.d.ts +1 -1
  141. package/dist/lib/types/component/input/RadioButton.d.ts +1 -1
  142. package/dist/lib/types/component/input/Slider.d.ts +1 -1
  143. package/dist/lib/types/component/input/Text.d.ts +0 -2
  144. package/dist/lib/types/component/input/Toggle.d.ts +1 -1
  145. package/dist/lib/types/component/menubar/MenuBar.d.ts +1 -1
  146. package/dist/lib/types/component/menubar/ToolBar.d.ts +1 -0
  147. package/dist/lib/types/component/table/Body.d.ts +1 -0
  148. package/dist/lib/types/component/table/cell/SortPriorityBadge.d.ts +1 -1
  149. package/dist/lib/types/component/table/cell/editor/CellEditorPool.d.ts +1 -0
  150. package/dist/lib/types/component/table/cell/editor/Date.d.ts +1 -0
  151. package/dist/lib/types/component/table/cell/editor/DateTime.d.ts +1 -0
  152. package/dist/lib/types/component/table/cell/editor/Time.d.ts +1 -0
  153. package/dist/lib/types/component/tree/Tree.d.ts +9 -1
  154. package/dist/lib/types/component/tree/index.d.ts +1 -1
  155. package/dist/lib/types/component/tree/renderer/Label.d.ts +1 -1
  156. package/dist/lib/types/core/Component.d.ts +5 -0
  157. package/dist/lib/types/core/Theme.d.ts +4 -2
  158. package/dist/lib/types/layout/LayoutManager.d.ts +8 -0
  159. package/dist/lib/validation.es.js +1 -1
  160. package/llms.txt +3 -0
  161. package/package.json +15 -15
  162. package/dist/lib/AnchorConstraints-DdDYSDkf.js +0 -2
  163. package/dist/lib/AnchorConstraints-DdDYSDkf.js.map +0 -1
  164. package/dist/lib/Border-CKKUk5G9.js +0 -2
  165. package/dist/lib/Button-MZDYJOMC.js +0 -2
  166. package/dist/lib/Button-MZDYJOMC.js.map +0 -1
  167. package/dist/lib/ComboBox-C04SfXAR.js +0 -2
  168. package/dist/lib/ComboBox-C04SfXAR.js.map +0 -1
  169. package/dist/lib/Component-fRQvgaEY.js +0 -2
  170. package/dist/lib/Component-fRQvgaEY.js.map +0 -1
  171. package/dist/lib/Container-0bsG2Q8Z.js +0 -2
  172. package/dist/lib/DOM-67StIm5G.js +0 -2
  173. package/dist/lib/DragManager-DRor_-1x.js +0 -2
  174. package/dist/lib/LayoutSerialization-D5bBas4W.js +0 -2
  175. package/dist/lib/LayoutSizes-qNaURyiw.js +0 -2
  176. package/dist/lib/LayoutSizes-qNaURyiw.js.map +0 -1
  177. package/dist/lib/List-CG4NvwuV.js +0 -2
  178. package/dist/lib/MemoryStore-DT6iWWco.js +0 -2
  179. package/dist/lib/Menu-CrZy2u0g.js +0 -2
  180. package/dist/lib/Menu-CrZy2u0g.js.map +0 -1
  181. package/dist/lib/Panel-Rd9zkNXx.js +0 -2
  182. package/dist/lib/RadioButton-D23rId-V.js +0 -2
  183. package/dist/lib/RadioButton-D23rId-V.js.map +0 -1
  184. package/dist/lib/Scrollbar-SOj9psiP.js +0 -2
  185. package/dist/lib/Scrollbar-SOj9psiP.js.map +0 -1
  186. package/dist/lib/Slider-DBnAZ-F7.js +0 -2
  187. package/dist/lib/Slider-DBnAZ-F7.js.map +0 -1
  188. package/dist/lib/TabButton-DKECTTk1.js +0 -2
  189. package/dist/lib/TabButton-DKECTTk1.js.map +0 -1
  190. package/dist/lib/Text-KB5LksJl.js +0 -2
  191. package/dist/lib/Text-KB5LksJl.js.map +0 -1
  192. package/dist/lib/VBox-P3WFGkPc.js +0 -2
  193. package/dist/lib/VBox-P3WFGkPc.js.map +0 -1
  194. package/dist/lib/selectionsEqual-Ci3_uflt.js +0 -2
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CodeEditor-BGlB232h.js","names":[],"sources":["../../src/typescript/lib/component/editor/theme.ts","../../src/typescript/lib/component/editor/CodeEditor.ts"],"sourcesContent":["// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0\n\nimport { EditorView } from \"@codemirror/view\";\nimport { HighlightStyle, syntaxHighlighting } from \"@codemirror/language\";\nimport { tags } from \"@lezer/highlight\";\nimport type { Extension } from \"@codemirror/state\";\n\n// The syntax palette has no dedicated project theme tokens (the framework\n// defines chrome/surface/accent tokens, not a per-token-kind syntax scheme),\n// so it is a fixed, IDE-conventional colour set chosen for light/dark\n// legibility rather than derived from CSS variables — mirroring how\n// `Markdown`'s code-block wash is a neutral constant rather than a token.\nconst SYNTAX_KEYWORD = \"#2563eb\"; // matches the framework's single accent hue\nconst SYNTAX_STRING = \"#16a34a\"; // green — conventional \"string\" colour\nconst SYNTAX_COMMENT = \"#6b7280\"; // muted grey — de-emphasises comments\nconst SYNTAX_LITERAL = \"#d97706\"; // amber — numbers/booleans/null\nconst SYNTAX_FUNCTION = \"#7c3aed\"; // violet — function/variable definitions\nconst SYNTAX_TYPE = \"#0891b2\"; // teal — type names\nconst SYNTAX_PROPERTY = \"#be185d\"; // pink — object/attribute property names\n\n/**\n * Builds the editor's theme extension: the chrome (background, gutters,\n * cursor, selection) via `EditorView.theme`, plus syntax-highlighting colours\n * via a `HighlightStyle`.\n *\n * The chrome reads the project's CSS custom-property tokens directly\n * (`--ts-ui-input-bg`, `--ts-ui-text-color`, `--ts-ui-font-mono`,\n * `--ts-ui-border-color`, `--ts-ui-indicator-focus`,\n * `--ts-ui-indicator-selection`), each with a light/dark-safe fallback, so a\n * `ThemeManager.setTheme` toggle recolours the editor with no rebuild — only\n * the underlying CSS variables change.\n *\n * @param dark - Whether the dark theme flag (`--ts-ui-color-scheme: dark`) is\n * currently active, forwarded to `EditorView.theme`'s `dark` option so\n * CodeMirror's own dark-mode heuristics (default scrollbar styling, base\n * theme selection) agree with the project's active theme.\n * @returns The combined chrome + syntax-highlighting extension.\n */\nexport function codeEditorTheme(dark: boolean): Extension {\n const chrome = EditorView.theme({\n \"&\": {\n height: \"100%\",\n color: \"var(--ts-ui-text-color, #1a1a1a)\",\n backgroundColor: \"var(--ts-ui-input-bg, #ffffff)\",\n },\n \".cm-content\": {\n fontFamily: \"var(--ts-ui-font-mono, ui-monospace, SFMono-Regular, Menlo, Consolas, monospace)\",\n caretColor: \"var(--ts-ui-indicator-focus, #2563eb)\",\n cursor: \"text\",\n },\n \".cm-gutters\": {\n color: \"var(--ts-ui-text-color, #1a1a1a)\",\n backgroundColor: \"var(--ts-ui-input-bg, #ffffff)\",\n borderRight: \"1px solid var(--ts-ui-border-color, rgba(127, 127, 127, 0.4))\",\n },\n \"&.cm-focused .cm-cursor\": {\n borderLeftColor: \"var(--ts-ui-indicator-focus, #2563eb)\",\n },\n \"&.cm-focused .cm-selectionBackground, .cm-selectionBackground\": {\n backgroundColor: \"var(--ts-ui-indicator-selection, rgba(37, 99, 235, 0.25))\",\n },\n \".cm-activeLine, .cm-activeLineGutter\": {\n backgroundColor: \"rgba(127, 127, 127, 0.08)\",\n },\n }, { dark });\n\n const highlight = syntaxHighlighting(HighlightStyle.define([\n { tag: tags.keyword, color: SYNTAX_KEYWORD },\n { tag: [tags.string, tags.special(tags.string)], color: SYNTAX_STRING },\n { tag: tags.comment, color: SYNTAX_COMMENT, fontStyle: \"italic\" },\n { tag: [tags.number, tags.bool, tags.null], color: SYNTAX_LITERAL },\n { tag: [tags.definition(tags.variableName), tags.function(tags.variableName)], color: SYNTAX_FUNCTION },\n { tag: tags.typeName, color: SYNTAX_TYPE },\n { tag: [tags.propertyName, tags.attributeName], color: SYNTAX_PROPERTY },\n { tag: tags.tagName, color: SYNTAX_KEYWORD },\n // Markdown constructs (the `markdown` language, e.g. the MarkdownEditor\n // source surface). The parser tags these; without a style here they\n // would render as plain text. Headings/links reuse the accent hue; bold\n // and italic carry weight/slant rather than colour so prose stays\n // readable; the markup marks (`#`, `**`, `` ` ``, `>`, `-`) and quotes\n // are muted so the content reads over the syntax.\n { tag: [tags.heading, tags.heading1, tags.heading2, tags.heading3,\n tags.heading4, tags.heading5, tags.heading6], color: SYNTAX_KEYWORD, fontWeight: \"bold\" },\n { tag: tags.strong, fontWeight: \"bold\" },\n { tag: tags.emphasis, fontStyle: \"italic\" },\n { tag: tags.monospace, color: SYNTAX_STRING },\n { tag: [tags.link, tags.url], color: SYNTAX_KEYWORD, textDecoration: \"underline\" },\n { tag: [tags.quote, tags.contentSeparator], color: SYNTAX_COMMENT },\n { tag: tags.processingInstruction, color: SYNTAX_COMMENT },\n ]));\n\n return [chrome, highlight];\n}\n","// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0\n\nimport { Animation } from \"~/core/Animation.js\";\nimport { Component, ComponentOptions } from \"~/core/Component.js\";\nimport { DOM } from \"~/core/DOM.js\";\nimport type { Handle } from \"~/core/DOM.js\";\nimport { ListenerBag } from \"~/core/ListenerBag.js\";\nimport { ThemeManager } from \"~/core/Theme.js\";\nimport { callable } from \"~/core/Callable.js\";\nimport { EditorView, keymap, drawSelection, lineNumbers, highlightActiveLine, highlightActiveLineGutter } from \"@codemirror/view\";\nimport { EditorState, Compartment } from \"@codemirror/state\";\nimport type { Extension } from \"@codemirror/state\";\nimport { history, defaultKeymap, historyKeymap, indentWithTab } from \"@codemirror/commands\";\nimport { indentOnInput, bracketMatching, indentRange } from \"@codemirror/language\";\nimport { getLanguage } from \"~/component/editor/LanguageRegistry.js\";\nimport { codeEditorTheme } from \"~/component/editor/theme.js\";\n\n/**\n * Payload of {@link CodeEditor}'s `\"change\"` event: the document text after\n * the edit that triggered it.\n *\n * @category Components\n */\nexport interface CodeEditorChange {\n value: string;\n}\n\n/**\n * Payload of {@link CodeEditor}'s `\"heightchange\"` event: the editor's new\n * height in pixels.\n *\n * @category Components\n */\nexport interface CodeEditorHeightChange {\n height: number;\n}\n\n/**\n * The events {@link CodeEditor} exposes through its custom `on` / `off` surface:\n *\n * - `\"change\"` — the document text changed (payload {@link CodeEditorChange}).\n * - `\"readonlyedit\"` — a user edit was rejected because the editor is read-only\n * (no payload); see {@link CodeEditor.on}.\n * - `\"heightchange\"` — {@link CodeEditorOptions.autoHeightMaxRows} is set and the\n * editor's own computed height changed (payload {@link CodeEditorHeightChange}).\n */\ntype CodeEditorEvent = \"change\" | \"readonlyedit\" | \"heightchange\";\n\n/**\n * Construction-time options for {@link CodeEditor}.\n *\n * @category Components\n */\nexport interface CodeEditorOptions extends ComponentOptions {\n /** Initial document text (also accepted as the positional first argument). */\n value?: string;\n /** Registered language id (e.g. `\"javascript\"`, `\"json\"`, `\"sql\"`). Unset renders plain text. */\n language?: string;\n /** Whether the editor rejects edits. Default `false`. */\n readOnly?: boolean;\n /**\n * Row count the editor grows to fit before its own vertical scrollbar\n * takes over. Unset (the default): today's behaviour — a fixed height\n * the caller controls via `setHeight`/`preferredSize`, filling its host.\n */\n autoHeightMaxRows?: number;\n /** Construction-time listener bag; the events are `\"change\"`, `\"readonlyedit\"`, and `\"heightchange\"`. */\n listeners?: { change?: (payload: CodeEditorChange) => void; readonlyedit?: () => void; heightchange?: (payload: CodeEditorHeightChange) => void };\n}\n\n/**\n * User-overridable defaults forwarded to `super` via the options bag. The\n * cascade in `Component`'s constructor dispatches each setter once with the\n * final value, so any field the caller supplied wins.\n */\nconst _defaultCodeEditorOptions: Partial<CodeEditorOptions> = {\n // Override Component's `overflow: \"hidden\"` default so the framework's\n // eased wheel scroller attaches: `applyStyle` reads the effective overflow\n // and installs the controller from it (see `Component.applyOverflowStyles`\n // -> `refreshWheelScrolling`), which then drives whatever\n // `getScrollElement` resolves to — CodeMirror's `.cm-scroller` once the\n // view is mounted. Inert as a style: `.cm-editor` is `height: 100%` and the\n // flash overlay is `inset: 0`, so the editor's own box has no overflow to\n // scroll and never paints a native bar of its own. This mirrors how an\n // overlay-mode `Panel` keeps `overflow: auto` on a panel element that can\n // likewise never scroll.\n overflow: \"auto\",\n};\n\n/** CodeMirror's scrolling viewport element, inside the mounted view. */\nconst CM_SCROLLER_SELECTOR = \".cm-scroller\";\n\n/** CodeMirror's content element, inside `.cm-scroller`. */\nconst CM_CONTENT_SELECTOR = \".cm-content\";\n\n// Padding-bottom applied once to an auto-height editor's `.cm-scroller`\n// (see the `_scrollElement` resolution in `mount`) so a sub-pixel content\n// overhang can never leave the scroller a fraction of a pixel short and\n// paint a permanent, non-functional vertical scrollbar. `.cm-scroller`'s\n// `scrollHeight` is a whole number but the content it measures is not, so\n// committing the reported extent verbatim discards up to a pixel of real\n// content. This must be a fixed, one-time style, not part of the height\n// `syncAutoHeight` (re)computes on every call: `.cm-content`'s own\n// `min-height: 100%` means its rendered height — and so `.cm-scroller`'s\n// `scrollHeight`, which can never report less than the scroller's own\n// `clientHeight` — floors at whatever height was last committed, so adding\n// this slop to the committed height itself fed straight back into the next\n// measurement and ratcheted the editor's height upward forever. Mirrors\n// ScrollStrip.arrowReserve's `+1` slop against the same rounding noise.\nconst SUBPIXEL_HEIGHT_SLOP_PX = 1;\n\n// `syncAutoHeight` trusts a height GROWTH only on the call where the\n// document/width shape genuinely changed (a real edit or resize) — never\n// again against the same shape, no matter how plausible the reading looks.\n// Committing a height changes `.cm-scroller`'s real `clientHeight`;\n// CodeMirror's own `ViewState.measure()` (@codemirror/view) runs on its own\n// schedule and compares that live value against its cached copy on every\n// pass, reporting a fresh `geometryChanged` update whenever they differ —\n// which they always do, immediately after any commit. That re-invokes\n// `syncAutoHeight` with no genuine content or width change. On a real\n// (non-integer) device-pixel ratio the re-measurement does not reliably read\n// back the exact value just committed (unlike the mount-time case\n// `SUBPIXEL_HEIGHT_SLOP_PX` handles, which converges): it can read\n// fractionally MORE, live-observed climbing by tens of pixels roughly every\n// 100ms, forever, with the editor merely visible and no further interaction.\n// A one-growth-of-slack budget was tried first, on the theory that an\n// initial pre-layout guess might need exactly one accurate follow-up once\n// CodeMirror's real layout became available. Live testing across several\n// unrelated blocks (Dialog, Drawer, LineChart, Button) refuted that: the\n// \"follow-up\" fired on essentially every multi-line editor regardless of\n// whether real settling was needed, each time adding a line or two of dead\n// space with nothing behind it — the same self-referential echo the\n// unbounded case shows, just bounded to a single step instead of climbing\n// forever. There is no reliable signal that distinguishes a genuine\n// follow-up correction from this echo, so none is trusted; a block whose\n// first, always-free commit undershoots true content is a distinct bug (the\n// initial measurement itself, not this guard) to fix at the source.\n\n/** Duration of the read-only rejection flash, in milliseconds. */\nconst READONLY_FLASH_MS = 300;\n\n/** Peak opacity of the read-only rejection wash — a subtle tint that keeps the text readable. */\nconst READONLY_FLASH_PEAK_OPACITY = 0.16;\n\n/**\n * Fill of the read-only rejection wash: the project's validation-error token,\n * with a light/dark-safe fallback, so the tint follows a `ThemeManager.setTheme`\n * toggle with no rebuild (the CSS variable resolves live).\n */\nconst READONLY_FLASH_COLOR = \"var(--ts-ui-validation-error-border, #dc2626)\";\n\n/**\n * Builds the readOnly-state extension: `EditorState.readOnly` blocks every\n * edit (including programmatic ones) while leaving the content DOM editable, so\n * the caret, cursor navigation, and text selection / copy all keep working —\n * the standard read-only experience. (`EditorView.editable.of(false)` would\n * additionally strip selection by making CodeMirror stop managing a caret in\n * the content, so it is deliberately *not* used here.)\n *\n * @param readOnly - Whether the editor should reject edits.\n * @returns The extension for the readOnly compartment.\n */\nfunction buildReadOnlyExtension(readOnly: boolean): Extension {\n return EditorState.readOnly.of(readOnly);\n}\n\n/**\n * A syntax-highlighting, formatting code editor wrapping CodeMirror 6.\n *\n * @remarks\n * `CodeEditor` deliberately omits IntelliSense (no autocomplete, no lint, no\n * language service) — its scope is highlighting plus one-command formatting.\n * CodeMirror's `EditorView` is a *foreign live widget*: it takes a real parent\n * element and mutates a whole DOM region it owns directly, exactly like the\n * `CanvasRenderingContext2D` a [`Canvas`](/api/component/display/classes/Canvas)\n * obtains from the seam. So `CodeEditor` is **live-only** — under the modelled\n * test sink it mounts nothing, and every editor operation guards on a `null`\n * view, matching `Canvas` / `WebGLCanvas`.\n *\n * The editor mounts once, in the component's first connected + sized layout\n * (`onFirstLayout`) — CodeMirror needs a real, sized parent to measure its\n * internal scroller correctly. It fills the assigned box and scrolls\n * internally; give it a sized host (a `Fit` panel or an explicit\n * `preferredSize`), the same as `Canvas`.\n *\n * Highlighting grammars and formatters load lazily, per language, through the\n * registry in `LanguageRegistry.ts` (`registerLanguage` / `getLanguage` /\n * `listLanguages`) — see that module and `languages.ts` for the five built-in\n * languages (JavaScript/TypeScript, JSON, HTML, SQL, Markdown).\n *\n * @example\n * ```typescript\n * import { CodeEditor } from '@jimka/typescript-ui/component/editor';\n *\n * const editor = new CodeEditor('const x = 1;', { language: 'javascript' });\n * panel.addComponent(editor);\n * await editor.format();\n * ```\n *\n * @category Components\n */\nclass CodeEditor extends Component<CodeEditorOptions> {\n\n /** The live CodeMirror view; `null` until mounted (or forever, offline). */\n private _view: EditorView | null = null;\n\n /** Overlay flashed on a rejected read-only edit; `null` until mounted (or forever, offline). */\n private _flashOverlay: Handle | null = null;\n\n // In-flight read-only flash, cancelled on teardown so its fallback timer\n // cannot fire against the overlay's released element handle.\n private _flashAnimation: Animation.CancelHandle | null = null;\n\n /** Reconfigured by {@link CodeEditor.setLanguage} to swap the active grammar. */\n private readonly _langCompartment: Compartment = new Compartment();\n\n /** Reconfigured by {@link CodeEditor.setReadOnly}. */\n private readonly _readOnlyCompartment: Compartment = new Compartment();\n\n /** Reconfigured on a theme change to recolour the editor. */\n private readonly _themeCompartment: Compartment = new Compartment();\n\n /** Custom-event fan-out for `\"change\"`. */\n private readonly _listeners: ListenerBag<CodeEditorEvent> = new ListenerBag<CodeEditorEvent>();\n\n /** Handle to detach the {@link ThemeManager.onThemeChange} listener on {@link CodeEditor.dispose}. */\n private readonly _unsubscribeTheme: () => void;\n\n /**\n * Handle for CodeMirror's own scrolling viewport, resolved once the view\n * mounts; `null` until then (or forever, offline). Backs\n * {@link CodeEditor.getScrollElement}.\n */\n private _scrollElement: Handle | null = null;\n\n /**\n * Handle for CodeMirror's own content element (`.cm-content`, inside\n * `.cm-scroller`), resolved once the view mounts; `null` until then (or\n * forever, offline). Used by {@link CodeEditor.syncAutoHeight} to read\n * its true, fractional rendered content height — `scrollHeight` /\n * `clientHeight` are integer DOM properties that can round away a\n * sub-pixel shortfall this element's own `getBoundingClientRect` still\n * shows.\n */\n private _contentElement: Handle | null = null;\n\n /**\n * `[lines, docLength, clientWidth]` as of the last call to\n * `syncAutoHeight`, or `null` before the first call. Used to tell a\n * genuine content/width change from a self-triggered geometry echo — a\n * growth is trusted only when this differs from the previous call.\n */\n private _lastSyncedShape: readonly [number, number, number] | null = null;\n\n /**\n * Horizontal-scrollbar height reserve, re-measured on every call to\n * `syncAutoHeight` (rendered content width — and so a real scrollbar's\n * presence — can change without the document/width shape itself\n * changing, e.g. once an async language grammar finishes loading and\n * re-flows the text). Cached here only so a later call can fold it into\n * `desired` without re-deriving it. See\n * {@link CodeEditor.syncAutoHeight}'s `@remarks` for why it's measured\n * this way at all.\n */\n private _lastHbarReserve = 0;\n\n /**\n * Constructs a code editor.\n *\n * @param value - Initial document text (optional; defaults to \"\").\n * @param options - Optional construction options.\n * @param subclassDefaults - Per-subclass default bag layered over this\n * class's defaults; subclasses forward their `_defaultXxxOptions`\n * constant here.\n */\n constructor(value?: string, options?: CodeEditorOptions, subclassDefaults?: Partial<CodeEditorOptions>) {\n super(options, { ..._defaultCodeEditorOptions, ...(subclassDefaults ?? {}) });\n\n // Positional argument: cache it only when the caller didn't also pass\n // `options.value` (which the super-time cascade already stored).\n if (value !== undefined && this._options.value === undefined) {\n this._options.value = value;\n }\n\n this._unsubscribeTheme = ThemeManager.onThemeChange(() => this.onThemeChange());\n\n this.applyListeners(options?.listeners);\n\n this.onFirstLayout(() => this.mount());\n }\n\n /**\n * Caches the `value` / `language` / `readOnly` fields onto `_options` after\n * inherited Component fields cascade through `super.applyOptions`. No view\n * exists yet at this point (the editor mounts later, in `onFirstLayout`), so\n * these are pure caches, applied to the freshly-created `EditorState` and\n * compartments in `mount()`.\n *\n * @param options - The options bag carrying the values to apply.\n * @returns This component, for method chaining.\n */\n protected applyOptions(options: CodeEditorOptions): this {\n super.applyOptions(options);\n\n if (options.value !== undefined) this._options.value = options.value;\n if (options.language !== undefined) this._options.language = options.language;\n if (options.readOnly !== undefined) this._options.readOnly = options.readOnly;\n if (options.autoHeightMaxRows !== undefined) this._options.autoHeightMaxRows = options.autoHeightMaxRows;\n\n return this;\n }\n\n /**\n * Returns the current document text: read live from the view when mounted,\n * else the cached pre-mount / offline value.\n *\n * @returns The document text, or `\"\"` when unset.\n */\n getValue(): string {\n if (this._view) {\n return this._view.state.doc.toString();\n }\n\n return this._options.value ?? \"\";\n }\n\n /**\n * Replaces the whole document. Caches the value; when a view is mounted,\n * also dispatches a full-document replace transaction.\n *\n * @param value - The new document text.\n * @returns This component, for method chaining.\n */\n setValue(value: string): this {\n this._options.value = value;\n\n if (this._view) {\n this._view.dispatch({\n changes: { from: 0, to: this._view.state.doc.length, insert: value },\n });\n }\n\n return this;\n }\n\n /**\n * Returns the active language id.\n *\n * @returns The registered language id, or `null` when unset.\n */\n getLanguage(): string | null {\n return this._options.language ?? null;\n }\n\n /**\n * Sets (or clears) the active language. Caches the id; when a view is\n * mounted and the id names a registered language, kicks off the grammar's\n * lazy `loadExtension()` and reconfigures the grammar compartment once it\n * resolves — guarded against a stale resolution by re-checking the active\n * language id, so a rapid double-swap applies only the latest.\n *\n * @param id - A registered language id, or `null` to clear highlighting.\n * @returns This component, for method chaining.\n */\n setLanguage(id: string | null): this {\n this._options.language = id ?? undefined;\n\n if (!this._view) {\n return this;\n }\n\n if (!id) {\n this._view.dispatch({ effects: this._langCompartment.reconfigure([]) });\n\n return this;\n }\n\n const def = getLanguage(id);\n\n if (!def) {\n return this;\n }\n\n void def.loadExtension().then((extension) => {\n if (this._view && this.getLanguage() === id) {\n this._view.dispatch({ effects: this._langCompartment.reconfigure(extension) });\n }\n });\n\n return this;\n }\n\n /**\n * Returns whether the editor currently rejects edits.\n *\n * @returns The readOnly state.\n */\n getReadOnly(): boolean {\n return this._options.readOnly ?? false;\n }\n\n /**\n * Sets whether the editor rejects edits. Caches the state; when a view is\n * mounted, also reconfigures the readOnly compartment.\n *\n * @param readOnly - Whether the editor should reject edits.\n * @returns This component, for method chaining.\n */\n setReadOnly(readOnly: boolean): this {\n this._options.readOnly = readOnly;\n\n if (this._view) {\n this._view.dispatch({ effects: this._readOnlyCompartment.reconfigure(buildReadOnlyExtension(readOnly)) });\n }\n\n return this;\n }\n\n /**\n * Returns the row-count cap this editor grows to before its own vertical\n * scrollbar takes over.\n *\n * @returns The configured {@link CodeEditorOptions.autoHeightMaxRows}, or\n * `null` when unset (today's fixed-height, fill-parent contract).\n */\n getAutoHeightMaxRows(): number | null {\n return this._options.autoHeightMaxRows ?? null;\n }\n\n /**\n * Moves keyboard focus into the editor.\n *\n * @remarks Overrides {@link core!Component.focus} because a `CodeEditor`'s own\n * element is a plain, non-focusable host `<div>` — CodeMirror owns the real\n * focusable target (its `contentDOM`), so the base `element.focus()` would be\n * a no-op. When mounted this hands focus to the live view; offline / before\n * mount it falls back to the base behaviour (also a no-op, matching every\n * other editor operation's null-view guard). The current selection / caret is\n * left untouched — pair with {@link CodeEditor.moveCursorToEnd} to also move it.\n *\n * @param preventScroll - Forwarded to the base fallback; CodeMirror's own\n * `focus()` takes no scroll option, so it is honoured only offline.\n * @returns This component, for method chaining.\n */\n focus(preventScroll: boolean = false): this {\n if (this._view) {\n this._view.focus();\n\n return this;\n }\n\n return super.focus(preventScroll);\n }\n\n /**\n * Places the caret at the end of the document (after the last character),\n * collapsing any selection, and scrolls it into view.\n *\n * @remarks A selection-only transaction — it changes no text, so it emits no\n * `\"change\"`. No-op before the view is mounted (offline / pre-mount), like\n * every other view operation. Pair with {@link CodeEditor.focus} to land the\n * caret ready for typing (e.g. on a freshly opened, pre-seeded editor).\n *\n * @returns This component, for method chaining.\n */\n moveCursorToEnd(): this {\n if (this._view) {\n const end = this._view.state.doc.length;\n\n this._view.dispatch({ selection: { anchor: end }, scrollIntoView: true });\n }\n\n return this;\n }\n\n /**\n * Formats the document via the active language's formatter, or re-indents\n * it (CodeMirror's own indentation service) when the language has none.\n *\n * @remarks If the formatter throws (invalid syntax), the rejection\n * propagates and the document is left **untouched** — the full-document\n * replace only runs after the formatter resolves successfully, so a\n * throwing formatter never reaches it. The cursor is preserved through\n * Prettier's `formatWithCursor` mapping, or clamped to the new document\n * length for a formatter with no cursor map (sql-formatter).\n *\n * @returns A promise that resolves once formatting completes, or rejects\n * with the formatter's error.\n */\n async format(): Promise<void> {\n const id = this.getLanguage();\n const def = id ? getLanguage(id) : undefined;\n\n if (!def?.loadFormatter) {\n this.reindentFallback();\n\n return;\n }\n\n const formatter = await def.loadFormatter();\n const source = this.getValue();\n const cursorOffset = this._view ? this._view.state.selection.main.head : 0;\n\n const result = await formatter(source, cursorOffset);\n\n this._options.value = result.formatted;\n\n if (this._view) {\n this._view.dispatch({\n changes: { from: 0, to: this._view.state.doc.length, insert: result.formatted },\n selection: { anchor: Math.min(result.cursorOffset, result.formatted.length) },\n });\n }\n }\n\n /**\n * The `format()` fallback for a language with no formatter: re-indents the\n * whole document via CodeMirror's own indentation service. Factored out\n * from `format()` so the dispatch decision (formatter vs. this fallback) is\n * unit-testable by spying on this method — the actual re-indent needs a\n * live view (guarded below) and is otherwise manual-verify only.\n */\n private reindentFallback(): void {\n if (this._view) {\n this._view.dispatch({ changes: indentRange(this._view.state, 0, this._view.state.doc.length) });\n }\n }\n\n /**\n * Registers a listener for the `\"change\"` event, fired whenever the\n * document changes (including via {@link CodeEditor.format} / {@link CodeEditor.setValue}).\n *\n * @param event - Must be `\"change\"`.\n * @param listener - Invoked with the new document text.\n * @returns This component, for method chaining.\n */\n on(event: \"change\", listener: (payload: CodeEditorChange) => void): this;\n /**\n * Registers a listener for the `\"readonlyedit\"` event, fired when a user\n * edit (typing, paste, drop) is rejected because the editor is read-only.\n *\n * @param event - Must be `\"readonlyedit\"`.\n * @param listener - Invoked with no arguments on each rejected edit.\n * @returns This component, for method chaining.\n */\n on(event: \"readonlyedit\", listener: () => void): this;\n /**\n * Registers a listener for the `\"heightchange\"` event, fired when\n * {@link CodeEditorOptions.autoHeightMaxRows} is set and the editor's own\n * computed height changes.\n *\n * @param event - Must be `\"heightchange\"`.\n * @param listener - Invoked with the editor's new height.\n * @returns This component, for method chaining.\n */\n on(event: \"heightchange\", listener: (payload: CodeEditorHeightChange) => void): this;\n on(event: CodeEditorEvent, listener: Function): this {\n this._listeners.add(event, listener);\n\n return this;\n }\n\n /**\n * Removes a previously registered `\"change\"` listener.\n *\n * @param event - Must be `\"change\"`.\n * @param listener - The exact callback reference to remove.\n * @returns This component, for method chaining.\n */\n off(event: \"change\", listener: (payload: CodeEditorChange) => void): this;\n /**\n * Removes a previously registered `\"readonlyedit\"` listener.\n *\n * @param event - Must be `\"readonlyedit\"`.\n * @param listener - The exact callback reference to remove.\n * @returns This component, for method chaining.\n */\n off(event: \"readonlyedit\", listener: () => void): this;\n /**\n * Removes a previously registered `\"heightchange\"` listener.\n *\n * @param event - Must be `\"heightchange\"`.\n * @param listener - The exact callback reference to remove.\n * @returns This component, for method chaining.\n */\n off(event: \"heightchange\", listener: (payload: CodeEditorHeightChange) => void): this;\n off(event: CodeEditorEvent, listener: Function): this {\n this._listeners.remove(event, listener);\n\n return this;\n }\n\n /**\n * Fans an event out to its registered listeners.\n *\n * @param event - The event name.\n * @param payload - The event payload (`\"change\"`/`\"heightchange\"`; `\"readonlyedit\"` has none).\n */\n protected emit(event: \"change\", payload: CodeEditorChange): void;\n protected emit(event: \"readonlyedit\"): void;\n protected emit(event: \"heightchange\", payload: CodeEditorHeightChange): void;\n protected emit(event: CodeEditorEvent, payload?: CodeEditorChange | CodeEditorHeightChange): void {\n this._listeners.fire(event, ...(payload ? [payload] : []));\n }\n\n /**\n * Detaches the theme-change listener and destroys the live CodeMirror\n * view, then defers to the base class for the rest of teardown. Call\n * before discarding a dynamically-built `CodeEditor`, mirroring\n * `Markdown.destructor`.\n */\n protected destructor(): void {\n // Before `super.destructor()` releases the overlay's element handle,\n // which the flash's fallback timer would otherwise write to.\n this._flashAnimation?.cancel();\n this._flashAnimation = null;\n\n this._unsubscribeTheme();\n\n // Before the view is destroyed below, so any later scroll read (the\n // base destructor's own teardown, a queued layout) resolves through the\n // base element rather than a handle whose node CodeMirror has removed.\n this._scrollElement = null;\n this._contentElement = null;\n\n // Nulled after destroy so a second destructor() pass on this same\n // instance (dispose() is documented idempotent — a harmless no-op —\n // but CodeMirror's own EditorView.destroy() is not guarded against a\n // repeat call) finds `_view` already null and no-ops via the `?.`\n // above. Cheap insurance on a path the offline test harness cannot\n // reach: it never constructs a live `EditorView`.\n this._view?.destroy();\n this._view = null;\n\n super.destructor();\n }\n\n /**\n * Routes every framework scroll read/write onto CodeMirror's own scrolling\n * viewport (`.cm-scroller`) rather than the editor's outer box, so the\n * eased wheel scroller, the scroll-offset cache, and\n * {@link CodeEditor.getMaxScrollTop} all act on the element that actually\n * moves.\n *\n * @returns CodeMirror's scroller handle once mounted, else the editor's own\n * element.\n *\n * @remarks Falls back to the base element before the view mounts (and\n * forever offline, where the view never mounts): the outer box has no\n * overflow, so every scroll read reports zero extent and the wheel handler\n * leaves the gesture unclaimed — the correct answer while there is nothing\n * to scroll.\n */\n protected getScrollElement(): Handle | undefined {\n return this._scrollElement ?? super.getScrollElement();\n }\n\n /**\n * Builds the `EditorState` and mounts the CodeMirror view through the DOM\n * seam's `mountView` escape. Idempotent (guards on an existing view).\n * Offline / before the element exists, `DOM.sink.mountView` returns `null`,\n * so `_view` stays `null` and every editor operation continues to no-op.\n */\n private mount(): void {\n if (this._view) {\n return;\n }\n\n const element = this.getElement();\n\n if (!element) {\n return;\n }\n\n const dark = ThemeManager.getTheme().colorScheme === \"dark\";\n\n const extensions: Extension[] = [\n history(),\n // `indentWithTab` is deliberately absent from `defaultKeymap`,\n // because binding Tab traps it inside the editor and a keyboard\n // user can no longer Tab out. A code editor that does not indent\n // on Tab is the worse trade, and `defaultKeymap` already carries\n // the escape hatch: Ctrl-m (Alt-Shift-m on macOS) toggles\n // CodeMirror's tab-focus mode, after which Tab moves focus again.\n // Listed last so its Tab / Shift-Tab bindings take precedence.\n keymap.of([...defaultKeymap, ...historyKeymap, indentWithTab]),\n drawSelection(),\n lineNumbers(),\n highlightActiveLine(),\n highlightActiveLineGutter(),\n indentOnInput(),\n bracketMatching(),\n this._readOnlyCompartment.of(buildReadOnlyExtension(this.getReadOnly())),\n this._themeCompartment.of(codeEditorTheme(dark)),\n this._langCompartment.of([]),\n EditorView.updateListener.of((update) => {\n if (update.docChanged) {\n this._options.value = update.state.doc.toString();\n this.emit(\"change\", { value: this._options.value });\n }\n\n if (update.heightChanged || update.geometryChanged) {\n this.syncAutoHeight(update.selectionSet && !update.docChanged);\n }\n }),\n EditorView.domEventHandlers({\n // A user edit while read-only is blocked by `EditorState.readOnly`\n // at the input layer — it never becomes a transaction, so it emits\n // no \"change\". These hooks surface the rejection as feedback:\n // typing / IME / delete fire `beforeinput`, while paste and drop are\n // prevented before `beforeinput` runs, so each needs its own hook.\n beforeinput: () => this.onEditIntent(),\n paste: () => this.onEditIntent(),\n drop: () => this.onEditIntent(),\n }),\n ];\n\n const state = EditorState.create({ doc: this._options.value ?? \"\", extensions });\n\n this._view = DOM.sink.mountView(element, (parent) => new EditorView({ parent, state }));\n\n if (this._view) {\n this.mountFlashOverlay(element);\n\n // Hand the framework's scroll plumbing CodeMirror's own viewport\n // (see getScrollElement). Resolved through the seam rather than\n // from `_view.scrollDOM`, so no raw element crosses the boundary;\n // the handle is interned weakly, so the live DOM keeps owning it\n // and it must not be tracked as one of this component's own.\n this._scrollElement = DOM.source.querySelector(element, CM_SCROLLER_SELECTOR);\n\n // Resolved from `_scrollElement` (not `element`) so the query is\n // scoped to this editor's own scroller, matching how `_scrollElement`\n // itself is resolved.\n if (this._scrollElement) {\n this._contentElement = DOM.source.querySelector(this._scrollElement, CM_CONTENT_SELECTOR);\n }\n\n // Auto-height mode only: two fixed, one-time styles, never\n // recomputed, so neither can feed back into a later measurement.\n if (this._scrollElement && this.getAutoHeightMaxRows() !== null) {\n DOM.sink.apply(this._scrollElement, {\n style: {\n // A one-time padding-bottom absorbs the sub-pixel\n // content overhang `syncAutoHeight` cannot safely\n // absorb itself — see SUBPIXEL_HEIGHT_SLOP_PX.\n // Recomputing it every call fed back into the next\n // `scrollHeight` read instead (`.cm-content`'s\n // `min-height: 100%` floors its own rendered height\n // at whatever `.cm-scroller`'s clientHeight last was),\n // ratcheting the height upward forever.\n paddingBottom: SUBPIXEL_HEIGHT_SLOP_PX + \"px\",\n // `syncAutoHeight` reserves room for a horizontal\n // scrollbar by comparing `scrollWidth` against\n // `.cm-scroller`'s own `clientWidth` — but that\n // `clientWidth` shrinks whenever `.cm-scroller` is\n // itself showing a *vertical* scrollbar (the native\n // scrollbar eats horizontal space). For a document\n // whose longest line sits within one scrollbar-width\n // of that boundary, this is circular: committing the\n // taller (reserved) height removes the vertical\n // scrollbar, which widens `clientWidth`, which drops\n // the horizontal reserve, which commits the shorter\n // height, which brings the vertical scrollbar back —\n // forever. `scrollbar-gutter: stable` reserves the\n // vertical scrollbar's track unconditionally, so\n // `clientWidth` no longer depends on whether a\n // vertical scrollbar is currently showing, breaking\n // the cycle at its source.\n scrollbarGutter: \"stable\",\n },\n });\n }\n }\n\n const language = this.getLanguage();\n\n if (language) {\n this.setLanguage(language);\n }\n\n // CM6's constructor-time initial update is not documented to\n // reliably invoke `updateListener`, so this call seeds the first\n // measurement explicitly rather than assuming it does.\n this.syncAutoHeight();\n }\n\n /**\n * Computes this editor's desired height when {@link CodeEditorOptions.autoHeightMaxRows}\n * is set — the real rendered content height, plus the horizontal scrollbar's\n * measured thickness when `.cm-scroller` is showing one, capped at the row\n * limit — and applies it via `setHeight()`, emitting `\"heightchange\"` when\n * the value actually moves. No-op offline (no `_view`, or `_scrollElement`\n * hasn't resolved) and when `autoHeightMaxRows` is unset (today's\n * fixed-height contract).\n *\n * @remarks Reads `.cm-scroller`'s live `scrollHeight`/`scrollWidth`/\n * `clientWidth` via `DOM.source.getScrollMetrics` rather than CodeMirror's\n * own `contentHeight`/`defaultLineHeight` getters. CodeMirror defers its own\n * internal line-height refresh while its view is scrolled outside the\n * browser's visible viewport (`ViewState.measure`'s `inView` gate, a\n * performance optimisation for large documents), so those getters can keep\n * reporting CodeMirror's pre-measurement default indefinitely for a fenced\n * block that upgrades below the page fold. `.cm-scroller`'s native scroll\n * metrics force a real reflow on every read and are accurate regardless of\n * that gate, since CodeMirror always renders a short document's line DOM\n * eagerly at construction. The row cap's per-row pixel height is derived\n * the same way — from the live line count, not `defaultLineHeight`.\n *\n * `.cm-scroller` carries a one-time `SUBPIXEL_HEIGHT_SLOP_PX` padding-\n * bottom (applied once, in `mount`) rather than this method adding it to\n * the height it computes — see that constant's comment for why the slop\n * cannot live here without ratcheting the editor's height upward on every\n * call.\n *\n * A growth this method applies is itself a geometry change CodeMirror's\n * own internal measurement reacts to independently of this component, so\n * a growth is trusted only on the call where the document/width shape\n * genuinely changed — see the comment above `_lastSyncedShape`'s\n * declaration for why no growth against an unchanged shape is trusted,\n * however plausible it looks.\n *\n * @param pureSelectionChange - True when the caller's `updateListener`\n * update carries a selection change but no document change. A cursor\n * move alone can never legitimately need more vertical space (a\n * monospace grid layout has no reflow to trigger), so a growth request\n * arriving this way is rejected outright, even on a call that would\n * otherwise read as a shape change — live-confirmed via a direct\n * mutation-log comparison: a click moving the cursor to a *different*\n * line reassigns `cm-activeLine` / `cm-activeLineGutter` and rewrites\n * `.cm-content`'s own style, CodeMirror's heavier internal refresh,\n * while a same-line reposition (or a single-line document, structurally\n * incapable of having a different line to click) never does.\n */\n private syncAutoHeight(pureSelectionChange = false): void {\n const maxRows = this.getAutoHeightMaxRows();\n\n if (!this._view || maxRows === null || !this._scrollElement) {\n return;\n }\n\n const metrics = DOM.source.getScrollMetrics(this._scrollElement);\n\n const padding = this._view.documentPadding.top + this._view.documentPadding.bottom;\n const perLineHeight = (metrics.scrollHeight - padding) / this._view.state.doc.lines;\n const capPx = perLineHeight * maxRows + padding;\n\n let contentDesired = Math.min(metrics.scrollHeight, capPx);\n\n if (pureSelectionChange && contentDesired > this.getHeight()) {\n return;\n }\n\n const shape = [this._view.state.doc.lines, this._view.state.doc.length, metrics.clientWidth] as const;\n const shapeChanged = this._lastSyncedShape === null || shape.some((v, i) => v !== this._lastSyncedShape![i]);\n\n this._lastSyncedShape = shape;\n\n // Captured before this call's own commits (the intermediate one\n // below, when shapeChanged), so the convergence/growth checks after\n // it compare against the height this call STARTED with rather than\n // one it already changed mid-call.\n const previousHeight = this.getHeight();\n\n // `.cm-scroller`'s one-time `scrollbar-gutter: stable` (see `mount`)\n // reserves a vertical scrollbar's worth of width unconditionally,\n // narrowing `clientWidth` regardless of whether a vertical scrollbar\n // ever actually renders — so whether a REAL horizontal scrollbar\n // renders cannot be predicted from `scrollWidth` vs. `clientWidth`\n // (with or without a scrollbar-width fudge factor): live measurement\n // found two blocks both with `scrollWidth > clientWidth` (7px and\n // 15px over) where only the second actually rendered one. The fix is\n // to measure the box's own rendered state directly instead of\n // predicting it — `offsetHeight` includes a real horizontal\n // scrollbar's thickness, `clientHeight` excludes it, so their\n // difference (floored at zero) is exactly the space it's costing.\n //\n // Measured on EVERY call, not just a shape change: a real\n // scrollbar's presence depends on rendered content width, which can\n // change WITHOUT the shape tuple above changing — live-confirmed via\n // a block whose language grammar loads asynchronously\n // (`setLanguage`'s `loadExtension().then(...)`, well after `mount`'s\n // synchronous initial measurement): a real, visible horizontal\n // scrollbar present at that initial measurement resolved on its own\n // once highlighting settled and re-flowed the text, but the shape\n // tuple (line count, doc length, container width) never changed, so\n // a reserve cached only on shape changes never got revisited and the\n // dead space it added stayed forever. Re-measuring costs one more\n // forced-layout read per call, same class as the several already\n // happening here, and is safe to trust unconditionally in a way a\n // content-height GROWTH is not: the box's own height is fed back\n // into `.cm-content`'s `min-height: 100%`, which is what makes a\n // height growth self-reinforcing, but a scrollbar's thickness is\n // independent of this element's height, so re-reading it here can't\n // manufacture its own feedback loop. Any resulting increase in the\n // committed height still passes through the same shape-gated growth\n // check below as always; a decrease passes through the same\n // sub-pixel-noise-guarded shrink check.\n //\n // On the call that first establishes a new shape, `.cm-scroller` is\n // still whatever height it had BEFORE (this component's own pre-sync\n // default on the very first call ever, or the previous shape's\n // height on a later one) — live-confirmed wrong: a block correctly\n // showing no scrollbar once content-sized measured a false 15px\n // reserve read against that stale height, and since no growth\n // against an unchanged shape is ever trusted (see above), the wrong\n // reading then locked in permanently. So on a shape change the\n // content-only height is committed FIRST, forcing a real layout pass\n // (a plain synchronous property read already forces one; the box\n // itself needs an actual write, not just a read, since the\n // scrollbar's presence is being measured against ITS height), and\n // the reserve is measured against that — all still within this one\n // call, so nothing paints in between. On a later call against an\n // unchanged shape the box is already content-sized from that\n // earlier commit, so `metrics.clientHeight` (read once, at the top\n // of this method, before any commit this call might make) is\n // already an accurate reference — no second commit needed.\n let settledClientHeight = metrics.clientHeight;\n\n if (shapeChanged) {\n this.setHeight(contentDesired);\n\n const settled = DOM.source.getScrollMetrics(this._scrollElement);\n\n settledClientHeight = settled.clientHeight;\n\n // The pre-commit `metrics.scrollHeight` above, and `settled`\n // here, are both integer DOM properties — browsers round or\n // floor them, which can hide a genuine sub-pixel shortfall\n // entirely: live-confirmed via a raw DOM snapshot where\n // CodeMirror's own gutter carried an inline `min-height:\n // 223.504px` (its internal, full-precision content measurement)\n // against a rounded 224px commit that STILL left a hair of real,\n // non-zero scroll range — yet `scrollHeight`/`clientHeight` both\n // read back as the same rounded 224, showing no gap at all. The\n // fractional `getBoundingClientRect`-based rect on `.cm-content`\n // itself doesn't round this away, so it's compared directly\n // against `.cm-scroller`'s own fractional content-box height\n // (its rect height minus the fixed padding-bottom applied in\n // `mount` — `.cm-content`'s `min-height: 100%` resolves against\n // that content box, not the padding-inclusive border box).\n // Skipped when this call's height came from the row cap, not\n // real content: a capped block is EXPECTED to keep overflowing\n // past its committed height — that's what drives its own\n // intentional internal scroll — so \"correcting\" it here would\n // defeat the cap.\n if (metrics.scrollHeight <= capPx && this._contentElement) {\n const contentRectHeight = DOM.source.getElementRect(this._contentElement).height;\n const scrollerContentBoxHeight = DOM.source.getElementRect(this._scrollElement).height - SUBPIXEL_HEIGHT_SLOP_PX;\n\n contentDesired += Math.max(0, contentRectHeight - scrollerContentBoxHeight);\n }\n }\n\n const offsetSize = DOM.source.getOffsetSize(this._scrollElement);\n\n this._lastHbarReserve = Math.max(0, offsetSize.offsetHeight - settledClientHeight);\n\n const desired = contentDesired + this._lastHbarReserve;\n\n if (desired === previousHeight) {\n return;\n }\n\n if (desired > previousHeight && !shapeChanged) {\n return;\n }\n\n // A shrink against an UNCHANGED shape, smaller than one pixel, can\n // only be integer-rounding noise, never genuine content: the\n // document/width haven't changed, so real content can't have gotten\n // shorter without an edit (which would itself be a shape change).\n // `metrics.scrollHeight` above is an integer DOM property — on a\n // later call against a shape whose height this method already\n // corrected upward by a fraction of a pixel (see the fractional\n // undershoot correction above), it reads back that already-correct\n // height rounded DOWN, which is strictly LESS than what this method\n // itself committed. Live-confirmed: that read straight back\n // through as a \"genuine\" shrink every time (shrinks are otherwise\n // always trusted, unlike growths), silently reverting the\n // correction on the very next geometryChanged event — CodeMirror's\n // own settling fires one almost immediately — so the fix never held\n // past its own first call.\n if (desired < previousHeight && !shapeChanged && previousHeight - desired < 1) {\n return;\n }\n\n this.setHeight(desired);\n this.emit(\"heightchange\", { height: desired });\n }\n\n /**\n * Creates the read-only rejection wash: a pointer-transparent overlay that\n * fills the editor box and sits above CodeMirror's content, appended after\n * the view so it paints on top. It rests at `opacity: 0`; {@link CodeEditor.flashReadOnly}\n * pulses it. Tracked as an owned handle, so the component's teardown releases it.\n *\n * @param host - The mounted editor element the overlay fills.\n */\n private mountFlashOverlay(host: Handle): void {\n const overlay = this.trackHandle(DOM.sink.createElement(\"div\"));\n\n DOM.sink.apply(overlay, {\n style: {\n position: \"absolute\",\n inset: \"0\",\n pointerEvents: \"none\",\n // Above CodeMirror's sticky line-number gutter (z-index 200) so the\n // wash covers the gutter too; `.cm-editor` forms no stacking context,\n // so the gutter would otherwise paint over a lower overlay.\n zIndex: \"300\",\n backgroundColor: READONLY_FLASH_COLOR,\n opacity: \"0\",\n },\n });\n DOM.sink.appendChild(host, overlay);\n\n this._flashOverlay = overlay;\n }\n\n /**\n * Reconfigures the theme compartment when the project theme changes, so\n * the editor's chrome + syntax colours follow a `ThemeManager.setTheme`\n * toggle with no rebuild. No-ops before the view exists.\n */\n private onThemeChange(): void {\n if (!this._view) {\n return;\n }\n\n const dark = ThemeManager.getTheme().colorScheme === \"dark\";\n\n this._view.dispatch({ effects: this._themeCompartment.reconfigure(codeEditorTheme(dark)) });\n }\n\n /**\n * DOM-event hook for the read-only rejection feedback, wired to\n * `beforeinput` / `paste` / `drop` in {@link CodeEditor.mount}. When the\n * editor is read-only it surfaces the attempt via\n * {@link CodeEditor.signalReadOnlyEdit}; it never consumes the event, so\n * CodeMirror's own `EditorState.readOnly` handling still blocks the edit.\n *\n * @returns Always `false` (event left unhandled).\n */\n private onEditIntent(): boolean {\n if (this.getReadOnly()) {\n this.signalReadOnlyEdit();\n }\n\n return false;\n }\n\n /**\n * Emits the `\"readonlyedit\"` event and plays the rejection flash — a\n * programmatic hook plus a built-in visual cue that an edit was refused\n * because the editor is read-only.\n */\n private signalReadOnlyEdit(): void {\n this.emit(\"readonlyedit\");\n this.flashReadOnly();\n }\n\n /**\n * Flashes a brief error-coloured wash over the editor as feedback for a\n * rejected edit: fades the overlay from a subtle tint back to transparent.\n * No-op before the overlay is mounted (offline / pre-mount), and — via\n * {@link Animation.play} — honours `prefers-reduced-motion`: under reduced\n * motion the `\"readonlyedit\"` event still fires but nothing animates.\n *\n * A full-box wash is used rather than a border/ring cue because the editor\n * is often large and mostly empty, so an edge flash sits far from where the\n * eye is (the caret) and reads as nothing; the wash covers the content the\n * user is looking at while staying faint enough to keep the text legible.\n */\n private flashReadOnly(): void {\n if (!this._flashOverlay) {\n return;\n }\n\n this._flashAnimation?.cancel();\n this._flashAnimation = Animation.play(this._flashOverlay, {\n from: { opacity: String(READONLY_FLASH_PEAK_OPACITY) },\n to: { opacity: \"0\" },\n durationMs: READONLY_FLASH_MS,\n properties: [\"opacity\"],\n });\n }\n}\n\nconst CodeEditorCallable = callable(CodeEditor);\ntype CodeEditorCallable = CodeEditor;\nexport {\n CodeEditor as _CodeEditor,\n CodeEditorCallable as CodeEditor,\n};\n"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import{t as e}from"./DOM-Ba8YRVel.js";import{l as t,n,o as r}from"./Position-PBVBW1JS.js";import{S as i,b as a,h as o,t as s,v as c}from"./Component-w65rPK75.js";import{t as l}from"./Glyph-DeJF_zsR.js";import{t as u}from"./Panel-CpNQTLNF.js";import{t as d}from"./AnimatedDropdown-kL47HPGP.js";import{t as f}from"./Fit-Cg3dPyZg.js";import{t as p}from"./Text-CdHf3B-1.js";import{t as m}from"./AbstractInput-B10DfLOf.js";import{t as h}from"./AbstractBooleanInput-CbW7ZrDT.js";import{n as g,r as _}from"./VBox-32fxpkDl.js";import{t as v}from"./LayoutConstraints-LIHYYd2F.js";import{t as y}from"./Button-T16zSZip.js";import{t as b}from"./Grid-BYBohJIA.js";import{chevron_left as x}from"./glyphs/solid/chevron_left.es.js";import{chevron_right as S}from"./glyphs/solid/chevron_right.es.js";import{clock as C}from"./glyphs/solid/clock.es.js";import{check as w}from"./glyphs/solid/check.es.js";import{r as T,t as E}from"./List-BPd-IXZR.js";import{chevron_down as ee}from"./glyphs/solid/chevron_down.es.js";var D=`var(--ts-ui-link-color, rgb(21, 101, 192))`;new a({scope:`selector`,name:`.Link`,styles:{textDecoration:`underline`}}),new a({scope:`selector`,name:`.Link:focus-visible`,styles:{outline:`2px solid var(--ts-ui-indicator-focus, rgb(30, 100, 200))`,outlineOffset:`1px`}});var O={tag:`a`,foregroundColor:D,cursor:`pointer`,interactive:!0},Link=class extends p{constructor(e,t,n){super(e,t,{...O,...n??{}}),i.addListener(this,`keydown`,this.handleKeyDown),this.applyListeners(t?.listeners)}applyOptions(e){return super.applyOptions(e),this.setInteractive(e.interactive??this.isInteractive()),this}isInteractive(){return this._options.interactive??this._defaultOptions.interactive??!0}setInteractive(e){return this._options.interactive=e,e?this.getAria().setRole(`link`).setTabIndex(0):this.getAria().clearRole().setTabIndex(null),this}on(e,t){return i.addListener(this,`click`,t),this}off(e,t){return i.removeListener(this,`click`,t),this}click(){return i.fireEvent(this,`click`),this}handleKeyDown(e){this.isInteractive()&&e.key===`Enter`&&(e.preventDefault(),this.click())}},k=o(Link);new a({scope:`selector`,name:`.TextField:focus, .TextArea:focus, .PasswordField:focus`,styles:{outline:`none`,boxShadow:`inset 0 0 0 2px var(--ts-ui-indicator-focus, rgb(30, 100, 200))`}});var A={tag:`input`,backgroundColor:`var(--ts-ui-input-bg, rgb(255, 255, 255))`,border:`var(--ts-ui-input-border)`,borderRadius:`var(--ts-ui-border-radius, 4px)`},TextInput=class extends m{constructor(e,t){super(e,{...A,...t??{}}),this.setElementCSSRules({fontFamily:`var(--ts-ui-font-family, sans-serif)`,fontSize:`var(--ts-ui-font-size, 14px)`,lineHeight:`calc(1em + var(--ts-ui-line-padding, 2px))`}),i.addListener(this,`input`,this.onInput)}onInput(){let t=this.getElement();this.setText(t?e.source.getValue(t):``),this.notifyChange(this.getValue())}applyOptions(e){return super.applyOptions(e),e.text!==void 0&&this.setText(e.text),e.textAlign!==void 0&&this.setTextAlign(e.textAlign),e.placeholder!==void 0&&this.setPlaceholder(e.placeholder),e.readOnly!==void 0&&this.setReadOnly(e.readOnly),e.enabled!==void 0&&this.setEnabled(e.enabled),e.maxLength!==void 0&&this.setMaxLength(e.maxLength),e.inputMode!==void 0&&this.setInputMode(e.inputMode),e.autoComplete!==void 0&&this.setAutoComplete(e.autoComplete),this}on(e,t){return e===`action`?(i.addListener(this,`input`,t),this):e===`keydown`?(i.addListener(this,`keydown`,t),this):super.on(e,t)}off(e,t){return e===`action`?(i.removeListener(this,`input`,t),this):e===`keydown`?(i.removeListener(this,`keydown`,t),this):super.off(e,t)}setType(e){return this._options.type=e,this.setElementAttribute(`type`,e),this}setName(e){return super.setName(e),e==null?this.removeElementAttribute(`name`):this.setElementAttribute(`name`,e),this}clearName(){return this._options.name===void 0?this:(this._options.name=void 0,this.removeElementAttribute(`name`),this)}getInputMode(){return this._options.inputMode??null}setInputMode(e){return this._options.inputMode===e?this:(this._options.inputMode=e,this.setElementAttribute(`inputmode`,e),this)}clearInputMode(){return this._options.inputMode===void 0?this:(this._options.inputMode=void 0,this.removeElementAttribute(`inputmode`),this)}getAutoComplete(){return this._options.autoComplete??null}setAutoComplete(e){return this._options.autoComplete===e?this:(this._options.autoComplete=e,this.setElementAttribute(`autocomplete`,e),this)}clearAutoComplete(){return this._options.autoComplete===void 0?this:(this._options.autoComplete=void 0,this.removeElementAttribute(`autocomplete`),this)}getBaseline(){return this.wrapInnerBaseline(t.measureTextBaseline())}getTextAlign(){return this._options.textAlign??null}setTextAlign(e){return this._options.textAlign=e,this.setElementCSSRule(`textAlign`,e),this}clearTextAlign(){return this.setTextAlign(null)}getText(){return this._options.text??``}setText(t){this._options.text=t||``;let n=this.getElement();return n&&e.sink.setValue(n,this._options.text),this}getValue(){return this.getText()}setValue(e){return this.setText(e)}getPlaceholder(){return this._options.placeholder??null}setPlaceholder(e){return this._options.placeholder=e,this.setElementAttribute(`placeholder`,e),this}clearPlaceholder(){return this._options.placeholder===void 0?this:(this._options.placeholder=void 0,this.removeElementAttribute(`placeholder`),this)}getMaxLength(){return this._options.maxLength??null}setMaxLength(e){return this._options.maxLength=e,this.setElementAttribute(`maxlength`,String(e)),this}clearMaxLength(){return this._options.maxLength===void 0?this:(this._options.maxLength=void 0,this.removeElementAttribute(`maxlength`),this)}select(t,n){let r=this.getElement();if(!r)return this;(!t||t<0)&&(t=0);let i=this._options.text??``;return(!n||n>i.length)&&(n=i.length+1),e.sink.setSelectionRange(r,t,n),this}applyEnabled(e){this.setDisabledAttribute(!e)}applyReadOnly(e){e?this.setElementAttribute(`readonly`,``):this.removeElementAttribute(`readonly`)}getElement(e=!1){return super.getElement(e)}init(t){super.init(t);let n=t||this.getElement();return this._options.type!==void 0&&e.sink.apply(n,{setAttr:{type:this._options.type}}),this._options.name!=null&&e.sink.apply(n,{setAttr:{name:this._options.name}}),this._options.placeholder!==void 0&&e.sink.apply(n,{setAttr:{placeholder:this._options.placeholder}}),this._options.readOnly&&e.sink.apply(n,{setAttr:{readonly:``}}),this._options.maxLength!==void 0&&e.sink.apply(n,{setAttr:{maxlength:String(this._options.maxLength)}}),this._options.inputMode!==void 0&&e.sink.apply(n,{setAttr:{inputmode:this._options.inputMode}}),this._options.autoComplete!==void 0&&e.sink.apply(n,{setAttr:{autocomplete:this._options.autoComplete}}),this}render(){let t=super.render();return e.sink.setValue(t,this._options.text??``),t}},j=o(TextInput),M={cursor:`text`,border:`none`,outline:`none`},PickerInput=class extends j{constructor(){super(void 0,M)}},N=o(PickerInput),PickerButton=class extends y{constructor(){super({chromeless:!0,insets:new n(0,4,0,4)})}},P=o(PickerButton),F={content:`''`,position:`absolute`,inset:`0`,border:`2px solid var(--ts-ui-indicator-focus, rgb(30, 100, 200))`,borderRadius:`inherit`,boxSizing:`border-box`,pointerEvents:`none`,zIndex:`1`};function registerFocusWithinRing(e){let t=e.split(`,`).map(e=>e.trim()+`:focus-within::after`).join(`, `);new a({scope:`selector`,name:t,styles:F})}registerFocusWithinRing(`.DateField, .TimeField, .DateTimeField`);var I=24,L={cursor:`text`,padding:new n(3,3,3,3),backgroundColor:`var(--ts-ui-input-bg, rgb(255, 255, 255))`,foregroundColor:`var(--ts-ui-text-color, black)`,border:`var(--ts-ui-input-border)`,borderRadius:`var(--ts-ui-border-radius, 4px)`},AbstractPickerField=class extends m{_input;_button;_dropdown=null;_value=null;_invalid=!1;_showSeconds=!1;constructor(e,t){super(e,{...L,...t??{}}),this._input=new N,this._input.setType(`text`),this._input.setInputMode(`none`),this._input.setAutoComplete(`off`),this._input.setPadding(new n(0,3,0,3)),this._button=new P,this.addComponent(this._input),this.addComponent(this._button),this.updateHeight(),this.subscribeTheme(()=>this.updateHeight()),i.addListener(this._input,`input`,()=>this.onInput()),i.addListener(this._input,`blur`,()=>this.onBlur()),i.addListener(this._input,`keydown`,e=>this.onKeyDown(e)),this._button.on(`action`,()=>this.onButtonClick()),this._button.addPointerDownListener(e=>this.onButtonPointerDown(e)),this._options.enabled!==void 0&&this.applyEnabled(this._options.enabled),this._options.readOnly!==void 0&&this.applyReadOnly(this._options.readOnly)}getDefaultBorder(){return L.border}applyOptions(e){return super.applyOptions(e),e.dropdownAnimated!==void 0&&this.setDropdownAnimated(e.dropdownAnimated),this}doLayout(){super.doLayout();let e=this.getContentBounds();if(!e)return this;let t=Math.max(0,e.width-I);return this._input.setX(e.x),this._input.setY(e.y),this._input.setWidth(t),this._input.setHeight(e.height),this._button.setX(e.x+t),this._button.setY(e.y),this._button.setWidth(I),this._button.setHeight(e.height),this._button.doLayout(),this}updateHeight(){let e=t.singleLineBoxHeight(this.getInsets(),this.getPadding(),this.getBorderSize()),n=this.getPreferredSizeConstraint()?.width??this.getPreferredWidth();this.setPreferredSize({width:n,height:e});let r=this.getMaxSizeConstraint()?.width??2**53-1;this.setMaxSize({width:r,height:e});let i=this.getMinSizeConstraint()?.width??0;this.setMinSize({width:i,height:e})}setValue(e){return this._value=e,this._input?.setText(e?this.formatValue(e):``),this}getValue(){return this._value}getBaseline(){return this.wrapInnerBaseline(this._input.getBaseline())}setDropdownAnimated(e){return this._options.dropdownAnimated=e,this._dropdown&&this._dropdown.setAnimated(e),this}isDropdownAnimated(){return this._options.dropdownAnimated??!0}applyEnabled(e){this._input.setEnabled(e)}applyReadOnly(e){this._input.setReadOnly(e)}onButtonClick(){this._dropdown?.isOpen()?this.closeDropdown():(this._input.focus(),this.openDropdown())}onButtonPointerDown(e){e.preventDefault()}onInput(){let e=this._input.getText();if(!e){this._value=null,this.setInvalid(!1),this.notifyChange(null);return}let t=this.parseRaw(e);t===null?this.setInvalid(!0):(this._value=t,this.setInvalid(!1),this.notifyChange(t))}onBlur(){this._invalid&&(this._input.setText(``),this._value=null,this.setInvalid(!1))}setInvalid(e){this._invalid!==e&&(this._invalid=e,e?this.setBorder({border:`1px solid var(--ts-ui-validation-error-border)`}):this.setBorder(this.getDefaultBorder()))}onKeyDown(e){if(this._dropdown&&this._dropdown.isOpen()&&this._dropdown.handleKey(e)){e.preventDefault();return}e.key===`ArrowDown`?(e.preventDefault(),this.openDropdown()):e.key===`Escape`&&this.closeDropdown()}ensureDropdown(){if(!this._dropdown){this._dropdown=this.createDropdown();let e=this._options.dropdownAnimated;e!==void 0&&this._dropdown.setAnimated(e)}return this._dropdown}openDropdown(){let e=this.ensureDropdown();e.isOpen()||(e.setCloseHandler(()=>this.closeDropdown()),e.setAnchorElement(this.getElement(!0)??null),e.showAt(this._input.getElement(!0),this._value))}closeDropdown(){this._dropdown&&this._dropdown.isOpen()&&this._dropdown.hideAnimated()}},R={cursor:`text`,padding:new n(3,3,3,3),backgroundColor:`var(--ts-ui-input-bg, rgb(255, 255, 255))`,foregroundColor:`var(--ts-ui-text-color, black)`},TextField=class extends j{constructor(e,t){super(e,{...R,...t??{}}),this.updateHeight(),this.subscribeTheme(()=>this.updateHeight()),this.setType(`text`)}updateHeight(){let e=t.singleLineBoxHeight(this.getInsets(),this.getPadding(),this.getBorderSize()),n=this.getPreferredSizeConstraint()?.width??200;this.setPreferredSize({width:n,height:e});let r=this.getMaxSizeConstraint()?.width??2**53-1;this.setMaxSize({width:r,height:e});let i=this.getMinSizeConstraint()?.width??0;this.setMinSize({width:i,height:e})}setBorder(e){super.setBorder(e);let n=t.singleLineBoxHeight(this.getInsets(),this.getPadding(),this.getBorderSize()),i=this.getPreferredSize(),a=this.getMinSize(),o=this.getMaxSize();return i&&this.setPreferredSize({width:i.width,height:n}),a&&this.setMinSize({width:a.width,height:n}),o&&!r(o.height)&&this.setMaxSize({width:o.width,height:n}),this}},z=o(TextField);new a({scope:`class`,name:`PickerColumnHeader`,styles:{opacity:`0.7`}}),new a({scope:`class`,name:`PickerCell`,styles:{borderRadius:`3px`}}),new a({scope:`selector`,name:`.PickerCell:hover`,styles:{backgroundColor:`var(--ts-ui-autocomplete-item-hover-bg, rgba(30, 100, 200, 0.08))`}}),new a({scope:`selector`,name:`.PickerCell.disabled`,styles:{pointerEvents:`none`,color:`var(--ts-ui-autocomplete-item-disabled-color, rgb(170, 170, 170))`,backgroundColor:`var(--ts-ui-picker-cell-disabled-bg, transparent)`}});var PickerColumnHeader=class extends p{constructor(e){super(e,{textAlign:`center`,fontSize:12})}},PickerCellList=class extends u{constructor(){super({layoutManager:new g({spacing:0,stretching:!0}),autoScroll:`y`,insets:new n(0,0,0,0)})}getMinSize(){let e=super.getMinSize();return e&&{width:e.width,height:0}}},PickerCell=class extends p{_selected=!1;_disabled=!1;_onClick;constructor(e,t){super(e,{textAlign:`center`,preferredSize:{width:0,height:22}}),this._onClick=t,this.setLineHeight(22),this.setCursor(`pointer`),i.addListener(this,`pointerdown`,this.handlePointerDown),i.addListener(this,`click`,this.handleClick)}handlePointerDown(e){e.preventDefault()}handleClick(){this._disabled||this._onClick()}setSelected(e){return this._selected===e?this:(this._selected=e,e?(this.setBackgroundColor(`var(--ts-ui-autocomplete-item-highlight-bg, rgba(30, 100, 200, 0.18))`),this.setFontWeight(`bold`)):(this.clearBackgroundColor(),this.setFontWeight(`normal`)),this)}isSelected(){return this._selected}setDisabled(t){if(this._disabled===t)return this;this._disabled=t,this.setCursor(t?`default`:`pointer`);let n=this.getElement();return n&&e.sink.apply(n,{toggleClass:{disabled:t}}),this}isDisabled(){return this._disabled}render(){let t=super.render();return this._disabled&&e.sink.apply(t,{addClass:[`disabled`]}),t}},PickerColumn=class extends s{_cellList;constructor(e){if(super(),this.setLayoutManager(new g({spacing:2,stretching:!0})),e!==null){let t=new PickerColumnHeader(e);t.setPreferredSize({width:0,height:18}),this.addComponent(t)}this._cellList=new PickerCellList;let t=new v;t.weight=1,this.addComponent(this._cellList,t)}addCell(e){return this._cellList.addComponent(e),this}clearCells(){return this._cellList.disposeAllComponents(),this}getCellList(){return this._cellList}scrollSelectedIntoView(){let n=this._cellList.getElement();if(!n)return this;let r=this._cellList.getComponents(),i=null;for(let e of r)if(e instanceof PickerCell&&e.isSelected()){i=e;break}if(!i)return this;let a=i.getElement();if(!a)return this;let o=e.source.getOffsetSize(a),s=e.source.getScrollMetrics(n),c=o.offsetTop,l=o.offsetHeight,u=s.clientHeight,d=c-(u-l)/2,f=s.scrollHeight-u,p=t.clamp(d,0,f);return e.sink.apply(n,{scrollTop:p}),this}setSelectedValue(e){for(let t of this._cellList.getComponents())t instanceof PickerCell&&t.setSelected(t.getText().valueOf()===e);return this}};l.register(x),l.register(S),new a({scope:`class`,name:`PickerDay`,styles:{borderRadius:`3px`}}),new a({scope:`selector`,name:`.PickerDay:hover`,styles:{backgroundColor:`var(--ts-ui-autocomplete-item-hover-bg, rgba(30, 100, 200, 0.08))`}}),new a({scope:`selector`,name:`.PickerDay.disabled`,styles:{pointerEvents:`none`,color:`var(--ts-ui-autocomplete-item-disabled-color, rgb(170, 170, 170))`,backgroundColor:`var(--ts-ui-picker-cell-disabled-bg, transparent)`}}),new a({scope:`class`,name:`PickerNavButton`,styles:{borderRadius:`3px`,color:`var(--ts-ui-picker-nav-fg, var(--ts-ui-text-color))`}}),new a({scope:`selector`,name:`.PickerNavButton:hover`,styles:{backgroundColor:`var(--ts-ui-picker-nav-hover-bg, rgba(30, 100, 200, 0.08))`}});var PickerDayHeader=class extends p{constructor(e){super(e,{textAlign:`center`,fontSize:12,preferredSize:{width:0,height:20}}),this.setLineHeight(20)}},PickerBlankCell=class extends s{constructor(){super({preferredSize:{width:0,height:24}})}},PickerNavButton=class extends s{constructor(e,t){super({preferredSize:{width:24,height:24}}),this.setLayoutManager(new f),this.setCursor(`pointer`),this.getAria().setRole(`button`);let n=new l(e);n.setPointerEvents(`none`),n.setPreferredSize({width:12,height:12}),this.addComponent(n),i.addListener(this,`pointerdown`,e=>e.preventDefault()),i.addListener(this,`click`,()=>t())}render(){let t=super.render();return e.sink.apply(t,{addClass:[`PickerNavButton`]}),t}},PickerMonthLabel=class extends p{constructor(e){super(``,{textAlign:`center`,fontWeight:`bold`}),this.setLineHeight(24),this.setCursor(`pointer`),this.getAria().setRole(`button`),this.getAria().setExpanded(!1),this.getAria().setTabIndex(0),i.addListener(this,`pointerdown`,e=>e.preventDefault()),i.addListener(this,`click`,()=>e())}render(){let t=super.render();return e.sink.apply(t,{addClass:[`PickerNavButton`]}),t}},PickerDay=class extends p{_date;_selected=!1;_disabled=!1;_onClick;constructor(e,t){super(String(e.getDate()),{textAlign:`center`,preferredSize:{width:0,height:24}}),this._date=e,this._onClick=t,this.setLineHeight(24),this.setCursor(`pointer`),i.addListener(this,`pointerdown`,e=>this.onPointerDown(e)),i.addListener(this,`click`,()=>this.onClick())}getDate(){return this._date}onPointerDown(e){e.preventDefault()}onClick(){this._disabled||this._onClick(this._date)}setSelected(e){return this._selected===e?this:(this._selected=e,e?(this.setBackgroundColor(`var(--ts-ui-autocomplete-item-highlight-bg, rgba(30, 100, 200, 0.18))`),this.setFontWeight(`bold`)):(this.clearBackgroundColor(),this.setFontWeight(`normal`)),this)}isSelected(){return this._selected}setDisabled(t){if(this._disabled===t)return this;this._disabled=t,this.setCursor(t?`default`:`pointer`);let n=this.getElement();return n&&e.sink.apply(n,{toggleClass:{disabled:t}}),this}isDisabled(){return this._disabled}render(){let t=super.render();return e.sink.apply(t,{addClass:[`PickerDay`]}),this._disabled&&e.sink.apply(t,{addClass:[`disabled`]}),t}};function dayStart(e){return new Date(e.getFullYear(),e.getMonth(),e.getDate(),0,0,0,0)}function dayEnd(e){return new Date(e.getFullYear(),e.getMonth(),e.getDate(),23,59,59,999)}var AbstractCalendarDropdown=class extends d{_onSelect;_value=null;_monthAnchor=new Date;_yearScrollOpen=!1;_root;_headerRow;_prevButton;_nextButton;_monthLabel;_weekdayRow;_dayGrid;_yearColumn=null;_highlightedDayIdx=-1;_highlightedYear=-1;_yearTypeBuffer=``;_yearTypeTimer=null;constructor(e,t,r){super(t,{zIndex:10050,layoutManager:new f,backgroundColor:`var(--ts-ui-autocomplete-bg, rgb(255, 255, 255))`,border:`var(--ts-ui-input-border)`,borderRadius:`var(--ts-ui-border-radius, 4px)`,shadow:`var(--ts-ui-autocomplete-shadow, 2px 4px 8px rgba(0,0,0,0.15))`,insets:new n(6,6,6,6),...r??{}}),this._onSelect=e,this.getAria().setRole(`group`),this.setContain(`layout`),this._root=new s,this._root.setLayoutManager(new g({spacing:4,stretching:!0})),this._headerRow=new s({preferredSize:{width:0,height:24}}),this._headerRow.setLayoutManager(new _({spacing:2,stretching:!0})),this._prevButton=new PickerNavButton(`chevron-left`,()=>this.prevMonth()),this._nextButton=new PickerNavButton(`chevron-right`,()=>this.nextMonth()),this._monthLabel=new PickerMonthLabel(()=>this.toggleYearScroller());let a=new v;a.weight=1,this._headerRow.addComponent(this._prevButton),this._headerRow.addComponent(this._monthLabel,a),this._headerRow.addComponent(this._nextButton),this._root.addComponent(this._headerRow),this._weekdayRow=new s({preferredSize:{width:0,height:20}}),this._weekdayRow.setLayoutManager(new b({columns:7,spacing:2}));for(let e of[`Sun`,`Mon`,`Tue`,`Wed`,`Thu`,`Fri`,`Sat`])this._weekdayRow.addComponent(new PickerDayHeader(e));this._root.addComponent(this._weekdayRow),this._dayGrid=new s({preferredSize:{width:0,height:154}}),this._dayGrid.setLayoutManager(new b({columns:7,spacing:2})),this._root.addComponent(this._dayGrid),this.addComponent(this._root),this.buildExtraRootChildren(),i.addSubtreeListener(this,`pointerdown`,e=>this.onPointerDown(e))}applyOptions(e){return super.applyOptions(e),e.minDate!==void 0&&(this._options.minDate=e.minDate),e.maxDate!==void 0&&(this._options.maxDate=e.maxDate),this}onPointerDown(t){e.source.isNode(t.target)&&e.source.getTagName(e.source.intern(t.target))===`INPUT`||t.preventDefault()}showAt(t,n){this._value=n?new Date(n.getTime()):null;let r=this._value??new Date;this._monthAnchor=new Date(r.getFullYear(),r.getMonth(),1),this._highlightedDayIdx=-1,this._highlightedYear=-1,this.resetYearTypeBuffer(),this._yearScrollOpen&&this.closeYearScroller(),this.pauseLayout(),this.rebuild(),this.resumeLayout();let i=this.computePanelHeight();return this.setWidth(this.getPanelWidth()),this.setHeight(i),this.doLayout(),this.placeAnchored(e.source.getElementRect(t)),this.showAnimated(),this}hideAnimated(){return super.hideAnimated(),this.resetYearTypeBuffer(),this}computePanelHeight(){let e=this.getPerimeterSize(),t=206+this.getExtraInnerHeight();return e.top+e.bottom+t}rebuild(){this.buildDayGrid(),this.rebuildExtraRowsAfterValueChange()}buildDayGrid(){this._dayGrid.disposeAllComponents(),this._highlightedDayIdx=-1;let e=this._monthAnchor.getFullYear(),t=this._monthAnchor.getMonth();this._monthLabel.setText(this._monthAnchor.toLocaleDateString(void 0,{month:`long`,year:`numeric`}));let n=new Date(e,t,1).getDay(),r=new Date(e,t+1,0).getDate();for(let e=0;e<n;e++)this._dayGrid.addComponent(new PickerBlankCell);for(let n=1;n<=r;n++){let r=new Date(e,t,n),i=new PickerDay(r,e=>this.onDateSelected(e));this.isDateInRange(r)||i.setDisabled(!0),this.isValueOnDay(r)&&i.setSelected(!0),this._dayGrid.addComponent(i)}let i=42-n-r;for(let e=0;e<i;e++)this._dayGrid.addComponent(new PickerBlankCell)}isValueOnDay(e){return this._value?this._value.getFullYear()===e.getFullYear()&&this._value.getMonth()===e.getMonth()&&this._value.getDate()===e.getDate():!1}isDateInRange(e){let t=this._options.minDate??null,n=this._options.maxDate??null;return!(t&&e.getTime()<dayStart(t).getTime()||n&&e.getTime()>dayEnd(n).getTime())}hasAnyInRange(e){let t=e.getFullYear(),n=e.getMonth(),r=new Date(t,n+1,0).getDate(),i=new Date(t,n,1),a=new Date(t,n,r),o=this._options.minDate??null,s=this._options.maxDate??null;return!(o&&dayEnd(a).getTime()<dayStart(o).getTime()||s&&dayStart(i).getTime()>dayEnd(s).getTime())}onDateSelected(e){this.applyDateSelection(e),this._monthAnchor=new Date(e.getFullYear(),e.getMonth(),1),this.notifyValueChanged(),this.rebuild(),this.doLayout()}notifyValueChanged(){this._value&&this._onSelect(new Date(this._value.getTime()))}prevMonth(){let e=new Date(this._monthAnchor.getFullYear(),this._monthAnchor.getMonth()-1,1);this.hasAnyInRange(e)&&(this._monthAnchor=e,this._yearScrollOpen?(this.updateMonthLabel(),this.refreshYearSelection()):(this.buildDayGrid(),this.doLayout()))}nextMonth(){let e=new Date(this._monthAnchor.getFullYear(),this._monthAnchor.getMonth()+1,1);this.hasAnyInRange(e)&&(this._monthAnchor=e,this._yearScrollOpen?(this.updateMonthLabel(),this.refreshYearSelection()):(this.buildDayGrid(),this.doLayout()))}updateMonthLabel(){this._monthLabel.setText(this._monthAnchor.toLocaleDateString(void 0,{month:`long`,year:`numeric`}))}toggleYearScroller(){this._yearScrollOpen?this.closeYearScroller():this.openYearScroller()}openYearScroller(){this._yearColumn||(this._yearColumn=new PickerColumn(null),this._yearColumn.setPreferredSize({width:0,height:154}),this._yearColumn.getAria().setRole(`listbox`)),this.buildYearScroller(),this._root.removeComponent(this._dayGrid),this._root.insertComponent(this._yearColumn,2),this._yearScrollOpen=!0,this._monthLabel.getAria().setExpanded(!0),this.doLayout(),this._yearColumn.scrollSelectedIntoView()}closeYearScroller(){this._yearColumn&&this._root.removeComponent(this._yearColumn),this._root.insertComponent(this._dayGrid,2),this._yearScrollOpen=!1,this._monthLabel.getAria().setExpanded(!1),this.resetYearTypeBuffer(),this.buildDayGrid(),this.doLayout()}buildYearScroller(){if(!this._yearColumn)return;this._yearColumn.clearCells(),this._highlightedYear=-1;let e=new Date,t=this._options.minDate?.getFullYear()??e.getFullYear()-120,n=this._options.maxDate?.getFullYear()??e.getFullYear()+50,r=this._monthAnchor.getFullYear();for(let e=t;e<=n;e++){let t=e,n=new PickerCell(String(t),()=>this.onYearSelected(t));t===r&&n.setSelected(!0),this._yearColumn.addCell(n)}}refreshYearSelection(){if(!this._yearColumn)return;let e=this._monthAnchor.getFullYear();for(let t of this._yearColumn.getCellList().getComponents())t instanceof PickerCell&&t.setSelected(t.getText().valueOf()===String(e))}onYearSelected(e){this._monthAnchor=new Date(e,this._monthAnchor.getMonth(),1),this.applyYearSelection(e),this.closeYearScroller()}resetYearTypeBuffer(){this._yearTypeBuffer=``,this._yearTypeTimer!==null&&(clearTimeout(this._yearTypeTimer),this._yearTypeTimer=null)}handleKey(e){return this.isOpen()?this._yearScrollOpen?this.handleKeyInYearScroller(e):this.handleKeyInDayGrid(e):!1}handleKeyInDayGrid(e){switch(e.key){case`ArrowLeft`:return this.moveHighlightedDay(-1);case`ArrowRight`:return this.moveHighlightedDay(1);case`ArrowUp`:return this.moveHighlightedDay(-7);case`ArrowDown`:return this.moveHighlightedDay(7);case`PageUp`:return this.prevMonth(),!0;case`PageDown`:return this.nextMonth(),!0;case`Home`:return this.highlightFirstDayOfMonth();case`End`:return this.highlightLastDayOfMonth();case`Enter`:case` `:return this.commitHighlightedDay();default:return!1}}getDayGridChildren(){return this._dayGrid.getComponents()}moveHighlightedDay(e){let t=this.getDayGridChildren(),n=[];for(let e=0;e<t.length;e++){let r=t[e];r instanceof PickerDay&&!r.isDisabled()&&n.push({idx:e,cell:r})}if(n.length===0)return!0;let r=-1;for(let e=0;e<n.length;e++)if(n[e].idx===this._highlightedDayIdx){r=e;break}if(r<0){r=0;for(let e=0;e<n.length;e++)if(n[e].cell.isSelected()){r=e;break}}let i=Math.max(0,Math.min(n.length-1,r+e));return this.setHighlightedDay(n[i].idx),!0}setHighlightedDay(e){let t=this.getDayGridChildren();if(this._highlightedDayIdx>=0&&this._highlightedDayIdx<t.length){let e=t[this._highlightedDayIdx];e instanceof PickerDay&&!this.matchesSelection(e)&&e.setSelected(!1)}if(e<0||e>=t.length){this._highlightedDayIdx=-1;return}let n=t[e];n instanceof PickerDay&&(n.setSelected(!0),this._highlightedDayIdx=e)}matchesSelection(e){return this.isValueOnDay(e.getDate())}highlightFirstDayOfMonth(){let e=this.getDayGridChildren();for(let t=0;t<e.length;t++){let n=e[t];if(n instanceof PickerDay&&!n.isDisabled())return this.setHighlightedDay(t),!0}return!0}highlightLastDayOfMonth(){let e=this.getDayGridChildren();for(let t=e.length-1;t>=0;t--){let n=e[t];if(n instanceof PickerDay&&!n.isDisabled())return this.setHighlightedDay(t),!0}return!0}commitHighlightedDay(){if(this._highlightedDayIdx<0)return!1;let e=this.getDayGridChildren()[this._highlightedDayIdx];return e instanceof PickerDay&&!e.isDisabled()&&(this.onDateSelected(e.getDate()),!0)}handleKeyInYearScroller(e){if(/^[0-9]$/.test(e.key))return this.appendYearDigit(e.key);switch(e.key){case`ArrowLeft`:case`ArrowUp`:return this.moveHighlightedYear(-1);case`ArrowRight`:case`ArrowDown`:return this.moveHighlightedYear(1);case`PageUp`:return this.moveHighlightedYear(-10);case`PageDown`:return this.moveHighlightedYear(10);case`Home`:return this.highlightFirstYear();case`End`:return this.highlightLastYear();case`Enter`:case` `:return this.commitHighlightedYear();case`Escape`:return this.closeYearScroller(),!0;default:return!1}}getYearCells(){if(!this._yearColumn)return[];let e=[];for(let t of this._yearColumn.getCellList().getComponents())t instanceof PickerCell&&e.push(t);return e}moveHighlightedYear(e){let t=this.getYearCells();if(t.length===0)return!0;let n=this.findHighlightedYearPos(t),r=Math.max(0,Math.min(t.length-1,n+e));return this.applyYearHighlight(t,r),!0}findHighlightedYearPos(e){if(this._highlightedYear<0){for(let t=0;t<e.length;t++)if(e[t].isSelected())return t;return 0}for(let t=0;t<e.length;t++)if(e[t].getText().valueOf()===String(this._highlightedYear))return t;return 0}applyYearHighlight(e,t){let n=this._monthAnchor.getFullYear();for(let t of e)t.setSelected(t.getText().valueOf()===String(n));e[t].setSelected(!0),this._highlightedYear=parseInt(e[t].getText().valueOf(),10),this._yearColumn&&this._yearColumn.scrollSelectedIntoView()}highlightFirstYear(){let e=this.getYearCells();return e.length===0||this.applyYearHighlight(e,0),!0}highlightLastYear(){let e=this.getYearCells();return e.length===0||this.applyYearHighlight(e,e.length-1),!0}commitHighlightedYear(){let e=this._highlightedYear>=0?this._highlightedYear:this._monthAnchor.getFullYear();return this.onYearSelected(e),!0}appendYearDigit(e){this._yearTypeBuffer.length>=4&&(this._yearTypeBuffer=``),this._yearTypeBuffer+=e,this._yearTypeTimer!==null&&clearTimeout(this._yearTypeTimer),this._yearTypeTimer=setTimeout(()=>this.resetYearTypeBuffer(),800);let t=this.getYearCells(),n=this._yearTypeBuffer,r=-1;for(let e=0;e<t.length;e++)if(t[e].getText().valueOf().startsWith(n)){r=e;break}return r>=0&&this.applyYearHighlight(t,r),n.length===4&&this.resetYearTypeBuffer(),!0}getExtraInnerHeight(){return 0}buildExtraRootChildren(){}rebuildExtraRowsAfterValueChange(){}applyDateSelection(e){this._value=new Date(e.getFullYear(),e.getMonth(),e.getDate(),0,0,0,0)}applyYearSelection(e){}},B=240,DatePickerDropdown=class extends AbstractCalendarDropdown{constructor(e,t){super(e,t)}getPanelWidth(){return B}onDateSelected(e){this.applyDateSelection(e),this._monthAnchor=new Date(e.getFullYear(),e.getMonth(),1),this.notifyValueChanged()}},V=o(DatePickerDropdown),TimeColumns=class extends s{_onChange;_showSeconds;_hours=-1;_minutes=-1;_seconds=-1;_hourColumn;_minuteColumn;_secondColumn;constructor(e,t){super({preferredSize:{width:0,height:176}}),this._onChange=e,this._showSeconds=t?.showSeconds??!1,this.setLayoutManager(new _({spacing:4,stretching:!0}));let n=new v;n.weight=1,this._hourColumn=this.buildColumn(`Hour`,24,1,e=>this.onUnitSelected(`hours`,e)),this._minuteColumn=this.buildColumn(`Min`,60,5,e=>this.onUnitSelected(`minutes`,e)),this.addComponent(this._hourColumn,n),this.addComponent(this._minuteColumn,n),this._showSeconds?(this._secondColumn=this.buildColumn(`Sec`,60,5,e=>this.onUnitSelected(`seconds`,e)),this.addComponent(this._secondColumn,n)):this._secondColumn=null}setTime(e){return e?(this._hours=e.getHours(),this._minutes=e.getMinutes(),this._seconds=this._showSeconds?e.getSeconds():0):(this._hours=-1,this._minutes=-1,this._seconds=-1),this.refreshColumns(),this}buildColumn(e,t,n,r){let i=new PickerColumn(e);for(let e=0;e<t;e+=n){let t=e,n=new PickerCell(String(t).padStart(2,`0`),()=>r(t));i.addCell(n)}return i}onUnitSelected(e,t){e===`hours`?this._hours=t:e===`minutes`?this._minutes=t:this._seconds=t,this._hours<0&&(this._hours=0),this._minutes<0&&(this._minutes=0),this._seconds<0&&(this._seconds=0),this.refreshColumns(),this._onChange(this._hours,this._minutes,this._showSeconds?this._seconds:0)}refreshColumns(){this._hourColumn.setSelectedValue(this.cellLabel(this._hours)),this._minuteColumn.setSelectedValue(this.cellLabel(this._minutes)),this._secondColumn?.setSelectedValue(this.cellLabel(this._seconds))}cellLabel(e){return e<0?null:String(e).padStart(2,`0`)}},H=140,U=200,W=220,TimePickerDropdown=class extends d{_showSeconds;_timeColumns;constructor(e,t){super(t,{zIndex:10050,layoutManager:new f,backgroundColor:`var(--ts-ui-autocomplete-bg, rgb(255, 255, 255))`,border:`var(--ts-ui-input-border)`,borderRadius:`var(--ts-ui-border-radius, 4px)`,shadow:`var(--ts-ui-autocomplete-shadow, 2px 4px 8px rgba(0,0,0,0.15))`,insets:new n(4,4,4,4)}),this._showSeconds=t?.showSeconds??!1,this.getAria().setRole(`group`),this.setContain(`layout`),this._timeColumns=new TimeColumns(e,{showSeconds:this._showSeconds}),this.addComponent(this._timeColumns),i.addSubtreeListener(this,`pointerdown`,e=>this.onPointerDown(e))}onPointerDown(e){e.preventDefault()}showAt(t,n){return this._timeColumns.setTime(n),this.setWidth(this._showSeconds?U:H),this.setHeight(W),this.placeAnchored(e.source.getElementRect(t)),this.showAnimated(),this.doLayout(),this}},G=o(TimePickerDropdown);l.register(C);var TimeField=class extends AbstractPickerField{constructor(e){super(e),this._button.setGlyph(`clock`),this._options.showSeconds!==void 0&&(this._showSeconds=this._options.showSeconds),this._options.value!==void 0&&this.setValue(this._options.value)}applyOptions(e){return super.applyOptions(e),e.showSeconds!==void 0&&(this._options.showSeconds=e.showSeconds),e.value!==void 0&&(this._options.value=e.value),this}formatValue(e){let t=String(e.getHours()).padStart(2,`0`),n=String(e.getMinutes()).padStart(2,`0`);return this._showSeconds?`${t}:${n}:${String(e.getSeconds()).padStart(2,`0`)}`:`${t}:${n}`}parseRaw(e){let[t,n,r]=e.split(`:`),i=Number(t),a=Number(n),o=r===void 0?0:Number(r);if(n===void 0||n===``||!(!isNaN(i)&&i>=0&&i<24)||!(!isNaN(a)&&a>=0&&a<60)||!(!isNaN(o)&&o>=0&&o<60))return null;let s=new Date;return s.setHours(i,a,o,0),s}createDropdown(){return new G((e,t,n)=>this.onTimeSelected(e,t,n),{showSeconds:this._showSeconds})}onTimeSelected(e,t,n){let r=new Date;r.setHours(e,t,n,0),this.onDropdownSelected(r)}onDropdownSelected(e){this.setValue(e),i.fireEvent(this._input,`input`)}getPreferredWidth(){return 140}},K=o(TimeField),q=240,DateTimePickerDropdown=class extends AbstractCalendarDropdown{constructor(e,t){super(e,t)}applyOptions(e){return super.applyOptions(e),e.showSeconds!==void 0&&(this._options.showSeconds=e.showSeconds),this}buildExtraRootChildren(){this._timeField=new K({showSeconds:this.isShowingSeconds()}),this._timeField.on(`change`,e=>this.onTimeFieldChange(e)),this._root.addComponent(this._timeField)}rebuildExtraRowsAfterValueChange(){this._timeField.setValue(this._value)}onTimeFieldChange(e){if(!e)return;let t=this._value??this.todayMidnight();t.setHours(e.getHours(),e.getMinutes(),this.isShowingSeconds()?e.getSeconds():0,0),this._value=t,this.notifyValueChanged()}applyDateSelection(e){this._value?this._value.setFullYear(e.getFullYear(),e.getMonth(),e.getDate()):this._value=new Date(e.getFullYear(),e.getMonth(),e.getDate(),0,0,0,0)}applyYearSelection(e){this._value&&(this._value.setFullYear(e),this.notifyValueChanged())}getPanelWidth(){return q}getExtraInnerHeight(){return 4+(this._timeField.getPreferredSize()?.height??0)}isShowingSeconds(){return this._options.showSeconds??!1}todayMidnight(){let e=new Date;return new Date(e.getFullYear(),e.getMonth(),e.getDate(),0,0,0,0)}},J=o(DateTimePickerDropdown);l.register(w);var Y={outline:`none`},Checkbox=class extends h{_box;_check;_dash;constructor(e,t){super({...e??{}},{...Y,...t??{}}),this.setLayoutManager(new _),this._box=new s,this._box.setPreferredSize({width:16,height:16}),this._box.setMinSize({width:16,height:16}),this._box.setMaxSize({width:16,height:16}),this._box.setSize({width:16,height:16}),this._box.setBackgroundColor(`var(--ts-ui-checkbox-bg, var(--ts-ui-form-bg, rgb(255, 255, 255)))`),this._box.setBorder(`1px solid var(--ts-ui-form-border, rgb(160, 160, 160))`),this._box.setBorderRadius(`var(--ts-ui-checkbox-radius, 3px)`),this._box.setCursor(`pointer`),this._check=new l(`check`),this._check.setForegroundColor(`var(--ts-ui-checkbox-check-color, rgb(255, 255, 255))`),this._check.setPreferredSize({width:12,height:12}),this._check.setMaxSize({width:12,height:12}),this._check.setX(1),this._check.setY(1),this._check.setOpacity(0),this._check.setPointerEvents(`none`),this._dash=new s,this._dash.setBackgroundColor(`var(--ts-ui-checkbox-check-color, rgb(255, 255, 255))`),this._dash.setPreferredSize({width:8,height:2}),this._dash.setMaxSize({width:8,height:2}),this._dash.setSize({width:8,height:2}),this._dash.setX(3),this._dash.setY(6),this._dash.setOpacity(0),this._dash.setPointerEvents(`none`),c.isReducedMotion()||(this._check.setTransition(`opacity 120ms ease-out`),this._dash.setTransition(`opacity 120ms ease-out`),this._box.setTransition(`background-color 120ms ease-out, border-color 120ms ease-out`)),this._box.addComponent(this._check),this._box.addComponent(this._dash),super.addComponent(this._box),this.getAria().setRole(`checkbox`),this.getAria().setTabIndex(0),this.getAria().setChecked(!1),i.addListener(this._box,`click`,()=>this.activateFromPointer()),this.installKeyboard(),this._options.value!==void 0&&this._options.selected===void 0&&(this._options.selected=this._options.value),this._options.selected!==void 0&&this.applySelected(this._options.selected,this._options.indeterminate??!1),this._options.indeterminate!==void 0&&this.applySelected(this._options.selected??!1,this._options.indeterminate),this._options.label!==void 0&&this.applyLabel(this._options.label),this._options.enabled!==void 0&&this.applyEnabled(this._options.enabled),this._options.readOnly!==void 0&&this.applyReadOnly(this._options.readOnly)}applyOptions(e){return super.applyOptions(e),e.selected!==void 0&&(this._options.selected=e.selected),e.value!==void 0&&(this._options.value=e.value),e.indeterminate!==void 0&&(this._options.indeterminate=e.indeterminate),e.label!==void 0&&(this._options.label=e.label),e.enabled!==void 0&&(this._options.enabled=e.enabled),e.readOnly!==void 0&&(this._options.readOnly=e.readOnly),this}activate(){if(this.isIndeterminate()){this.setSelected(!0);return}this.setSelected(!this.isSelected())}getInteractiveSurface(){return this._box}isSelected(){return this._options.selected??!1}setSelected(e){let t=!!e;return t===this.isSelected()&&!this.isIndeterminate()?this:(this._options.selected=t,this._options.indeterminate=!1,this.applySelected(t,!1),this.notifyChange(t),this.getElement()?i.fireEvent(this,`click`):console.warn(`Checkbox '`+this.getId()+`' setSelected before mount; synthetic 'click' skipped.`),this)}getValue(){return this.isSelected()}setValue(e){return this.setSelected(e)}isIndeterminate(){return this._options.indeterminate??!1}setIndeterminate(e){let t=!!e;return t===this.isIndeterminate()?this:(this._options.indeterminate=t,this.applySelected(this.isSelected(),t),this)}setAnimated(e){let t=e&&!c.isReducedMotion();return this._check.setTransition(t?`opacity 120ms ease-out`:`none`),this._dash.setTransition(t?`opacity 120ms ease-out`:`none`),this._box.setTransition(t?`background-color 120ms ease-out, border-color 120ms ease-out`:`none`),this}on(e,t){return e===`action`?(i.addListener(this,`click`,t),this):super.on(e,t)}off(e,t){return e===`action`?(i.removeListener(this,`click`,t),this):super.off(e,t)}applySelected(e,t){t?this.getAria().setChecked(`mixed`):this.getAria().setChecked(e);let n=t?`var(--ts-ui-checkbox-bg-indeterminate, rgb(160, 160, 160))`:e?`var(--ts-ui-checkbox-bg-selected, rgb(30, 100, 200))`:`var(--ts-ui-checkbox-bg, var(--ts-ui-form-bg, rgb(255, 255, 255)))`,r=e||t?`1px solid `+(t?`var(--ts-ui-checkbox-bg-indeterminate, rgb(160, 160, 160))`:`var(--ts-ui-checkbox-bg-selected, rgb(30, 100, 200))`):`1px solid var(--ts-ui-form-border, rgb(160, 160, 160))`;this._box.setBackgroundColor(n),this._box.setBorder(r),this._check.setOpacity(e&&!t?1:0),this._dash.setOpacity(+!!t)}},X=o(Checkbox);l.register(ee);var Z={tag:`div`,backgroundColor:`var(--ts-ui-input-bg, rgb(255, 255, 255))`,foregroundColor:`var(--ts-ui-text-color, black)`,border:`var(--ts-ui-input-border)`,borderRadius:`var(--ts-ui-border-radius, 4px)`,cursor:`pointer`,insets:new n(3,6,3,6)},Q=200,te=22,ne=16,$=200,ComboBoxDropdown=class extends d{_list;_minWidth=$;constructor(e){super(void 0,{layoutManager:new f,backgroundColor:`var(--ts-ui-autocomplete-bg, rgb(255, 255, 255))`,border:`var(--ts-ui-input-border)`,borderRadius:`var(--ts-ui-border-radius, 4px)`,shadow:`var(--ts-ui-autocomplete-shadow, 2px 4px 8px rgba(0,0,0,0.15))`}),this.setContain(`layout`),this._list=new E,this._list.setBorder(`none`),this._list.setBorderRadius(`0`),this._list.setFocusOnRowClick(!1),this.addComponent(this._list),this._list.on(`action`,()=>e(this._list.getSelectedIndex()))}handleKey(e){return this._list.handleKey(e)}showAt(t,n,r){this.pauseLayout(),this._list.setItemsArray(n),this._list.setSelectedIndex(r,!1),this.resumeLayout();let i=this.getPerimeterSize(),a=i.top+i.bottom,o=i.left+i.right,s=n.length*te+a,c=Math.min(s,Q),l=e.source.getElementRect(t),u=this.measureWidestLabel(n)+ne+o,d=l.width,f=Math.max(l.width,this._minWidth),p=Math.min(Math.max(u,d),f,e.source.getViewportSize().width);return this.setWidth(p),this.setHeight(c),this.placeAnchored(l),this.showAnimated(),this.doLayout(),this}setMinWidth(e){return this._minWidth=e,this}getMinWidth(){return this._minWidth}getList(){return this._list}measureWidestLabel(e){let n=0;for(let r of e){let e=t.measureTextWidth(r.label);e>n&&(n=e)}return n}};new a({scope:`class`,name:`ComboBox`,styles:{userSelect:`none`,whiteSpace:`nowrap`}}),new a({scope:`class`,name:`ComboBoxLabel`,styles:{overflow:`hidden`,textOverflow:`ellipsis`}}),new a({scope:`selector`,name:`.ComboBoxDropdown .List:focus::after`,styles:{content:`none`}});var ComboBoxLabel=class extends s{_lineHeight=null;_renderer;constructor(e){super({tag:`span`}),this.setPointerEvents(`none`),this._renderer=e()}setItem(e,t){return this._renderer.update({item:e,index:t}),this}setRenderer(t){let n=this.getElement();if(n){let t=this._renderer.getElement();t&&e.source.getParentNode(t)===n&&e.sink.removeChild(n,t)}return this._renderer=t,n&&e.sink.appendChild(n,this._renderer.getElement(!0)),this}setLineHeight(e){return this._lineHeight=typeof e==`number`?e+`px`:e,this.setElementCSSRule(`lineHeight`,this._lineHeight),this}getLineHeight(){return this._lineHeight}init(t){super.init(t);let n=t||this.getElement();return n&&e.sink.appendChild(n,this._renderer.getElement(!0)),this}doLayout(){super.doLayout();let e=this.getContentBounds();return e?(this._renderer.setAutoCommitStyle(!1),this._renderer.setX(e.x),this._renderer.setY(e.y),this._renderer.setWidth(e.width),this._renderer.setHeight(e.height),this._renderer.setAutoCommitStyle(!0),this._renderer.layoutChildren(e.width,e.height),this):this}},ComboBoxCaret=class extends s{_glyph=new l(`chevron-down`);_size;constructor(){super({tag:`span`}),this._size=t.lineHeightPx({linePadding:!1}),this.setMinSize({width:this._size,height:this._size}),this.setMaxSize({width:this._size,height:this._size}),this.setPointerEvents(`none`),this._glyph.setPreferredSize({width:this._size,height:this._size}),this._glyph.setPointerEvents(`none`),this.addComponent(this._glyph)}getCaretSize(){return this._size}getGlyph(){return this._glyph}},ComboBox=class extends m{_dropdown;_label;_caret;_pendingValue=null;_boundStore=null;_onStoreRefresh;constructor(e,t){super(e,{...Z,...t??{}}),this.getAria().setRole(`combobox`),this.getAria().setExpanded(!1),this.getAria().setTabIndex(0),this._label=new ComboBoxLabel(this._options.rendererFactory??(()=>new T)),this._caret=new ComboBoxCaret,this.addComponent(this._label),this.addComponent(this._caret),this._dropdown=new ComboBoxDropdown(e=>this.onRowSelected(e)),this._options.dropdownAnimated!==void 0&&this._dropdown.setAnimated(this._options.dropdownAnimated),this._options.dropdownMinWidth!==void 0&&this._dropdown.setMinWidth(this._options.dropdownMinWidth),this._options.rendererFactory!==void 0&&this._dropdown.getList().setRendererFactory(this._options.rendererFactory),this.refreshLabel(),this.updateHeight(),this.subscribeTheme(()=>this.updateHeight()),i.addListener(this,`click`,()=>this.toggleDropdown()),i.addListener(this,`keydown`,e=>this.onKeyDown(e)),this._dropdown.setCloseHandler(()=>this.closeDropdown()),this._onStoreRefresh=()=>this.onStoreRefresh(),this._options.store!==void 0&&this._options.displayField!==void 0&&this.setStore(this._options.store,this._options.displayField,this._options.valueField,this._options.glyphField),this._options.items!==void 0&&this.setItems(this._options.items),this._options.selectedIndex!==void 0&&this.setSelectedIndex(this._options.selectedIndex,!1),this._options.value!==void 0&&this.setValue(this._options.value),this._options.selectedItem!==void 0&&this.setValue(this._options.selectedItem),this._options.enabled!==void 0&&this.applyEnabled(this._options.enabled),this._options.readOnly!==void 0&&this.applyReadOnly(this._options.readOnly)}applyOptions(e){return super.applyOptions(e),e.items!==void 0&&(this._options.items=e.items),e.store!==void 0&&(this._options.store=e.store),e.displayField!==void 0&&(this._options.displayField=e.displayField),e.valueField!==void 0&&(this._options.valueField=e.valueField),e.glyphField!==void 0&&(this._options.glyphField=e.glyphField),e.rendererFactory!==void 0&&(this._options.rendererFactory=e.rendererFactory),e.selectedIndex!==void 0&&(this._options.selectedIndex=e.selectedIndex),e.value!==void 0&&(this._options.value=e.value),e.selectedItem!==void 0&&(this._options.selectedItem=e.selectedItem),e.dropdownAnimated!==void 0&&(this._options.dropdownAnimated=e.dropdownAnimated),e.dropdownMinWidth!==void 0&&this.setDropdownMinWidth(e.dropdownMinWidth),this}updateHeight(){let e=t.singleLineBoxHeight(this.getInsets(),this.getPadding(),this.getBorderSize()),n=this.getPreferredSizeConstraint()?.width??200;this.setPreferredSize({width:n,height:e});let r=this.getMaxSizeConstraint()?.width??2**53-1;this.setMaxSize({width:r,height:e});let i=this.getMinSizeConstraint()?.width??0;this.setMinSize({width:i,height:e})}doLayout(){super.doLayout();let e=this.getContentBounds();if(!e)return this;let t=this._caret.getCaretSize(),n=Math.max(0,e.width-t-6),r=e.x+n+6,i=e.y+Math.max(0,(e.height-t)/2);return this._label.setX(e.x),this._label.setY(e.y),this._label.setWidth(n),this._label.setHeight(e.height),this._label.setLineHeight(e.height),this._label.doLayout(),this._caret.setX(r),this._caret.setY(i),this._caret.setWidth(t),this._caret.setHeight(t),this}getBaseline(){return this.wrapInnerBaseline(t.measureTextBaseline())}openDropdown(){return this._dropdown.isOpen()||this.toggleDropdown(),this}toggleDropdown(){if(this._dropdown.isOpen()){this.closeDropdown();return}let e=this.getElement(!0),t=this._dropdown.getList();this._dropdown.setAnchorElement(e),this._dropdown.showAt(e,t.getItems(),t.getSelectedIndex()),this.getAria().setExpanded(!0),this.setCaretOpen(!0)}setCaretOpen(e){let t=this._caret.getGlyph(),n=this._dropdown.isAnimated()?this._dropdown.getDurationMs():0;t.setTransition(`transform ${n}ms ease`),t.setTransform(e?`rotate(180deg)`:`rotate(0deg)`)}closeDropdown(){this._dropdown.isOpen()&&(this._dropdown.hideAnimated(),this.getAria().setExpanded(!1),this.setCaretOpen(!1))}onKeyDown(e){if(this._dropdown.isOpen()){if(this._dropdown.handleKey(e)){e.preventDefault();return}e.key===`Escape`&&(e.preventDefault(),this.closeDropdown());return}switch(e.key){case`ArrowDown`:case`ArrowUp`:case`Enter`:case` `:e.preventDefault(),this.toggleDropdown()}}onRowSelected(e){this.setSelectedIndex(e,!0),this.closeDropdown()}computeSelectedItem(){let e=this._dropdown.getList(),t=e.getSelectedIndex(),n=e.getItems();return t>=0&&t<n.length?{item:n[t],index:t}:{item:{key:``,label:``},index:-1}}refreshLabel(){let{item:e,index:t}=this.computeSelectedItem();this._label.setItem(e,t)}on(e,t){return super.on(e===`action`?`change`:e,t)}off(e,t){return super.off(e===`action`?`change`:e,t)}setValue(e){return this._pendingValue=e,this._dropdown.getList().setValue(e),this.refreshLabel(),this}getValue(){return this._dropdown.getList().getValue()||(this._pendingValue??``)}getSelectedIndex(){return this._dropdown.getList().getSelectedIndex()}setSelectedIndex(e,t=!0){return this._dropdown.getList().setSelectedIndex(e,!1),this._pendingValue=null,this.refreshLabel(),t&&this.notifyChange(this.getValue()),this}getItems(){return this._dropdown.getList().getItems()}setItems(e){return this._dropdown.getList().setItems(e),this.reapplyPendingValue(),this.autoSelectFirstIfEmpty(),this.refreshLabel(),this}addItem(e){return this._dropdown.getList().addItem(e),this.reapplyPendingValue(),this.autoSelectFirstIfEmpty(),this.refreshLabel(),this}setStore(e,t,n,r){return this._options.store=e,this._options.displayField=t,this._options.valueField=n,this._options.glyphField=r,this._boundStore&&[`load`,`add`,`remove`,`datachange`].forEach(e=>this._boundStore.off(e,this._onStoreRefresh)),this._dropdown.getList().setStore(e,t,n,r),this._boundStore=e,[`load`,`add`,`remove`,`datachange`].forEach(t=>e.on(t,this._onStoreRefresh)),this.reapplyPendingValue(),this.autoSelectFirstIfEmpty(),this.refreshLabel(),this}getStore(){return this._dropdown.getList().getStore()}setRendererFactory(e){return this._options.rendererFactory=e,this._dropdown.getList().setRendererFactory(e),this._label.setRenderer(e()),this.refreshLabel(),this}getRendererFactory(){return this._dropdown.getList().getRendererFactory()}getSelectedRecord(){return this._dropdown.getList().getSelectedRecord()}reapplyPendingValue(){if(this._pendingValue===null)return;let e=this._dropdown.getList();e.setValue(this._pendingValue),e.getSelectedIndex()>=0&&(this._pendingValue=null)}autoSelectFirstIfEmpty(){let e=this._dropdown.getList();e.getSelectedIndex()<0&&e.getItems().length>0&&e.setSelectedIndex(0,!1)}onStoreRefresh(){this.reapplyPendingValue(),this.autoSelectFirstIfEmpty(),this.refreshLabel()}setDropdownAnimated(e){return this._options.dropdownAnimated=e,this._dropdown.setAnimated(e),this}isDropdownAnimated(){return this._options.dropdownAnimated??!0}setDropdownMinWidth(e){return this._options.dropdownMinWidth=e,this._dropdown.setMinWidth(e),this}getDropdownMinWidth(){return this._options.dropdownMinWidth??$}applyEnabled(e){this.getAria().setDisabled(!e),this.getAria().setTabIndex(e?0:-1),this.setCursor(e?`pointer`:`default`),e||this.closeDropdown()}applyReadOnly(e){this.getAria().setReadOnly(e)}},re=o(ComboBox);export{G as a,PickerCellList as c,AbstractPickerField as d,registerFocusWithinRing as f,k as g,j as h,K as i,PickerColumn as l,N as m,X as n,V as o,P as p,J as r,PickerCell as s,re as t,z as u};
2
+ //# sourceMappingURL=ComboBox-C9FYMuLv.js.map