diff --git a/src/ctree-dialogs/ctree-dialogs.html b/src/ctree-dialogs/ctree-dialogs.html index fa60a4a..4e4cbfb 100644 --- a/src/ctree-dialogs/ctree-dialogs.html +++ b/src/ctree-dialogs/ctree-dialogs.html @@ -77,7 +77,7 @@ - + @@ -122,9 +122,9 @@ observer: '_descriptionConfigIdChanged', }, - descriptionSegmentVariationIds: { + descriptionSegmentIds: { type: Array, - observer: '_descriptionSegmentVariationIdsChanged', + observer: '_descriptionSegmentIdsChanged', }, feedbackSegment: Number, @@ -206,10 +206,10 @@ } else if (this.queryParams.hasOwnProperty('c')) { delete this.queryParams.c; } - if (isElement && this.descriptionSegmentVariationIds && this.descriptionSegmentVariationIds.length > 0) { + if (isElement && this.descriptionSegmentIds && this.descriptionSegmentIds.length > 0) { // TODO: use this for Polymer 2.0 - //this.queryParams.s = this.descriptionSegmentVariationIds.join(','); - this.set('queryParams.s', this.descriptionSegmentVariationIds.join(',')); + //this.queryParams.s = this.descriptionSegmentIds.join(','); + this.set('queryParams.s', this.descriptionSegmentIds.join(',')); } else if (this.queryParams.hasOwnProperty('s')) { delete this.queryParams.s; } @@ -283,19 +283,19 @@ } }, - _descriptionSegmentVariationsParamChanged: function(descriptionSegmentVariationIdsStr) { - if (descriptionSegmentVariationIdsStr) { - var descriptionSegmentVariationIds = descriptionSegmentVariationIdsStr.split(','); - for (var i = 0; i < descriptionSegmentVariationIds.length; i++) { - var id = parseInt(descriptionSegmentVariationIds[i]); + _descriptionSegmentVariationsParamChanged: function(descriptionSegmentIdsStr) { + if (descriptionSegmentIdsStr) { + var descriptionSegmentIds = descriptionSegmentIdsStr.split(','); + for (var i = 0; i < descriptionSegmentIds.length; i++) { + var id = parseInt(descriptionSegmentIds[i]); if (id != NaN) { - descriptionSegmentVariationIds[i] = id; + descriptionSegmentIds[i] = id; } else { - descriptionSegmentVariationIds.splice(i, 1); + descriptionSegmentIds.splice(i, 1); i--; } } - this.descriptionSegmentVariationIds = descriptionSegmentVariationIds; + this.descriptionSegmentIds = descriptionSegmentIds; } else if (this.queryParams.d === 'element' && this.queryParams.hasOwnProperty('s')) { delete this.queryParams.s; @@ -367,10 +367,10 @@ // TODO: }, - _descriptionSegmentVariationIdsChanged: function(descriptionSegmentVariationIds) { + _descriptionSegmentIdsChanged: function(descriptionSegmentIds) { if (this.queryParams.d === 'element') { - if (descriptionSegmentVariationIds.length > 0) { - this.set('queryParams.s', descriptionSegmentVariationIds.join(',')); + if (descriptionSegmentIds.length > 0) { + this.set('queryParams.s', descriptionSegmentIds.join(',')); } else if (this.queryParams.hasOwnProperty('s')) { delete this.queryParams.s; // TODO: use this for Polymer 2.0 diff --git a/src/ctree-dialogs/ctree-element-dialog-accessor.html b/src/ctree-dialogs/ctree-element-dialog-accessor.html index 80965c2..ae38edc 100644 --- a/src/ctree-dialogs/ctree-element-dialog-accessor.html +++ b/src/ctree-dialogs/ctree-element-dialog-accessor.html @@ -61,7 +61,10 @@ * segments: [{ * id: Number, * type: SegmentType, - * variations: [], // data type depends on type + * variations: [{ + * id: Number, + * data: dynamic, // data type depends on segment type + * }, ...], * }, ...], * }, ...], * feedback: [{ @@ -71,19 +74,11 @@ * bookmarked: Boolean, * } */ - element: { - type: Object, - }, - - descriptionConfigId: { - type: Number, - observer: '_descriptionConfigIdChanged', - }, - - descriptionSegmentIds: { - type: Array, - observer: '_descriptionSegmentIdsChanged', - }, + element: Object, + + descriptionConfigId: Number, + + descriptionSegmentIds: Array, feedbackSegment: Number, diff --git a/src/ctree-element-preview/ctree-element-preview.html b/src/ctree-element-preview/ctree-element-preview.html index e14e921..1e1089f 100644 --- a/src/ctree-element-preview/ctree-element-preview.html +++ b/src/ctree-element-preview/ctree-element-preview.html @@ -34,6 +34,7 @@ + @@ -117,7 +118,7 @@ - +
@@ -139,6 +140,10 @@ Polymer({ is: 'ctree-element-preview', + behaviors: [ + Polymer.CTreeElementDescriptionBehavior, + ], + properties: { /** * The unique key identifying a cTree. If the site only has one cTree @@ -166,60 +171,6 @@ observer: '_listItemChanged', }, - /** - * Element data - * - * Structure: - * { - * id: Number, - * type: ElementType, - * title: String, - * parents: [Number], - * children: [Number], - * childrenSearchComplete: Boolean, - * designer: String, // TODO: should probably be an object (user ID or reference to public user object) - * description: [{ - * id: Number, - * contributors: [String], // TODO: should probably be an object (user ID or reference to public user object) - * segments: [{ - * id: Number, - * type: SegmentType, - * variations: [], // data type depends on type - * }, ...], - * }, ...], - * feedback: [{ - * reviewer: String, // TODO: should probably be an object (user ID or reference to public user object) - * text: String, - * }, ...], - * bookmarked: Boolean, - * } - */ - element: { - type: Object, - observer: '_elementChanged', - }, - - /** - * ID of description config to show. If this ID isn't included in the - * element the first config from the element is used. - */ - descriptionConfig: { - type: Number, - observer: '_descriptionConfigChanged', - }, - - /** - * IDs of variation to show for each segment. For any segments where the - * ID isn't included in the description config the first variation is used. - * - * Structure: - * [Number, ...] - */ - descriptionSegments: { - type: Array, - observer: '_descriptionSegmentsChanged', - }, - /** * Comment to display at the bottom of the element preview. */ @@ -240,8 +191,6 @@ value: false, observer: '_viewedChanged', }, - - _bulkChange: Boolean, }, _isEmpty: function(str) { @@ -249,57 +198,21 @@ }, _listItemChanged: function(listItem) { - var descriptionChanged = false; - - this._bulkChange = true; - if (typeof listItem.element !== 'undefined' && listItem.element !== this.element) { - this.element = listItem.element; - descriptionChanged = true; - } - if (typeof listItem.descriptionConfig !== 'undefined' && listItem.descriptionConfig !== this.descriptionConfig) { - this.descriptionConfig = listItem.descriptionConfig; - descriptionChanged = true; - } - if (typeof listItem.descriptionSegments !== 'undefined' && listItem.descriptionSegments !== this.descriptionSegments) { - this.descriptionSegments = listItem.descriptionSegments; - descriptionChanged = true; - } - this._bulkChange = false; - - if (descriptionChanged) { - this._updateDescription(this.element, this.descriptionConfig, this.descriptionSegments); - } + this._bulkUpdateDescriptionProperties(listItem.element, listItem.descriptionConfig, listItem.descriptionSegments); this.viewed = listItem.viewed; }, _elementChanged: function(element) { - // TODO: remove this call once make _updateDescription an explicit observer after updating to Polymer 2.0 - this._updateDescription(element, this.descriptionConfig, this.descriptionSegments); - this.viewed = element.viewed; }, - // TODO: remove these individual observers and make _updateDescription an explicit observer once update to Polymer 2.0 - _descriptionConfigChanged: function(descriptionConfig) { - this._updateDescription(this.element, descriptionConfig, this.descriptionSegments); - }, - - _descriptionSegmentsChanged: function(descriptionSegments) { - this._updateDescription(this.element, this.descriptionConfig, descriptionSegments); - }, - - _getFromArrayWithId: Polymer.CTreeLoader.getFromArrayWithId, - - _updateDescription: function(element, descriptionConfig, descriptionSegments) { - if (this._bulkChange || !this.element.description || this.element.description.length == 0) return; - var description = this._getFromArrayWithId(this.element.description, this.descriptionConfig); - if (!description || !description.segments || (descriptionSegments && description.segments.length != descriptionSegments.length)) return; - + _descriptionChanged: function(description, descriptionSegments) { // clear segments var segmentsElement = this.$.segments; - while (segmentsElement.firstChild) { - segmentsElement.removeChild(segmentsElement.firstChild); + var child; + while (child = segmentsElement.firstChild) { + segmentsElement.removeChild(child); } // add thumbnail @@ -311,7 +224,8 @@ if (type.canBeThumbnail) { thumbnailIndex = i; var component = document.createElement(type.componentName); - component.data = this._getFromArrayWithId(segment.variations, descriptionSegments ? descriptionSegments[i] : undefined); + var variation = this._getFromArrayWithId(segment.variations, descriptionSegments ? descriptionSegments[i] : undefined); + component.data = variation.data; component.scale = '80%'; component.heightPercent = '56.25%'; segmentsElement.appendChild(component); @@ -327,7 +241,8 @@ var segment = segments[i]; var type = segment.type; var component = document.createElement(type.componentName); - component.data = this._getFromArrayWithId(segment.variations, descriptionSegments ? descriptionSegments[i] : undefined); + var variation = this._getFromArrayWithId(segment.variations, descriptionSegments ? descriptionSegments[i] : undefined); + component.data = variation.data; component.scale = '80%'; segmentsElement.appendChild(component); } diff --git a/src/ctree-element-screen/ctree-description.html b/src/ctree-element-screen/ctree-description.html new file mode 100644 index 0000000..d5bd997 --- /dev/null +++ b/src/ctree-element-screen/ctree-description.html @@ -0,0 +1,415 @@ + + + + + + + + +/** + * TODO: use template instead of manually adding items, so we can automatically + * use data binding. An example of using multiple templates ca be found at + * https://github.com/Polymer/polymer/issues/3755: + * this.templatize(tplA); + * this.templatize(tplB); + * for(let i = 0 ; i < 3 ; i++) { + * this._templatized = tplA; + * this.ctor = tplA._content._ctor; + * this.appendChild(this.stamp({nameA: i}).root); + * + * this._templatized = tplB; + * this.ctor = tplB._content._ctor; + * this.appendChild(this.stamp({nameB: i}).root); + * } + * + * TODO: try making + buttons only visible while editing, and make them a new + * component type (to allow selection of segment type when clicked) + */ + + + + + diff --git a/src/ctree-element-screen/ctree-details-page.html b/src/ctree-element-screen/ctree-details-page.html index fd47cd7..de74202 100644 --- a/src/ctree-element-screen/ctree-details-page.html +++ b/src/ctree-element-screen/ctree-details-page.html @@ -31,8 +31,10 @@ + + @@ -123,20 +88,34 @@ * @param {{segment: segmentData}} detail Contains data for segment whos feedback button was tapped. */ + behaviors: [ + Polymer.CTreeElementDescriptionBehavior, + ], + properties: { + /** + * Segments data + * + * Structure: + * [{ + * id: Number, + * type: SegmentType, + * variations: [{ + * id: Number, + * data: dynamic, // data type depends on segment type + * }, ...], + * }, ...], + */ segments: { type: Array, - value: ["", "", ""], + observer: '__segmentsChanged', }, - descriptionConfigId: { - type: Number, - observer: '_onDescriptionConfigChanged', - }, + __tempSegments: Array, }, - _onDescriptionConfigChanged: function(descriptionConfigId) { - // TODO: refresh description details + _descriptionChanged: function(description, descriptionSegments) { + this.segments = description.segments; // TODO: copy array using .slice() so we can mutate it separately? }, _fireContributorsTapped: function() { @@ -147,10 +126,15 @@ this.fire('related-tapped'); }, - _fireFeedbackTapped: function(e, detail) { - // TODO: figure out segment data from e or detail & pass as detail segmentData - this.fire('feedback-tapped', {segmentData: {}}); + __segmentsChanged: function(e, detail) { + if (this.segments) { + this.__tempSegments = this.segments.slice(); + } else { + this.__tempSegments = this.segments; + } }, + + // TODO: before close element or switch description check if tempSegments changed, and if ask user if they want to save their changes }); diff --git a/src/ctree-element-screen/ctree-element-screen.html b/src/ctree-element-screen/ctree-element-screen.html index 2f55b23..2f739cd 100644 --- a/src/ctree-element-screen/ctree-element-screen.html +++ b/src/ctree-element-screen/ctree-element-screen.html @@ -87,15 +87,15 @@ - + - - - + + + - + @@ -137,15 +137,15 @@ notify: true, }, - descriptionConfigId: { + descriptionConfig: { type: Number, - observer: '_descriptionConfigIdChanged', + observer: '_descriptionConfigChanged', notify: true, }, - descriptionSegmentVariationIds: { + descriptionSegments: { type: Array, - observer: '_descriptionSegmentVariationIdsChanged', + observer: '_descriptionSegmentsChanged', notify: true, }, @@ -180,7 +180,7 @@ this._ensureDescriptionConfigSet(); } else if (page == 'related') { // applies to entire element so enter general state instead of specific description config state - this.descriptionConfigId = null; + this.descriptionConfig = null; } this.$.importPage.load(); }, @@ -189,21 +189,21 @@ if (element) { this.elementId = element.id; } - if (!this.descriptionConfigId && element) { + if (!this.descriptionConfig && element) { this._pageChanged(this.page); } // TODO: }, - _descriptionConfigIdChanged: function(descriptionConfigId) { - this._descriptionVersionBarVisible = (descriptionConfigId ? true : false); - if (!descriptionConfigId && this.element) { + _descriptionConfigChanged: function(descriptionConfig) { + this._descriptionVersionBarVisible = (descriptionConfig ? true : false); + if (!descriptionConfig && this.element) { this._pageChanged(this.page); } // TODO: }, - _descriptionSegmentVariationIdsChanged: function(descriptionSegmentVariationIds) { + _descriptionSegmentsChanged: function(descriptionSegments) { // TODO: }, @@ -219,9 +219,9 @@ }, _ensureDescriptionConfigSet: function() { - if (!this.descriptionConfigId) { + if (!this.descriptionConfig) { // TODO: get first config ID from element data - this.descriptionConfigId = 1; + this.descriptionConfig = 1; } }, @@ -243,7 +243,7 @@ this.historyContributor = detail.contributor; if (detail.generalHistory) { // history shown should be for the entire element, not a specific description config - this.descriptionConfigId = null; + this.descriptionConfig = null; } this.page = 'history'; }, diff --git a/src/ctree-element-screen/ctree-segment-container.html b/src/ctree-element-screen/ctree-segment-container.html new file mode 100644 index 0000000..00beec0 --- /dev/null +++ b/src/ctree-element-screen/ctree-segment-container.html @@ -0,0 +1,329 @@ + + + + + + + + + + + + + diff --git a/src/ctree-element/ctree-element-description-behavior.html b/src/ctree-element/ctree-element-description-behavior.html new file mode 100644 index 0000000..d4cd2d1 --- /dev/null +++ b/src/ctree-element/ctree-element-description-behavior.html @@ -0,0 +1,160 @@ + + + + + + + + + diff --git a/src/ctree-feedback-bar/ctree-feedback-bar.html b/src/ctree-feedback-bar/ctree-feedback-bar.html index 40d6a14..1c21100 100644 --- a/src/ctree-feedback-bar/ctree-feedback-bar.html +++ b/src/ctree-feedback-bar/ctree-feedback-bar.html @@ -67,11 +67,26 @@ */ properties: { + /** + * Segments data + * + * Structure: + * { + * id: Number, + * type: SegmentType, + * variations: [{ + * id: Number, + * data: dynamic, // data type depends on segment type + * }, ...], + * } + */ + segment: { + type: Object, + }, }, _fireFeedbackTapped: function() { - // TODO: figure out segment data & pass as detail segmentData - this.fire('feedback-tapped', {segmentData: {}}); + this.fire('feedback-tapped', {segment: this.segment}); }, }); diff --git a/src/ctree-icons/ctree-icons.html b/src/ctree-icons/ctree-icons.html index 615cb3f..eb9b92b 100644 --- a/src/ctree-icons/ctree-icons.html +++ b/src/ctree-icons/ctree-icons.html @@ -57,6 +57,8 @@ + + diff --git a/src/ctree-loader/ctree-element-loader-test.html b/src/ctree-loader/ctree-element-loader-test.html index 5955043..4f5e15d 100644 --- a/src/ctree-loader/ctree-element-loader-test.html +++ b/src/ctree-loader/ctree-element-loader-test.html @@ -110,7 +110,10 @@ * segments: [{ * id: Number, * type: SegmentType, - * variations: [], // data type depends on type + * variations: [{ + * id: Number, + * data: dynamic, // data type depends on segment type + * }, ...], * }, ...], * }, ...], * feedback: [{ diff --git a/src/ctree-loader/ctree-loader-behavior-test.html b/src/ctree-loader/ctree-loader-behavior-test.html index 490e1ba..dc0df17 100644 --- a/src/ctree-loader/ctree-loader-behavior-test.html +++ b/src/ctree-loader/ctree-loader-behavior-test.html @@ -40,6 +40,7 @@ // monostate data var cTreesData = {}; var globalUsersData = {}; + var nextVariationId = 1; // test configuration values var Test = { @@ -218,27 +219,27 @@ var element = testElements[i]; var description = []; - for (var j = Math.floor(Math.random() * (Test.MAX_DESCRIPTION_CONFIGS - 1)) + 1; j >= 0; j--) { + for (var j = Math.floor(Math.random() * (Test.MAX_DESCRIPTION_CONFIGS - 1)); j >= 0; j--) { var segments = []; var contributors = []; // TODO: add contributors, ordered from most contributions to least (pick contributors for each segment added, also include feedback) - for (var k = Math.floor(Math.random() * (Test.MAX_DESCRIPTION_SEGMENTS - 1)) + 1; k >= 0; k--) { + for (var k = Math.floor(Math.random() * (Test.MAX_DESCRIPTION_SEGMENTS - 1)); k >= 0; k--) { var descriptionSegmentTypeId = Math.floor(Math.random() * (segmentTypes.length - 1)) + 1; // no ID 0 var descriptionSegmentVariations = []; - for (var l = Math.floor(Math.random() * (Test.MAX_DESCRIPTION_SEGMENT_VARIATIONS - 1)) + 1; l >= 0; l--) { - var segment; + for (var l = Math.floor(Math.random() * (Test.MAX_DESCRIPTION_SEGMENT_VARIATIONS - 1)); l >= 0; l--) { + var segmentData; switch (descriptionSegmentTypeId) { case 1: // Text (String) - segment = Lorem.generate('2-5s'); + segmentData = Lorem.generate('2-5s'); break; case 2: // Image (String) - segment = Lorem.imageUrl(); - if (!segment.startsWith('http')) { - segment = imagePath + segment; + segmentData = Lorem.imageUrl(); + if (!segmentData.startsWith('http')) { + segmentData = imagePath + segmentData; } break; } - if (segment) { - descriptionSegmentVariations.push(segment); + if (segmentData) { + descriptionSegmentVariations.push({id: nextVariationId++, data: segmentData}); } else { console.warn('failed to create segment'); } @@ -395,7 +396,10 @@ * segments: [{ * id: Number, * type: SegmentType, - * variations: [], // data type depends on type + * variations: [{ + * id: Number, + * data: dynamic, // data type depends on segment type + * }, ...], * }, ...], * }, ...], * feedback: [{ @@ -531,6 +535,16 @@ SIBLING: 32, }; + /** + * Gets the first object from the array with the id property equal to the id + * parameter passed to this function. If defaultToFirst is true this will + * return the first item from the array if no matching item is found, else + * will return undefined. + * + * @param {Array} array + * @param {number} id + * @param {boolean} [defaultToFirst=true] + */ Polymer.CTreeLoader.getFromArrayWithId = function(array, id, defaultToFirst=true) { if (!array) return undefined; diff --git a/src/ctree-segments/ctree-segment-behavior.html b/src/ctree-segments/ctree-segment-behavior.html index 85b8fea..644fc66 100644 --- a/src/ctree-segments/ctree-segment-behavior.html +++ b/src/ctree-segments/ctree-segment-behavior.html @@ -43,7 +43,7 @@ * static getText(data) * * Gets text interpretation of data for segment type. If no text interpretation - * is possible this may function may not be defined or may return an undefined + * is possible this function may not be defined or may return an undefined * result. * * @param {Object} data Segment type specific data to get text interpretation for @@ -51,7 +51,71 @@ */ Polymer.CTreeSegmentBehavior = { - // TODO: add shared behavior code for segments + /** + * Notify segment container that a new variation should be added. + * + * @event add-segment-variation + * @param {{data: variationData}} detail New segment variation data. + */ + + properties: { + data: Object, + + editing: { + type: Boolean, + value: false, + notify: true, + }, + + validChangeMade: { + type: Boolean, + value: false, + }, + + loadingChangeMade: { + type: Boolean, + value: false, + }, + + heightPercent: String, + + scale: { + type: String, + value: '100%', + }, + + _editUpdateDelay: { + type: Number, + value: 800, + }, + + __editUpdateHandle: Number, + }, + + _addSegmentVariation: function(data) { + if (!this.validChangeMade) return; + + this.validChangeMade = false; + // TODO: prompt user to select reason for new segment (list of default reasons from behavior & custom reasons from type) + // TODO: may be able to remove this once saving variation to loader + this.fire('add-segment-variation', {data: data}); + }, + + _delayEditUpdate: function() { + this.cancelAsync(this.__editUpdateHandle); + this.__editUpdateHandle = this.async(() => { + this.__editUpdateHandle = undefined; + this._editUpdate(); + }, this._editUpdateDelay); + }, + + _cancelEditUpdate: function() { + this.cancelAsync(this.__editUpdateHandle); + }, + + _editUpdate: function() { + // TODO: override to add custom logic when edit update timer elapsed + }, }; diff --git a/src/ctree-segments/ctree-segment-image.html b/src/ctree-segments/ctree-segment-image.html index a13c41e..ab97286 100644 --- a/src/ctree-segments/ctree-segment-image.html +++ b/src/ctree-segments/ctree-segment-image.html @@ -29,6 +29,9 @@ + + + @@ -52,10 +55,35 @@ width: 100%; background-color: #000; } + #url { + position: absolute; + bottom: 0; + left: 0; + right: 0; + padding: 8px; + background-color: rgba(255, 255, 255, 0.8); + } + #loadingIndicator { + position: absolute; + left: 50%; + top: 50%; + transform: translate(-50%, -50%); + } + paper-input[hidden] { + display: none !important; + } + paper-icon-button[hidden] { + display: none !important; + }
- + + + + + +
@@ -68,29 +96,81 @@ ], properties: { - data: { - type: Object, - observer: '_dataChanged', + _changed: { + type: Boolean, + value: false, }, + }, - heightPercent: { - type: String, - observer: '_heightPercentageChanged', - }, + observers: [ + '_editingChanged(editing)', + '_dataChanged(data)', + '_heightPercentageChanged(heightPercent)', + '__updateValidChangeMade(_changed, loading, error)', + '__updatLoadingChangeMade(editing, loading)', + ], + + _editingChanged: function(editing) { + if (editing) { + this.$.url.focus(); + } }, _dataChanged: function(data) { + this.validChangeMade = false; + this.loadingChangeMade = false; + this._changed = false; this.$.image.src = data; + this.$.url.value = data; }, _heightPercentageChanged: function(heightPercentage) { if (heightPercentage && heightPercentage.length > 0) { this.$.image.style.height = '100%'; + this.$.image.sizing = 'cover'; this.$.container.style.paddingTop = heightPercentage; } else { this.$.image.style.height = 'auto'; } }, + + _inputChanged: function(value) { + if (this.$.url.value === this.$.image.src) { + this._cancelEditUpdate(); + this._waiting = false; + } else { + this._delayEditUpdate(); + } + }, + + _checkForEnter: function(e) { + // check if 'enter' was pressed + if (e.keyCode === 13) { + this._editSaveClicked(); + } + }, + + _editUpdate: function() { + var value = this.$.url.value.trim(); + this.$.image.src = value; + this._changed = (value !== this.data); + }, + + _editSaveClicked: function() { + this._addSegmentVariation(this.$.image.src); + }, + + _editCancelClicked: function() { + this.editing = false; + }, + + __updateValidChangeMade: function(changed, loading, error) { + this.validChangeMade = changed && !loading && !error; + }, + + __updatLoadingChangeMade: function(editing, loading) { + this.loadingChangeMade = editing && loading; + }, }); diff --git a/src/ctree-segments/ctree-segment-text.html b/src/ctree-segments/ctree-segment-text.html index c54e57d..caf9189 100644 --- a/src/ctree-segments/ctree-segment-text.html +++ b/src/ctree-segments/ctree-segment-text.html @@ -28,6 +28,9 @@ --> + + + @@ -38,12 +41,39 @@ :host { display: block; } - #text { + .text { + width: calc(100% - 16px); padding: 4px 8px; } + #input { + width: 100%; + } + #buttons > div { + display: inline-block; + position: relative; + padding: 8px; + } + #buttons > div[hidden] { + display: none !important; + } -
+
+
+ +
+
+ + Save + +
+
+ + Cancel + +
+
+