UNPKG

@taiga-ui/cdk

Version:

Base library for creating Angular components and applications using Taiga UI principles regarding of actual visual appearance

189 lines • 11.5 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.migrateSelect = migrateSelect; const insert_todo_1 = require("../../../../utils/insert-todo"); const elements_1 = require("../../../../utils/templates/elements"); const template_resource_1 = require("../../../../utils/templates/template-resource"); const control_state_attrs_1 = require("../../../utils/templates/control-state-attrs"); const replace_tag_1 = require("../../../utils/templates/replace-tag"); const SELECT_MIGRATION_TODO = `<!-- ${insert_todo_1.TODO_MARK} tui-select was partially migrated. Complete migration manually. See examples: https://taiga-ui.dev/components/select -->\n`; const VALUE_CONTENT_ATTR = 'valueContent'; const CONTENT_ATTR = 'content'; const TEXTFIELD_LABEL_OUTSIDE_ATTR = 'tuiTextfieldLabelOutside'; const CONTROL_ATTR_NAMES = [ 'formControlName', '[formControl]', 'formControl', '[(ngModel)]', '[ngModel]', 'ngModel', ]; const CONTROL_ATTRS = new Set(CONTROL_ATTR_NAMES.map((name) => name.toLowerCase())); function migrateSelect({ resource, recorder, fileSystem, }) { const template = (0, template_resource_1.getTemplateFromTemplateResource)(resource, fileSystem); const templateOffset = (0, template_resource_1.getTemplateOffset)(resource); const elements = (0, elements_1.findElementsByTagName)(template, 'tui-select'); elements.forEach((element) => { var _a, _b, _c, _d, _e, _f, _g, _h, _j; const startOffset = (_a = element.sourceCodeLocation) === null || _a === void 0 ? void 0 : _a.startOffset; const controlAttrs = element.attrs.filter((attr) => CONTROL_ATTRS.has(attr.name.toLowerCase())); const controlStateAttrs = (0, control_state_attrs_1.getControlStateAttrs)(element); if (typeof startOffset === 'number') { recorder.insertLeft(templateOffset + startOffset, SELECT_MIGRATION_TODO); } renameAttr(recorder, templateOffset, element, `[${VALUE_CONTENT_ATTR}]`, `[${CONTENT_ATTR}]`); renameAttr(recorder, templateOffset, element, VALUE_CONTENT_ATTR, CONTENT_ATTR); const labelOutsideAttr = element.attrs.find((attr) => attr.name.toLowerCase() === `[${TEXTFIELD_LABEL_OUTSIDE_ATTR}]`.toLowerCase() || attr.name.toLowerCase() === TEXTFIELD_LABEL_OUTSIDE_ATTR.toLowerCase()); const isBinding = (_b = labelOutsideAttr === null || labelOutsideAttr === void 0 ? void 0 : labelOutsideAttr.name.startsWith('[')) !== null && _b !== void 0 ? _b : false; const isLabelOutsideTrue = (labelOutsideAttr === null || labelOutsideAttr === void 0 ? void 0 : labelOutsideAttr.value) === 'true' || (!!labelOutsideAttr && !isBinding && labelOutsideAttr.value === ''); const isLabelOutsideDynamic = !!labelOutsideAttr && !isLabelOutsideTrue && labelOutsideAttr.value !== 'false'; removeAttr(recorder, templateOffset, element, `[${TEXTFIELD_LABEL_OUTSIDE_ATTR}]`, template); removeAttr(recorder, templateOffset, element, TEXTFIELD_LABEL_OUTSIDE_ATTR, template); controlAttrs.forEach((attr) => { removeAttr(recorder, templateOffset, element, attr.name, template); }); (0, control_state_attrs_1.removeControlStateAttrs)(recorder, templateOffset, element, template, controlStateAttrs); const hasChevron = element.attrs.some((attr) => attr.name.toLowerCase() === 'tuiChevron'.toLowerCase()); (0, replace_tag_1.replaceTag)(recorder, element.sourceCodeLocation, 'tui-select', 'tui-textfield', template, templateOffset, hasChevron ? [] : ['tuiChevron']); const placeholder = getPlaceholderText(element); const inputs = element.childNodes.filter((node) => node.nodeName === 'input'); if (inputs.length) { if (isLabelOutsideTrue && placeholder) { removeTextContent(recorder, templateOffset, element); } else if (!isLabelOutsideDynamic && !isLabelOutsideTrue) { wrapTextInLabel(recorder, templateOffset, element); } inputs.forEach((input) => { var _a, _b, _c; input.attrs.forEach((attr) => { var _a, _b, _c; if (!/^tuitextfieldlegacy$|^tuitextfield$/i.test(attr.name)) { return; } const { startOffset = 0, endOffset = 0 } = (_c = (_b = (_a = input.sourceCodeLocation) === null || _a === void 0 ? void 0 : _a.attrs) === null || _b === void 0 ? void 0 : _b[attr.name]) !== null && _c !== void 0 ? _c : {}; recorder.remove(templateOffset + startOffset, endOffset - startOffset); recorder.insertRight(templateOffset + startOffset, 'tuiSelect'); }); const formAttrs = formatControlAttrs(controlAttrs); const controlStateStr = (0, control_state_attrs_1.stringifyControlStateAttrs)(controlStateAttrs); const placeholderAttr = isLabelOutsideTrue && placeholder ? ` placeholder="${placeholder}"` : ''; const insertOffset = ((_c = (_b = (_a = input.sourceCodeLocation) === null || _a === void 0 ? void 0 : _a.startTag) === null || _b === void 0 ? void 0 : _b.startOffset) !== null && _c !== void 0 ? _c : 0) + '<input'.length; if (formAttrs || placeholderAttr || controlStateStr) { recorder.insertRight(templateOffset + insertOffset, `${placeholderAttr}${formAttrs ? ` ${formAttrs}` : ''}${controlStateStr}`); } }); } else { const formAttrs = formatControlAttrs(controlAttrs); const controlStateStr = (0, control_state_attrs_1.stringifyControlStateAttrs)(controlStateAttrs); const firstElementChildOffset = (_d = (_c = element.childNodes.find((node) => node.nodeName !== '#text')) === null || _c === void 0 ? void 0 : _c.sourceCodeLocation) === null || _d === void 0 ? void 0 : _d.startOffset; const insertOffset = (_g = firstElementChildOffset !== null && firstElementChildOffset !== void 0 ? firstElementChildOffset : (_f = (_e = element.sourceCodeLocation) === null || _e === void 0 ? void 0 : _e.endTag) === null || _f === void 0 ? void 0 : _f.startOffset) !== null && _g !== void 0 ? _g : 0; const placeholderAttr = isLabelOutsideTrue && placeholder ? ` placeholder="${placeholder}"` : ''; const inputTemplate = `\n<input${placeholderAttr} tuiSelect${formAttrs ? ` ${formAttrs}` : ''}${controlStateStr} />\n`; if (isLabelOutsideTrue) { removeTextContent(recorder, templateOffset, element); } else if (!isLabelOutsideDynamic) { wrapTextInLabel(recorder, templateOffset, element); } recorder.insertRight(templateOffset + insertOffset, inputTemplate); } if (isLabelOutsideDynamic && typeof startOffset === 'number') { const lineStart = template.lastIndexOf('\n', startOffset - 1) + 1; const indent = (_j = (_h = /^[ \t]*/.exec(template.slice(lineStart, startOffset))) === null || _h === void 0 ? void 0 : _h[0]) !== null && _j !== void 0 ? _j : ''; recorder.insertRight(templateOffset + startOffset, `<!-- ${insert_todo_1.TODO_MARK} [tuiTextfieldLabelOutside] is dynamic and cannot be migrated automatically. Use <label tuiLabel> inside <tui-textfield> for floating label or input[placeholder] for outside label -->\n${indent}`); } }); } function renameAttr(recorder, templateOffset, element, from, to) { var _a, _b; const attrLocation = (_b = (_a = element.sourceCodeLocation) === null || _a === void 0 ? void 0 : _a.attrs) === null || _b === void 0 ? void 0 : _b[from.toLowerCase()]; if (!attrLocation) { return; } recorder.remove(templateOffset + attrLocation.startOffset, from.length); recorder.insertRight(templateOffset + attrLocation.startOffset, to); } function removeAttr(recorder, templateOffset, element, name, template) { var _a, _b; const attrLocation = (_b = (_a = element.sourceCodeLocation) === null || _a === void 0 ? void 0 : _a.attrs) === null || _b === void 0 ? void 0 : _b[name.toLowerCase()]; if (!attrLocation) { return; } const lineStart = template.lastIndexOf('\n', attrLocation.startOffset) + 1; const lineEnd = template.indexOf('\n', attrLocation.endOffset); const attrText = template.slice(attrLocation.startOffset, attrLocation.endOffset); const lineText = lineEnd === -1 ? '' : template.slice(lineStart, lineEnd); if (lineText.trim() === attrText.trim() && lineEnd !== -1) { recorder.remove(templateOffset + lineStart, lineEnd - lineStart + 1); return; } recorder.remove(templateOffset + attrLocation.startOffset - 1, attrLocation.endOffset - attrLocation.startOffset + 1); } function getPlaceholderText(element) { var _a; const textNode = element.childNodes.find((node) => isTextNode(node) ? !!node.value.trim() : false); return (_a = textNode === null || textNode === void 0 ? void 0 : textNode.value.trim()) !== null && _a !== void 0 ? _a : ''; } function removeTextContent(recorder, templateOffset, element) { element.childNodes.forEach((node) => { var _a, _b, _c, _d; if (node.nodeName !== '#text') { return; } const textNode = node; const start = (_b = (_a = textNode.sourceCodeLocation) === null || _a === void 0 ? void 0 : _a.startOffset) !== null && _b !== void 0 ? _b : 0; const end = (_d = (_c = textNode.sourceCodeLocation) === null || _c === void 0 ? void 0 : _c.endOffset) !== null && _d !== void 0 ? _d : start; if (!textNode.value.trim()) { return; } recorder.remove(templateOffset + start, end - start); }); } function formatControlAttrs(attrs) { return attrs .map(({ name, value }) => `${normalizeAttrName(name)}="${value}"`) .join(' '); } function normalizeAttrName(name) { switch (name.toLowerCase()) { case '[(ngModel)]'.toLowerCase(): return '[(ngModel)]'; case '[formControl]'.toLowerCase(): return '[formControl]'; case '[ngModel]'.toLowerCase(): return '[ngModel]'; case 'formControl'.toLowerCase(): return 'formControl'; case 'formControlName'.toLowerCase(): return 'formControlName'; case 'ngModel'.toLowerCase(): return 'ngModel'; default: return name; } } function wrapTextInLabel(recorder, templateOffset, element) { var _a, _b, _c, _d; const textNode = element.childNodes.find((node) => isTextNode(node) && !!node.value.trim()); if (!textNode) { return; } const start = ((_b = (_a = textNode.sourceCodeLocation) === null || _a === void 0 ? void 0 : _a.startOffset) !== null && _b !== void 0 ? _b : 0) + templateOffset; const end = ((_d = (_c = textNode.sourceCodeLocation) === null || _c === void 0 ? void 0 : _c.endOffset) !== null && _d !== void 0 ? _d : 0) + templateOffset; recorder.insertRight(start, '\n<label tuiLabel>'); recorder.insertRight(end, '</label>\n'); } function isTextNode(node) { return node.nodeName === '#text'; } //# sourceMappingURL=migrate-select.js.map