@nyaruka/temba-components 0.141.1 → 0.142.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.
- package/CHANGELOG.md +15 -0
- package/dist/static/svg/index.svg +1 -1
- package/dist/temba-components.js +849 -655
- package/dist/temba-components.js.map +1 -1
- package/out-tsc/src/Icons.js +3 -1
- package/out-tsc/src/Icons.js.map +1 -1
- package/out-tsc/src/display/Button.js +2 -2
- package/out-tsc/src/display/Button.js.map +1 -1
- package/out-tsc/src/display/FloatingTab.js.map +1 -1
- package/out-tsc/src/flow/CanvasMenu.js +24 -1
- package/out-tsc/src/flow/CanvasMenu.js.map +1 -1
- package/out-tsc/src/flow/CanvasNode.js +7 -2
- package/out-tsc/src/flow/CanvasNode.js.map +1 -1
- package/out-tsc/src/flow/Editor.js +654 -66
- package/out-tsc/src/flow/Editor.js.map +1 -1
- package/out-tsc/src/flow/NodeEditor.js +8 -5
- package/out-tsc/src/flow/NodeEditor.js.map +1 -1
- package/out-tsc/src/flow/Plumber.js +40 -28
- package/out-tsc/src/flow/Plumber.js.map +1 -1
- package/out-tsc/src/flow/actions/send_msg.js +2 -1
- package/out-tsc/src/flow/actions/send_msg.js.map +1 -1
- package/out-tsc/src/flow/nodes/wait_for_response.js +1 -1
- package/out-tsc/src/flow/nodes/wait_for_response.js.map +1 -1
- package/out-tsc/src/flow/reflow.js +393 -0
- package/out-tsc/src/flow/reflow.js.map +1 -0
- package/out-tsc/src/flow/types.js.map +1 -1
- package/out-tsc/src/flow/utils.js +18 -3
- package/out-tsc/src/flow/utils.js.map +1 -1
- package/out-tsc/src/form/Compose.js +5 -0
- package/out-tsc/src/form/Compose.js.map +1 -1
- package/out-tsc/src/form/FieldRenderer.js +1 -3
- package/out-tsc/src/form/FieldRenderer.js.map +1 -1
- package/out-tsc/src/layout/Dialog.js +2 -0
- package/out-tsc/src/layout/Dialog.js.map +1 -1
- package/out-tsc/src/list/SortableList.js +39 -19
- package/out-tsc/src/list/SortableList.js.map +1 -1
- package/out-tsc/test/temba-canvas-menu.test.js +44 -0
- package/out-tsc/test/temba-canvas-menu.test.js.map +1 -1
- package/out-tsc/test/temba-flow-collision.test.js +25 -0
- package/out-tsc/test/temba-flow-collision.test.js.map +1 -1
- package/out-tsc/test/temba-flow-editor-zoom.test.js +491 -0
- package/out-tsc/test/temba-flow-editor-zoom.test.js.map +1 -0
- package/out-tsc/test/temba-flow-editor.test.js +145 -1
- package/out-tsc/test/temba-flow-editor.test.js.map +1 -1
- package/out-tsc/test/temba-flow-node-drag.test.js +123 -0
- package/out-tsc/test/temba-flow-node-drag.test.js.map +1 -1
- package/out-tsc/test/temba-flow-plumber.test.js +31 -0
- package/out-tsc/test/temba-flow-plumber.test.js.map +1 -1
- package/out-tsc/test/temba-flow-reflow.test.js +472 -0
- package/out-tsc/test/temba-flow-reflow.test.js.map +1 -0
- package/out-tsc/test/temba-sortable-list.test.js +93 -0
- package/out-tsc/test/temba-sortable-list.test.js.map +1 -1
- package/package.json +1 -1
- package/screenshots/truth/actions/add_contact_groups/editor/descriptive-group-names.png +0 -0
- package/screenshots/truth/actions/add_contact_groups/editor/long-group-names.png +0 -0
- package/screenshots/truth/actions/add_contact_groups/editor/many-groups.png +0 -0
- package/screenshots/truth/actions/add_contact_urn/editor/expression-facebook.png +0 -0
- package/screenshots/truth/actions/add_contact_urn/editor/expression-phone.png +0 -0
- package/screenshots/truth/actions/add_contact_urn/editor/facebook-id.png +0 -0
- package/screenshots/truth/actions/add_contact_urn/editor/instagram-handle.png +0 -0
- package/screenshots/truth/actions/add_contact_urn/editor/line-id.png +0 -0
- package/screenshots/truth/actions/add_contact_urn/editor/phone-number.png +0 -0
- package/screenshots/truth/actions/add_contact_urn/editor/telegram-id.png +0 -0
- package/screenshots/truth/actions/add_contact_urn/editor/viber-id.png +0 -0
- package/screenshots/truth/actions/add_contact_urn/editor/wechat-id.png +0 -0
- package/screenshots/truth/actions/add_contact_urn/editor/whatsapp.png +0 -0
- package/screenshots/truth/actions/enter_flow/editor/basic-flow.png +0 -0
- package/screenshots/truth/actions/enter_flow/editor/long-flow-name.png +0 -0
- package/screenshots/truth/actions/remove_contact_groups/editor/long-descriptive-group-names.png +0 -0
- package/screenshots/truth/actions/remove_contact_groups/editor/many-groups.png +0 -0
- package/screenshots/truth/actions/say_msg/editor/multiline-text.png +0 -0
- package/screenshots/truth/actions/say_msg/editor/simple-text.png +0 -0
- package/screenshots/truth/actions/say_msg/editor/text-with-audio-url.png +0 -0
- package/screenshots/truth/actions/send_broadcast/editor/contacts-only.png +0 -0
- package/screenshots/truth/actions/send_broadcast/editor/groups-and-contacts.png +0 -0
- package/screenshots/truth/actions/send_broadcast/editor/groups-only.png +0 -0
- package/screenshots/truth/actions/send_broadcast/editor/many-groups.png +0 -0
- package/screenshots/truth/actions/send_broadcast/editor/multiline-text.png +0 -0
- package/screenshots/truth/actions/send_email/editor/empty-body.png +0 -0
- package/screenshots/truth/actions/send_email/editor/empty-subject.png +0 -0
- package/screenshots/truth/actions/send_email/editor/long-subject.png +0 -0
- package/screenshots/truth/actions/send_email/editor/multiline-body.png +0 -0
- package/screenshots/truth/actions/send_email/editor/multiple-recipients.png +0 -0
- package/screenshots/truth/actions/send_email/editor/simple-email.png +0 -0
- package/screenshots/truth/actions/send_email/editor/with-expressions.png +0 -0
- package/screenshots/truth/actions/send_msg/editor/long-quick-replies.png +0 -0
- package/screenshots/truth/actions/send_msg/editor/multiline-text-with-replies.png +0 -0
- package/screenshots/truth/actions/send_msg/editor/simple-text.png +0 -0
- package/screenshots/truth/actions/send_msg/editor/text-with-linebreaks.png +0 -0
- package/screenshots/truth/actions/send_msg/editor/text-with-many-quick-replies.png +0 -0
- package/screenshots/truth/actions/send_msg/editor/text-with-quick-replies.png +0 -0
- package/screenshots/truth/actions/send_msg/editor/text-without-quick-replies.png +0 -0
- package/screenshots/truth/actions/set_contact_channel/editor/sms-channel.png +0 -0
- package/screenshots/truth/actions/set_contact_channel/editor/whatsapp-channel.png +0 -0
- package/screenshots/truth/actions/set_contact_field/editor/clear-value.png +0 -0
- package/screenshots/truth/actions/set_contact_field/editor/set-value.png +0 -0
- package/screenshots/truth/actions/set_contact_language/editor/english.png +0 -0
- package/screenshots/truth/actions/set_contact_language/editor/french.png +0 -0
- package/screenshots/truth/actions/set_contact_status/editor/active.png +0 -0
- package/screenshots/truth/actions/set_contact_status/editor/archived.png +0 -0
- package/screenshots/truth/actions/set_contact_status/editor/blocked.png +0 -0
- package/screenshots/truth/actions/set_run_result/editor/expression-value.png +0 -0
- package/screenshots/truth/actions/set_run_result/editor/with-category.png +0 -0
- package/screenshots/truth/actions/start_session/editor/contact-query.png +0 -0
- package/screenshots/truth/actions/start_session/editor/contacts-only.png +0 -0
- package/screenshots/truth/actions/start_session/editor/create-contact.png +0 -0
- package/screenshots/truth/actions/start_session/editor/groups-and-contacts.png +0 -0
- package/screenshots/truth/actions/start_session/editor/groups-only.png +0 -0
- package/screenshots/truth/actions/start_session/editor/many-recipients.png +0 -0
- package/screenshots/truth/list/fields-dragging.png +0 -0
- package/screenshots/truth/list/sortable-dragging.png +0 -0
- package/screenshots/truth/modax/simple.png +0 -0
- package/screenshots/truth/nodes/split_by_llm/editor/information-extraction.png +0 -0
- package/screenshots/truth/nodes/split_by_llm/editor/sentiment-analysis.png +0 -0
- package/screenshots/truth/nodes/split_by_llm/editor/summarization.png +0 -0
- package/screenshots/truth/nodes/split_by_llm/editor/translation-task.png +0 -0
- package/screenshots/truth/nodes/split_by_llm_categorize/editor/basic-categorization.png +0 -0
- package/screenshots/truth/nodes/split_by_llm_categorize/editor/custom-input-and-result-name.png +0 -0
- package/screenshots/truth/nodes/split_by_llm_categorize/editor/feedback-categorization.png +0 -0
- package/screenshots/truth/nodes/split_by_llm_categorize/editor/many-categories.png +0 -0
- package/screenshots/truth/nodes/split_by_llm_categorize/editor/minimal-categories.png +0 -0
- package/screenshots/truth/nodes/split_by_random/editor/ab-test-multiple-variants.png +0 -0
- package/screenshots/truth/nodes/split_by_random/editor/sampling-split.png +0 -0
- package/screenshots/truth/nodes/split_by_random/editor/three-way-split.png +0 -0
- package/screenshots/truth/nodes/split_by_random/editor/two-bucket-split.png +0 -0
- package/screenshots/truth/nodes/wait_for_dial/editor/dial-with-limits.png +0 -0
- package/screenshots/truth/nodes/wait_for_digits/editor/basic-digits-wait.png +0 -0
- package/screenshots/truth/nodes/wait_for_digits/editor/digits-with-rules.png +0 -0
- package/screenshots/truth/nodes/wait_for_menu/editor/menu-with-digits.png +0 -0
- package/screenshots/truth/nodes/wait_for_response/editor/basic-wait.png +0 -0
- package/screenshots/truth/nodes/wait_for_response/editor/custom-result-name.png +0 -0
- package/screenshots/truth/nodes/wait_for_response/editor/no-timeout.png +0 -0
- package/screenshots/truth/nodes/wait_for_response/editor/short-timeout.png +0 -0
- package/src/Icons.ts +3 -1
- package/src/display/Button.ts +2 -2
- package/src/display/FloatingTab.ts +1 -1
- package/src/flow/CanvasMenu.ts +28 -3
- package/src/flow/CanvasNode.ts +7 -2
- package/src/flow/Editor.ts +755 -75
- package/src/flow/NodeEditor.ts +8 -4
- package/src/flow/Plumber.ts +65 -35
- package/src/flow/actions/send_msg.ts +2 -1
- package/src/flow/nodes/wait_for_response.ts +1 -1
- package/src/flow/reflow.ts +534 -0
- package/src/flow/types.ts +1 -0
- package/src/flow/utils.ts +19 -3
- package/src/form/Compose.ts +5 -0
- package/src/form/FieldRenderer.ts +1 -3
- package/src/layout/Dialog.ts +2 -0
- package/src/list/SortableList.ts +40 -19
- package/static/svg/index.svg +1 -1
- package/static/svg/work/traced/expand-06.svg +1 -0
- package/static/svg/work/used/expand-06.svg +3 -0
- package/test/temba-canvas-menu.test.ts +55 -0
- package/test/temba-flow-collision.test.ts +31 -0
- package/test/temba-flow-editor-zoom.test.ts +583 -0
- package/test/temba-flow-editor.test.ts +187 -1
- package/test/temba-flow-node-drag.test.ts +171 -0
- package/test/temba-flow-plumber.test.ts +38 -0
- package/test/temba-flow-reflow.test.ts +703 -0
- package/test/temba-sortable-list.test.ts +120 -0
- package/screenshots/truth/actions/call_llm/editor/information-extraction.png +0 -0
- package/screenshots/truth/actions/call_llm/editor/sentiment-analysis.png +0 -0
- package/screenshots/truth/actions/call_llm/editor/summarization.png +0 -0
- package/screenshots/truth/actions/call_llm/editor/translation-task.png +0 -0
- package/screenshots/truth/actions/call_llm/render/information-extraction.png +0 -0
- package/screenshots/truth/actions/call_llm/render/sentiment-analysis.png +0 -0
- package/screenshots/truth/actions/call_llm/render/summarization.png +0 -0
- package/screenshots/truth/actions/call_llm/render/translation-task.png +0 -0
- package/screenshots/truth/actions/send_broadcast/editor/with-attachments.png +0 -0
- package/screenshots/truth/actions/send_broadcast/render/with-attachments.png +0 -0
- package/screenshots/truth/compose/attachments-with-failures.png +0 -0
- package/screenshots/truth/compose/attachments-with-files-and-failures.png +0 -0
- package/screenshots/truth/contacts/tickets-assignment.png +0 -0
- package/screenshots/truth/contacts/tickets.png +0 -0
- package/screenshots/truth/flow/editor-basic.png +0 -0
- package/screenshots/truth/formfield/markdown-errors.png +0 -0
- package/screenshots/truth/formfield/no-errors.png +0 -0
- package/screenshots/truth/formfield/plain-text-errors.png +0 -0
- package/screenshots/truth/formfield/widget-only-markdown-errors.png +0 -0
- package/screenshots/truth/omnibox/selected.png +0 -0
- package/screenshots/truth/select/enabled-multi-selection.png +0 -0
- package/screenshots/truth/select/endpoint-initial-value-updated.png +0 -0
- package/screenshots/truth/select/endpoint-initial-value.png +0 -0
- package/screenshots/truth/select/initial-value.png +0 -0
- package/screenshots/truth/select/multi-reorder-final.png +0 -0
- package/screenshots/truth/select/multi-reorder-initial.png +0 -0
- package/screenshots/truth/select/selected-multi-test.png +0 -0
- package/screenshots/truth/select/value-initial.png +0 -0
- package/screenshots/truth/wait-for-response/rules-editor.png +0 -0
- package/screenshots/truth/wait-for-response/timeout-editor-unchecked.png +0 -0
- package/screenshots/truth/wait-for-response/timeout-editor.png +0 -0
- package/screenshots/truth/webchat/connecting-state.png +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FieldRenderer.js","sourceRoot":"","sources":["../../../src/form/FieldRenderer.ts"],"names":[],"mappings":"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","sourcesContent":["import { html, TemplateResult } from 'lit';\nimport { spread } from '@open-wc/lit-helpers';\nimport {\n FieldConfig,\n TextFieldConfig,\n TextareaFieldConfig,\n SelectFieldConfig,\n CheckboxFieldConfig,\n MessageEditorFieldConfig,\n KeyValueFieldConfig,\n ArrayFieldConfig,\n MediaFieldConfig\n} from '../flow/types';\nimport { Attachment } from '../interfaces';\nimport { DEFAULT_MEDIA_ENDPOINT } from '../utils';\n\n/**\n * FieldRenderer provides a consistent way to render field configurations\n * into web components across different contexts (NodeEditor, ArrayEditor, etc.)\n */\nexport class FieldRenderer {\n /**\n * Renders a field based on its configuration\n * @param fieldName - The name of the field\n * @param config - The field configuration\n * @param value - The current value of the field\n * @param context - Additional context for rendering\n * @returns A TemplateResult for the rendered field\n */\n static renderField(\n fieldName: string,\n config: FieldConfig,\n value: any,\n context: FieldRenderContext = {}\n ): TemplateResult {\n /*const {\n errors = [],\n onChange,\n showLabel = true,\n flavor,\n extraClasses = '',\n style = ''\n } = context;*/\n switch (config.type) {\n case 'text':\n return FieldRenderer.renderTextInput(fieldName, config, value, context);\n\n case 'textarea':\n return FieldRenderer.renderTextarea(\n fieldName,\n config as TextareaFieldConfig,\n value,\n context\n );\n\n case 'select':\n return FieldRenderer.renderSelect(\n fieldName,\n config as SelectFieldConfig,\n value,\n context\n );\n\n case 'checkbox':\n return FieldRenderer.renderCheckbox(\n fieldName,\n config as CheckboxFieldConfig,\n value,\n context\n );\n\n case 'key-value':\n return FieldRenderer.renderKeyValue(\n fieldName,\n config as KeyValueFieldConfig,\n value,\n context\n );\n\n case 'array':\n return FieldRenderer.renderArray(\n fieldName,\n config as ArrayFieldConfig,\n value,\n context\n );\n\n case 'message-editor':\n return FieldRenderer.renderMessageEditor(\n fieldName,\n config as MessageEditorFieldConfig,\n value,\n context\n );\n\n case 'media':\n return FieldRenderer.renderMedia(\n fieldName,\n config as MediaFieldConfig,\n value,\n context\n );\n\n default:\n return html`<div>Unsupported field type: ${(config as any).type}</div>`;\n }\n }\n\n private static renderTextInput(\n fieldName: string,\n config: TextFieldConfig,\n value: any,\n context: FieldRenderContext\n ): TemplateResult {\n const {\n errors = [],\n onChange,\n showLabel = true,\n extraClasses,\n style\n } = context;\n\n // If field supports expression evaluation, use temba-completion\n if (config.evaluated) {\n return html`<temba-completion\n name=\"${fieldName}\"\n label=\"${showLabel ? config.label : ''}\"\n ?required=\"${config.required}\"\n .errors=\"${errors}\"\n .value=\"${value || ''}\"\n placeholder=\"${config.placeholder || ''}\"\n expressions=\"session\"\n .helpText=\"${config.helpText || ''}\"\n class=\"${extraClasses}\"\n style=\"${style}\"\n @input=\"${onChange || (() => {})}\"\n ></temba-completion>`;\n }\n\n return html`<temba-textinput\n name=\"${fieldName}\"\n label=\"${showLabel ? config.label : ''}\"\n ?required=\"${config.required}\"\n .errors=\"${errors}\"\n .value=\"${value || ''}\"\n placeholder=\"${config.placeholder || ''}\"\n .helpText=\"${config.helpText || ''}\"\n flavor=\"${config.flavor || 'default'}\"\n class=\"${extraClasses}\"\n style=\"${style}\"\n @input=\"${onChange || (() => {})}\"\n ></temba-textinput>`;\n }\n\n private static renderTextarea(\n fieldName: string,\n config: TextareaFieldConfig,\n value: any,\n context: FieldRenderContext\n ): TemplateResult {\n const {\n errors = [],\n onChange,\n showLabel = true,\n extraClasses,\n style\n } = context;\n\n const minHeightStyle = config.minHeight\n ? `--textarea-min-height: ${config.minHeight}px;`\n : '';\n const combinedStyle = `${minHeightStyle}${style}`;\n\n // If field supports expression evaluation, use temba-completion\n if (config.evaluated) {\n return html`<temba-completion\n name=\"${fieldName}\"\n label=\"${showLabel ? config.label : ''}\"\n ?required=\"${config.required}\"\n .errors=\"${errors}\"\n .value=\"${value || ''}\"\n placeholder=\"${config.placeholder || ''}\"\n textarea\n expressions=\"session\"\n .helpText=\"${config.helpText || ''}\"\n class=\"${extraClasses}\"\n style=\"${combinedStyle}\"\n @input=\"${onChange || (() => {})}\"\n ></temba-completion>`;\n }\n\n return html`<temba-textinput\n name=\"${fieldName}\"\n label=\"${showLabel ? config.label : ''}\"\n ?required=\"${config.required}\"\n .errors=\"${errors}\"\n .value=\"${value || ''}\"\n placeholder=\"${config.placeholder || ''}\"\n textarea\n .rows=\"${config.rows || 3}\"\n .helpText=\"${config.helpText || ''}\"\n class=\"${extraClasses}\"\n style=\"${combinedStyle}\"\n @input=\"${onChange || (() => {})}\"\n ></temba-textinput>`;\n }\n\n private static renderSelect(\n fieldName: string,\n config: SelectFieldConfig,\n value: any,\n context: FieldRenderContext\n ): TemplateResult {\n const {\n errors = [],\n onChange,\n showLabel = true,\n flavor,\n extraClasses,\n style\n } = context;\n\n // Get options - use dynamic options if available, otherwise use static options\n const optionsToRender = config.getDynamicOptions\n ? config.getDynamicOptions()\n : config.options;\n\n return html`<temba-select\n name=\"${fieldName}\"\n label=\"${showLabel ? config.label : ''}\"\n ?required=\"${config.required}\"\n .errors=\"${errors}\"\n .values=${value}\n ?multi=\"${config.multi}\"\n ?searchable=\"${config.searchable}\"\n ?tags=\"${config.tags}\"\n ?emails=\"${config.emails}\"\n ?clearable=\"${config.clearable || false}\"\n placeholder=\"${config.placeholder || ''}\"\n maxItems=\"${config.maxItems || 0}\"\n valueKey=\"${config.valueKey || 'value'}\"\n nameKey=\"${config.nameKey || 'name'}\"\n endpoint=\"${config.endpoint || ''}\"\n .helpText=\"${config.helpText || ''}\"\n flavor=\"${flavor || config.flavor || 'small'}\"\n class=\"${extraClasses}\"\n style=\"${style}\"\n .getName=${config.getName}\n .createArbitraryOption=${config.createArbitraryOption}\n ?allowCreate=\"${config.allowCreate || false}\"\n @change=\"${onChange || (() => {})}\"\n >\n ${optionsToRender?.map((option: any) => {\n if (typeof option === 'string') {\n return html`<temba-option\n name=\"${option}\"\n value=\"${option}\"\n ></temba-option>`;\n } else {\n return html`<temba-option ${spread(option)}></temba-option>`;\n }\n })}\n </temba-select>`;\n }\n\n private static renderCheckbox(\n fieldName: string,\n config: CheckboxFieldConfig,\n value: any,\n context: FieldRenderContext\n ): TemplateResult {\n const {\n errors = [],\n onChange,\n extraClasses,\n style,\n formData = {}\n } = context;\n\n // Handle dynamic labels\n const label =\n typeof config.label === 'function'\n ? config.label(formData)\n : config.label;\n\n // Build custom style including labelPadding\n const customStyle = config.labelPadding\n ? `--checkbox-padding: ${config.labelPadding}; ${style || ''}`\n : style || '';\n\n return html`<div class=\"form-field\">\n <temba-checkbox\n name=\"${fieldName}\"\n label=\"${label}\"\n .helpText=\"${config.helpText || ''}\"\n ?required=\"${config.required}\"\n .errors=\"${errors}\"\n ?checked=\"${value || false}\"\n size=\"${config.size || 1.2}\"\n animateChange=\"${config.animateChange || 'pulse'}\"\n class=\"${extraClasses}\"\n style=\"${customStyle}\"\n @change=\"${onChange || (() => {})}\"\n ></temba-checkbox>\n ${errors.length\n ? html`<div class=\"field-errors\">${errors.join(', ')}</div>`\n : ''}\n </div>`;\n }\n\n private static renderKeyValue(\n fieldName: string,\n config: KeyValueFieldConfig,\n value: any,\n context: FieldRenderContext\n ): TemplateResult {\n const {\n errors = [],\n onChange,\n showLabel = true,\n extraClasses,\n style\n } = context;\n\n return html`<div class=\"form-field\">\n ${showLabel ? html`<label>${config.label}</label>` : ''}\n <temba-key-value-editor\n name=\"${fieldName}\"\n .value=\"${value || []}\"\n .sortable=\"${config.sortable}\"\n .keyPlaceholder=\"${config.keyPlaceholder || 'Key'}\"\n .valuePlaceholder=\"${config.valuePlaceholder || 'Value'}\"\n .minRows=\"${config.minRows || 0}\"\n class=\"${extraClasses}\"\n style=\"${style}\"\n @change=\"${onChange || (() => {})}\"\n ></temba-key-value-editor>\n ${errors.length\n ? html`<div class=\"field-errors\">${errors.join(', ')}</div>`\n : ''}\n </div>`;\n }\n\n private static renderArray(\n fieldName: string,\n config: ArrayFieldConfig,\n value: any,\n context: FieldRenderContext\n ): TemplateResult {\n const {\n errors = [],\n onChange,\n showLabel = true,\n extraClasses,\n style\n } = context;\n\n return html`<div class=\"form-field\">\n ${config.helpText\n ? html`<div\n style=\"color: #666; font-size: 13px; margin-bottom: 14px;\"\n >\n ${config.helpText}\n </div>`\n : ''}\n <temba-array-editor\n name=\"${fieldName}\"\n .label=\"${showLabel ? config.label : ''}\"\n .value=\"${value || []}\"\n .itemConfig=\"${config.itemConfig}\"\n .sortable=\"${config.sortable}\"\n .itemLabel=\"${config.itemLabel || 'Item'}\"\n .minItems=\"${config.minItems || 0}\"\n .maxItems=\"${config.maxItems || 0}\"\n ?maintainEmptyItem=\"${config.maintainEmptyItem !== false}\"\n .onItemChange=\"${config.onItemChange}\"\n .isEmptyItemFn=\"${config.isEmptyItem}\"\n class=\"${extraClasses}\"\n style=\"${style}\"\n @change=\"${onChange || (() => {})}\"\n ></temba-array-editor>\n ${errors.length\n ? html`<div class=\"field-errors\">${errors.join(', ')}</div>`\n : ''}\n </div>`;\n }\n\n private static urlToAttachments(url: string): Attachment[] {\n if (!url || !url.trim()) return [];\n const filename = url.split('/').pop() || 'recording';\n const ext = filename.split('.').pop()?.toLowerCase() || '';\n const contentTypes: Record<string, string> = {\n mp3: 'audio/mpeg',\n wav: 'audio/wav',\n ogg: 'audio/ogg',\n m4a: 'audio/mp4'\n };\n return [\n {\n uuid: '',\n content_type: contentTypes[ext] || 'audio/mpeg',\n url,\n filename,\n size: 0,\n error: ''\n }\n ];\n }\n\n private static renderMedia(\n fieldName: string,\n config: MediaFieldConfig,\n value: any,\n context: FieldRenderContext\n ): TemplateResult {\n const { onChange, showLabel = true } = context;\n const endpoint = config.endpoint || DEFAULT_MEDIA_ENDPOINT;\n const attachments = FieldRenderer.urlToAttachments(value);\n\n return html`\n <div>\n ${showLabel && config.label\n ? html`<label\n style=\"margin-bottom: 5px; margin-left: 4px; display: block; font-weight: 400; font-size: var(--label-size); letter-spacing: 0.05em; line-height: normal; color: var(--color-label, #777);\"\n >${config.label}</label\n >`\n : ''}\n <temba-media-picker\n name=\"${fieldName}\"\n accept=\"${config.accept || ''}\"\n endpoint=\"${endpoint}\"\n max=\"1\"\n .attachments=\"${attachments}\"\n @change=\"${onChange || (() => {})}\"\n ></temba-media-picker>\n </div>\n `;\n }\n\n private static renderMessageEditor(\n fieldName: string,\n config: MessageEditorFieldConfig,\n value: any,\n context: FieldRenderContext\n ): TemplateResult {\n const {\n errors = [],\n onChange,\n showLabel = true,\n extraClasses,\n style,\n additionalData = {}\n } = context;\n\n return html`<temba-message-editor\n name=\"${fieldName}\"\n label=\"${showLabel ? config.label : ''}\"\n ?required=\"${config.required}\"\n .errors=\"${errors}\"\n .value=\"${value || ''}\"\n .attachments=\"${additionalData.attachments || []}\"\n placeholder=\"${config.placeholder || ''}\"\n .helpText=\"${config.helpText || ''}\"\n ?autogrow=\"${config.autogrow}\"\n ?gsm=\"${config.gsm}\"\n ?disableCompletion=\"${config.disableCompletion}\"\n counter=\"${config.counter || ''}\"\n accept=\"${config.accept || ''}\"\n endpoint=\"${config.endpoint || ''}\"\n max-attachments=\"${config.maxAttachments || 3}\"\n minHeight=\"${config.minHeight || 60}\"\n class=\"${extraClasses}\"\n style=\"${style}\"\n @change=\"${onChange || (() => {})}\"\n ></temba-message-editor>`;\n }\n}\n\nexport interface FieldRenderContext {\n /** Array of error messages for the field */\n errors?: string[];\n /** Change event handler */\n onChange?: (event: Event) => void;\n /** Whether to show the field label */\n showLabel?: boolean;\n /** Flavor for components that support it (like temba-select) */\n flavor?: string;\n /** Additional CSS classes to apply */\n extraClasses?: string;\n /** Additional CSS styles to apply */\n style?: string;\n /** Additional data needed for specific field types */\n additionalData?: Record<string, any>;\n /** Form data for dynamic field configurations */\n formData?: Record<string, any>;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"FieldRenderer.js","sourceRoot":"","sources":["../../../src/form/FieldRenderer.ts"],"names":[],"mappings":"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","sourcesContent":["import { html, TemplateResult } from 'lit';\nimport { spread } from '@open-wc/lit-helpers';\nimport {\n FieldConfig,\n TextFieldConfig,\n TextareaFieldConfig,\n SelectFieldConfig,\n CheckboxFieldConfig,\n MessageEditorFieldConfig,\n KeyValueFieldConfig,\n ArrayFieldConfig,\n MediaFieldConfig\n} from '../flow/types';\nimport { Attachment } from '../interfaces';\nimport { DEFAULT_MEDIA_ENDPOINT } from '../utils';\n\n/**\n * FieldRenderer provides a consistent way to render field configurations\n * into web components across different contexts (NodeEditor, ArrayEditor, etc.)\n */\nexport class FieldRenderer {\n /**\n * Renders a field based on its configuration\n * @param fieldName - The name of the field\n * @param config - The field configuration\n * @param value - The current value of the field\n * @param context - Additional context for rendering\n * @returns A TemplateResult for the rendered field\n */\n static renderField(\n fieldName: string,\n config: FieldConfig,\n value: any,\n context: FieldRenderContext = {}\n ): TemplateResult {\n /*const {\n errors = [],\n onChange,\n showLabel = true,\n flavor,\n extraClasses = '',\n style = ''\n } = context;*/\n switch (config.type) {\n case 'text':\n return FieldRenderer.renderTextInput(fieldName, config, value, context);\n\n case 'textarea':\n return FieldRenderer.renderTextarea(\n fieldName,\n config as TextareaFieldConfig,\n value,\n context\n );\n\n case 'select':\n return FieldRenderer.renderSelect(\n fieldName,\n config as SelectFieldConfig,\n value,\n context\n );\n\n case 'checkbox':\n return FieldRenderer.renderCheckbox(\n fieldName,\n config as CheckboxFieldConfig,\n value,\n context\n );\n\n case 'key-value':\n return FieldRenderer.renderKeyValue(\n fieldName,\n config as KeyValueFieldConfig,\n value,\n context\n );\n\n case 'array':\n return FieldRenderer.renderArray(\n fieldName,\n config as ArrayFieldConfig,\n value,\n context\n );\n\n case 'message-editor':\n return FieldRenderer.renderMessageEditor(\n fieldName,\n config as MessageEditorFieldConfig,\n value,\n context\n );\n\n case 'media':\n return FieldRenderer.renderMedia(\n fieldName,\n config as MediaFieldConfig,\n value,\n context\n );\n\n default:\n return html`<div>Unsupported field type: ${(config as any).type}</div>`;\n }\n }\n\n private static renderTextInput(\n fieldName: string,\n config: TextFieldConfig,\n value: any,\n context: FieldRenderContext\n ): TemplateResult {\n const {\n errors = [],\n onChange,\n showLabel = true,\n extraClasses,\n style\n } = context;\n\n // If field supports expression evaluation, use temba-completion\n if (config.evaluated) {\n return html`<temba-completion\n name=\"${fieldName}\"\n label=\"${showLabel ? config.label : ''}\"\n ?required=\"${config.required}\"\n .errors=\"${errors}\"\n .value=\"${value || ''}\"\n placeholder=\"${config.placeholder || ''}\"\n expressions=\"session\"\n .helpText=\"${config.helpText || ''}\"\n class=\"${extraClasses}\"\n style=\"${style}\"\n @input=\"${onChange || (() => {})}\"\n ></temba-completion>`;\n }\n\n return html`<temba-textinput\n name=\"${fieldName}\"\n label=\"${showLabel ? config.label : ''}\"\n ?required=\"${config.required}\"\n .errors=\"${errors}\"\n .value=\"${value || ''}\"\n placeholder=\"${config.placeholder || ''}\"\n .helpText=\"${config.helpText || ''}\"\n flavor=\"${config.flavor || 'default'}\"\n class=\"${extraClasses}\"\n style=\"${style}\"\n @input=\"${onChange || (() => {})}\"\n ></temba-textinput>`;\n }\n\n private static renderTextarea(\n fieldName: string,\n config: TextareaFieldConfig,\n value: any,\n context: FieldRenderContext\n ): TemplateResult {\n const {\n errors = [],\n onChange,\n showLabel = true,\n extraClasses,\n style\n } = context;\n\n const minHeightStyle = config.minHeight\n ? `--textarea-min-height: ${config.minHeight}px;`\n : '';\n const combinedStyle = `${minHeightStyle}${style}`;\n\n // If field supports expression evaluation, use temba-completion\n if (config.evaluated) {\n return html`<temba-completion\n name=\"${fieldName}\"\n label=\"${showLabel ? config.label : ''}\"\n ?required=\"${config.required}\"\n .errors=\"${errors}\"\n .value=\"${value || ''}\"\n placeholder=\"${config.placeholder || ''}\"\n textarea\n expressions=\"session\"\n .helpText=\"${config.helpText || ''}\"\n class=\"${extraClasses}\"\n style=\"${combinedStyle}\"\n @input=\"${onChange || (() => {})}\"\n ></temba-completion>`;\n }\n\n return html`<temba-textinput\n name=\"${fieldName}\"\n label=\"${showLabel ? config.label : ''}\"\n ?required=\"${config.required}\"\n .errors=\"${errors}\"\n .value=\"${value || ''}\"\n placeholder=\"${config.placeholder || ''}\"\n textarea\n .rows=\"${config.rows || 3}\"\n .helpText=\"${config.helpText || ''}\"\n class=\"${extraClasses}\"\n style=\"${combinedStyle}\"\n @input=\"${onChange || (() => {})}\"\n ></temba-textinput>`;\n }\n\n private static renderSelect(\n fieldName: string,\n config: SelectFieldConfig,\n value: any,\n context: FieldRenderContext\n ): TemplateResult {\n const {\n errors = [],\n onChange,\n showLabel = true,\n flavor,\n extraClasses,\n style\n } = context;\n\n // Get options - use dynamic options if available, otherwise use static options\n const optionsToRender = config.getDynamicOptions\n ? config.getDynamicOptions()\n : config.options;\n\n return html`<temba-select\n name=\"${fieldName}\"\n label=\"${showLabel ? config.label : ''}\"\n ?required=\"${config.required}\"\n .errors=\"${errors}\"\n .values=${value}\n ?multi=\"${config.multi}\"\n ?searchable=\"${config.searchable}\"\n ?tags=\"${config.tags}\"\n ?emails=\"${config.emails}\"\n ?clearable=\"${config.clearable || false}\"\n placeholder=\"${config.placeholder || ''}\"\n maxItems=\"${config.maxItems || 0}\"\n valueKey=\"${config.valueKey || 'value'}\"\n nameKey=\"${config.nameKey || 'name'}\"\n endpoint=\"${config.endpoint || ''}\"\n .helpText=\"${config.helpText || ''}\"\n flavor=\"${flavor || config.flavor || 'small'}\"\n class=\"${extraClasses}\"\n style=\"${style}\"\n .getName=${config.getName}\n .createArbitraryOption=${config.createArbitraryOption}\n ?allowCreate=\"${config.allowCreate || false}\"\n @change=\"${onChange || (() => {})}\"\n >\n ${optionsToRender?.map((option: any) => {\n if (typeof option === 'string') {\n return html`<temba-option\n name=\"${option}\"\n value=\"${option}\"\n ></temba-option>`;\n } else {\n return html`<temba-option ${spread(option)}></temba-option>`;\n }\n })}\n </temba-select>`;\n }\n\n private static renderCheckbox(\n fieldName: string,\n config: CheckboxFieldConfig,\n value: any,\n context: FieldRenderContext\n ): TemplateResult {\n const {\n errors = [],\n onChange,\n extraClasses,\n style,\n formData = {}\n } = context;\n\n // Handle dynamic labels\n const label =\n typeof config.label === 'function'\n ? config.label(formData)\n : config.label;\n\n // Build custom style including labelPadding\n const customStyle = config.labelPadding\n ? `--checkbox-padding: ${config.labelPadding}; ${style || ''}`\n : style || '';\n\n return html`<div class=\"form-field\">\n <temba-checkbox\n name=\"${fieldName}\"\n label=\"${label}\"\n .helpText=\"${config.helpText || ''}\"\n ?required=\"${config.required}\"\n .errors=\"${errors}\"\n ?checked=\"${value || false}\"\n size=\"${config.size || 1.2}\"\n animateChange=\"${config.animateChange || 'pulse'}\"\n class=\"${extraClasses}\"\n style=\"${customStyle}\"\n @change=\"${onChange || (() => {})}\"\n ></temba-checkbox>\n ${errors.length\n ? html`<div class=\"field-errors\">${errors.join(', ')}</div>`\n : ''}\n </div>`;\n }\n\n private static renderKeyValue(\n fieldName: string,\n config: KeyValueFieldConfig,\n value: any,\n context: FieldRenderContext\n ): TemplateResult {\n const {\n errors = [],\n onChange,\n showLabel = true,\n extraClasses,\n style\n } = context;\n\n return html`<div class=\"form-field\">\n ${showLabel ? html`<label>${config.label}</label>` : ''}\n <temba-key-value-editor\n name=\"${fieldName}\"\n .value=\"${value || []}\"\n .sortable=\"${config.sortable}\"\n .keyPlaceholder=\"${config.keyPlaceholder || 'Key'}\"\n .valuePlaceholder=\"${config.valuePlaceholder || 'Value'}\"\n .minRows=\"${config.minRows || 0}\"\n class=\"${extraClasses}\"\n style=\"${style}\"\n @change=\"${onChange || (() => {})}\"\n ></temba-key-value-editor>\n ${errors.length\n ? html`<div class=\"field-errors\">${errors.join(', ')}</div>`\n : ''}\n </div>`;\n }\n\n private static renderArray(\n fieldName: string,\n config: ArrayFieldConfig,\n value: any,\n context: FieldRenderContext\n ): TemplateResult {\n const {\n errors = [],\n onChange,\n showLabel = true,\n extraClasses,\n style\n } = context;\n\n return html`<div class=\"form-field\">\n ${config.helpText\n ? html`<div style=\"color: #666; font-size: 13px; margin-bottom: 14px;\">\n ${config.helpText}\n </div>`\n : ''}\n <temba-array-editor\n name=\"${fieldName}\"\n .label=\"${showLabel ? config.label : ''}\"\n .value=\"${value || []}\"\n .itemConfig=\"${config.itemConfig}\"\n .sortable=\"${config.sortable}\"\n .itemLabel=\"${config.itemLabel || 'Item'}\"\n .minItems=\"${config.minItems || 0}\"\n .maxItems=\"${config.maxItems || 0}\"\n ?maintainEmptyItem=\"${config.maintainEmptyItem !== false}\"\n .onItemChange=\"${config.onItemChange}\"\n .isEmptyItemFn=\"${config.isEmptyItem}\"\n class=\"${extraClasses}\"\n style=\"${style}\"\n @change=\"${onChange || (() => {})}\"\n ></temba-array-editor>\n ${errors.length\n ? html`<div class=\"field-errors\">${errors.join(', ')}</div>`\n : ''}\n </div>`;\n }\n\n private static urlToAttachments(url: string): Attachment[] {\n if (!url || !url.trim()) return [];\n const filename = url.split('/').pop() || 'recording';\n const ext = filename.split('.').pop()?.toLowerCase() || '';\n const contentTypes: Record<string, string> = {\n mp3: 'audio/mpeg',\n wav: 'audio/wav',\n ogg: 'audio/ogg',\n m4a: 'audio/mp4'\n };\n return [\n {\n uuid: '',\n content_type: contentTypes[ext] || 'audio/mpeg',\n url,\n filename,\n size: 0,\n error: ''\n }\n ];\n }\n\n private static renderMedia(\n fieldName: string,\n config: MediaFieldConfig,\n value: any,\n context: FieldRenderContext\n ): TemplateResult {\n const { onChange, showLabel = true } = context;\n const endpoint = config.endpoint || DEFAULT_MEDIA_ENDPOINT;\n const attachments = FieldRenderer.urlToAttachments(value);\n\n return html`\n <div>\n ${showLabel && config.label\n ? html`<label\n style=\"margin-bottom: 5px; margin-left: 4px; display: block; font-weight: 400; font-size: var(--label-size); letter-spacing: 0.05em; line-height: normal; color: var(--color-label, #777);\"\n >${config.label}</label\n >`\n : ''}\n <temba-media-picker\n name=\"${fieldName}\"\n accept=\"${config.accept || ''}\"\n endpoint=\"${endpoint}\"\n max=\"1\"\n .attachments=\"${attachments}\"\n @change=\"${onChange || (() => {})}\"\n ></temba-media-picker>\n </div>\n `;\n }\n\n private static renderMessageEditor(\n fieldName: string,\n config: MessageEditorFieldConfig,\n value: any,\n context: FieldRenderContext\n ): TemplateResult {\n const {\n errors = [],\n onChange,\n showLabel = true,\n extraClasses,\n style,\n additionalData = {}\n } = context;\n\n return html`<temba-message-editor\n name=\"${fieldName}\"\n label=\"${showLabel ? config.label : ''}\"\n ?required=\"${config.required}\"\n .errors=\"${errors}\"\n .value=\"${value || ''}\"\n .attachments=\"${additionalData.attachments || []}\"\n placeholder=\"${config.placeholder || ''}\"\n .helpText=\"${config.helpText || ''}\"\n ?autogrow=\"${config.autogrow}\"\n ?gsm=\"${config.gsm}\"\n ?disableCompletion=\"${config.disableCompletion}\"\n counter=\"${config.counter || ''}\"\n accept=\"${config.accept || ''}\"\n endpoint=\"${config.endpoint || ''}\"\n max-attachments=\"${config.maxAttachments || 3}\"\n minHeight=\"${config.minHeight || 60}\"\n class=\"${extraClasses}\"\n style=\"${style}\"\n @change=\"${onChange || (() => {})}\"\n ></temba-message-editor>`;\n }\n}\n\nexport interface FieldRenderContext {\n /** Array of error messages for the field */\n errors?: string[];\n /** Change event handler */\n onChange?: (event: Event) => void;\n /** Whether to show the field label */\n showLabel?: boolean;\n /** Flavor for components that support it (like temba-select) */\n flavor?: string;\n /** Additional CSS classes to apply */\n extraClasses?: string;\n /** Additional CSS styles to apply */\n style?: string;\n /** Additional data needed for specific field types */\n additionalData?: Record<string, any>;\n /** Form data for dynamic field configurations */\n formData?: Record<string, any>;\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Dialog.js","sourceRoot":"","sources":["../../../src/layout/Dialog.ts"],"names":[],"mappings":"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","sourcesContent":["import { property } from 'lit/decorators.js';\nimport { TemplateResult, html, css } from 'lit';\nimport { Button } from '../display/Button';\nimport { CustomEventType } from '../interfaces';\nimport { styleMap } from 'lit-html/directives/style-map.js';\nimport { getClasses } from '../utils';\nimport { ResizeElement } from '../ResizeElement';\n\nexport enum ButtonType {\n PRIMARY = 'primary',\n SECONDARY = 'secondary',\n DESTRUCTIVE = 'destructive'\n}\nexport class DialogButton {\n name?: string;\n id?: string;\n details?: any;\n type?: string;\n closes?: boolean;\n}\n\nexport class Dialog extends ResizeElement {\n static get widths(): { [size: string]: string } {\n return {\n small: '400px',\n medium: '600px',\n large: '655px',\n xlarge: '800px'\n };\n }\n\n static get styles() {\n return css`\n :host {\n position: absolute;\n z-index: 10000;\n font-family: var(--font-family);\n background: white;\n }\n\n .flex-grow {\n flex-grow: 1;\n }\n\n .flex {\n display: flex;\n flex-direction: column;\n width: 100%;\n position: relative;\n left: 0px;\n top: 0px;\n align-items: center;\n height: 100vh;\n }\n\n .mobile .flex {\n height: 100%;\n position: fixed;\n }\n\n .mobile .grow-top {\n flex-grow: 0;\n }\n\n .mobile .grow-bottom {\n flex-grow: 0;\n }\n\n .grow-top {\n flex-grow: 1;\n }\n\n .grow-bottom {\n flex-grow: 3;\n }\n\n .bottom-padding {\n padding: 3rem;\n }\n\n .dialog-mask {\n width: 100%;\n height: 100%;\n background: rgba(0, 0, 0, 0.5);\n opacity: 0;\n position: fixed;\n top: 0px;\n left: 0px;\n transition: opacity linear calc(var(--transition-speed) / 2ms);\n pointer-events: none;\n }\n\n .mobile.dialog-mask .dialog-container {\n border-radius: 0px;\n }\n\n .dialog-mask .dialog-container {\n position: relative;\n transition: transform var(--transition-speed) ease-in-out,\n opacity ease-in-out calc(var(--transition-speed) - 50ms);\n border-radius: var(--curvature);\n box-shadow: 0px 0px 2px 4px rgba(0, 0, 0, 0.06);\n overflow: hidden;\n transform: scale(0.9) translatey(2em);\n background: white;\n margin: auto;\n display: flex;\n flex-direction: column;\n }\n\n .dialog-body {\n background: #fff;\n overflow-y: auto;\n overflow-x: hidden;\n flex-grow: 1;\n }\n\n .dialog-mask.dialog-open {\n opacity: 1;\n pointer-events: auto;\n }\n\n .dialog-mask.dialog-open .dialog-container {\n top: inherit;\n }\n\n .dialog-mask.dialog-animation-end .dialog-container {\n transform: scale(1) translate(0, 0) !important;\n }\n\n .dialog-mask.dialog-ready .dialog-container {\n transform: none;\n }\n\n .dialog-mask.dialog-loading .dialog-container {\n margin-top: -10000px;\n }\n\n .header-text {\n display: flex;\n flex-direction: row;\n align-items: center;\n font-size: 20px;\n padding: 12px 20px;\n color: var(--header-text);\n background: var(--header-bg);\n }\n\n .header-text .title {\n flex-grow: 1;\n }\n\n .header-text .status {\n font-size: 0.6em;\n font-weight: bold;\n }\n\n .dialog-footer {\n background: var(--color-primary-light);\n padding: 10px;\n display: flex;\n flex-flow: row;\n align-items: center;\n }\n\n temba-button {\n margin-left: 10px;\n }\n\n .dialog-body temba-loading {\n position: absolute;\n right: 12px;\n margin-top: -30px;\n padding-bottom: 9px;\n display: none;\n }\n\n #page-loader {\n text-align: center;\n display: block;\n position: relative;\n opacity: 0;\n margin: auto;\n margin-top: 30px;\n width: 154px;\n transition: opacity calc(var(--transition-speed) * 5ms) ease-in\n calc(var(--transition-speed * 2));\n visibility: hidden;\n }\n\n .dialog-mask.dialog-loading #page-loader {\n opacity: 1;\n visibility: visible;\n }\n\n #submit-loader {\n flex-grow: 1;\n text-align: right;\n }\n `;\n }\n\n @property({ type: Boolean })\n open: boolean;\n\n @property()\n header: string;\n\n @property()\n body: string;\n\n @property({ type: Boolean })\n submitting: boolean;\n\n @property({ type: Boolean })\n destructive: boolean;\n\n @property({ type: Boolean })\n disabled: boolean;\n\n @property({ type: Boolean })\n loading: boolean;\n\n @property({ type: Boolean })\n hideOnClick: boolean;\n\n @property({ type: Boolean })\n noFocus: boolean;\n\n @property()\n size = 'medium';\n\n @property({ type: String })\n primaryButtonName = 'Ok';\n\n @property({ type: String })\n cancelButtonName = 'Cancel';\n\n @property({ type: String })\n width = null;\n\n @property()\n submittingName = 'Saving';\n\n @property()\n animationEnd: boolean;\n\n @property()\n ready: boolean;\n\n @property({ type: Array })\n buttons: DialogButton[] = [];\n\n @property({ attribute: false })\n onButtonClicked: (button: Button) => void;\n\n @property({ type: Number })\n originX: number | null = null;\n\n @property({ type: Number })\n originY: number | null = null;\n\n scrollOffset: any = 0;\n\n public constructor() {\n super();\n }\n\n private updateButtons() {\n this.buttons = [];\n if (this.cancelButtonName) {\n this.buttons.push({\n name: this.cancelButtonName,\n type: ButtonType.SECONDARY,\n closes: true\n });\n }\n\n if (this.primaryButtonName) {\n this.buttons.push({\n name: this.primaryButtonName,\n type: ButtonType.PRIMARY\n });\n }\n this.requestUpdate();\n }\n\n public updated(changes: Map<string, any>) {\n super.updated(changes);\n\n if (changes.has('cancelButtonName') || changes.has('primaryButtonName')) {\n this.updateButtons();\n }\n\n if (changes.has('open')) {\n const body = document.querySelector('body');\n\n if (this.open) {\n if (this.originX != null && this.originY != null) {\n // Spring-from-origin animation: measure final position, then\n // set initial transform at click point and transition to center\n const ox = this.originX;\n const oy = this.originY;\n this.originX = null;\n this.originY = null;\n\n requestAnimationFrame(() => {\n const container = this.shadowRoot?.querySelector(\n '.dialog-container'\n ) as HTMLElement;\n if (container) {\n const rect = container.getBoundingClientRect();\n const cx = rect.left + rect.width / 2;\n const cy = rect.top + rect.height / 2;\n const dx = ox - cx;\n const dy = oy - cy;\n\n // Disable transition so we can set the start position instantly\n container.style.transition = 'none';\n container.style.transform = `translate(${dx}px, ${dy}px) scale(0.2)`;\n // Force reflow to register the start position\n container.getBoundingClientRect();\n\n // Re-enable transition and trigger animation to final position\n container.style.transition = '';\n this.animationEnd = true;\n window.setTimeout(() => {\n this.ready = true;\n this.animationEnd = false;\n container.style.transform = '';\n }, 400);\n }\n });\n } else {\n // Default animation (no origin)\n this.animationEnd = true;\n window.setTimeout(() => {\n this.ready = true;\n this.animationEnd = false;\n }, 400);\n }\n\n this.scrollOffset = -document.documentElement.scrollTop;\n body.style.position = 'fixed';\n body.style.overflowY = 'scroll';\n body.style.top = this.scrollOffset + 'px';\n body.style.width = '100%';\n body.style.overflowY = 'hidden';\n } else {\n body.style.position = '';\n body.style.overflowY = '';\n body.style.width = '';\n body.style.marginRight = '';\n body.style.paddingRight = '0px';\n window.scrollTo(0, parseInt(this.scrollOffset || '0') * -1);\n }\n\n // make sure our buttons aren't in progress on show\n if (this.open && !changes.get('open')) {\n this.shadowRoot\n .querySelectorAll('temba-button')\n .forEach((button: Button) => {\n if (button) button.submitting = false;\n });\n\n if (!this.noFocus) {\n this.focusFirstInput();\n }\n } else {\n window.setTimeout(() => {\n this.ready = false;\n }, 400);\n }\n }\n }\n\n public focusFirstInput(): void {\n window.setTimeout(() => {\n let input = this.querySelector(\n 'temba-textinput, temba-completion, input[type=\"text\"], textarea'\n ) as any;\n if (input) {\n input = input.textInputElement || input.inputElement || input;\n if (!input.readOnly) {\n input.focus();\n input.click();\n }\n }\n }, 100);\n }\n\n public handleClick(evt: MouseEvent) {\n const button = evt.currentTarget as Button;\n if (!button.disabled) {\n let detail: DialogButton = {};\n if (button.index >= 0 && button.index < this.buttons.length) {\n detail = this.buttons[button.index];\n }\n\n this.fireCustomEvent(CustomEventType.ButtonClicked, { button, detail });\n if (button.name === this.cancelButtonName || (detail && detail.closes)) {\n this.open = false;\n }\n }\n }\n\n private getDocumentHeight(): number {\n const body = document.body;\n const html = document.documentElement;\n return Math.max(\n body.scrollHeight,\n body.offsetHeight,\n html.clientHeight,\n html.scrollHeight,\n html.offsetHeight\n );\n }\n\n private clickCancel() {\n const cancel = this.getCancelButton();\n if (cancel) {\n cancel.click();\n }\n }\n\n public getCancelButton(): Button {\n return this.shadowRoot.querySelector(\n `temba-button[name='${this.cancelButtonName}']`\n );\n }\n\n public getPrimaryButton(): Button {\n return this.shadowRoot.querySelector(`temba-button[primary]`);\n }\n\n private handleKeyUp(event: KeyboardEvent) {\n if (event.key === 'Escape') {\n this.clickCancel();\n }\n }\n\n private handleClickMask(event: MouseEvent) {\n if (this.hideOnClick) {\n const id = (event.target as HTMLElement).id;\n if (id === 'dialog-mask' || id === 'dialog-bg') {\n this.fireCustomEvent(CustomEventType.DialogHidden);\n this.clickCancel();\n }\n }\n }\n\n public show(): void {\n this.open = true;\n }\n\n public hide(): void {\n this.open = false;\n }\n\n public render(): TemplateResult {\n const dialogStyle = {\n width: this.width\n };\n\n if (!this.width) {\n dialogStyle['width'] = Dialog.widths[this.size];\n }\n\n if (this.isMobile()) {\n dialogStyle['width'] = '100%';\n dialogStyle['height'] = '100%';\n delete dialogStyle['maxWidth'];\n }\n\n const header = this.header\n ? html`\n <div class=\"dialog-header\">\n <div class=\"header-text\">\n <div class=\"title\">${this.header}</div>\n </div>\n </div>\n `\n : null;\n\n return html`\n <div\n id=\"dialog-mask\"\n @click=${this.handleClickMask}\n class=\"dialog-mask ${getClasses({\n 'dialog-open': this.open,\n 'dialog-loading': this.loading,\n 'dialog-animation-end': this.animationEnd,\n 'dialog-ready': this.ready,\n mobile: this.isMobile()\n })}\"\n >\n <div style=\"position: absolute; width: 100%;\">\n <temba-loading\n id=\"page-loader\"\n units=\"6\"\n size=\"12\"\n color=\"#ccc\"\n ></temba-loading>\n </div>\n\n <div class=\"flex\">\n <div class=\"grow-top\" style=\"${\n this.isMobile() ? 'flex-grow:0' : ''\n }\"></div>\n <div\n @keyup=${this.handleKeyUp}\n style=${styleMap(dialogStyle)}\n class=\"dialog-container\"\n >\n ${header}\n <div class=\"dialog-body\" @keypress=${this.handleKeyUp}>\n ${this.body ? this.body : html`<slot></slot>`}\n <temba-loading units=\"6\" size=\"8\"></temba-loading>\n </div>\n\n <div class=\"dialog-footer\">\n <div class=\"flex-grow\">\n <slot name=\"gutter\"></slot>\n </div>\n ${this.buttons.map(\n (button: DialogButton, index) => html`\n <temba-button\n name=${button.name}\n ?destructive=${button.type == 'primary' && this.destructive}\n ?primary=${button.type == 'primary' && !this.destructive}\n ?secondary=${button.type == 'secondary'}\n ?submitting=${this.submitting}\n ?disabled=${this.disabled && !button.closes}\n index=${index}\n @click=${this.handleClick}\n ></temba-button>\n `\n )}\n </div>\n </div>\n <div class=\"grow-bottom\"></div>\n </div>\n </div>\n </div>\n `;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"Dialog.js","sourceRoot":"","sources":["../../../src/layout/Dialog.ts"],"names":[],"mappings":"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","sourcesContent":["import { property } from 'lit/decorators.js';\nimport { TemplateResult, html, css } from 'lit';\nimport { Button } from '../display/Button';\nimport { CustomEventType } from '../interfaces';\nimport { styleMap } from 'lit-html/directives/style-map.js';\nimport { getClasses } from '../utils';\nimport { ResizeElement } from '../ResizeElement';\n\nexport enum ButtonType {\n PRIMARY = 'primary',\n SECONDARY = 'secondary',\n DESTRUCTIVE = 'destructive'\n}\nexport class DialogButton {\n name?: string;\n id?: string;\n details?: any;\n type?: string;\n closes?: boolean;\n}\n\nexport class Dialog extends ResizeElement {\n static get widths(): { [size: string]: string } {\n return {\n small: '400px',\n medium: '600px',\n large: '655px',\n xlarge: '800px'\n };\n }\n\n static get styles() {\n return css`\n :host {\n position: absolute;\n z-index: 10000;\n font-family: var(--font-family);\n background: white;\n }\n\n .flex-grow {\n flex-grow: 1;\n }\n\n .flex {\n display: flex;\n flex-direction: column;\n width: 100%;\n position: relative;\n left: 0px;\n top: 0px;\n align-items: center;\n height: 100vh;\n }\n\n .mobile .flex {\n height: 100%;\n position: fixed;\n }\n\n .mobile .grow-top {\n flex-grow: 0;\n }\n\n .mobile .grow-bottom {\n flex-grow: 0;\n }\n\n .grow-top {\n flex-grow: 1;\n }\n\n .grow-bottom {\n flex-grow: 3;\n }\n\n .bottom-padding {\n padding: 3rem;\n }\n\n .dialog-mask {\n width: 100%;\n height: 100%;\n background: rgba(0, 0, 0, 0.5);\n opacity: 0;\n position: fixed;\n top: 0px;\n left: 0px;\n transition: opacity linear calc(var(--transition-speed) / 2ms);\n pointer-events: none;\n }\n\n .mobile.dialog-mask .dialog-container {\n border-radius: 0px;\n }\n\n .dialog-mask .dialog-container {\n position: relative;\n transition: transform var(--transition-speed) ease-in-out,\n opacity ease-in-out calc(var(--transition-speed) - 50ms);\n border-radius: var(--curvature);\n box-shadow: 0px 0px 2px 4px rgba(0, 0, 0, 0.06);\n overflow: hidden;\n transform: scale(0.9) translatey(2em);\n background: white;\n margin: auto;\n display: flex;\n flex-direction: column;\n }\n\n .dialog-body {\n background: #fff;\n overflow-y: auto;\n overflow-x: hidden;\n flex-grow: 1;\n }\n\n .dialog-mask.dialog-open {\n opacity: 1;\n pointer-events: auto;\n }\n\n .dialog-mask.dialog-open .dialog-container {\n top: inherit;\n }\n\n .dialog-mask.dialog-animation-end .dialog-container {\n transform: scale(1) translate(0, 0) !important;\n }\n\n .dialog-mask.dialog-ready .dialog-container {\n transform: none;\n }\n\n .dialog-mask.dialog-loading .dialog-container {\n margin-top: -10000px;\n }\n\n .header-text {\n display: flex;\n flex-direction: row;\n align-items: center;\n font-size: 20px;\n padding: 12px 20px;\n color: var(--header-text);\n background: var(--header-bg);\n }\n\n .header-text .title {\n flex-grow: 1;\n }\n\n .header-text .status {\n font-size: 0.6em;\n font-weight: bold;\n }\n\n .dialog-footer {\n background: var(--color-primary-light);\n padding: 10px;\n display: flex;\n flex-flow: row;\n align-items: center;\n }\n\n temba-button {\n margin-left: 10px;\n --button-y: 0.4em;\n --button-x: 1em;\n }\n\n .dialog-body temba-loading {\n position: absolute;\n right: 12px;\n margin-top: -30px;\n padding-bottom: 9px;\n display: none;\n }\n\n #page-loader {\n text-align: center;\n display: block;\n position: relative;\n opacity: 0;\n margin: auto;\n margin-top: 30px;\n width: 154px;\n transition: opacity calc(var(--transition-speed) * 5ms) ease-in\n calc(var(--transition-speed * 2));\n visibility: hidden;\n }\n\n .dialog-mask.dialog-loading #page-loader {\n opacity: 1;\n visibility: visible;\n }\n\n #submit-loader {\n flex-grow: 1;\n text-align: right;\n }\n `;\n }\n\n @property({ type: Boolean })\n open: boolean;\n\n @property()\n header: string;\n\n @property()\n body: string;\n\n @property({ type: Boolean })\n submitting: boolean;\n\n @property({ type: Boolean })\n destructive: boolean;\n\n @property({ type: Boolean })\n disabled: boolean;\n\n @property({ type: Boolean })\n loading: boolean;\n\n @property({ type: Boolean })\n hideOnClick: boolean;\n\n @property({ type: Boolean })\n noFocus: boolean;\n\n @property()\n size = 'medium';\n\n @property({ type: String })\n primaryButtonName = 'Ok';\n\n @property({ type: String })\n cancelButtonName = 'Cancel';\n\n @property({ type: String })\n width = null;\n\n @property()\n submittingName = 'Saving';\n\n @property()\n animationEnd: boolean;\n\n @property()\n ready: boolean;\n\n @property({ type: Array })\n buttons: DialogButton[] = [];\n\n @property({ attribute: false })\n onButtonClicked: (button: Button) => void;\n\n @property({ type: Number })\n originX: number | null = null;\n\n @property({ type: Number })\n originY: number | null = null;\n\n scrollOffset: any = 0;\n\n public constructor() {\n super();\n }\n\n private updateButtons() {\n this.buttons = [];\n if (this.cancelButtonName) {\n this.buttons.push({\n name: this.cancelButtonName,\n type: ButtonType.SECONDARY,\n closes: true\n });\n }\n\n if (this.primaryButtonName) {\n this.buttons.push({\n name: this.primaryButtonName,\n type: ButtonType.PRIMARY\n });\n }\n this.requestUpdate();\n }\n\n public updated(changes: Map<string, any>) {\n super.updated(changes);\n\n if (changes.has('cancelButtonName') || changes.has('primaryButtonName')) {\n this.updateButtons();\n }\n\n if (changes.has('open')) {\n const body = document.querySelector('body');\n\n if (this.open) {\n if (this.originX != null && this.originY != null) {\n // Spring-from-origin animation: measure final position, then\n // set initial transform at click point and transition to center\n const ox = this.originX;\n const oy = this.originY;\n this.originX = null;\n this.originY = null;\n\n requestAnimationFrame(() => {\n const container = this.shadowRoot?.querySelector(\n '.dialog-container'\n ) as HTMLElement;\n if (container) {\n const rect = container.getBoundingClientRect();\n const cx = rect.left + rect.width / 2;\n const cy = rect.top + rect.height / 2;\n const dx = ox - cx;\n const dy = oy - cy;\n\n // Disable transition so we can set the start position instantly\n container.style.transition = 'none';\n container.style.transform = `translate(${dx}px, ${dy}px) scale(0.2)`;\n // Force reflow to register the start position\n container.getBoundingClientRect();\n\n // Re-enable transition and trigger animation to final position\n container.style.transition = '';\n this.animationEnd = true;\n window.setTimeout(() => {\n this.ready = true;\n this.animationEnd = false;\n container.style.transform = '';\n }, 400);\n }\n });\n } else {\n // Default animation (no origin)\n this.animationEnd = true;\n window.setTimeout(() => {\n this.ready = true;\n this.animationEnd = false;\n }, 400);\n }\n\n this.scrollOffset = -document.documentElement.scrollTop;\n body.style.position = 'fixed';\n body.style.overflowY = 'scroll';\n body.style.top = this.scrollOffset + 'px';\n body.style.width = '100%';\n body.style.overflowY = 'hidden';\n } else {\n body.style.position = '';\n body.style.overflowY = '';\n body.style.width = '';\n body.style.marginRight = '';\n body.style.paddingRight = '0px';\n window.scrollTo(0, parseInt(this.scrollOffset || '0') * -1);\n }\n\n // make sure our buttons aren't in progress on show\n if (this.open && !changes.get('open')) {\n this.shadowRoot\n .querySelectorAll('temba-button')\n .forEach((button: Button) => {\n if (button) button.submitting = false;\n });\n\n if (!this.noFocus) {\n this.focusFirstInput();\n }\n } else {\n window.setTimeout(() => {\n this.ready = false;\n }, 400);\n }\n }\n }\n\n public focusFirstInput(): void {\n window.setTimeout(() => {\n let input = this.querySelector(\n 'temba-textinput, temba-completion, input[type=\"text\"], textarea'\n ) as any;\n if (input) {\n input = input.textInputElement || input.inputElement || input;\n if (!input.readOnly) {\n input.focus();\n input.click();\n }\n }\n }, 100);\n }\n\n public handleClick(evt: MouseEvent) {\n const button = evt.currentTarget as Button;\n if (!button.disabled) {\n let detail: DialogButton = {};\n if (button.index >= 0 && button.index < this.buttons.length) {\n detail = this.buttons[button.index];\n }\n\n this.fireCustomEvent(CustomEventType.ButtonClicked, { button, detail });\n if (button.name === this.cancelButtonName || (detail && detail.closes)) {\n this.open = false;\n }\n }\n }\n\n private getDocumentHeight(): number {\n const body = document.body;\n const html = document.documentElement;\n return Math.max(\n body.scrollHeight,\n body.offsetHeight,\n html.clientHeight,\n html.scrollHeight,\n html.offsetHeight\n );\n }\n\n private clickCancel() {\n const cancel = this.getCancelButton();\n if (cancel) {\n cancel.click();\n }\n }\n\n public getCancelButton(): Button {\n return this.shadowRoot.querySelector(\n `temba-button[name='${this.cancelButtonName}']`\n );\n }\n\n public getPrimaryButton(): Button {\n return this.shadowRoot.querySelector(`temba-button[primary]`);\n }\n\n private handleKeyUp(event: KeyboardEvent) {\n if (event.key === 'Escape') {\n this.clickCancel();\n }\n }\n\n private handleClickMask(event: MouseEvent) {\n if (this.hideOnClick) {\n const id = (event.target as HTMLElement).id;\n if (id === 'dialog-mask' || id === 'dialog-bg') {\n this.fireCustomEvent(CustomEventType.DialogHidden);\n this.clickCancel();\n }\n }\n }\n\n public show(): void {\n this.open = true;\n }\n\n public hide(): void {\n this.open = false;\n }\n\n public render(): TemplateResult {\n const dialogStyle = {\n width: this.width\n };\n\n if (!this.width) {\n dialogStyle['width'] = Dialog.widths[this.size];\n }\n\n if (this.isMobile()) {\n dialogStyle['width'] = '100%';\n dialogStyle['height'] = '100%';\n delete dialogStyle['maxWidth'];\n }\n\n const header = this.header\n ? html`\n <div class=\"dialog-header\">\n <div class=\"header-text\">\n <div class=\"title\">${this.header}</div>\n </div>\n </div>\n `\n : null;\n\n return html`\n <div\n id=\"dialog-mask\"\n @click=${this.handleClickMask}\n class=\"dialog-mask ${getClasses({\n 'dialog-open': this.open,\n 'dialog-loading': this.loading,\n 'dialog-animation-end': this.animationEnd,\n 'dialog-ready': this.ready,\n mobile: this.isMobile()\n })}\"\n >\n <div style=\"position: absolute; width: 100%;\">\n <temba-loading\n id=\"page-loader\"\n units=\"6\"\n size=\"12\"\n color=\"#ccc\"\n ></temba-loading>\n </div>\n\n <div class=\"flex\">\n <div class=\"grow-top\" style=\"${\n this.isMobile() ? 'flex-grow:0' : ''\n }\"></div>\n <div\n @keyup=${this.handleKeyUp}\n style=${styleMap(dialogStyle)}\n class=\"dialog-container\"\n >\n ${header}\n <div class=\"dialog-body\" @keypress=${this.handleKeyUp}>\n ${this.body ? this.body : html`<slot></slot>`}\n <temba-loading units=\"6\" size=\"8\"></temba-loading>\n </div>\n\n <div class=\"dialog-footer\">\n <div class=\"flex-grow\">\n <slot name=\"gutter\"></slot>\n </div>\n ${this.buttons.map(\n (button: DialogButton, index) => html`\n <temba-button\n name=${button.name}\n ?destructive=${button.type == 'primary' && this.destructive}\n ?primary=${button.type == 'primary' && !this.destructive}\n ?secondary=${button.type == 'secondary'}\n ?submitting=${this.submitting}\n ?disabled=${this.disabled && !button.closes}\n index=${index}\n @click=${this.handleClick}\n ></temba-button>\n `\n )}\n </div>\n </div>\n <div class=\"grow-bottom\"></div>\n </div>\n </div>\n </div>\n `;\n }\n}\n"]}
|
|
@@ -56,7 +56,8 @@ export class SortableList extends RapidElement {
|
|
|
56
56
|
this.externalDrag = false;
|
|
57
57
|
this.ghostElement = null;
|
|
58
58
|
this.downEle = null;
|
|
59
|
-
this.originalElementRect = null; // Store
|
|
59
|
+
this.originalElementRect = null; // Store viewport dimensions for ghost
|
|
60
|
+
this.originalLayoutSize = null; // Store layout dimensions for placeholders
|
|
60
61
|
this.originalDragIndex = -1; // Store original index before moving element
|
|
61
62
|
this.xOffset = 0;
|
|
62
63
|
this.yOffset = 0;
|
|
@@ -248,16 +249,17 @@ export class SortableList extends RapidElement {
|
|
|
248
249
|
return;
|
|
249
250
|
this.dropPlaceholder = document.createElement('div');
|
|
250
251
|
this.dropPlaceholder.className = 'drop-placeholder sortable';
|
|
251
|
-
//
|
|
252
|
-
if (this.
|
|
253
|
-
const
|
|
254
|
-
this.dropPlaceholder.style.width =
|
|
255
|
-
this.dropPlaceholder.style.height =
|
|
256
|
-
this.dropPlaceholder.style.minHeight =
|
|
252
|
+
// Use layout-space dimensions for placeholders (unaffected by ancestor transforms)
|
|
253
|
+
if (this.originalLayoutSize) {
|
|
254
|
+
const size = this.originalLayoutSize;
|
|
255
|
+
this.dropPlaceholder.style.width = size.width + 'px';
|
|
256
|
+
this.dropPlaceholder.style.height = size.height + 'px';
|
|
257
|
+
this.dropPlaceholder.style.minHeight = size.height + 'px';
|
|
257
258
|
this.dropPlaceholder.style.borderRadius = 'var(--curvature)';
|
|
258
259
|
this.dropPlaceholder.style.flexShrink = '0';
|
|
259
260
|
this.dropPlaceholder.style.background = '#f3f4f6';
|
|
260
|
-
this.dropPlaceholder.style.
|
|
261
|
+
this.dropPlaceholder.style.outline = '2px dashed #d1d5db';
|
|
262
|
+
this.dropPlaceholder.style.outlineOffset = '-2px';
|
|
261
263
|
}
|
|
262
264
|
// Insert the placeholder in the correct position in the DOM
|
|
263
265
|
if (insertAfter) {
|
|
@@ -278,15 +280,16 @@ export class SortableList extends RapidElement {
|
|
|
278
280
|
return;
|
|
279
281
|
this.dropPlaceholder = document.createElement('div');
|
|
280
282
|
this.dropPlaceholder.className = 'drop-placeholder sortable';
|
|
281
|
-
//
|
|
282
|
-
const
|
|
283
|
-
this.dropPlaceholder.style.width =
|
|
284
|
-
this.dropPlaceholder.style.height =
|
|
285
|
-
this.dropPlaceholder.style.minHeight =
|
|
283
|
+
// Use layout-space dimensions for placeholders (unaffected by ancestor transforms)
|
|
284
|
+
const size = this.originalLayoutSize;
|
|
285
|
+
this.dropPlaceholder.style.width = size.width + 'px';
|
|
286
|
+
this.dropPlaceholder.style.height = size.height + 'px';
|
|
287
|
+
this.dropPlaceholder.style.minHeight = size.height + 'px';
|
|
286
288
|
this.dropPlaceholder.style.borderRadius = 'var(--curvature)';
|
|
287
289
|
this.dropPlaceholder.style.flexShrink = '0';
|
|
288
290
|
this.dropPlaceholder.style.background = '#f3f4f6';
|
|
289
|
-
this.dropPlaceholder.style.
|
|
291
|
+
this.dropPlaceholder.style.outline = '2px dashed #d1d5db';
|
|
292
|
+
this.dropPlaceholder.style.outlineOffset = '-2px';
|
|
290
293
|
// Insert the placeholder right after the hidden original element
|
|
291
294
|
this.downEle.insertAdjacentElement('afterend', this.dropPlaceholder);
|
|
292
295
|
}
|
|
@@ -308,7 +311,11 @@ export class SortableList extends RapidElement {
|
|
|
308
311
|
this.draggingEle = ele;
|
|
309
312
|
// Use getBoundingClientRect for accurate offsets and store original dimensions
|
|
310
313
|
const rect = ele.getBoundingClientRect();
|
|
311
|
-
this.originalElementRect = rect; // Store
|
|
314
|
+
this.originalElementRect = rect; // Store viewport rect for ghost positioning
|
|
315
|
+
this.originalLayoutSize = {
|
|
316
|
+
width: ele.offsetWidth,
|
|
317
|
+
height: ele.offsetHeight
|
|
318
|
+
}; // Store layout dimensions for placeholders
|
|
312
319
|
this.xOffset = event.clientX - rect.left;
|
|
313
320
|
this.yOffset = event.clientY - rect.top;
|
|
314
321
|
this.yDown = event.clientY;
|
|
@@ -334,16 +341,29 @@ export class SortableList extends RapidElement {
|
|
|
334
341
|
this.downEle.style.display = 'none';
|
|
335
342
|
// Style the clone as a ghost
|
|
336
343
|
this.ghostElement.classList.add('ghost');
|
|
337
|
-
//
|
|
344
|
+
// Detect ancestor scale transform (e.g. zoom) by comparing viewport
|
|
345
|
+
// to layout dimensions, so the ghost renders content at the right scale
|
|
338
346
|
const rect = this.originalElementRect;
|
|
347
|
+
const layoutSize = this.originalLayoutSize;
|
|
348
|
+
const ancestorScale = layoutSize.width > 0 ? rect.width / layoutSize.width : 1;
|
|
349
|
+
const hasAncestorScale = Math.abs(ancestorScale - 1) > 0.001;
|
|
339
350
|
this.ghostElement.style.position = 'fixed';
|
|
340
351
|
this.ghostElement.style.left = event.clientX - this.xOffset + 'px';
|
|
341
352
|
this.ghostElement.style.top = event.clientY - this.yOffset + 'px';
|
|
342
|
-
this.ghostElement.style.width = rect.width + 'px';
|
|
343
|
-
this.ghostElement.style.height = rect.height + 'px';
|
|
344
353
|
this.ghostElement.style.zIndex = '99999';
|
|
345
354
|
this.ghostElement.style.opacity = '0.8';
|
|
346
|
-
|
|
355
|
+
if (hasAncestorScale) {
|
|
356
|
+
// Use layout dimensions with ancestor scale so content renders correctly
|
|
357
|
+
this.ghostElement.style.width = layoutSize.width + 'px';
|
|
358
|
+
this.ghostElement.style.height = layoutSize.height + 'px';
|
|
359
|
+
this.ghostElement.style.transform = `scale(${ancestorScale * 1.03})`;
|
|
360
|
+
this.ghostElement.style.transformOrigin = '0 0';
|
|
361
|
+
}
|
|
362
|
+
else {
|
|
363
|
+
this.ghostElement.style.width = rect.width + 'px';
|
|
364
|
+
this.ghostElement.style.height = rect.height + 'px';
|
|
365
|
+
this.ghostElement.style.transform = 'scale(1.03)';
|
|
366
|
+
}
|
|
347
367
|
// allow component to customize the ghost node
|
|
348
368
|
if (this.prepareGhost) {
|
|
349
369
|
this.prepareGhost(this.ghostElement);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SortableList.js","sourceRoot":"","sources":["../../../src/list/SortableList.ts"],"names":[],"mappings":"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","sourcesContent":["import { css, html, 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;\n\n// padding around container for external drag detection\nconst EXTERNAL_DRAG_PADDING = 50;\n\nexport class SortableList extends RapidElement {\n originalDownDisplay: string;\n static get styles() {\n return css`\n :host {\n margin: auto;\n }\n\n .container {\n user-select: none;\n position: relative;\n display: grid;\n grid-template-columns: 1fr;\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 .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 @property({ type: String })\n dragHandle: string;\n\n @property({ type: String })\n gap: string = '0em';\n\n @property({ type: Boolean })\n externalDrag: boolean = false;\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 originalElementRect: DOMRect = null; // Store original dimensions\n originalDragIndex: number = -1; // Store original index before moving element\n xOffset = 0;\n yOffset = 0;\n yDown = 0;\n xDown = 0;\n\n draggingIdx = -1;\n draggingEle = null;\n dropPlaceholder: HTMLDivElement = null;\n pendingDropIndex = -1;\n pendingTargetElement: HTMLElement = null;\n isExternalDrag = false;\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 private getSortableElements(): Element[] {\n const eles = this.shadowRoot\n .querySelector('slot')\n .assignedElements()\n .filter(\n (ele) =>\n ele.classList.contains('sortable') &&\n !ele.classList.contains('drop-placeholder')\n );\n return eles;\n }\n\n private isMouseOverContainer(mouseX: number, mouseY: number): boolean {\n const container = this.shadowRoot.querySelector('.container');\n if (!container) return false;\n\n const rect = container.getBoundingClientRect();\n // add some padding to make it easier to stay within the container\n return (\n mouseX >= rect.left - EXTERNAL_DRAG_PADDING &&\n mouseX <= rect.right + EXTERNAL_DRAG_PADDING &&\n mouseY >= rect.top - EXTERNAL_DRAG_PADDING &&\n mouseY <= rect.bottom + EXTERNAL_DRAG_PADDING\n );\n }\n\n private cloneElementWithState(element: HTMLElement): HTMLElement {\n // First create a basic clone\n const clone = element.cloneNode(true) as HTMLElement;\n\n // Helper function to copy form element values recursively\n const copyFormValues = (original: HTMLElement, cloned: HTMLElement) => {\n try {\n // Copy input values\n const originalInputs = original.querySelectorAll(\n 'input, textarea, select'\n );\n const clonedInputs = cloned.querySelectorAll('input, textarea, select');\n\n originalInputs.forEach((originalInput, index) => {\n const clonedInput = clonedInputs[index] as\n | HTMLInputElement\n | HTMLTextAreaElement\n | HTMLSelectElement;\n if (clonedInput) {\n if (originalInput instanceof HTMLInputElement) {\n const originalHtmlInput = originalInput as HTMLInputElement;\n const clonedHtmlInput = clonedInput as HTMLInputElement;\n\n if (\n originalHtmlInput.type === 'checkbox' ||\n originalHtmlInput.type === 'radio'\n ) {\n clonedHtmlInput.checked = originalHtmlInput.checked;\n } else {\n clonedHtmlInput.value = originalHtmlInput.value;\n }\n } else if (originalInput instanceof HTMLTextAreaElement) {\n (clonedInput as HTMLTextAreaElement).value = originalInput.value;\n } else if (originalInput instanceof HTMLSelectElement) {\n (clonedInput as HTMLSelectElement).selectedIndex =\n originalInput.selectedIndex;\n }\n }\n });\n\n // Copy properties from all custom elements that might have a value property\n const allOriginalElements = Array.from(original.querySelectorAll('*'));\n const allClonedElements = Array.from(cloned.querySelectorAll('*'));\n\n allOriginalElements.forEach((originalEl, index) => {\n const clonedEl = allClonedElements[index];\n if (clonedEl && originalEl) {\n // Special handling for temba components\n if (\n originalEl.tagName &&\n originalEl.tagName.toLowerCase().startsWith('temba-')\n ) {\n try {\n // Copy common temba component properties\n const tembaProps = [\n 'value',\n 'values',\n 'selectedValue',\n 'checked',\n 'selected',\n 'textContent'\n ];\n tembaProps.forEach((prop) => {\n if (\n prop in originalEl &&\n (originalEl as any)[prop] !== undefined\n ) {\n (clonedEl as any)[prop] = (originalEl as any)[prop];\n }\n });\n\n // Copy all attributes for temba components to preserve state\n Array.from(originalEl.attributes).forEach((attr) => {\n clonedEl.setAttribute(attr.name, attr.value);\n });\n } catch (e) {\n // Ignore errors when copying temba properties\n }\n } else {\n // Try to copy value property for other elements\n try {\n if (\n 'value' in originalEl &&\n (originalEl as any).value !== undefined\n ) {\n (clonedEl as any).value = (originalEl as any).value;\n }\n } catch (e) {\n // Ignore errors when copying properties\n }\n\n // Copy data attributes that might contain state\n try {\n Array.from(originalEl.attributes).forEach((attr) => {\n if (\n attr.name.startsWith('data-') ||\n attr.name.startsWith('aria-')\n ) {\n clonedEl.setAttribute(attr.name, attr.value);\n }\n });\n } catch (e) {\n // Ignore errors when copying attributes\n }\n }\n }\n });\n } catch (e) {\n // If anything fails, just return the basic clone\n console.warn('Failed to copy form values in cloneElementWithState:', e);\n }\n };\n\n // Copy form values for the root element and all descendants\n copyFormValues(element, clone);\n\n return clone;\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 showDropPlaceholder(\n targetElement: HTMLElement,\n insertAfter: boolean\n ) {\n this.hideDropPlaceholder();\n\n if (!targetElement || !this.draggingEle) return;\n\n // Don't show placeholder if we're targeting the dragging element itself\n if (targetElement === this.draggingEle) return;\n\n this.dropPlaceholder = document.createElement('div');\n\n this.dropPlaceholder.className = 'drop-placeholder sortable';\n\n // Copy dimensions from the original element (before it was hidden)\n if (this.originalElementRect) {\n const rect = this.originalElementRect;\n this.dropPlaceholder.style.width = rect.width + 'px';\n this.dropPlaceholder.style.height = rect.height + 'px';\n this.dropPlaceholder.style.minHeight = rect.height + 'px';\n this.dropPlaceholder.style.borderRadius = 'var(--curvature)';\n this.dropPlaceholder.style.flexShrink = '0';\n this.dropPlaceholder.style.background = '#f3f4f6';\n this.dropPlaceholder.style.border = '2px dashed #d1d5db';\n }\n\n // Insert the placeholder in the correct position in the DOM\n if (insertAfter) {\n targetElement.insertAdjacentElement('afterend', this.dropPlaceholder);\n } else {\n targetElement.insertAdjacentElement('beforebegin', this.dropPlaceholder);\n }\n }\n\n private hideDropPlaceholder() {\n if (this.dropPlaceholder) {\n this.dropPlaceholder.remove();\n this.dropPlaceholder = null;\n }\n }\n\n private showInitialPlaceholder() {\n if (!this.downEle || !this.originalElementRect) return;\n\n this.dropPlaceholder = document.createElement('div');\n this.dropPlaceholder.className = 'drop-placeholder sortable';\n\n // Copy dimensions from the original element\n const rect = this.originalElementRect;\n this.dropPlaceholder.style.width = rect.width + 'px';\n this.dropPlaceholder.style.height = rect.height + 'px';\n this.dropPlaceholder.style.minHeight = rect.height + 'px';\n this.dropPlaceholder.style.borderRadius = 'var(--curvature)';\n this.dropPlaceholder.style.flexShrink = '0';\n this.dropPlaceholder.style.background = '#f3f4f6';\n this.dropPlaceholder.style.border = '2px dashed #d1d5db';\n\n // Insert the placeholder right after the hidden original element\n this.downEle.insertAdjacentElement('afterend', this.dropPlaceholder);\n }\n\n private handleMouseDown(event: MouseEvent) {\n let ele = event.target as HTMLDivElement;\n\n // if we have a drag handle, only allow dragging from that element\n if (this.dragHandle) {\n if (!ele.classList.contains(this.dragHandle)) {\n return;\n }\n }\n\n ele = ele.closest('.sortable');\n if (ele) {\n event.preventDefault();\n event.stopPropagation();\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 and store original dimensions\n const rect = ele.getBoundingClientRect();\n this.originalElementRect = rect; // Store the original rect before hiding\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 // Capture the original index BEFORE hiding the element\n this.originalDragIndex = this.getRowIndex(this.downEle.id);\n\n // Create a clone of the element to use as the ghost\n this.ghostElement = this.cloneElementWithState(\n this.downEle\n ) as HTMLDivElement;\n\n // Hide the original element during dragging using inline styles\n this.originalDownDisplay = this.downEle.style.display;\n this.downEle.style.display = 'none';\n\n // Style the clone as a ghost\n this.ghostElement.classList.add('ghost');\n\n // Use the stored original dimensions for positioning\n const rect = this.originalElementRect;\n\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.width = rect.width + 'px';\n this.ghostElement.style.height = rect.height + 'px';\n this.ghostElement.style.zIndex = '99999';\n this.ghostElement.style.opacity = '0.8';\n this.ghostElement.style.transform = 'scale(1.03)';\n\n // allow component to customize the ghost node\n if (this.prepareGhost) {\n this.prepareGhost(this.ghostElement);\n }\n\n // Add the clone to document.body for dragging\n document.body.appendChild(this.ghostElement);\n\n // Show initial placeholder in the original position to maintain layout\n this.showInitialPlaceholder();\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 // check if the drag is over the container (only if external dragging is allowed)\n const isOverContainer = this.externalDrag\n ? this.isMouseOverContainer(event.clientX, event.clientY)\n : true; // always consider \"over container\" if external drag is disabled\n\n // detect transition between internal and external drag (only if allowed)\n if (this.externalDrag && !isOverContainer && !this.isExternalDrag) {\n // transitioning to external drag\n this.isExternalDrag = true;\n this.hideDropPlaceholder();\n\n // hide the ghost element when dragging externally\n if (this.ghostElement) {\n this.ghostElement.style.display = 'none';\n }\n\n this.fireCustomEvent(CustomEventType.DragExternal, {\n id: this.downEle.id,\n mouseX: event.clientX,\n mouseY: event.clientY\n });\n } else if (this.externalDrag && isOverContainer && this.isExternalDrag) {\n // transitioning back to internal drag\n this.isExternalDrag = false;\n\n // show the ghost element again when dragging internally\n if (this.ghostElement) {\n this.ghostElement.style.display = 'block';\n }\n\n this.fireCustomEvent(CustomEventType.DragInternal, {\n id: this.downEle.id\n });\n }\n\n // only show drop placeholder and calculate drop position if internal drag\n if (!this.isExternalDrag) {\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\n // Use the original drag index we captured before moving the element\n const originalDragIdx = this.originalDragIndex;\n\n // Calculate where the dragged element will end up in the final array\n // targetIdx is the position of target element in current DOM (missing dragged element)\n\n let dropIdx;\n if (targetIdx < originalDragIdx) {\n // Target is before the original drag position - moving backward\n dropIdx = insertAfter ? targetIdx + 1 : targetIdx;\n } else {\n // Target was originally after the drag position - moving forward\n // When moving the dragged element forward (i.e., to a higher index), the targetIdx is based on the current DOM,\n // which no longer includes the dragged element. This means all elements after the original position have shifted left by one,\n // so we need to subtract 1 from targetIdx to get the correct insertion index. If inserting after the target, we use targetIdx as is.\n dropIdx = insertAfter ? targetIdx : targetIdx - 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 placeholder\n this.showDropPlaceholder(targetElement, insertAfter);\n } else {\n this.hideDropPlaceholder();\n this.dropTargetId = null;\n this.pendingDropIndex = -1;\n this.pendingTargetElement = null;\n }\n } else {\n // external drag - continue firing external drag events with updated position\n this.fireCustomEvent(CustomEventType.DragExternal, {\n id: this.downEle.id,\n mouseX: event.clientX,\n mouseY: event.clientY\n });\n }\n }\n }\n\n private handleMouseUp(evt: MouseEvent) {\n if (this.draggingId && this.ghostElement) {\n evt.preventDefault();\n evt.stopPropagation();\n\n // Remove the ghost clone from document.body\n if (this.ghostElement) {\n this.ghostElement.remove();\n }\n\n // Restore visibility of the original element by clearing inline styles\n if (this.downEle) {\n this.downEle.style.display = this.originalDownDisplay;\n }\n\n // Clear visual effects before firing events\n this.hideDropPlaceholder();\n\n // fire the order changed event only when dropped if we have a valid drop position\n if (\n !this.isExternalDrag &&\n this.pendingDropIndex >= 0 &&\n this.pendingTargetElement\n ) {\n // Use the original drag index we captured before hiding the element\n const originalDragIdx = this.originalDragIndex;\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 AND this is not an external drag\n // External drags are handled by external drop handlers\n if (fromIdx !== toIdx && !this.isExternalDrag) {\n this.fireCustomEvent(CustomEventType.OrderChanged, {\n swap: [fromIdx, toIdx]\n });\n }\n }\n\n this.fireCustomEvent(CustomEventType.DragStop, {\n id: this.draggingId,\n isExternal: this.isExternalDrag,\n mouseX: evt.clientX,\n mouseY: evt.clientY\n });\n\n this.draggingId = null;\n this.dropTargetId = null;\n this.downEle = null;\n this.originalElementRect = null;\n this.originalDragIndex = -1;\n this.pendingDropIndex = -1;\n this.pendingTargetElement = null;\n this.isExternalDrag = false;\n\n // Clear the ghost reference since we removed it\n this.ghostElement = null;\n\n this.hideDropPlaceholder();\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\n class=\"container ${this.horizontal ? 'horizontal' : ''}\"\n style=\"gap: ${this.gap}\"\n >\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":"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","sourcesContent":["import { css, html, 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;\n\n// padding around container for external drag detection\nconst EXTERNAL_DRAG_PADDING = 50;\n\nexport class SortableList extends RapidElement {\n originalDownDisplay: string;\n static get styles() {\n return css`\n :host {\n margin: auto;\n }\n\n .container {\n user-select: none;\n position: relative;\n display: grid;\n grid-template-columns: 1fr;\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 .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 @property({ type: String })\n dragHandle: string;\n\n @property({ type: String })\n gap: string = '0em';\n\n @property({ type: Boolean })\n externalDrag: boolean = false;\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 originalElementRect: DOMRect = null; // Store viewport dimensions for ghost\n originalLayoutSize: { width: number; height: number } = null; // Store layout dimensions for placeholders\n originalDragIndex: number = -1; // Store original index before moving element\n xOffset = 0;\n yOffset = 0;\n yDown = 0;\n xDown = 0;\n\n draggingIdx = -1;\n draggingEle = null;\n dropPlaceholder: HTMLDivElement = null;\n pendingDropIndex = -1;\n pendingTargetElement: HTMLElement = null;\n isExternalDrag = false;\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 private getSortableElements(): Element[] {\n const eles = this.shadowRoot\n .querySelector('slot')\n .assignedElements()\n .filter(\n (ele) =>\n ele.classList.contains('sortable') &&\n !ele.classList.contains('drop-placeholder')\n );\n return eles;\n }\n\n private isMouseOverContainer(mouseX: number, mouseY: number): boolean {\n const container = this.shadowRoot.querySelector('.container');\n if (!container) return false;\n\n const rect = container.getBoundingClientRect();\n // add some padding to make it easier to stay within the container\n return (\n mouseX >= rect.left - EXTERNAL_DRAG_PADDING &&\n mouseX <= rect.right + EXTERNAL_DRAG_PADDING &&\n mouseY >= rect.top - EXTERNAL_DRAG_PADDING &&\n mouseY <= rect.bottom + EXTERNAL_DRAG_PADDING\n );\n }\n\n private cloneElementWithState(element: HTMLElement): HTMLElement {\n // First create a basic clone\n const clone = element.cloneNode(true) as HTMLElement;\n\n // Helper function to copy form element values recursively\n const copyFormValues = (original: HTMLElement, cloned: HTMLElement) => {\n try {\n // Copy input values\n const originalInputs = original.querySelectorAll(\n 'input, textarea, select'\n );\n const clonedInputs = cloned.querySelectorAll('input, textarea, select');\n\n originalInputs.forEach((originalInput, index) => {\n const clonedInput = clonedInputs[index] as\n | HTMLInputElement\n | HTMLTextAreaElement\n | HTMLSelectElement;\n if (clonedInput) {\n if (originalInput instanceof HTMLInputElement) {\n const originalHtmlInput = originalInput as HTMLInputElement;\n const clonedHtmlInput = clonedInput as HTMLInputElement;\n\n if (\n originalHtmlInput.type === 'checkbox' ||\n originalHtmlInput.type === 'radio'\n ) {\n clonedHtmlInput.checked = originalHtmlInput.checked;\n } else {\n clonedHtmlInput.value = originalHtmlInput.value;\n }\n } else if (originalInput instanceof HTMLTextAreaElement) {\n (clonedInput as HTMLTextAreaElement).value = originalInput.value;\n } else if (originalInput instanceof HTMLSelectElement) {\n (clonedInput as HTMLSelectElement).selectedIndex =\n originalInput.selectedIndex;\n }\n }\n });\n\n // Copy properties from all custom elements that might have a value property\n const allOriginalElements = Array.from(original.querySelectorAll('*'));\n const allClonedElements = Array.from(cloned.querySelectorAll('*'));\n\n allOriginalElements.forEach((originalEl, index) => {\n const clonedEl = allClonedElements[index];\n if (clonedEl && originalEl) {\n // Special handling for temba components\n if (\n originalEl.tagName &&\n originalEl.tagName.toLowerCase().startsWith('temba-')\n ) {\n try {\n // Copy common temba component properties\n const tembaProps = [\n 'value',\n 'values',\n 'selectedValue',\n 'checked',\n 'selected',\n 'textContent'\n ];\n tembaProps.forEach((prop) => {\n if (\n prop in originalEl &&\n (originalEl as any)[prop] !== undefined\n ) {\n (clonedEl as any)[prop] = (originalEl as any)[prop];\n }\n });\n\n // Copy all attributes for temba components to preserve state\n Array.from(originalEl.attributes).forEach((attr) => {\n clonedEl.setAttribute(attr.name, attr.value);\n });\n } catch (e) {\n // Ignore errors when copying temba properties\n }\n } else {\n // Try to copy value property for other elements\n try {\n if (\n 'value' in originalEl &&\n (originalEl as any).value !== undefined\n ) {\n (clonedEl as any).value = (originalEl as any).value;\n }\n } catch (e) {\n // Ignore errors when copying properties\n }\n\n // Copy data attributes that might contain state\n try {\n Array.from(originalEl.attributes).forEach((attr) => {\n if (\n attr.name.startsWith('data-') ||\n attr.name.startsWith('aria-')\n ) {\n clonedEl.setAttribute(attr.name, attr.value);\n }\n });\n } catch (e) {\n // Ignore errors when copying attributes\n }\n }\n }\n });\n } catch (e) {\n // If anything fails, just return the basic clone\n console.warn('Failed to copy form values in cloneElementWithState:', e);\n }\n };\n\n // Copy form values for the root element and all descendants\n copyFormValues(element, clone);\n\n return clone;\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 showDropPlaceholder(\n targetElement: HTMLElement,\n insertAfter: boolean\n ) {\n this.hideDropPlaceholder();\n\n if (!targetElement || !this.draggingEle) return;\n\n // Don't show placeholder if we're targeting the dragging element itself\n if (targetElement === this.draggingEle) return;\n\n this.dropPlaceholder = document.createElement('div');\n\n this.dropPlaceholder.className = 'drop-placeholder sortable';\n\n // Use layout-space dimensions for placeholders (unaffected by ancestor transforms)\n if (this.originalLayoutSize) {\n const size = this.originalLayoutSize;\n this.dropPlaceholder.style.width = size.width + 'px';\n this.dropPlaceholder.style.height = size.height + 'px';\n this.dropPlaceholder.style.minHeight = size.height + 'px';\n this.dropPlaceholder.style.borderRadius = 'var(--curvature)';\n this.dropPlaceholder.style.flexShrink = '0';\n this.dropPlaceholder.style.background = '#f3f4f6';\n this.dropPlaceholder.style.outline = '2px dashed #d1d5db';\n this.dropPlaceholder.style.outlineOffset = '-2px';\n }\n\n // Insert the placeholder in the correct position in the DOM\n if (insertAfter) {\n targetElement.insertAdjacentElement('afterend', this.dropPlaceholder);\n } else {\n targetElement.insertAdjacentElement('beforebegin', this.dropPlaceholder);\n }\n }\n\n private hideDropPlaceholder() {\n if (this.dropPlaceholder) {\n this.dropPlaceholder.remove();\n this.dropPlaceholder = null;\n }\n }\n\n private showInitialPlaceholder() {\n if (!this.downEle || !this.originalElementRect) return;\n\n this.dropPlaceholder = document.createElement('div');\n this.dropPlaceholder.className = 'drop-placeholder sortable';\n\n // Use layout-space dimensions for placeholders (unaffected by ancestor transforms)\n const size = this.originalLayoutSize;\n this.dropPlaceholder.style.width = size.width + 'px';\n this.dropPlaceholder.style.height = size.height + 'px';\n this.dropPlaceholder.style.minHeight = size.height + 'px';\n this.dropPlaceholder.style.borderRadius = 'var(--curvature)';\n this.dropPlaceholder.style.flexShrink = '0';\n this.dropPlaceholder.style.background = '#f3f4f6';\n this.dropPlaceholder.style.outline = '2px dashed #d1d5db';\n this.dropPlaceholder.style.outlineOffset = '-2px';\n\n // Insert the placeholder right after the hidden original element\n this.downEle.insertAdjacentElement('afterend', this.dropPlaceholder);\n }\n\n private handleMouseDown(event: MouseEvent) {\n let ele = event.target as HTMLDivElement;\n\n // if we have a drag handle, only allow dragging from that element\n if (this.dragHandle) {\n if (!ele.classList.contains(this.dragHandle)) {\n return;\n }\n }\n\n ele = ele.closest('.sortable');\n if (ele) {\n event.preventDefault();\n event.stopPropagation();\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 and store original dimensions\n const rect = ele.getBoundingClientRect();\n this.originalElementRect = rect; // Store viewport rect for ghost positioning\n this.originalLayoutSize = {\n width: ele.offsetWidth,\n height: ele.offsetHeight\n }; // Store layout dimensions for placeholders\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 // Capture the original index BEFORE hiding the element\n this.originalDragIndex = this.getRowIndex(this.downEle.id);\n\n // Create a clone of the element to use as the ghost\n this.ghostElement = this.cloneElementWithState(\n this.downEle\n ) as HTMLDivElement;\n\n // Hide the original element during dragging using inline styles\n this.originalDownDisplay = this.downEle.style.display;\n this.downEle.style.display = 'none';\n\n // Style the clone as a ghost\n this.ghostElement.classList.add('ghost');\n\n // Detect ancestor scale transform (e.g. zoom) by comparing viewport\n // to layout dimensions, so the ghost renders content at the right scale\n const rect = this.originalElementRect;\n const layoutSize = this.originalLayoutSize;\n const ancestorScale =\n layoutSize.width > 0 ? rect.width / layoutSize.width : 1;\n const hasAncestorScale = Math.abs(ancestorScale - 1) > 0.001;\n\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.zIndex = '99999';\n this.ghostElement.style.opacity = '0.8';\n\n if (hasAncestorScale) {\n // Use layout dimensions with ancestor scale so content renders correctly\n this.ghostElement.style.width = layoutSize.width + 'px';\n this.ghostElement.style.height = layoutSize.height + 'px';\n this.ghostElement.style.transform = `scale(${ancestorScale * 1.03})`;\n this.ghostElement.style.transformOrigin = '0 0';\n } else {\n this.ghostElement.style.width = rect.width + 'px';\n this.ghostElement.style.height = rect.height + 'px';\n this.ghostElement.style.transform = 'scale(1.03)';\n }\n\n // allow component to customize the ghost node\n if (this.prepareGhost) {\n this.prepareGhost(this.ghostElement);\n }\n\n // Add the clone to document.body for dragging\n document.body.appendChild(this.ghostElement);\n\n // Show initial placeholder in the original position to maintain layout\n this.showInitialPlaceholder();\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 // check if the drag is over the container (only if external dragging is allowed)\n const isOverContainer = this.externalDrag\n ? this.isMouseOverContainer(event.clientX, event.clientY)\n : true; // always consider \"over container\" if external drag is disabled\n\n // detect transition between internal and external drag (only if allowed)\n if (this.externalDrag && !isOverContainer && !this.isExternalDrag) {\n // transitioning to external drag\n this.isExternalDrag = true;\n this.hideDropPlaceholder();\n\n // hide the ghost element when dragging externally\n if (this.ghostElement) {\n this.ghostElement.style.display = 'none';\n }\n\n this.fireCustomEvent(CustomEventType.DragExternal, {\n id: this.downEle.id,\n mouseX: event.clientX,\n mouseY: event.clientY\n });\n } else if (this.externalDrag && isOverContainer && this.isExternalDrag) {\n // transitioning back to internal drag\n this.isExternalDrag = false;\n\n // show the ghost element again when dragging internally\n if (this.ghostElement) {\n this.ghostElement.style.display = 'block';\n }\n\n this.fireCustomEvent(CustomEventType.DragInternal, {\n id: this.downEle.id\n });\n }\n\n // only show drop placeholder and calculate drop position if internal drag\n if (!this.isExternalDrag) {\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\n // Use the original drag index we captured before moving the element\n const originalDragIdx = this.originalDragIndex;\n\n // Calculate where the dragged element will end up in the final array\n // targetIdx is the position of target element in current DOM (missing dragged element)\n\n let dropIdx;\n if (targetIdx < originalDragIdx) {\n // Target is before the original drag position - moving backward\n dropIdx = insertAfter ? targetIdx + 1 : targetIdx;\n } else {\n // Target was originally after the drag position - moving forward\n // When moving the dragged element forward (i.e., to a higher index), the targetIdx is based on the current DOM,\n // which no longer includes the dragged element. This means all elements after the original position have shifted left by one,\n // so we need to subtract 1 from targetIdx to get the correct insertion index. If inserting after the target, we use targetIdx as is.\n dropIdx = insertAfter ? targetIdx : targetIdx - 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 placeholder\n this.showDropPlaceholder(targetElement, insertAfter);\n } else {\n this.hideDropPlaceholder();\n this.dropTargetId = null;\n this.pendingDropIndex = -1;\n this.pendingTargetElement = null;\n }\n } else {\n // external drag - continue firing external drag events with updated position\n this.fireCustomEvent(CustomEventType.DragExternal, {\n id: this.downEle.id,\n mouseX: event.clientX,\n mouseY: event.clientY\n });\n }\n }\n }\n\n private handleMouseUp(evt: MouseEvent) {\n if (this.draggingId && this.ghostElement) {\n evt.preventDefault();\n evt.stopPropagation();\n\n // Remove the ghost clone from document.body\n if (this.ghostElement) {\n this.ghostElement.remove();\n }\n\n // Restore visibility of the original element by clearing inline styles\n if (this.downEle) {\n this.downEle.style.display = this.originalDownDisplay;\n }\n\n // Clear visual effects before firing events\n this.hideDropPlaceholder();\n\n // fire the order changed event only when dropped if we have a valid drop position\n if (\n !this.isExternalDrag &&\n this.pendingDropIndex >= 0 &&\n this.pendingTargetElement\n ) {\n // Use the original drag index we captured before hiding the element\n const originalDragIdx = this.originalDragIndex;\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 AND this is not an external drag\n // External drags are handled by external drop handlers\n if (fromIdx !== toIdx && !this.isExternalDrag) {\n this.fireCustomEvent(CustomEventType.OrderChanged, {\n swap: [fromIdx, toIdx]\n });\n }\n }\n\n this.fireCustomEvent(CustomEventType.DragStop, {\n id: this.draggingId,\n isExternal: this.isExternalDrag,\n mouseX: evt.clientX,\n mouseY: evt.clientY\n });\n\n this.draggingId = null;\n this.dropTargetId = null;\n this.downEle = null;\n this.originalElementRect = null;\n this.originalDragIndex = -1;\n this.pendingDropIndex = -1;\n this.pendingTargetElement = null;\n this.isExternalDrag = false;\n\n // Clear the ghost reference since we removed it\n this.ghostElement = null;\n\n this.hideDropPlaceholder();\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\n class=\"container ${this.horizontal ? 'horizontal' : ''}\"\n style=\"gap: ${this.gap}\"\n >\n <slot @mousedown=${this.handleMouseDown}></slot>\n </div>\n `;\n }\n}\n"]}
|
|
@@ -81,6 +81,50 @@ describe('temba-canvas-menu', () => {
|
|
|
81
81
|
});
|
|
82
82
|
expect(menu.open).to.be.false;
|
|
83
83
|
});
|
|
84
|
+
it('shows reflow option when showReflow is true', async () => {
|
|
85
|
+
var _a;
|
|
86
|
+
const menu = await createCanvasMenu();
|
|
87
|
+
menu.show(100, 100, { x: 50, y: 50 }, true, true);
|
|
88
|
+
await menu.updateComplete;
|
|
89
|
+
const menuItems = (_a = menu.shadowRoot) === null || _a === void 0 ? void 0 : _a.querySelectorAll('.menu-item');
|
|
90
|
+
expect(menuItems === null || menuItems === void 0 ? void 0 : menuItems.length).to.equal(4);
|
|
91
|
+
const titles = Array.from(menuItems || []).map((item) => { var _a; return (_a = item.querySelector('.menu-item-title')) === null || _a === void 0 ? void 0 : _a.textContent; });
|
|
92
|
+
expect(titles).to.deep.equal([
|
|
93
|
+
'Add Action',
|
|
94
|
+
'Add Split',
|
|
95
|
+
'Add Sticky Note',
|
|
96
|
+
'Reflow'
|
|
97
|
+
]);
|
|
98
|
+
});
|
|
99
|
+
it('fires reflow selection event when reflow is clicked', async () => {
|
|
100
|
+
var _a;
|
|
101
|
+
const menu = await createCanvasMenu();
|
|
102
|
+
menu.show(100, 100, { x: 50, y: 50 }, true, true);
|
|
103
|
+
await menu.updateComplete;
|
|
104
|
+
let selectionDetail = null;
|
|
105
|
+
menu.addEventListener('temba-selection', (event) => {
|
|
106
|
+
selectionDetail = event.detail;
|
|
107
|
+
});
|
|
108
|
+
const menuItems = (_a = menu.shadowRoot) === null || _a === void 0 ? void 0 : _a.querySelectorAll('.menu-item');
|
|
109
|
+
const reflowItem = menuItems === null || menuItems === void 0 ? void 0 : menuItems[3];
|
|
110
|
+
reflowItem.click();
|
|
111
|
+
await menu.updateComplete;
|
|
112
|
+
expect(selectionDetail).to.deep.equal({
|
|
113
|
+
action: 'reflow',
|
|
114
|
+
position: { x: 50, y: 50 }
|
|
115
|
+
});
|
|
116
|
+
expect(menu.open).to.be.false;
|
|
117
|
+
});
|
|
118
|
+
it('hides reflow option by default', async () => {
|
|
119
|
+
var _a;
|
|
120
|
+
const menu = await createCanvasMenu();
|
|
121
|
+
menu.show(100, 100, { x: 50, y: 50 });
|
|
122
|
+
await menu.updateComplete;
|
|
123
|
+
const menuItems = (_a = menu.shadowRoot) === null || _a === void 0 ? void 0 : _a.querySelectorAll('.menu-item');
|
|
124
|
+
expect(menuItems === null || menuItems === void 0 ? void 0 : menuItems.length).to.equal(3);
|
|
125
|
+
const titles = Array.from(menuItems || []).map((item) => { var _a; return (_a = item.querySelector('.menu-item-title')) === null || _a === void 0 ? void 0 : _a.textContent; });
|
|
126
|
+
expect(titles).to.not.include('Reflow');
|
|
127
|
+
});
|
|
84
128
|
it('adjusts position to stay within viewport bounds', async () => {
|
|
85
129
|
var _a, _b;
|
|
86
130
|
const menu = await createCanvasMenu();
|