@nyaruka/temba-components 0.123.0 → 0.124.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 (87) hide show
  1. package/.github/copilot-instructions.md +22 -4
  2. package/CHANGELOG.md +11 -0
  3. package/demo/drag-drop-demo.html +141 -0
  4. package/demo/index.html +15 -0
  5. package/demo/test-drag-drop.html +94 -0
  6. package/dist/temba-components.js +323 -191
  7. package/dist/temba-components.js.map +1 -1
  8. package/out-tsc/src/fields/FieldManager.js +27 -34
  9. package/out-tsc/src/fields/FieldManager.js.map +1 -1
  10. package/out-tsc/src/list/SortableList.js +257 -60
  11. package/out-tsc/src/list/SortableList.js.map +1 -1
  12. package/out-tsc/src/omnibox/Omnibox.js +1 -1
  13. package/out-tsc/src/omnibox/Omnibox.js.map +1 -1
  14. package/out-tsc/src/select/Select.js +198 -38
  15. package/out-tsc/src/select/Select.js.map +1 -1
  16. package/out-tsc/src/webchat/WebChat.js +5 -2
  17. package/out-tsc/src/webchat/WebChat.js.map +1 -1
  18. package/out-tsc/test/temba-flow-editor-node.test.js +273 -0
  19. package/out-tsc/test/temba-flow-editor-node.test.js.map +1 -0
  20. package/out-tsc/test/temba-flow-editor.test.js +244 -0
  21. package/out-tsc/test/temba-flow-editor.test.js.map +1 -0
  22. package/out-tsc/test/temba-flow-plumber.test.js +145 -0
  23. package/out-tsc/test/temba-flow-plumber.test.js.map +1 -0
  24. package/out-tsc/test/temba-flow-render.test.js +171 -0
  25. package/out-tsc/test/temba-flow-render.test.js.map +1 -0
  26. package/out-tsc/test/temba-omnibox.test.js +2 -3
  27. package/out-tsc/test/temba-omnibox.test.js.map +1 -1
  28. package/out-tsc/test/temba-select.test.js +134 -53
  29. package/out-tsc/test/temba-select.test.js.map +1 -1
  30. package/out-tsc/test/temba-sortable-list.test.js +91 -15
  31. package/out-tsc/test/temba-sortable-list.test.js.map +1 -1
  32. package/out-tsc/test/temba-webchat-lightbox-fix.test.js +42 -0
  33. package/out-tsc/test/temba-webchat-lightbox-fix.test.js.map +1 -0
  34. package/out-tsc/test/utils.test.js +30 -0
  35. package/out-tsc/test/utils.test.js.map +1 -1
  36. package/package.json +1 -1
  37. package/screenshots/truth/flow/editor-basic.png +0 -0
  38. package/screenshots/truth/list/fields-dragging.png +0 -0
  39. package/screenshots/truth/list/sortable-dragging.png +0 -0
  40. package/screenshots/truth/list/sortable-dropped.png +0 -0
  41. package/screenshots/truth/list/sortable.png +0 -0
  42. package/screenshots/truth/omnibox/selected.png +0 -0
  43. package/screenshots/truth/select/disabled-multi-selection.png +0 -0
  44. package/screenshots/truth/select/disabled-selection.png +0 -0
  45. package/screenshots/truth/select/disabled.png +0 -0
  46. package/screenshots/truth/select/embedded.png +0 -0
  47. package/screenshots/truth/select/empty-options.png +0 -0
  48. package/screenshots/truth/select/expression-selected.png +0 -0
  49. package/screenshots/truth/select/expressions.png +0 -0
  50. package/screenshots/truth/select/functions.png +0 -0
  51. package/screenshots/truth/select/local-options.png +0 -0
  52. package/screenshots/truth/select/multi-reorder-final.png +0 -0
  53. package/screenshots/truth/select/multi-reorder-initial.png +0 -0
  54. package/screenshots/truth/select/multi-with-endpoint.png +0 -0
  55. package/screenshots/truth/select/multiple-initial-values.png +0 -0
  56. package/screenshots/truth/select/remote-options.png +0 -0
  57. package/screenshots/truth/select/search-enabled.png +0 -0
  58. package/screenshots/truth/select/search-multi-no-matches.png +0 -0
  59. package/screenshots/truth/select/search-selected-focus.png +0 -0
  60. package/screenshots/truth/select/search-selected.png +0 -0
  61. package/screenshots/truth/select/search-with-selected.png +0 -0
  62. package/screenshots/truth/select/searching.png +0 -0
  63. package/screenshots/truth/select/selected-multi-maxitems-reached.png +0 -0
  64. package/screenshots/truth/select/selected-multi.png +0 -0
  65. package/screenshots/truth/select/selected-single.png +0 -0
  66. package/screenshots/truth/select/selection-clearable.png +0 -0
  67. package/screenshots/truth/select/static-initial-value.png +0 -0
  68. package/screenshots/truth/select/static-initial-via-selected.png +0 -0
  69. package/screenshots/truth/select/truncated-selection.png +0 -0
  70. package/screenshots/truth/select/with-placeholder.png +0 -0
  71. package/screenshots/truth/select/without-placeholder.png +0 -0
  72. package/screenshots/truth/templates/default.png +0 -0
  73. package/screenshots/truth/templates/unapproved.png +0 -0
  74. package/src/fields/FieldManager.ts +30 -38
  75. package/src/list/SortableList.ts +291 -67
  76. package/src/omnibox/Omnibox.ts +1 -1
  77. package/src/select/Select.ts +213 -42
  78. package/src/webchat/WebChat.ts +5 -2
  79. package/test/temba-flow-editor-node.test.ts +344 -0
  80. package/test/temba-flow-editor.test.ts +301 -0
  81. package/test/temba-flow-plumber.test.ts +189 -0
  82. package/test/temba-flow-render.test.ts +220 -0
  83. package/test/temba-omnibox.test.ts +2 -3
  84. package/test/temba-select.test.ts +180 -79
  85. package/test/temba-sortable-list.test.ts +108 -15
  86. package/test/temba-webchat-lightbox-fix.test.ts +57 -0
  87. package/test/utils.test.ts +52 -0
@@ -1 +1 @@
1
- {"version":3,"file":"SortableList.js","sourceRoot":"","sources":["../../../src/list/SortableList.ts"],"names":[],"mappings":"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","sourcesContent":["import { css, html, PropertyValueMap, TemplateResult } from 'lit';\nimport { property } from 'lit/decorators.js';\nimport { CustomEventType } from '../interfaces';\nimport { RapidElement } from '../RapidElement';\n\n/**\n * A simple list that can be sorted by dragging\n */\n\n// how far we have to drag before it starts\nconst DRAG_THRESHOLD = 5;\nexport class SortableList extends RapidElement {\n static get styles() {\n return css`\n :host {\n margin: auto;\n }\n\n .container {\n user-select: none;\n }\n\n .dragging {\n background: var(--color-selection);\n }\n\n .sortable {\n transition: all 300ms ease-in-out;\n display: flex;\n padding: 0.4em 0;\n }\n\n .sortable:hover temba-icon {\n opacity: 1;\n cursor: move;\n }\n\n .ghost {\n position: absolute;\n opacity: 0.5;\n transition: none;\n }\n\n .slot {\n flex-grow: 1;\n }\n\n slot > * {\n user-select: none;\n }\n\n temba-icon {\n opacity: 0.1;\n padding: 0.2em 0.5em;\n transition: all 300ms ease-in-out;\n }\n `;\n }\n\n @property({ type: String })\n draggingId: string;\n\n ghostElement: HTMLDivElement = null;\n downEle: HTMLDivElement = null;\n xOffset = 0;\n yOffset = 0;\n yDown = 0;\n\n draggingIdx = -1;\n draggingEle = null;\n\n public constructor() {\n super();\n this.handleMouseMove = this.handleMouseMove.bind(this);\n this.handleMouseUp = this.handleMouseUp.bind(this);\n this.handleMouseDown = this.handleMouseDown.bind(this);\n }\n\n protected firstUpdated(\n _changedProperties: PropertyValueMap<any> | Map<PropertyKey, unknown>\n ): void {\n super.firstUpdated(_changedProperties);\n }\n\n public getIds() {\n return this.shadowRoot\n .querySelector('slot')\n .assignedElements()\n .map((ele) => ele.id);\n }\n\n private getRowIndex(id: string): number {\n return this.shadowRoot\n .querySelector('slot')\n .assignedElements()\n .findIndex((ele) => ele.id === id);\n }\n\n private getOverlappingElement(mouseY: number): HTMLDivElement {\n const ghostRect = this.ghostElement.getBoundingClientRect();\n\n const ele = this.shadowRoot\n .querySelector('slot')\n .assignedElements()\n .find((otherEle) => {\n const rect = otherEle.getBoundingClientRect();\n\n // don't return ourselves\n if (otherEle.id === this.ghostElement.id) {\n return false;\n }\n\n if (mouseY > this.yDown) {\n // moving down\n return ghostRect.top < rect.bottom && ghostRect.bottom > rect.bottom;\n } else {\n // moving up\n return rect.top < ghostRect.bottom && rect.bottom > ghostRect.bottom;\n }\n });\n return ele as HTMLDivElement;\n }\n\n private handleMouseDown(event: MouseEvent) {\n let ele = event.target as HTMLDivElement;\n ele = ele.closest('.sortable');\n if (ele) {\n this.downEle = ele;\n this.draggingId = ele.id;\n this.draggingIdx = this.getRowIndex(ele.id);\n this.draggingEle = ele;\n\n this.xOffset = event.clientX - ele.offsetLeft;\n this.yOffset = event.clientY - ele.offsetTop;\n this.yDown = event.clientY;\n\n document.addEventListener('mousemove', this.handleMouseMove);\n document.addEventListener('mouseup', this.handleMouseUp);\n }\n }\n\n private handleMouseMove(event: MouseEvent) {\n const scrollTop = this.shadowRoot\n .querySelector('slot')\n .assignedElements()[0].parentElement.scrollTop;\n\n if (\n !this.ghostElement &&\n this.downEle &&\n Math.abs(event.clientY - this.yDown) > DRAG_THRESHOLD\n ) {\n this.fireCustomEvent(CustomEventType.DragStart, {\n id: this.downEle.id\n });\n\n this.ghostElement = this.downEle.cloneNode(true) as HTMLDivElement;\n this.ghostElement.classList.add('ghost');\n\n const computedStyle = getComputedStyle(this.downEle);\n\n this.ghostElement.style.width =\n this.downEle.clientWidth -\n parseFloat(computedStyle.paddingLeft) -\n parseFloat(computedStyle.paddingRight) +\n 'px';\n const container = this.shadowRoot.querySelector('.container');\n\n container.appendChild(this.ghostElement);\n\n this.downEle = null;\n }\n\n if (this.ghostElement) {\n this.ghostElement.style.left = event.clientX - this.xOffset + 'px';\n this.ghostElement.style.top =\n event.clientY - this.yOffset - scrollTop + 'px';\n\n const other = this.getOverlappingElement(event.clientY);\n if (other) {\n const otherIdx = this.getRowIndex(other.id);\n const dragId = this.ghostElement.id;\n const otherId = other.id;\n\n this.fireCustomEvent(CustomEventType.OrderChanged, {\n from: dragId,\n to: otherId,\n fromIdx: this.draggingIdx,\n toIdx: otherIdx\n });\n\n // TODO: Dont do swapping, just send the full order?\n this.draggingIdx = otherIdx;\n this.draggingId = otherId;\n }\n }\n }\n\n private handleMouseUp() {\n if (this.draggingId) {\n this.fireCustomEvent(CustomEventType.DragStop, {\n id: this.draggingId\n });\n\n this.draggingId = null;\n this.downEle = null;\n\n if (this.ghostElement) {\n this.ghostElement.remove();\n this.ghostElement = null;\n }\n }\n document.removeEventListener('mousemove', this.handleMouseMove);\n document.removeEventListener('mouseup', this.handleMouseUp);\n this.dispatchEvent(new Event('change'));\n }\n\n public render(): TemplateResult {\n return html`\n <div class=\"container\">\n <slot @mousedown=${this.handleMouseDown}></slot>\n </div>\n `;\n }\n}\n"]}
1
+ {"version":3,"file":"SortableList.js","sourceRoot":"","sources":["../../../src/list/SortableList.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,GAAG,EAAE,IAAI,EAAoC,MAAM,KAAK,CAAC;AAClE,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAC7C,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAE/C;;GAEG;AAEH,2CAA2C;AAC3C,MAAM,cAAc,GAAG,CAAC,CAAC;AACzB,MAAM,OAAO,YAAa,SAAQ,YAAY;IAC5C,MAAM,KAAK,MAAM;QACf,OAAO,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAqFT,CAAC;IACJ,CAAC;IAiCD;QACE,KAAK,EAAE,CAAC;QA5BV,eAAU,GAAY,KAAK,CAAC;QAY5B,iBAAY,GAAmB,IAAI,CAAC;QACpC,YAAO,GAAmB,IAAI,CAAC;QAC/B,YAAO,GAAG,CAAC,CAAC;QACZ,YAAO,GAAG,CAAC,CAAC;QACZ,UAAK,GAAG,CAAC,CAAC;QACV,UAAK,GAAG,CAAC,CAAC;QAEV,gBAAW,GAAG,CAAC,CAAC,CAAC;QACjB,gBAAW,GAAG,IAAI,CAAC;QACnB,kBAAa,GAAmB,IAAI,CAAC;QACrC,qBAAgB,GAAG,CAAC,CAAC,CAAC;QACtB,yBAAoB,GAAgB,IAAI,CAAC;QAEjC,iBAAY,GAAqC,IAAI,CAAC;QAI5D,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACvD,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACnD,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACzD,CAAC;IAES,YAAY,CACpB,kBAAqE;QAErE,KAAK,CAAC,YAAY,CAAC,kBAAkB,CAAC,CAAC;IACzC,CAAC;IAEO,mBAAmB;QACzB,OAAO,IAAI,CAAC,UAAU;aACnB,aAAa,CAAC,MAAM,CAAC;aACrB,gBAAgB,EAAE;aAClB,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,SAAS,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC;IACzD,CAAC;IAEM,MAAM;QACX,OAAO,IAAI,CAAC,mBAAmB,EAAE,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IACzD,CAAC;IAEO,WAAW,CAAC,EAAU;QAC5B,OAAO,IAAI,CAAC,mBAAmB,EAAE,CAAC,SAAS,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;IACtE,CAAC;IAEO,iBAAiB,CACvB,MAAc,EACd,MAAc;QAEd,MAAM,QAAQ,GAAG,IAAI,CAAC,mBAAmB,EAAE,CAAC,MAAM,CAChD,CAAC,GAAG,EAAE,EAAE,WAAC,OAAA,GAAG,CAAC,EAAE,MAAK,MAAA,IAAI,CAAC,WAAW,0CAAE,EAAE,CAAA,CAAA,EAAA,CACzC,CAAC;QAEF,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,IAAI,CAAC;QAEvC,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YACpB,4EAA4E;YAC5E,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,QAAQ,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBACzC,MAAM,GAAG,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;gBACxB,MAAM,IAAI,GAAG,GAAG,CAAC,qBAAqB,EAAE,CAAC;gBACzC,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC;gBAE3C,IAAI,MAAM,GAAG,OAAO,EAAE,CAAC;oBACrB,6BAA6B;oBAC7B,OAAO,EAAE,OAAO,EAAE,GAAqB,EAAE,WAAW,EAAE,KAAK,EAAE,CAAC;gBAChE,CAAC;YACH,CAAC;YACD,wDAAwD;YACxD,OAAO;gBACL,OAAO,EAAE,QAAQ,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAmB;gBACxD,WAAW,EAAE,IAAI;aAClB,CAAC;QACJ,CAAC;aAAM,CAAC;YACN,0EAA0E;YAC1E,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,QAAQ,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBACzC,MAAM,GAAG,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;gBACxB,MAAM,IAAI,GAAG,GAAG,CAAC,qBAAqB,EAAE,CAAC;gBACzC,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC;gBAE3C,IAAI,MAAM,GAAG,OAAO,EAAE,CAAC;oBACrB,6BAA6B;oBAC7B,OAAO,EAAE,OAAO,EAAE,GAAqB,EAAE,WAAW,EAAE,KAAK,EAAE,CAAC;gBAChE,CAAC;YACH,CAAC;YACD,wDAAwD;YACxD,OAAO;gBACL,OAAO,EAAE,QAAQ,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAmB;gBACxD,WAAW,EAAE,IAAI;aAClB,CAAC;QACJ,CAAC;IACH,CAAC;IAEO,iBAAiB,CAAC,aAA0B,EAAE,WAAoB;QACxE,IAAI,CAAC,iBAAiB,EAAE,CAAC;QAEzB,IAAI,CAAC,aAAa;YAAE,OAAO;QAE3B,MAAM,SAAS,GAAG,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC,YAAY,CAAC,CAAC;QAC9D,IAAI,CAAC,aAAa,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;QACnD,IAAI,CAAC,aAAa,CAAC,SAAS,GAAG,gBAAgB,CAAC;QAEhD,MAAM,UAAU,GAAG,aAAa,CAAC,qBAAqB,EAAE,CAAC;QACzD,MAAM,aAAa,GAAG,SAAS,CAAC,qBAAqB,EAAE,CAAC;QAExD,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YACpB,4CAA4C;YAC5C,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,MAAM,GAAG,UAAU,CAAC,MAAM,GAAG,IAAI,CAAC;YAC3D,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,GAAG,GAAG,UAAU,CAAC,GAAG,GAAG,aAAa,CAAC,GAAG,GAAG,IAAI,CAAC;YAEzE,IAAI,WAAW,EAAE,CAAC;gBAChB,yBAAyB;gBACzB,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,IAAI;oBAC3B,UAAU,CAAC,KAAK,GAAG,aAAa,CAAC,IAAI,GAAG,IAAI,CAAC;YACjD,CAAC;iBAAM,CAAC;gBACN,0BAA0B;gBAC1B,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,IAAI;oBAC3B,UAAU,CAAC,IAAI,GAAG,aAAa,CAAC,IAAI,GAAG,IAAI,CAAC;YAChD,CAAC;QACH,CAAC;aAAM,CAAC;YACN,4CAA4C;YAC5C,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,KAAK,GAAG,UAAU,CAAC,KAAK,GAAG,IAAI,CAAC;YACzD,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,IAAI;gBAC3B,UAAU,CAAC,IAAI,GAAG,aAAa,CAAC,IAAI,GAAG,IAAI,CAAC;YAE9C,IAAI,WAAW,EAAE,CAAC;gBAChB,yBAAyB;gBACzB,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,GAAG;oBAC1B,UAAU,CAAC,MAAM,GAAG,aAAa,CAAC,GAAG,GAAG,IAAI,CAAC;YACjD,CAAC;iBAAM,CAAC;gBACN,0BAA0B;gBAC1B,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,GAAG;oBAC1B,UAAU,CAAC,GAAG,GAAG,aAAa,CAAC,GAAG,GAAG,IAAI,CAAC;YAC9C,CAAC;QACH,CAAC;QAED,SAAS,CAAC,WAAW,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;IAC5C,CAAC;IAEO,iBAAiB;QACvB,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;YACvB,IAAI,CAAC,aAAa,CAAC,MAAM,EAAE,CAAC;YAC5B,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC;QAC5B,CAAC;IACH,CAAC;IAEO,eAAe,CAAC,KAAiB;QACvC,IAAI,GAAG,GAAG,KAAK,CAAC,MAAwB,CAAC;QACzC,GAAG,GAAG,GAAG,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;QAC/B,IAAI,GAAG,EAAE,CAAC;YACR,KAAK,CAAC,cAAc,EAAE,CAAC;YACvB,KAAK,CAAC,eAAe,EAAE,CAAC;YAExB,IAAI,CAAC,OAAO,GAAG,GAAG,CAAC;YACnB,IAAI,CAAC,UAAU,GAAG,GAAG,CAAC,EAAE,CAAC;YACzB,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAC5C,IAAI,CAAC,WAAW,GAAG,GAAG,CAAC;YAEvB,iDAAiD;YACjD,MAAM,IAAI,GAAG,GAAG,CAAC,qBAAqB,EAAE,CAAC;YACzC,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC;YACzC,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC;YACxC,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC;YAC3B,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC;YAE3B,QAAQ,CAAC,gBAAgB,CAAC,WAAW,EAAE,IAAI,CAAC,eAAe,CAAC,CAAC;YAC7D,QAAQ,CAAC,gBAAgB,CAAC,SAAS,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC;QAC3D,CAAC;IACH,CAAC;IAEO,eAAe,CAAC,KAAiB;QACvC,IACE,CAAC,IAAI,CAAC,YAAY;YAClB,IAAI,CAAC,OAAO;YACZ,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,cAAc;gBACpD,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,cAAc,CAAC,EACxD,CAAC;YACD,IAAI,CAAC,eAAe,CAAC,eAAe,CAAC,SAAS,EAAE;gBAC9C,EAAE,EAAE,IAAI,CAAC,OAAO,CAAC,EAAE;aACpB,CAAC,CAAC;YAEH,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,IAAI,CAAmB,CAAC;YACnE,IAAI,CAAC,YAAY,CAAC,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;YAEzC,0CAA0C;YAC1C,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,aAAa,GAAG,MAAM,CAAC;YAC1C,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,GAAG,KAAK,CAAC;YAEnC,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,qBAAqB,EAAE,CAAC;YAClD,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,UAAU,GAAG,wBAAwB,CAAC;YAE9D,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;YAClD,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;YACpD,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,QAAQ,GAAG,OAAO,CAAC;YAC3C,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,IAAI,GAAG,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;YACnE,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,GAAG,GAAG,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;YAClE,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,aAAa,GAAG,MAAM,CAAC;YAC/C,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,MAAM;gBAC5B,yCAAyC,CAAC;YAC5C,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,MAAM,GAAG,OAAO,CAAC;YACzC,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,UAAU,GAAG,MAAM,CAAC;YAC5C,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,OAAO,GAAG,KAAK,CAAC;YACxC,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,SAAS,GAAG,8BAA8B,CAAC;YACnE,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,YAAY,GAAG,kBAAkB,CAAC;YAE1D,8CAA8C;YAC9C,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;gBACtB,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;YACvC,CAAC;YAED,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;YAE7C,uBAAuB;YAEvB,4CAA4C;YAC5C,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC;gBACvB,IAAI,CAAC,YAAY,GAAG,CAAC,CAAa,EAAE,EAAE;oBACpC,CAAC,CAAC,eAAe,EAAE,CAAC;oBACpB,CAAC,CAAC,cAAc,EAAE,CAAC;gBACrB,CAAC,CAAC;gBACF,uEAAuE;gBACvE,QAAQ,CAAC,gBAAgB,CAAC,OAAO,EAAE,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,CAAC;YAC9D,CAAC;QACH,CAAC;QAED,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;YACtB,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,IAAI,GAAG,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;YACnE,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,GAAG,GAAG,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;YAElE,MAAM,UAAU,GAAG,IAAI,CAAC,iBAAiB,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;YACxE,IAAI,UAAU,EAAE,CAAC;gBACf,MAAM,EAAE,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,GAAG,UAAU,CAAC;gBAC3D,MAAM,SAAS,GAAG,IAAI,CAAC,WAAW,CAAC,aAAa,CAAC,EAAE,CAAC,CAAC;gBACrD,MAAM,eAAe,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;gBAE9D,oCAAoC;gBACpC,IAAI,OAAO,GAAG,SAAS,CAAC;gBACxB,IAAI,WAAW,EAAE,CAAC;oBAChB,OAAO,IAAI,CAAC,CAAC;gBACf,CAAC;gBAED,iDAAiD;gBACjD,IAAI,eAAe,GAAG,OAAO,EAAE,CAAC;oBAC9B,OAAO,IAAI,CAAC,CAAC;gBACf,CAAC;gBAED,mDAAmD;gBACnD,IAAI,CAAC,YAAY,GAAG,aAAa,CAAC,EAAE,CAAC;gBACrC,IAAI,CAAC,gBAAgB,GAAG,OAAO,CAAC;gBAChC,IAAI,CAAC,oBAAoB,GAAG,aAAa,CAAC;gBAE1C,sBAAsB;gBACtB,IAAI,CAAC,iBAAiB,CAAC,aAAa,EAAE,WAAW,CAAC,CAAC;YACrD,CAAC;iBAAM,CAAC;gBACN,IAAI,CAAC,iBAAiB,EAAE,CAAC;gBACzB,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;gBACzB,IAAI,CAAC,gBAAgB,GAAG,CAAC,CAAC,CAAC;gBAC3B,IAAI,CAAC,oBAAoB,GAAG,IAAI,CAAC;YACnC,CAAC;QACH,CAAC;IACH,CAAC;IAEO,aAAa,CAAC,GAAe;QACnC,IAAI,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;YACzC,GAAG,CAAC,cAAc,EAAE,CAAC;YACrB,GAAG,CAAC,eAAe,EAAE,CAAC;YAEtB,yCAAyC;YAEzC,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;gBACjB,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,aAAa,GAAG,EAAE,CAAC;gBACtC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,GAAG,GAAG,CAAC;YACnC,CAAC;YAED,kFAAkF;YAClF,IAAI,IAAI,CAAC,gBAAgB,IAAI,CAAC,IAAI,IAAI,CAAC,oBAAoB,EAAE,CAAC;gBAC5D,MAAM,eAAe,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;gBAE9D,iEAAiE;gBACjE,MAAM,OAAO,GAAG,eAAe,CAAC;gBAChC,MAAM,KAAK,GAAG,IAAI,CAAC,gBAAgB,CAAC;gBAEpC,6CAA6C;gBAC7C,IAAI,OAAO,KAAK,KAAK,EAAE,CAAC;oBACtB,IAAI,CAAC,eAAe,CAAC,eAAe,CAAC,YAAY,EAAE;wBACjD,IAAI,EAAE,CAAC,OAAO,EAAE,KAAK,CAAC;qBACvB,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;YAED,IAAI,CAAC,eAAe,CAAC,eAAe,CAAC,QAAQ,EAAE;gBAC7C,EAAE,EAAE,IAAI,CAAC,UAAU;aACpB,CAAC,CAAC;YAEH,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;YACvB,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;YACzB,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;YACpB,IAAI,CAAC,gBAAgB,GAAG,CAAC,CAAC,CAAC;YAC3B,IAAI,CAAC,oBAAoB,GAAG,IAAI,CAAC;YAEjC,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;gBACtB,8BAA8B;gBAC9B,IAAI,IAAI,CAAC,YAAY,CAAC,UAAU,EAAE,CAAC;oBACjC,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,WAAW,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;gBAC9D,CAAC;gBACD,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;YAC3B,CAAC;YAED,IAAI,CAAC,iBAAiB,EAAE,CAAC;YAEzB,4DAA4D;YAC5D,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;gBACtB,oCAAoC;gBACpC,UAAU,CAAC,GAAG,EAAE;oBACd,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;wBACtB,QAAQ,CAAC,mBAAmB,CAAC,OAAO,EAAE,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,CAAC;wBAC/D,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;oBAC3B,CAAC;gBACH,CAAC,EAAE,GAAG,CAAC,CAAC;YACV,CAAC;QACH,CAAC;QACD,QAAQ,CAAC,mBAAmB,CAAC,WAAW,EAAE,IAAI,CAAC,eAAe,CAAC,CAAC;QAChE,QAAQ,CAAC,mBAAmB,CAAC,SAAS,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC;QAC5D,IAAI,CAAC,aAAa,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC;IAC1C,CAAC;IAEM,MAAM;QACX,OAAO,IAAI,CAAA;8BACe,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE;2BACtC,IAAI,CAAC,eAAe;;KAE1C,CAAC;IACJ,CAAC;CACF;AAzVC;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;gDACR;AAGnB;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;gDACA;AAG5B;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;kDACN;AAOrB;IADC,QAAQ,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;kDACa","sourcesContent":["import { css, html, PropertyValueMap, TemplateResult } from 'lit';\nimport { property } from 'lit/decorators.js';\nimport { CustomEventType } from '../interfaces';\nimport { RapidElement } from '../RapidElement';\n\n/**\n * A simple list that can be sorted by dragging\n */\n\n// how far we have to drag before it starts\nconst DRAG_THRESHOLD = 2;\nexport class SortableList extends RapidElement {\n static get styles() {\n return css`\n :host {\n margin: auto;\n }\n\n .container {\n user-select: none;\n position: relative;\n }\n\n .container.horizontal {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n }\n\n .dragging {\n background: var(--color-selection);\n }\n\n .dragged-item {\n opacity: 0;\n pointer-events: none;\n }\n\n .sortable {\n transition: all 300ms ease-in-out;\n display: flex;\n padding: 0.4em 0;\n }\n\n .container.horizontal .sortable {\n padding: 0;\n margin-right: 0.25em;\n margin-bottom: 0.25em;\n }\n\n .drop-indicator {\n position: absolute;\n background: var(--color-primary-dark, #1c7cd6);\n z-index: 1000;\n pointer-events: none;\n }\n\n .container.horizontal .drop-indicator {\n width: 2px;\n margin-top: -5px;\n padding-bottom: 10px;\n }\n\n .container:not(.horizontal) .drop-indicator {\n height: 2px;\n left: 0;\n }\n\n .sortable:hover temba-icon {\n opacity: 1;\n cursor: move;\n }\n\n .ghost {\n position: absolute;\n opacity: 0.7;\n transition: none;\n background: var(--color-background, white);\n border: 1px solid var(--color-primary, #1c7cd6);\n border-radius: 4px;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);\n pointer-events: none;\n z-index: 999;\n }\n\n .slot {\n flex-grow: 1;\n }\n\n slot > * {\n user-select: none;\n }\n\n temba-icon {\n opacity: 0.1;\n padding: 0.2em 0.5em;\n transition: all 300ms ease-in-out;\n }\n `;\n }\n\n @property({ type: String })\n draggingId: string;\n\n @property({ type: Boolean })\n horizontal: boolean = false;\n\n @property({ type: String })\n dropTargetId: string;\n\n /**\n * Optional callback to allow parent components to customize the ghost node.\n * Called after the ghost node is cloned but before it is appended to the DOM.\n */\n @property({ attribute: false })\n prepareGhost?: (ghost: HTMLElement) => void;\n\n ghostElement: HTMLDivElement = null;\n downEle: HTMLDivElement = null;\n xOffset = 0;\n yOffset = 0;\n yDown = 0;\n xDown = 0;\n\n draggingIdx = -1;\n draggingEle = null;\n dropIndicator: HTMLDivElement = null;\n pendingDropIndex = -1;\n pendingTargetElement: HTMLElement = null;\n\n private clickBlocker: ((e: MouseEvent) => void) | null = null;\n\n public constructor() {\n super();\n this.handleMouseMove = this.handleMouseMove.bind(this);\n this.handleMouseUp = this.handleMouseUp.bind(this);\n this.handleMouseDown = this.handleMouseDown.bind(this);\n }\n\n protected firstUpdated(\n _changedProperties: PropertyValueMap<any> | Map<PropertyKey, unknown>\n ): void {\n super.firstUpdated(_changedProperties);\n }\n\n private getSortableElements(): Element[] {\n return this.shadowRoot\n .querySelector('slot')\n .assignedElements()\n .filter((ele) => ele.classList.contains('sortable'));\n }\n\n public getIds() {\n return this.getSortableElements().map((ele) => ele.id);\n }\n\n private getRowIndex(id: string): number {\n return this.getSortableElements().findIndex((ele) => ele.id === id);\n }\n\n private getDropTargetInfo(\n mouseX: number,\n mouseY: number\n ): { element: HTMLDivElement; insertAfter: boolean } | null {\n const elements = this.getSortableElements().filter(\n (ele) => ele.id !== this.draggingEle?.id\n );\n\n if (elements.length === 0) return null;\n\n if (this.horizontal) {\n // For horizontal layout, find the insertion point based on mouse X position\n for (let i = 0; i < elements.length; i++) {\n const ele = elements[i];\n const rect = ele.getBoundingClientRect();\n const centerX = rect.left + rect.width / 2;\n\n if (mouseX < centerX) {\n // Insert before this element\n return { element: ele as HTMLDivElement, insertAfter: false };\n }\n }\n // If we're past all elements, insert after the last one\n return {\n element: elements[elements.length - 1] as HTMLDivElement,\n insertAfter: true\n };\n } else {\n // For vertical layout, find the insertion point based on mouse Y position\n for (let i = 0; i < elements.length; i++) {\n const ele = elements[i];\n const rect = ele.getBoundingClientRect();\n const centerY = rect.top + rect.height / 2;\n\n if (mouseY < centerY) {\n // Insert before this element\n return { element: ele as HTMLDivElement, insertAfter: false };\n }\n }\n // If we're past all elements, insert after the last one\n return {\n element: elements[elements.length - 1] as HTMLDivElement,\n insertAfter: true\n };\n }\n }\n\n private showDropIndicator(targetElement: HTMLElement, insertAfter: boolean) {\n this.hideDropIndicator();\n\n if (!targetElement) return;\n\n const container = this.shadowRoot.querySelector('.container');\n this.dropIndicator = document.createElement('div');\n this.dropIndicator.className = 'drop-indicator';\n\n const targetRect = targetElement.getBoundingClientRect();\n const containerRect = container.getBoundingClientRect();\n\n if (this.horizontal) {\n // For horizontal layout, show vertical line\n this.dropIndicator.style.height = targetRect.height + 'px';\n this.dropIndicator.style.top = targetRect.top - containerRect.top + 'px';\n\n if (insertAfter) {\n // Show line after target\n this.dropIndicator.style.left =\n targetRect.right - containerRect.left + 'px';\n } else {\n // Show line before target\n this.dropIndicator.style.left =\n targetRect.left - containerRect.left + 'px';\n }\n } else {\n // For vertical layout, show horizontal line\n this.dropIndicator.style.width = targetRect.width + 'px';\n this.dropIndicator.style.left =\n targetRect.left - containerRect.left + 'px';\n\n if (insertAfter) {\n // Show line after target\n this.dropIndicator.style.top =\n targetRect.bottom - containerRect.top + 'px';\n } else {\n // Show line before target\n this.dropIndicator.style.top =\n targetRect.top - containerRect.top + 'px';\n }\n }\n\n container.appendChild(this.dropIndicator);\n }\n\n private hideDropIndicator() {\n if (this.dropIndicator) {\n this.dropIndicator.remove();\n this.dropIndicator = null;\n }\n }\n\n private handleMouseDown(event: MouseEvent) {\n let ele = event.target as HTMLDivElement;\n ele = ele.closest('.sortable');\n if (ele) {\n event.preventDefault();\n event.stopPropagation();\n\n this.downEle = ele;\n this.draggingId = ele.id;\n this.draggingIdx = this.getRowIndex(ele.id);\n this.draggingEle = ele;\n\n // Use getBoundingClientRect for accurate offsets\n const rect = ele.getBoundingClientRect();\n this.xOffset = event.clientX - rect.left;\n this.yOffset = event.clientY - rect.top;\n this.yDown = event.clientY;\n this.xDown = event.clientX;\n\n document.addEventListener('mousemove', this.handleMouseMove);\n document.addEventListener('mouseup', this.handleMouseUp);\n }\n }\n\n private handleMouseMove(event: MouseEvent) {\n if (\n !this.ghostElement &&\n this.downEle &&\n (Math.abs(event.clientY - this.yDown) > DRAG_THRESHOLD ||\n Math.abs(event.clientX - this.xDown) > DRAG_THRESHOLD)\n ) {\n this.fireCustomEvent(CustomEventType.DragStart, {\n id: this.downEle.id\n });\n\n this.ghostElement = this.downEle.cloneNode(true) as HTMLDivElement;\n this.ghostElement.classList.add('ghost');\n\n // dim the original element while dragging\n this.downEle.style.pointerEvents = 'none';\n this.downEle.style.opacity = '0.5';\n\n const rect = this.downEle.getBoundingClientRect();\n this.ghostElement.style.transition = 'transform 300ms linear';\n\n this.ghostElement.style.width = rect.width + 'px';\n this.ghostElement.style.height = rect.height + 'px';\n this.ghostElement.style.position = 'fixed';\n this.ghostElement.style.left = event.clientX - this.xOffset + 'px';\n this.ghostElement.style.top = event.clientY - this.yOffset + 'px';\n this.ghostElement.style.pointerEvents = 'none';\n this.ghostElement.style.border =\n '1px solid var(--color-primary, #1c7cd6)';\n this.ghostElement.style.zIndex = '99999';\n this.ghostElement.style.background = '#fff';\n this.ghostElement.style.opacity = '0.7';\n this.ghostElement.style.boxShadow = '0 2px 8px rgba(0, 0, 0, 0.2)';\n this.ghostElement.style.borderRadius = 'var(--curvature)';\n\n // allow component to customize the ghost node\n if (this.prepareGhost) {\n this.prepareGhost(this.ghostElement);\n }\n\n document.body.appendChild(this.ghostElement);\n\n // this.downEle = null;\n\n // Add global click blocker when drag starts\n if (!this.clickBlocker) {\n this.clickBlocker = (e: MouseEvent) => {\n e.stopPropagation();\n e.preventDefault();\n };\n // Use capture phase to intercept clicks before they reach any elements\n document.addEventListener('click', this.clickBlocker, true);\n }\n }\n\n if (this.ghostElement) {\n this.ghostElement.style.left = event.clientX - this.xOffset + 'px';\n this.ghostElement.style.top = event.clientY - this.yOffset + 'px';\n\n const targetInfo = this.getDropTargetInfo(event.clientX, event.clientY);\n if (targetInfo) {\n const { element: targetElement, insertAfter } = targetInfo;\n const targetIdx = this.getRowIndex(targetElement.id);\n const originalDragIdx = this.getRowIndex(this.draggingEle.id);\n\n // Calculate the intended drop index\n let dropIdx = targetIdx;\n if (insertAfter) {\n dropIdx += 1;\n }\n\n // Adjust dropIdx if dragging forward in the list\n if (originalDragIdx < dropIdx) {\n dropIdx -= 1;\n }\n\n // Store pending drop info but don't fire event yet\n this.dropTargetId = targetElement.id;\n this.pendingDropIndex = dropIdx;\n this.pendingTargetElement = targetElement;\n\n // Show drop indicator\n this.showDropIndicator(targetElement, insertAfter);\n } else {\n this.hideDropIndicator();\n this.dropTargetId = null;\n this.pendingDropIndex = -1;\n this.pendingTargetElement = null;\n }\n }\n }\n\n private handleMouseUp(evt: MouseEvent) {\n if (this.draggingId && this.ghostElement) {\n evt.preventDefault();\n evt.stopPropagation();\n\n // restore visibility of the dragged item\n\n if (this.downEle) {\n this.downEle.style.pointerEvents = '';\n this.downEle.style.opacity = '1';\n }\n\n // fire the order changed event only when dropped if we have a valid drop position\n if (this.pendingDropIndex >= 0 && this.pendingTargetElement) {\n const originalDragIdx = this.getRowIndex(this.draggingEle.id);\n\n // use swap-based logic - report which indexes need to be swapped\n const fromIdx = originalDragIdx;\n const toIdx = this.pendingDropIndex;\n\n // only fire if the position actually changed\n if (fromIdx !== toIdx) {\n this.fireCustomEvent(CustomEventType.OrderChanged, {\n swap: [fromIdx, toIdx]\n });\n }\n }\n\n this.fireCustomEvent(CustomEventType.DragStop, {\n id: this.draggingId\n });\n\n this.draggingId = null;\n this.dropTargetId = null;\n this.downEle = null;\n this.pendingDropIndex = -1;\n this.pendingTargetElement = null;\n\n if (this.ghostElement) {\n // Remove from body if present\n if (this.ghostElement.parentNode) {\n this.ghostElement.parentNode.removeChild(this.ghostElement);\n }\n this.ghostElement = null;\n }\n\n this.hideDropIndicator();\n\n // Keep the click blocker active for a short time after drop\n if (this.clickBlocker) {\n // We'll clean it up after a timeout\n setTimeout(() => {\n if (this.clickBlocker) {\n document.removeEventListener('click', this.clickBlocker, true);\n this.clickBlocker = null;\n }\n }, 100);\n }\n }\n document.removeEventListener('mousemove', this.handleMouseMove);\n document.removeEventListener('mouseup', this.handleMouseUp);\n this.dispatchEvent(new Event('change'));\n }\n\n public render(): TemplateResult {\n return html`\n <div class=\"container ${this.horizontal ? 'horizontal' : ''}\">\n <slot @mousedown=${this.handleMouseDown}></slot>\n </div>\n `;\n }\n}\n"]}
@@ -72,7 +72,7 @@ export class Omnibox extends Select {
72
72
  renderSelectedItemDefault(option) {
73
73
  return html `
74
74
  <div
75
- style="flex:1 1 auto; display: flex; align-items: stretch; color: var(--color-text-dark); font-size: 12px;"
75
+ style="flex:1 1 auto; text-overflow:ellipsis; overflow:hidden; white-space:nowrap; display: flex; align-items: stretch; color: var(--color-text-dark); font-size: 12px;"
76
76
  >
77
77
  <div style="align-self: center; padding: 0px 7px; color: #bbb">
78
78
  ${this.getIcon(option)}
@@ -1 +1 @@
1
- {"version":3,"file":"Omnibox.js","sourceRoot":"","sources":["../../../src/omnibox/Omnibox.ts"],"names":[],"mappings":"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","sourcesContent":["import { TemplateResult, html, PropertyValues } from 'lit';\nimport { property } from 'lit/decorators.js';\nimport { styleMap } from 'lit-html/directives/style-map.js';\nimport { Select, SelectOption } from '../select/Select';\nimport { Icon } from '../vectoricon';\n\nenum OmniType {\n Group = 'group',\n Contact = 'contact'\n}\n\nexport interface OmniOption extends SelectOption {\n id: string;\n name: string;\n type: OmniType;\n urn?: string;\n count?: number;\n contact?: string;\n scheme?: string;\n}\n\nconst postNameStyle = {\n color: 'var(--color-text-dark)',\n padding: '0px 6px',\n fontSize: '12px'\n};\n\nexport class Omnibox extends Select<OmniOption> {\n @property({ type: String })\n valueKey = 'uuid';\n\n @property({ type: Boolean })\n groups = false;\n\n @property({ type: Boolean })\n contacts = false;\n\n @property({ type: String })\n placeholder = 'Select recipients';\n\n @property({ type: Boolean })\n multi = true;\n\n @property({ type: Boolean })\n searchable = true;\n\n @property({ type: Boolean })\n searchOnFocus = true;\n\n @property({ type: Boolean })\n queryParam = 'search';\n\n public update(changes: PropertyValues): void {\n super.update(changes);\n\n if (\n (changes.has('groups') || changes.has('contacts')) &&\n (this.groups || this.contacts)\n ) {\n let types = '&types=';\n if (this.groups) {\n types += 'g';\n }\n\n if (this.contacts) {\n types += 'c';\n }\n\n this.endpoint = this.endpoint + types;\n }\n }\n\n /** An option in the drop down */\n public renderOptionDefault(option: OmniOption): TemplateResult {\n return html`\n <div style=\"display:flex;\">\n <div style=\"margin-right: 8px\">${this.getIcon(option)}</div>\n <div style=\"flex: 1\">${option.name}</div>\n <div\n style=\"background: rgba(50, 50, 50, 0.15); margin-left: 5px; display: flex; align-items: center; border-radius: 4px\"\n >\n ${this.getPostName(option)}\n </div>\n </div>\n `;\n }\n\n private getPostName(option: OmniOption): TemplateResult {\n const style = { ...postNameStyle };\n\n if (option.urn && option.type === OmniType.Contact) {\n if (option.urn !== option.name) {\n return html`<div style=${styleMap(style)}>${option.urn}</div>`;\n }\n }\n\n if (option.type === OmniType.Group) {\n return html`\n <div style=${styleMap(style)}>${option.count.toLocaleString()}</div>\n `;\n }\n\n return null;\n }\n\n /** Selection in the multi-select select box */\n public renderSelectedItemDefault(option: OmniOption): TemplateResult {\n return html`\n <div\n style=\"flex:1 1 auto; display: flex; align-items: stretch; color: var(--color-text-dark); font-size: 12px;\"\n >\n <div style=\"align-self: center; padding: 0px 7px; color: #bbb\">\n ${this.getIcon(option)}\n </div>\n <div\n class=\"name\"\n style=\"align-self: center; padding: 0px; font-size: 12px;\"\n >\n ${option.name}\n </div>\n <div\n style=\"background: rgba(100, 100, 100, 0.05); border-left: 1px solid rgba(100, 100, 100, 0.1); margin-left: 12px; display: flex; align-items: center\"\n >\n ${this.getPostName(option)}\n </div>\n </div>\n `;\n }\n\n private getIcon(option: OmniOption): TemplateResult {\n if (option.type === OmniType.Group) {\n return html`<temba-icon name=\"${Icon.group}\"></temba-icon>`;\n }\n\n if (option.type === OmniType.Contact) {\n return html`<temba-icon name=\"${Icon.contact}\"></temba-icon>`;\n }\n }\n}\n"]}
1
+ {"version":3,"file":"Omnibox.js","sourceRoot":"","sources":["../../../src/omnibox/Omnibox.ts"],"names":[],"mappings":"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","sourcesContent":["import { TemplateResult, html, PropertyValues } from 'lit';\nimport { property } from 'lit/decorators.js';\nimport { styleMap } from 'lit-html/directives/style-map.js';\nimport { Select, SelectOption } from '../select/Select';\nimport { Icon } from '../vectoricon';\n\nenum OmniType {\n Group = 'group',\n Contact = 'contact'\n}\n\nexport interface OmniOption extends SelectOption {\n id: string;\n name: string;\n type: OmniType;\n urn?: string;\n count?: number;\n contact?: string;\n scheme?: string;\n}\n\nconst postNameStyle = {\n color: 'var(--color-text-dark)',\n padding: '0px 6px',\n fontSize: '12px'\n};\n\nexport class Omnibox extends Select<OmniOption> {\n @property({ type: String })\n valueKey = 'uuid';\n\n @property({ type: Boolean })\n groups = false;\n\n @property({ type: Boolean })\n contacts = false;\n\n @property({ type: String })\n placeholder = 'Select recipients';\n\n @property({ type: Boolean })\n multi = true;\n\n @property({ type: Boolean })\n searchable = true;\n\n @property({ type: Boolean })\n searchOnFocus = true;\n\n @property({ type: Boolean })\n queryParam = 'search';\n\n public update(changes: PropertyValues): void {\n super.update(changes);\n\n if (\n (changes.has('groups') || changes.has('contacts')) &&\n (this.groups || this.contacts)\n ) {\n let types = '&types=';\n if (this.groups) {\n types += 'g';\n }\n\n if (this.contacts) {\n types += 'c';\n }\n\n this.endpoint = this.endpoint + types;\n }\n }\n\n /** An option in the drop down */\n public renderOptionDefault(option: OmniOption): TemplateResult {\n return html`\n <div style=\"display:flex;\">\n <div style=\"margin-right: 8px\">${this.getIcon(option)}</div>\n <div style=\"flex: 1\">${option.name}</div>\n <div\n style=\"background: rgba(50, 50, 50, 0.15); margin-left: 5px; display: flex; align-items: center; border-radius: 4px\"\n >\n ${this.getPostName(option)}\n </div>\n </div>\n `;\n }\n\n private getPostName(option: OmniOption): TemplateResult {\n const style = { ...postNameStyle };\n\n if (option.urn && option.type === OmniType.Contact) {\n if (option.urn !== option.name) {\n return html`<div style=${styleMap(style)}>${option.urn}</div>`;\n }\n }\n\n if (option.type === OmniType.Group) {\n return html`\n <div style=${styleMap(style)}>${option.count.toLocaleString()}</div>\n `;\n }\n\n return null;\n }\n\n /** Selection in the multi-select select box */\n public renderSelectedItemDefault(option: OmniOption): TemplateResult {\n return html`\n <div\n style=\"flex:1 1 auto; text-overflow:ellipsis; overflow:hidden; white-space:nowrap; display: flex; align-items: stretch; color: var(--color-text-dark); font-size: 12px;\"\n >\n <div style=\"align-self: center; padding: 0px 7px; color: #bbb\">\n ${this.getIcon(option)}\n </div>\n <div\n class=\"name\"\n style=\"align-self: center; padding: 0px; font-size: 12px;\"\n >\n ${option.name}\n </div>\n <div\n style=\"background: rgba(100, 100, 100, 0.05); border-left: 1px solid rgba(100, 100, 100, 0.1); margin-left: 12px; display: flex; align-items: center\"\n >\n ${this.getPostName(option)}\n </div>\n </div>\n `;\n }\n\n private getIcon(option: OmniOption): TemplateResult {\n if (option.type === OmniType.Group) {\n return html`<temba-icon name=\"${Icon.group}\"></temba-icon>`;\n }\n\n if (option.type === OmniType.Contact) {\n return html`<temba-icon name=\"${Icon.contact}\"></temba-icon>`;\n }\n }\n}\n"]}
@@ -4,6 +4,7 @@ import { html, css } from 'lit';
4
4
  import { property, state } from 'lit/decorators.js';
5
5
  import { getUrl, getClasses, fetchResults, postJSON } from '../utils';
6
6
  import '../options/Options';
7
+ import '../list/SortableList';
7
8
  import { FormElement } from '../FormElement';
8
9
  import { lru } from 'tiny-lru';
9
10
  import { CustomEventType } from '../interfaces';
@@ -52,7 +53,7 @@ export class Select extends FormElement {
52
53
  background: rgba(100, 100, 100, 0.05);
53
54
  }
54
55
 
55
- .selected-item.multi .remove-item {
56
+ . selected-item.multi .remove-item {
56
57
  display: none;
57
58
  }
58
59
 
@@ -88,7 +89,7 @@ export class Select extends FormElement {
88
89
  padding-top: 1px;
89
90
  box-shadow: var(--widget-box-shadow);
90
91
  position: relative;
91
- min-height: var(--temba-select-min-height, 2.5em);
92
+ min-height: var(--temba-select-min-height, 2.4em);
92
93
  }
93
94
 
94
95
  temba-icon.select-open:hover,
@@ -124,7 +125,7 @@ export class Select extends FormElement {
124
125
  flex-direction: row;
125
126
  align-items: stretch;
126
127
  user-select: none;
127
- padding: var(--temba-select-selected-padding);
128
+ padding: var(--temba-select-selected-padding, 0px 4px);
128
129
  }
129
130
 
130
131
  .searchable .selected {
@@ -183,6 +184,18 @@ export class Select extends FormElement {
183
184
  background: rgba(100, 100, 100, 0.3);
184
185
  }
185
186
 
187
+ .multi .selected-item.sortable {
188
+ cursor: move;
189
+ }
190
+
191
+ .multi .selected-item.dragging {
192
+ opacity: 0.5;
193
+ }
194
+
195
+ .multi temba-sortable-list {
196
+ margin: 0 !important;
197
+ }
198
+
186
199
  input {
187
200
  font-size: 13px;
188
201
  width: 0px;
@@ -201,16 +214,15 @@ export class Select extends FormElement {
201
214
  border: 0px solid purple !important;
202
215
  }
203
216
 
204
- .input-wrapper {
205
- min-width: 1px;
206
- }
207
-
208
217
  .input-wrapper:focus-within {
209
218
  min-width: 1px;
210
219
  }
211
220
 
212
221
  .input-wrapper {
222
+ min-width: 1px;
213
223
  margin-left: 6px;
224
+ margin-right: -6px;
225
+ display: flex;
214
226
  }
215
227
 
216
228
  .multi .input-wrapper {
@@ -250,9 +262,9 @@ export class Select extends FormElement {
250
262
  box-shadow: none !important;
251
263
  }
252
264
 
253
- .input-wrapper {
254
- display: flex;
255
- margin-right: 0em;
265
+ .multi .input-wrapper {
266
+ flex-shrink: 0;
267
+ min-width: 100px;
256
268
  }
257
269
 
258
270
  .input-wrapper .searchbox {
@@ -267,6 +279,7 @@ export class Select extends FormElement {
267
279
  color: var(--color-placeholder);
268
280
  display: none;
269
281
  line-height: var(--temba-select-selected-line-height);
282
+ margin-left: 6px;
270
283
  }
271
284
 
272
285
  .footer {
@@ -308,6 +321,10 @@ export class Select extends FormElement {
308
321
  pointer-events: none;
309
322
  padding: 0px;
310
323
  }
324
+
325
+ .ghost .remove-item {
326
+ display: none !important;
327
+ }
311
328
  `;
312
329
  }
313
330
  constructor() {
@@ -368,6 +385,7 @@ export class Select extends FormElement {
368
385
  this.renderSelectedItemDefault = this.renderSelectedItemDefault.bind(this);
369
386
  this.prepareOptionsDefault = this.prepareOptionsDefault.bind(this);
370
387
  this.isMatchDefault = this.isMatchDefault.bind(this);
388
+ this.handleOrderChanged = this.handleOrderChanged.bind(this);
371
389
  }
372
390
  prepareOptionsDefault(options) {
373
391
  return options;
@@ -1032,8 +1050,12 @@ export class Select extends FormElement {
1032
1050
  this.cursorIndex = event.detail.index;
1033
1051
  }
1034
1052
  handleContainerClick(event) {
1035
- event.stopPropagation();
1036
- event.preventDefault();
1053
+ if (this.disabled) {
1054
+ // prevent opening dropdown right after drag-and-drop
1055
+ event.stopPropagation();
1056
+ event.preventDefault();
1057
+ return;
1058
+ }
1037
1059
  this.focused = true;
1038
1060
  if (event.target.tagName !== 'INPUT') {
1039
1061
  const input = this.shadowRoot.querySelector('input');
@@ -1067,6 +1089,9 @@ export class Select extends FormElement {
1067
1089
  ];
1068
1090
  }
1069
1091
  handleArrowClick(event) {
1092
+ if (this.disabled) {
1093
+ return;
1094
+ }
1070
1095
  if (this.isOpen()) {
1071
1096
  event.preventDefault();
1072
1097
  event.stopPropagation();
@@ -1080,7 +1105,16 @@ export class Select extends FormElement {
1080
1105
  // special case for icons on any option type
1081
1106
  const icon = option.icon;
1082
1107
  return html `
1083
- <div class="option-name" style="display:flex">
1108
+ <div
1109
+ class="option-name"
1110
+ style="flex: 1 1 auto;
1111
+ align-self: center;
1112
+ white-space: nowrap;
1113
+ overflow: hidden;
1114
+ text-overflow: ellipsis;
1115
+ padding: 2px 8px;
1116
+ display: flex;"
1117
+ >
1084
1118
  ${icon
1085
1119
  ? html `<temba-icon
1086
1120
  name="${icon}"
@@ -1138,6 +1172,17 @@ export class Select extends FormElement {
1138
1172
  const idx = this.values.indexOf(valueToRemove);
1139
1173
  if (idx > -1) {
1140
1174
  this.values.splice(idx, 1);
1175
+ // Also remove the 'selected' attribute from the corresponding temba-option element
1176
+ const valueToMatch = this.getValue(valueToRemove);
1177
+ for (const child of this.children) {
1178
+ if (child.tagName === 'TEMBA-OPTION') {
1179
+ const childValue = child.getAttribute('value');
1180
+ if (childValue === valueToMatch) {
1181
+ child.removeAttribute('selected');
1182
+ break;
1183
+ }
1184
+ }
1185
+ }
1141
1186
  }
1142
1187
  this.requestUpdate('values', oldValues);
1143
1188
  this.infoText = '';
@@ -1161,6 +1206,25 @@ export class Select extends FormElement {
1161
1206
  this.staticOptions.length === 0 &&
1162
1207
  !this.endpoint);
1163
1208
  }
1209
+ handleOrderChanged(event) {
1210
+ const detail = event.detail;
1211
+ // Handle new swap-based format
1212
+ if (detail.swap && Array.isArray(detail.swap) && detail.swap.length === 2) {
1213
+ const [fromIdx, toIdx] = detail.swap;
1214
+ // Only reorder if the indexes are different and valid
1215
+ if (fromIdx !== toIdx &&
1216
+ fromIdx >= 0 &&
1217
+ toIdx >= 0 &&
1218
+ fromIdx < this.values.length &&
1219
+ toIdx < this.values.length) {
1220
+ const oldValues = [...this.values];
1221
+ // Move the item from fromIdx to toIdx
1222
+ const movedItem = this.values.splice(fromIdx, 1)[0];
1223
+ this.values.splice(toIdx, 0, movedItem);
1224
+ this.requestUpdate('values', oldValues);
1225
+ }
1226
+ }
1227
+ }
1164
1228
  render() {
1165
1229
  const placeholder = this.values.length === 0 ? this.placeholder : '';
1166
1230
  const placeholderDiv = html `
@@ -1237,33 +1301,126 @@ export class Select extends FormElement {
1237
1301
  ></temba-loading>`
1238
1302
  : null}
1239
1303
  ${!this.multi && !this.resolving ? input : null}
1240
- ${this.values.map((selected, index) => html `
1241
- <div
1242
- class="selected-item ${index === this.selectedIndex
1243
- ? 'focused'
1244
- : ''}"
1245
- >
1246
- ${this.multi
1304
+ ${this.multi && this.values.length > 1
1247
1305
  ? html `
1248
- <div
1249
- class="remove-item"
1250
- style="margin-top:1px"
1251
- @click=${(evt) => {
1252
- evt.preventDefault();
1253
- evt.stopPropagation();
1254
- this.handleRemoveSelection(selected);
1306
+ <temba-sortable-list
1307
+ horizontal
1308
+ @temba-order-changed=${this.handleOrderChanged}
1309
+ .prepareGhost=${(item) => {
1310
+ item.style.transform = 'scale(1)';
1311
+ item.querySelector('.remove-item').style.display =
1312
+ 'none';
1255
1313
  }}
1256
- >
1257
- <temba-icon
1258
- name="${Icon.delete_small}"
1259
- size="1"
1260
- ></temba-icon>
1261
- </div>
1262
- `
1263
- : null}
1264
- ${this.renderSelectedItem(selected)}
1265
- </div>
1266
- `)}
1314
+ >
1315
+ ${this.values.map((selected, index) => html `
1316
+ <div
1317
+ class="selected-item sortable ${index ===
1318
+ this.selectedIndex
1319
+ ? 'focused'
1320
+ : ''} ${this.draggingId === `selected-${index}`
1321
+ ? 'dragging'
1322
+ : ''}"
1323
+ id="selected-${index}"
1324
+ style="
1325
+ vertical-align: middle;
1326
+ background: rgba(100,100,100,0.1);
1327
+ user-select: none;
1328
+ border-radius: 2px;
1329
+ align-items: center;
1330
+ flex-direction: row;
1331
+ flex-wrap: nowrap;
1332
+ margin: 2px 2px;
1333
+ display: flex;
1334
+ overflow: hidden;
1335
+ color: var(--color-widget-text);
1336
+ line-height: var(--temba-select-selected-line-height);
1337
+ --icon-color: var(--color-text-dark);
1338
+ ${index === this.selectedIndex
1339
+ ? 'background: rgba(100,100,100,0.3);'
1340
+ : ''}
1341
+ ${this.draggingId === `selected-${index}`
1342
+ ? 'opacity: 0.5;'
1343
+ : ''}
1344
+ "
1345
+ >
1346
+ ${this.multi
1347
+ ? html `
1348
+ <div
1349
+ class="remove-item"
1350
+ style="
1351
+ cursor: pointer;
1352
+ display: inline-block;
1353
+ padding: 3px 6px;
1354
+ border-right: 1px solid rgba(100,100,100,0.2);
1355
+ margin: 0;
1356
+ background: rgba(100,100,100,0.05);
1357
+ margin-top:1px;
1358
+ "
1359
+ @click=${(evt) => {
1360
+ evt.preventDefault();
1361
+ evt.stopPropagation();
1362
+ this.handleRemoveSelection(selected);
1363
+ }}
1364
+ >
1365
+ <temba-icon
1366
+ name="${Icon.delete_small}"
1367
+ size="1"
1368
+ ></temba-icon>
1369
+ </div>
1370
+ `
1371
+ : null}
1372
+ ${this.renderSelectedItem(selected)}
1373
+ </div>
1374
+ `)}
1375
+ </temba-sortable-list>
1376
+ `
1377
+ : this.values.map((selected, index) => html `
1378
+ <div
1379
+ class="selected-item ${index === this.selectedIndex
1380
+ ? 'focused'
1381
+ : ''}"
1382
+ style="
1383
+ display: flex;
1384
+ overflow: hidden;
1385
+ color: var(--color-widget-text);
1386
+ line-height: var(--temba-select-selected-line-height);
1387
+ --icon-color: var(--color-text-dark);
1388
+ ${index === this.selectedIndex
1389
+ ? 'background: rgba(100,100,100,0.3);'
1390
+ : ''}
1391
+ "
1392
+ >
1393
+ ${this.multi
1394
+ ? html `
1395
+ <div
1396
+ class="remove-item"
1397
+ style="
1398
+ cursor: pointer;
1399
+ display: inline-block;
1400
+ padding: 3px 6px;
1401
+ border-right: 1px solid rgba(100,100,100,0.2);
1402
+ margin: 0;
1403
+ background: rgba(100,100,100,0.05);
1404
+ margin-top:1px;
1405
+ "
1406
+ @click=${(evt) => {
1407
+ evt.preventDefault();
1408
+ evt.stopPropagation();
1409
+ this.handleRemoveSelection(selected);
1410
+ }}
1411
+ >
1412
+ <temba-icon
1413
+ name="${Icon.delete_small}"
1414
+ size="1"
1415
+ ></temba-icon>
1416
+ </div>
1417
+ `
1418
+ : null}
1419
+ ${!this.input
1420
+ ? this.renderSelectedItem(selected)
1421
+ : null}
1422
+ </div>
1423
+ `)}
1267
1424
  ${this.multi ? input : null}
1268
1425
  </div>
1269
1426
 
@@ -1509,4 +1666,7 @@ __decorate([
1509
1666
  __decorate([
1510
1667
  property({ type: Boolean })
1511
1668
  ], Select.prototype, "allowAnchor", void 0);
1669
+ __decorate([
1670
+ property({ type: String })
1671
+ ], Select.prototype, "draggingId", void 0);
1512
1672
  //# sourceMappingURL=Select.js.map