@nyaruka/temba-components 0.129.8 → 0.129.10
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 +37 -3
- package/demo/data/flows/sample-flow.json +186 -96
- package/demo/test-colorpicker.html +30 -0
- package/dist/temba-components.js +1126 -1111
- package/dist/temba-components.js.map +1 -1
- package/out-tsc/src/events.js.map +1 -1
- package/out-tsc/src/excellent/helpers.js +2 -2
- package/out-tsc/src/excellent/helpers.js.map +1 -1
- package/out-tsc/src/flow/CanvasNode.js +25 -7
- package/out-tsc/src/flow/CanvasNode.js.map +1 -1
- package/out-tsc/src/flow/Editor.js +11 -1
- package/out-tsc/src/flow/Editor.js.map +1 -1
- package/out-tsc/src/flow/NodeEditor.js +133 -290
- package/out-tsc/src/flow/NodeEditor.js.map +1 -1
- package/out-tsc/src/flow/actions/add_input_labels.js +40 -0
- package/out-tsc/src/flow/actions/add_input_labels.js.map +1 -1
- package/out-tsc/src/flow/actions/call_llm.js +56 -3
- package/out-tsc/src/flow/actions/call_llm.js.map +1 -1
- package/out-tsc/src/flow/actions/call_webhook.js +1 -1
- package/out-tsc/src/flow/actions/call_webhook.js.map +1 -1
- package/out-tsc/src/flow/actions/open_ticket.js +65 -3
- package/out-tsc/src/flow/actions/open_ticket.js.map +1 -1
- package/out-tsc/src/flow/actions/set_run_result.js +75 -0
- package/out-tsc/src/flow/actions/set_run_result.js.map +1 -1
- package/out-tsc/src/flow/config.js +4 -0
- package/out-tsc/src/flow/config.js.map +1 -1
- package/out-tsc/src/flow/nodes/split_by_llm_categorize.js +227 -0
- package/out-tsc/src/flow/nodes/split_by_llm_categorize.js.map +1 -0
- package/out-tsc/src/flow/nodes/split_by_ticket.js +18 -0
- package/out-tsc/src/flow/nodes/split_by_ticket.js.map +1 -0
- package/out-tsc/src/flow/nodes/wait_for_response.js +27 -1
- package/out-tsc/src/flow/nodes/wait_for_response.js.map +1 -1
- package/out-tsc/src/flow/types.js +0 -65
- package/out-tsc/src/flow/types.js.map +1 -1
- package/out-tsc/src/form/ArrayEditor.js +63 -117
- package/out-tsc/src/form/ArrayEditor.js.map +1 -1
- package/out-tsc/src/form/BaseListEditor.js +4 -3
- package/out-tsc/src/form/BaseListEditor.js.map +1 -1
- package/out-tsc/src/form/Checkbox.js +77 -24
- package/out-tsc/src/form/Checkbox.js.map +1 -1
- package/out-tsc/src/form/ColorPicker.js +28 -40
- package/out-tsc/src/form/ColorPicker.js.map +1 -1
- package/out-tsc/src/form/Completion.js +44 -53
- package/out-tsc/src/form/Completion.js.map +1 -1
- package/out-tsc/src/form/Compose.js +7 -8
- package/out-tsc/src/form/Compose.js.map +1 -1
- package/out-tsc/src/form/ContactSearch.js +3 -4
- package/out-tsc/src/form/ContactSearch.js.map +1 -1
- package/out-tsc/src/form/DatePicker.js +29 -36
- package/out-tsc/src/form/DatePicker.js.map +1 -1
- package/out-tsc/src/form/{FormField.js → FieldElement.js} +81 -53
- package/out-tsc/src/form/FieldElement.js.map +1 -0
- package/out-tsc/src/form/FieldRenderer.js +306 -0
- package/out-tsc/src/form/FieldRenderer.js.map +1 -0
- package/out-tsc/src/form/ImagePicker.js +122 -126
- package/out-tsc/src/form/ImagePicker.js.map +1 -1
- package/out-tsc/src/form/KeyValueEditor.js +41 -37
- package/out-tsc/src/form/KeyValueEditor.js.map +1 -1
- package/out-tsc/src/form/MessageEditor.js +55 -63
- package/out-tsc/src/form/MessageEditor.js.map +1 -1
- package/out-tsc/src/form/TembaSlider.js +3 -3
- package/out-tsc/src/form/TembaSlider.js.map +1 -1
- package/out-tsc/src/form/TemplateEditor.js +3 -3
- package/out-tsc/src/form/TemplateEditor.js.map +1 -1
- package/out-tsc/src/form/TextInput.js +23 -27
- package/out-tsc/src/form/TextInput.js.map +1 -1
- package/out-tsc/src/form/select/Select.js +57 -35
- package/out-tsc/src/form/select/Select.js.map +1 -1
- package/out-tsc/src/form/select/UserSelect.js +8 -9
- package/out-tsc/src/form/select/UserSelect.js.map +1 -1
- package/out-tsc/src/form/select/WorkspaceSelect.js +7 -8
- package/out-tsc/src/form/select/WorkspaceSelect.js.map +1 -1
- package/out-tsc/src/live/ContactChat.js +62 -44
- package/out-tsc/src/live/ContactChat.js.map +1 -1
- package/out-tsc/src/live/ContactFieldEditor.js.map +1 -1
- package/out-tsc/src/markdown.js +13 -11
- package/out-tsc/src/markdown.js.map +1 -1
- package/out-tsc/temba-modules.js +3 -2
- package/out-tsc/temba-modules.js.map +1 -1
- package/out-tsc/test/ActionHelper.js +2 -0
- package/out-tsc/test/ActionHelper.js.map +1 -1
- package/out-tsc/test/NodeHelper.js +148 -0
- package/out-tsc/test/NodeHelper.js.map +1 -0
- package/out-tsc/test/actions/call_llm.test.js +103 -0
- package/out-tsc/test/actions/call_llm.test.js.map +1 -0
- package/out-tsc/test/nodes/split_by_llm_categorize.test.js +532 -0
- package/out-tsc/test/nodes/split_by_llm_categorize.test.js.map +1 -0
- package/out-tsc/test/nodes/split_by_random.test.js +150 -0
- package/out-tsc/test/nodes/split_by_random.test.js.map +1 -0
- package/out-tsc/test/nodes/wait_for_digits.test.js +150 -0
- package/out-tsc/test/nodes/wait_for_digits.test.js.map +1 -0
- package/out-tsc/test/nodes/wait_for_response.test.js +171 -0
- package/out-tsc/test/nodes/wait_for_response.test.js.map +1 -0
- package/out-tsc/test/temba-add-input-labels.test.js +70 -0
- package/out-tsc/test/temba-add-input-labels.test.js.map +1 -0
- package/out-tsc/test/temba-checkbox.test.js +16 -0
- package/out-tsc/test/temba-checkbox.test.js.map +1 -1
- package/out-tsc/test/temba-field-renderer.test.js +296 -0
- package/out-tsc/test/temba-field-renderer.test.js.map +1 -0
- package/out-tsc/test/temba-integration-markdown.test.js +2 -4
- package/out-tsc/test/temba-integration-markdown.test.js.map +1 -1
- package/out-tsc/test/temba-markdown.test.js +1 -1
- package/out-tsc/test/temba-markdown.test.js.map +1 -1
- package/out-tsc/test/temba-node-editor.test.js +400 -0
- package/out-tsc/test/temba-node-editor.test.js.map +1 -1
- package/out-tsc/test/temba-select.test.js +6 -3
- package/out-tsc/test/temba-select.test.js.map +1 -1
- package/out-tsc/test/temba-slider.test.js +0 -1
- package/out-tsc/test/temba-slider.test.js.map +1 -1
- package/out-tsc/test/temba-webchat.test.js +1 -1
- package/out-tsc/test/temba-webchat.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/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/remove_contact_groups/editor/cleanup-groups.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/remove_contact_groups/editor/multiple-groups.png +0 -0
- package/screenshots/truth/actions/remove_contact_groups/editor/remove-from-all-groups.png +0 -0
- package/screenshots/truth/actions/remove_contact_groups/editor/single-group.png +0 -0
- package/screenshots/truth/actions/send_email/editor/complex-business-email.png +0 -0
- package/screenshots/truth/actions/send_email/editor/multiple-recipients.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/checkbox/checkbox-label-background-hover.png +0 -0
- package/screenshots/truth/checkbox/checkbox-no-label-no-background-hover.png +0 -0
- package/screenshots/truth/checkbox/checkbox-with-help-text.png +0 -0
- package/screenshots/truth/checkbox/checked.png +0 -0
- package/screenshots/truth/checkbox/default.png +0 -0
- package/screenshots/truth/colorpicker/default.png +0 -0
- package/screenshots/truth/colorpicker/focused.png +0 -0
- package/screenshots/truth/colorpicker/initialized.png +0 -0
- package/screenshots/truth/colorpicker/selected.png +0 -0
- package/screenshots/truth/editor/router.png +0 -0
- package/screenshots/truth/editor/send_msg.png +0 -0
- package/screenshots/truth/editor/set_contact_language.png +0 -0
- package/screenshots/truth/editor/set_contact_name.png +0 -0
- package/screenshots/truth/editor/set_run_result.png +0 -0
- package/screenshots/truth/editor/wait.png +0 -0
- package/screenshots/truth/field-renderer/checkbox-checked.png +0 -0
- package/screenshots/truth/field-renderer/checkbox-unchecked.png +0 -0
- package/screenshots/truth/field-renderer/checkbox-with-errors.png +0 -0
- package/screenshots/truth/field-renderer/context-comparison.png +0 -0
- package/screenshots/truth/field-renderer/key-value-with-label.png +0 -0
- package/screenshots/truth/field-renderer/message-editor-with-label.png +0 -0
- package/screenshots/truth/field-renderer/select-multi.png +0 -0
- package/screenshots/truth/field-renderer/select-no-label.png +0 -0
- package/screenshots/truth/field-renderer/select-with-label.png +0 -0
- package/screenshots/truth/field-renderer/text-evaluated.png +0 -0
- package/screenshots/truth/field-renderer/text-no-label.png +0 -0
- package/screenshots/truth/field-renderer/text-with-errors.png +0 -0
- package/screenshots/truth/field-renderer/text-with-label.png +0 -0
- package/screenshots/truth/field-renderer/textarea-evaluated.png +0 -0
- package/screenshots/truth/field-renderer/textarea-with-label.png +0 -0
- package/screenshots/truth/integration/checkbox-markdown-errors.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_llm_categorize/render/basic-categorization.png +0 -0
- package/screenshots/truth/nodes/split_by_llm_categorize/render/custom-input-and-result-name.png +0 -0
- package/screenshots/truth/nodes/split_by_llm_categorize/render/feedback-categorization.png +0 -0
- package/screenshots/truth/nodes/split_by_llm_categorize/render/many-categories.png +0 -0
- package/screenshots/truth/nodes/split_by_llm_categorize/render/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/split_by_random/render/ab-test-multiple-variants.png +0 -0
- package/screenshots/truth/nodes/split_by_random/render/sampling-split.png +0 -0
- package/screenshots/truth/nodes/split_by_random/render/three-way-split.png +0 -0
- package/screenshots/truth/nodes/split_by_random/render/two-bucket-split.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/phone-number-collection.png +0 -0
- package/screenshots/truth/nodes/wait_for_digits/editor/single-digit-with-timeout.png +0 -0
- package/screenshots/truth/nodes/wait_for_digits/editor/verification-code.png +0 -0
- package/screenshots/truth/nodes/wait_for_digits/render/basic-digits-wait.png +0 -0
- package/screenshots/truth/nodes/wait_for_digits/render/phone-number-collection.png +0 -0
- package/screenshots/truth/nodes/wait_for_digits/render/single-digit-with-timeout.png +0 -0
- package/screenshots/truth/nodes/wait_for_digits/render/verification-code.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/screenshots/truth/nodes/wait_for_response/render/basic-wait.png +0 -0
- package/screenshots/truth/nodes/wait_for_response/render/custom-result-name.png +0 -0
- package/screenshots/truth/nodes/wait_for_response/render/no-timeout.png +0 -0
- package/screenshots/truth/nodes/wait_for_response/render/short-timeout.png +0 -0
- package/screenshots/truth/omnibox/selected.png +0 -0
- package/screenshots/truth/run-list/basic.png +0 -0
- package/screenshots/truth/select/functions.png +0 -0
- package/screenshots/truth/select/multi-with-endpoint.png +0 -0
- package/screenshots/truth/select/search-enabled.png +0 -0
- package/src/events.ts +12 -6
- package/src/excellent/helpers.ts +2 -2
- package/src/flow/CanvasNode.ts +22 -1
- package/src/flow/Editor.ts +12 -1
- package/src/flow/NodeEditor.ts +186 -374
- package/src/flow/actions/add_input_labels.ts +45 -0
- package/src/flow/actions/call_llm.ts +57 -3
- package/src/flow/actions/call_webhook.ts +1 -1
- package/src/flow/actions/open_ticket.ts +74 -3
- package/src/flow/actions/set_run_result.ts +83 -0
- package/src/flow/config.ts +4 -0
- package/src/flow/nodes/split_by_llm_categorize.ts +277 -0
- package/src/flow/nodes/split_by_ticket.ts +19 -0
- package/src/flow/nodes/wait_for_response.ts +28 -1
- package/src/flow/types.ts +26 -127
- package/src/form/ArrayEditor.ts +79 -139
- package/src/form/BaseListEditor.ts +4 -4
- package/src/form/Checkbox.ts +81 -24
- package/src/form/ColorPicker.ts +31 -43
- package/src/form/Completion.ts +49 -56
- package/src/form/Compose.ts +8 -8
- package/src/form/ContactSearch.ts +3 -4
- package/src/form/DatePicker.ts +32 -38
- package/src/form/{FormField.ts → FieldElement.ts} +108 -55
- package/src/form/FieldRenderer.ts +466 -0
- package/src/form/ImagePicker.ts +107 -110
- package/src/form/KeyValueEditor.ts +43 -39
- package/src/form/MessageEditor.ts +61 -67
- package/src/form/TembaSlider.ts +3 -3
- package/src/form/TemplateEditor.ts +3 -3
- package/src/form/TextInput.ts +26 -29
- package/src/form/select/Select.ts +63 -37
- package/src/form/select/UserSelect.ts +10 -11
- package/src/form/select/WorkspaceSelect.ts +9 -10
- package/src/live/ContactChat.ts +62 -47
- package/src/live/ContactFieldEditor.ts +2 -2
- package/src/markdown.ts +19 -11
- package/src/store/flow-definition.d.ts +5 -2
- package/static/api/labels.json +31 -0
- package/static/api/topics.json +24 -9
- package/static/api/users.json +35 -16
- package/static/css/temba-components.css +3 -3
- package/stress-test.js +18 -13
- package/temba-modules.ts +3 -2
- package/test/ActionHelper.ts +2 -0
- package/test/NodeHelper.ts +184 -0
- package/test/actions/call_llm.test.ts +137 -0
- package/test/nodes/README.md +78 -0
- package/test/nodes/split_by_llm_categorize.test.ts +698 -0
- package/test/nodes/split_by_random.test.ts +177 -0
- package/test/nodes/wait_for_digits.test.ts +176 -0
- package/test/nodes/wait_for_response.test.ts +206 -0
- package/test/temba-add-input-labels.test.ts +87 -0
- package/test/temba-checkbox.test.ts +26 -0
- package/test/temba-field-renderer.test.ts +482 -0
- package/test/temba-integration-markdown.test.ts +2 -4
- package/test/temba-markdown.test.ts +1 -1
- package/test/temba-node-editor.test.ts +496 -0
- package/test/temba-select.test.ts +6 -6
- package/test/temba-slider.test.ts +0 -1
- package/test/temba-webchat.test.ts +1 -1
- package/test-assets/contacts/history.json +7 -20
- package/test-assets/select/llms.json +18 -0
- package/web-dev-mock.mjs +96 -6
- package/web-dev-server.config.mjs +29 -7
- package/out-tsc/src/form/FormElement.js +0 -67
- package/out-tsc/src/form/FormElement.js.map +0 -1
- package/out-tsc/src/form/FormField.js.map +0 -1
- package/out-tsc/test/temba-formfield.test.js +0 -94
- package/out-tsc/test/temba-formfield.test.js.map +0 -1
- package/src/form/FormElement.ts +0 -69
- package/test/temba-flow-editor.test.ts.backup +0 -563
- package/test/temba-formfield.test.ts +0 -121
- package/test/temba-utils-index.test.ts.backup +0 -1737
package/src/flow/types.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { TemplateResult } from 'lit-html';
|
|
2
|
-
import { Action } from '../store/flow-definition';
|
|
2
|
+
import { Action, Node } from '../store/flow-definition';
|
|
3
3
|
|
|
4
4
|
export interface ValidationResult {
|
|
5
5
|
valid: boolean;
|
|
@@ -65,39 +65,16 @@ export interface SliderAttributes {
|
|
|
65
65
|
range?: boolean;
|
|
66
66
|
}
|
|
67
67
|
|
|
68
|
-
|
|
69
|
-
export type WidgetConfig =
|
|
70
|
-
| { type: 'temba-textinput'; attributes?: TextInputAttributes }
|
|
71
|
-
| { type: 'temba-completion'; attributes?: CompletionAttributes }
|
|
72
|
-
| { type: 'temba-select'; attributes?: SelectAttributes }
|
|
73
|
-
| { type: 'temba-checkbox'; attributes?: CheckboxAttributes }
|
|
74
|
-
| { type: 'temba-slider'; attributes?: SliderAttributes }
|
|
75
|
-
| { type: string; attributes?: { [key: string]: any } }; // Generic fallback
|
|
68
|
+
export interface FormData extends Record<string, any> {}
|
|
76
69
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
required?: boolean;
|
|
83
|
-
maxLength?: number;
|
|
84
|
-
minLength?: number;
|
|
85
|
-
pattern?: string;
|
|
86
|
-
|
|
87
|
-
// Widget configuration
|
|
88
|
-
widget: WidgetConfig;
|
|
89
|
-
|
|
90
|
-
// Conditional behavior based on other field values
|
|
91
|
-
conditions?: {
|
|
92
|
-
// When to show this field
|
|
93
|
-
visible?: (formData: any) => boolean;
|
|
94
|
-
|
|
95
|
-
// When this field is disabled
|
|
96
|
-
disabled?: (formData: any) => boolean;
|
|
97
|
-
};
|
|
70
|
+
export interface FormConfig {
|
|
71
|
+
form?: Record<string, FieldConfig>;
|
|
72
|
+
layout?: LayoutItem[];
|
|
73
|
+
sanitize?: (formData: FormData) => void;
|
|
74
|
+
validate?: (formData: FormData) => ValidationResult;
|
|
98
75
|
}
|
|
99
76
|
|
|
100
|
-
export interface NodeConfig {
|
|
77
|
+
export interface NodeConfig extends FormConfig {
|
|
101
78
|
type: string;
|
|
102
79
|
name?: string;
|
|
103
80
|
color?: string;
|
|
@@ -108,22 +85,28 @@ export interface NodeConfig {
|
|
|
108
85
|
operand?: string;
|
|
109
86
|
configurable?: boolean; // can the rules be configured in the UI
|
|
110
87
|
rules?: {
|
|
111
|
-
type:
|
|
88
|
+
type:
|
|
89
|
+
| 'has_number_between'
|
|
90
|
+
| 'has_string'
|
|
91
|
+
| 'has_value'
|
|
92
|
+
| 'has_not_value'
|
|
93
|
+
| 'has_text';
|
|
112
94
|
arguments: string[];
|
|
113
95
|
categoryName: string;
|
|
114
96
|
}[];
|
|
115
97
|
};
|
|
116
|
-
|
|
117
|
-
toFormData?: (node:
|
|
118
|
-
fromFormData?: (formData:
|
|
98
|
+
|
|
99
|
+
toFormData?: (node: Node) => FormData;
|
|
100
|
+
fromFormData?: (formData: FormData, originalNode: Node) => Node;
|
|
101
|
+
render?: (node: Node) => TemplateResult;
|
|
119
102
|
}
|
|
120
103
|
|
|
121
104
|
// New field configuration system for generic form generation
|
|
122
105
|
export interface BaseFieldConfig {
|
|
123
106
|
label?: string;
|
|
124
107
|
required?: boolean;
|
|
125
|
-
evaluated?: boolean;
|
|
126
|
-
dependsOn?: string[];
|
|
108
|
+
evaluated?: boolean;
|
|
109
|
+
dependsOn?: string[];
|
|
127
110
|
computeValue?: (
|
|
128
111
|
values: Record<string, any>,
|
|
129
112
|
currentValue: any,
|
|
@@ -137,7 +120,7 @@ export interface BaseFieldConfig {
|
|
|
137
120
|
helpText?: string;
|
|
138
121
|
|
|
139
122
|
// Layout properties
|
|
140
|
-
maxWidth?: string;
|
|
123
|
+
maxWidth?: string;
|
|
141
124
|
|
|
142
125
|
// Conditional rendering
|
|
143
126
|
conditions?: {
|
|
@@ -160,7 +143,7 @@ export interface TextareaFieldConfig extends BaseFieldConfig {
|
|
|
160
143
|
|
|
161
144
|
export interface SelectFieldConfig extends BaseFieldConfig {
|
|
162
145
|
type: 'select';
|
|
163
|
-
options
|
|
146
|
+
options?: string[] | { value: string; label: string }[];
|
|
164
147
|
multi?: boolean;
|
|
165
148
|
clearable?: boolean;
|
|
166
149
|
searchable?: boolean;
|
|
@@ -171,7 +154,10 @@ export interface SelectFieldConfig extends BaseFieldConfig {
|
|
|
171
154
|
nameKey?: string;
|
|
172
155
|
endpoint?: string;
|
|
173
156
|
emails?: boolean;
|
|
157
|
+
getName?: (item: any) => string;
|
|
174
158
|
flavor?: 'small' | 'large';
|
|
159
|
+
createArbitraryOption?: (input: string, options: any[]) => any;
|
|
160
|
+
allowCreate?: boolean;
|
|
175
161
|
}
|
|
176
162
|
|
|
177
163
|
export interface KeyValueFieldConfig extends BaseFieldConfig {
|
|
@@ -256,7 +242,7 @@ export type LayoutItem =
|
|
|
256
242
|
| GroupLayoutConfig
|
|
257
243
|
| string; // string is shorthand for field
|
|
258
244
|
|
|
259
|
-
export interface ActionConfig {
|
|
245
|
+
export interface ActionConfig extends FormConfig {
|
|
260
246
|
name: string;
|
|
261
247
|
color: string;
|
|
262
248
|
evaluated?: string[];
|
|
@@ -265,13 +251,8 @@ export interface ActionConfig {
|
|
|
265
251
|
form?: Record<string, FieldConfig>;
|
|
266
252
|
layout?: LayoutItem[]; // optional layout configuration - array of layout items
|
|
267
253
|
|
|
268
|
-
// Action editor configuration (legacy)
|
|
269
|
-
// Form-level transformations
|
|
270
|
-
sanitize?: (formData: any) => any;
|
|
271
254
|
toFormData?: (action: Action) => any;
|
|
272
255
|
fromFormData?: (formData: any) => Action;
|
|
273
|
-
|
|
274
|
-
validate?: (action: Action) => ValidationResult;
|
|
275
256
|
}
|
|
276
257
|
|
|
277
258
|
export const COLORS = {
|
|
@@ -287,85 +268,3 @@ export const COLORS = {
|
|
|
287
268
|
add: '#309c42',
|
|
288
269
|
remove: '#e74c3c'
|
|
289
270
|
};
|
|
290
|
-
|
|
291
|
-
// Default property type mappings
|
|
292
|
-
export function getDefaultComponent(value: any): WidgetConfig['type'] {
|
|
293
|
-
if (typeof value === 'boolean') {
|
|
294
|
-
return 'temba-checkbox';
|
|
295
|
-
}
|
|
296
|
-
if (typeof value === 'number') {
|
|
297
|
-
return 'temba-textinput';
|
|
298
|
-
}
|
|
299
|
-
if (Array.isArray(value)) {
|
|
300
|
-
return 'temba-select'; // For arrays, use multi-select
|
|
301
|
-
}
|
|
302
|
-
// Default to text input for strings and unknown types
|
|
303
|
-
return 'temba-textinput';
|
|
304
|
-
}
|
|
305
|
-
|
|
306
|
-
// Get component properties for default mappings with proper typing
|
|
307
|
-
export function getDefaultComponentProps(value: any): PropertyConfig {
|
|
308
|
-
if (typeof value === 'boolean') {
|
|
309
|
-
return {
|
|
310
|
-
widget: { type: 'temba-checkbox' }
|
|
311
|
-
};
|
|
312
|
-
}
|
|
313
|
-
if (typeof value === 'number') {
|
|
314
|
-
return {
|
|
315
|
-
widget: {
|
|
316
|
-
type: 'temba-textinput',
|
|
317
|
-
attributes: { type: 'number' }
|
|
318
|
-
}
|
|
319
|
-
};
|
|
320
|
-
}
|
|
321
|
-
if (Array.isArray(value)) {
|
|
322
|
-
if (value.length > 0 && typeof value[0] === 'string') {
|
|
323
|
-
return {
|
|
324
|
-
widget: {
|
|
325
|
-
type: 'temba-select',
|
|
326
|
-
attributes: { multi: true, tags: true }
|
|
327
|
-
}
|
|
328
|
-
};
|
|
329
|
-
}
|
|
330
|
-
return {
|
|
331
|
-
widget: {
|
|
332
|
-
type: 'temba-select',
|
|
333
|
-
attributes: { multi: true }
|
|
334
|
-
}
|
|
335
|
-
};
|
|
336
|
-
}
|
|
337
|
-
return {
|
|
338
|
-
widget: { type: 'temba-textinput' }
|
|
339
|
-
};
|
|
340
|
-
}
|
|
341
|
-
|
|
342
|
-
// Type guard functions for working with WidgetConfig
|
|
343
|
-
export function isTextInputWidget(
|
|
344
|
-
config: WidgetConfig
|
|
345
|
-
): config is { type: 'temba-textinput'; attributes?: TextInputAttributes } {
|
|
346
|
-
return config.type === 'temba-textinput';
|
|
347
|
-
}
|
|
348
|
-
|
|
349
|
-
export function isCompletionWidget(
|
|
350
|
-
config: WidgetConfig
|
|
351
|
-
): config is { type: 'temba-completion'; attributes?: CompletionAttributes } {
|
|
352
|
-
return config.type === 'temba-completion';
|
|
353
|
-
}
|
|
354
|
-
|
|
355
|
-
export function isSelectWidget(
|
|
356
|
-
config: WidgetConfig
|
|
357
|
-
): config is { type: 'temba-select'; attributes?: SelectAttributes } {
|
|
358
|
-
return config.type === 'temba-select';
|
|
359
|
-
}
|
|
360
|
-
|
|
361
|
-
export function isCheckboxWidget(
|
|
362
|
-
config: WidgetConfig
|
|
363
|
-
): config is { type: 'temba-checkbox'; attributes?: CheckboxAttributes } {
|
|
364
|
-
return config.type === 'temba-checkbox';
|
|
365
|
-
}
|
|
366
|
-
|
|
367
|
-
export function isSliderWidget(
|
|
368
|
-
config: WidgetConfig
|
|
369
|
-
): config is { type: 'slider'; attributes?: SliderAttributes } {
|
|
370
|
-
return config.type === 'temba-slider';
|
|
371
|
-
}
|
package/src/form/ArrayEditor.ts
CHANGED
|
@@ -2,6 +2,7 @@ import { html, css, TemplateResult } from 'lit';
|
|
|
2
2
|
import { customElement, property } from 'lit/decorators.js';
|
|
3
3
|
import { FieldConfig, SelectFieldConfig } from '../flow/types';
|
|
4
4
|
import { BaseListEditor, ListItem } from './BaseListEditor';
|
|
5
|
+
import { FieldRenderer } from './FieldRenderer';
|
|
5
6
|
|
|
6
7
|
@customElement('temba-array-editor')
|
|
7
8
|
export class TembaArrayEditor extends BaseListEditor<ListItem> {
|
|
@@ -125,94 +126,49 @@ export class TembaArrayEditor extends BaseListEditor<ListItem> {
|
|
|
125
126
|
return currentValue;
|
|
126
127
|
}
|
|
127
128
|
|
|
128
|
-
private
|
|
129
|
+
private renderArrayField(
|
|
129
130
|
itemIndex: number,
|
|
130
131
|
fieldName: string,
|
|
131
132
|
config: FieldConfig
|
|
132
133
|
): TemplateResult {
|
|
133
134
|
const computedValue = this.computeFieldValue(itemIndex, fieldName, config);
|
|
134
135
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
.
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
@change=${(e: any) =>
|
|
151
|
-
this.handleFieldChange(itemIndex, fieldName, e.target.value)}
|
|
152
|
-
></temba-textinput>`;
|
|
153
|
-
|
|
154
|
-
case 'select': {
|
|
155
|
-
const selectConfig = config as SelectFieldConfig;
|
|
156
|
-
const fieldValue = this.computeFieldValue(itemIndex, fieldName, config);
|
|
157
|
-
|
|
158
|
-
return html`<temba-select
|
|
159
|
-
class="form-control"
|
|
160
|
-
?clearable="${selectConfig.clearable || false}"
|
|
161
|
-
?searchable="${selectConfig.searchable || false}"
|
|
162
|
-
?tags="${selectConfig.tags || false}"
|
|
163
|
-
?multi="${selectConfig.multi || false}"
|
|
164
|
-
?emails="${selectConfig.emails || false}"
|
|
165
|
-
placeholder="${selectConfig.placeholder || ''}"
|
|
166
|
-
maxItems="${selectConfig.maxItems || 0}"
|
|
167
|
-
valueKey="${selectConfig.valueKey || 'value'}"
|
|
168
|
-
nameKey="${selectConfig.nameKey || 'name'}"
|
|
169
|
-
endpoint="${selectConfig.endpoint || ''}"
|
|
170
|
-
value="${fieldValue || ''}"
|
|
171
|
-
flavor="small"
|
|
172
|
-
@change="${(e: Event) => {
|
|
173
|
-
const target = e.target as any;
|
|
174
|
-
let value: any;
|
|
175
|
-
|
|
176
|
-
// For temba-select, extract the correct value
|
|
177
|
-
if (target.tagName === 'TEMBA-SELECT') {
|
|
178
|
-
if (target.multi || target.emails || target.tags) {
|
|
179
|
-
value = target.values || [];
|
|
180
|
-
} else {
|
|
181
|
-
// Single select: extract value from first selected option
|
|
182
|
-
const values = target.values || [];
|
|
183
|
-
value =
|
|
184
|
-
values.length > 0 && values[0]
|
|
185
|
-
? values[0].value !== undefined
|
|
186
|
-
? values[0].value
|
|
187
|
-
: values[0]
|
|
188
|
-
: '';
|
|
189
|
-
}
|
|
136
|
+
// Use FieldRenderer for consistent field rendering
|
|
137
|
+
return FieldRenderer.renderField(fieldName, config, computedValue, {
|
|
138
|
+
showLabel: false, // ArrayEditor doesn't show labels for individual fields
|
|
139
|
+
flavor: 'small', // ArrayEditor uses small flavor
|
|
140
|
+
extraClasses: 'form-control',
|
|
141
|
+
onChange: (e: Event) => {
|
|
142
|
+
let value: any;
|
|
143
|
+
const target = e.target as any;
|
|
144
|
+
|
|
145
|
+
// Handle different field types and their change events
|
|
146
|
+
if (config.type === 'select') {
|
|
147
|
+
// For temba-select, extract the correct value
|
|
148
|
+
if (target.tagName === 'TEMBA-SELECT') {
|
|
149
|
+
if (target.multi || target.emails || target.tags) {
|
|
150
|
+
value = target.values || [];
|
|
190
151
|
} else {
|
|
191
|
-
value
|
|
152
|
+
// Single select: extract value from first selected option
|
|
153
|
+
const values = target.values || [];
|
|
154
|
+
value =
|
|
155
|
+
values.length > 0 && values[0]
|
|
156
|
+
? values[0].value !== undefined
|
|
157
|
+
? values[0].value
|
|
158
|
+
: values[0]
|
|
159
|
+
: '';
|
|
192
160
|
}
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
></temba-option>`;
|
|
203
|
-
} else {
|
|
204
|
-
return html`<temba-option
|
|
205
|
-
name="${option.label || option.name}"
|
|
206
|
-
value="${option.value}"
|
|
207
|
-
></temba-option>`;
|
|
208
|
-
}
|
|
209
|
-
})}
|
|
210
|
-
</temba-select>`;
|
|
161
|
+
} else {
|
|
162
|
+
value = target.value;
|
|
163
|
+
}
|
|
164
|
+
} else {
|
|
165
|
+
// For other field types, use the target value directly
|
|
166
|
+
value = target.value;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
this.handleFieldChange(itemIndex, fieldName, value);
|
|
211
170
|
}
|
|
212
|
-
|
|
213
|
-
default:
|
|
214
|
-
return html`<span>Unsupported field type: ${config.type}</span>`;
|
|
215
|
-
}
|
|
171
|
+
});
|
|
216
172
|
}
|
|
217
173
|
|
|
218
174
|
renderItem(item: ListItem, index: number): TemplateResult {
|
|
@@ -224,7 +180,7 @@ export class TembaArrayEditor extends BaseListEditor<ListItem> {
|
|
|
224
180
|
${Object.entries(this.itemConfig).map(
|
|
225
181
|
([fieldName, config]) => html`
|
|
226
182
|
<div class="field">
|
|
227
|
-
${this.
|
|
183
|
+
${this.renderArrayField(index, fieldName, config)}
|
|
228
184
|
</div>
|
|
229
185
|
`
|
|
230
186
|
)}
|
|
@@ -247,72 +203,56 @@ export class TembaArrayEditor extends BaseListEditor<ListItem> {
|
|
|
247
203
|
return 'array-editor';
|
|
248
204
|
}
|
|
249
205
|
|
|
250
|
-
|
|
251
|
-
return
|
|
252
|
-
|
|
253
|
-
Add ${this.itemLabel}
|
|
254
|
-
</button>
|
|
255
|
-
`;
|
|
256
|
-
}
|
|
206
|
+
static get styles() {
|
|
207
|
+
return css`
|
|
208
|
+
${super.styles}
|
|
257
209
|
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
.array-item {
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
.item-header {
|
|
266
|
-
display: flex;
|
|
267
|
-
justify-content: space-between;
|
|
268
|
-
align-items: center;
|
|
269
|
-
}
|
|
210
|
+
.array-editor {
|
|
211
|
+
}
|
|
270
212
|
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
color: #333;
|
|
274
|
-
}
|
|
213
|
+
.array-item {
|
|
214
|
+
}
|
|
275
215
|
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
216
|
+
.item-header {
|
|
217
|
+
display: flex;
|
|
218
|
+
justify-content: space-between;
|
|
219
|
+
align-items: center;
|
|
220
|
+
}
|
|
281
221
|
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
222
|
+
.item-title {
|
|
223
|
+
font-weight: 600;
|
|
224
|
+
color: #333;
|
|
225
|
+
}
|
|
285
226
|
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
227
|
+
.item-fields {
|
|
228
|
+
display: flex;
|
|
229
|
+
gap: 12px;
|
|
230
|
+
align-items: center;
|
|
231
|
+
}
|
|
289
232
|
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
font-weight: 500;
|
|
294
|
-
color: #555;
|
|
295
|
-
font-size: 14px;
|
|
296
|
-
}
|
|
233
|
+
.field {
|
|
234
|
+
flex: 1;
|
|
235
|
+
}
|
|
297
236
|
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
237
|
+
.add-btn,
|
|
238
|
+
.remove-btn {
|
|
239
|
+
padding: 8px;
|
|
240
|
+
border: 1px solid #ccc;
|
|
241
|
+
border-radius: 4px;
|
|
242
|
+
background: white;
|
|
243
|
+
cursor: pointer;
|
|
244
|
+
font-size: 14px;
|
|
245
|
+
}
|
|
307
246
|
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
247
|
+
.add-btn:hover,
|
|
248
|
+
.remove-btn:hover {
|
|
249
|
+
background: #f8f8f8;
|
|
250
|
+
}
|
|
312
251
|
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
252
|
+
.remove-btn {
|
|
253
|
+
background: #fefefe;
|
|
254
|
+
color: #999;
|
|
255
|
+
}
|
|
256
|
+
`;
|
|
257
|
+
}
|
|
318
258
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { TemplateResult, html } from 'lit';
|
|
2
2
|
import { property } from 'lit/decorators.js';
|
|
3
|
+
import { FieldElement } from './FieldElement';
|
|
3
4
|
|
|
4
5
|
export interface ListItem {
|
|
5
6
|
[key: string]: any;
|
|
@@ -22,7 +23,7 @@ export interface ListEditorConfig {
|
|
|
22
23
|
|
|
23
24
|
export abstract class BaseListEditor<
|
|
24
25
|
T extends ListItem = ListItem
|
|
25
|
-
> extends
|
|
26
|
+
> extends FieldElement {
|
|
26
27
|
@property({ attribute: false })
|
|
27
28
|
protected _items: T[] = [];
|
|
28
29
|
|
|
@@ -60,9 +61,8 @@ export abstract class BaseListEditor<
|
|
|
60
61
|
return !this.maxItems || this._items.length < this.maxItems;
|
|
61
62
|
}
|
|
62
63
|
|
|
63
|
-
|
|
64
|
+
renderWidget(): TemplateResult {
|
|
64
65
|
const items = this.displayItems;
|
|
65
|
-
|
|
66
66
|
return html`
|
|
67
67
|
<div class=${this.getContainerClass()}>
|
|
68
68
|
<div
|
package/src/form/Checkbox.ts
CHANGED
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
import { TemplateResult, html, css } from 'lit';
|
|
2
|
-
import {
|
|
2
|
+
import { FieldElement } from './FieldElement';
|
|
3
3
|
import { property } from 'lit/decorators.js';
|
|
4
4
|
import { Icon } from '../Icons';
|
|
5
|
+
import { renderMarkdownInline } from '../markdown';
|
|
5
6
|
|
|
6
|
-
export class Checkbox extends
|
|
7
|
+
export class Checkbox extends FieldElement {
|
|
7
8
|
static get styles() {
|
|
8
9
|
return css`
|
|
10
|
+
${super.styles}
|
|
11
|
+
|
|
9
12
|
:host {
|
|
10
13
|
color: var(--color-text);
|
|
11
14
|
display: inline-block;
|
|
@@ -24,25 +27,45 @@ export class Checkbox extends FormElement {
|
|
|
24
27
|
background: var(--checkbox-hover-bg, #f9f9f9);
|
|
25
28
|
}
|
|
26
29
|
|
|
27
|
-
temba-field {
|
|
28
|
-
--help-text-margin-left: 24px;
|
|
29
|
-
cursor: pointer;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
30
|
.checkbox-container {
|
|
33
31
|
cursor: pointer;
|
|
34
32
|
display: flex;
|
|
33
|
+
align-items: flex-start;
|
|
35
34
|
user-select: none;
|
|
36
35
|
-webkit-user-select: none;
|
|
37
36
|
}
|
|
38
37
|
|
|
38
|
+
.checkbox-container temba-icon {
|
|
39
|
+
align-self: flex-start;
|
|
40
|
+
vertical-align: top;
|
|
41
|
+
line-height: 1;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
.label-and-help {
|
|
45
|
+
flex-grow: 1;
|
|
46
|
+
margin-left: 8px;
|
|
47
|
+
}
|
|
48
|
+
|
|
39
49
|
.checkbox-label {
|
|
40
50
|
font-family: var(--font-family);
|
|
41
51
|
padding: 0px;
|
|
42
|
-
margin
|
|
52
|
+
margin: 0px;
|
|
43
53
|
font-size: 14px;
|
|
44
54
|
line-height: 19px;
|
|
45
|
-
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
.checkbox-help-text {
|
|
58
|
+
font-family: var(--font-family);
|
|
59
|
+
font-size: var(--help-text-size, 0.85em);
|
|
60
|
+
line-height: normal;
|
|
61
|
+
color: var(--color-text-help);
|
|
62
|
+
margin-top: 4px;
|
|
63
|
+
opacity: 1;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/* Checkbox help text should align with the checkbox icon, not indented */
|
|
67
|
+
.help-text {
|
|
68
|
+
margin-left: 0;
|
|
46
69
|
}
|
|
47
70
|
|
|
48
71
|
.far {
|
|
@@ -123,7 +146,7 @@ export class Checkbox extends FormElement {
|
|
|
123
146
|
super.click();
|
|
124
147
|
}
|
|
125
148
|
|
|
126
|
-
|
|
149
|
+
protected renderWidget(): TemplateResult {
|
|
127
150
|
const icon = html`<temba-icon
|
|
128
151
|
name="${this.checked
|
|
129
152
|
? Icon.checkbox_checked
|
|
@@ -132,27 +155,61 @@ export class Checkbox extends FormElement {
|
|
|
132
155
|
: Icon.checkbox}"
|
|
133
156
|
size="${this.size}"
|
|
134
157
|
animatechange="${this.animateChange}"
|
|
135
|
-
|
|
158
|
+
></temba-icon>`;
|
|
136
159
|
|
|
137
160
|
return html`
|
|
138
|
-
<div
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
?disabled=${this.disabled}
|
|
146
|
-
@click=${this.handleClick}
|
|
147
|
-
>
|
|
148
|
-
<div class="checkbox-container ${this.disabled ? 'disabled' : ''}">
|
|
149
|
-
${icon}
|
|
161
|
+
<div
|
|
162
|
+
class="wrapper ${this.label ? 'label' : ''}"
|
|
163
|
+
@click=${this.handleClick}
|
|
164
|
+
>
|
|
165
|
+
<div class="checkbox-container ${this.disabled ? 'disabled' : ''}">
|
|
166
|
+
${icon}
|
|
167
|
+
<div class="label-and-help">
|
|
150
168
|
${this.label && String(this.label).trim()
|
|
151
169
|
? html`<div class="checkbox-label">${this.label}</div>`
|
|
152
170
|
: null}
|
|
171
|
+
${this.helpText && this.helpText !== 'None'
|
|
172
|
+
? html` <div class="checkbox-help-text">${this.helpText}</div> `
|
|
173
|
+
: null}
|
|
153
174
|
</div>
|
|
154
|
-
</
|
|
175
|
+
</div>
|
|
176
|
+
</div>
|
|
177
|
+
`;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
protected renderField(): TemplateResult {
|
|
181
|
+
// Use standard FieldElement behavior but skip the field label since checkbox renders its own inline
|
|
182
|
+
const hasErrors = !this.hideErrors && this.errors && this.errors.length > 0;
|
|
183
|
+
const errors = hasErrors
|
|
184
|
+
? this.errors.map((error: string) => {
|
|
185
|
+
return html`
|
|
186
|
+
<div class="alert-error">${renderMarkdownInline(error)}</div>
|
|
187
|
+
`;
|
|
188
|
+
})
|
|
189
|
+
: [];
|
|
190
|
+
|
|
191
|
+
if (this.widgetOnly) {
|
|
192
|
+
return html`
|
|
193
|
+
<div class="${this.disabled ? 'disabled' : ''}">
|
|
194
|
+
${this.renderWidget()}
|
|
195
|
+
</div>
|
|
196
|
+
${errors}
|
|
197
|
+
`;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
// This matches FieldElement.renderField() but without the field label
|
|
201
|
+
return html`
|
|
202
|
+
<div
|
|
203
|
+
class="field ${this.disabled ? 'disabled' : ''} ${hasErrors
|
|
204
|
+
? 'has-error'
|
|
205
|
+
: ''}"
|
|
206
|
+
>
|
|
207
|
+
<div class="widget">${this.renderWidget()} ${errors}</div>
|
|
155
208
|
</div>
|
|
156
209
|
`;
|
|
157
210
|
}
|
|
211
|
+
|
|
212
|
+
public render(): TemplateResult {
|
|
213
|
+
return this.renderField();
|
|
214
|
+
}
|
|
158
215
|
}
|