@taiga-ui/eslint-plugin-experience-next 0.518.0 → 0.519.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/index.esm.js +53 -4
  2. package/package.json +1 -1
package/index.esm.js CHANGED
@@ -250598,6 +250598,11 @@ function isInteractiveElement(node) {
250598
250598
  }
250599
250599
 
250600
250600
  const MESSAGE_ID$b = 'noNestedInteractive';
250601
+ // Elements that act as DOM portals or isolated list containers:
250602
+ // their children are rendered outside the current DOM subtree.
250603
+ const PORTAL_ELEMENTS = new Set(['tui-data-list', 'tui-textfield']);
250604
+ // Structural directives that portal their host element into an overlay.
250605
+ const PORTAL_STRUCTURAL_DIRECTIVES = new Set(['tuiDropdown']);
250601
250606
  function getAvailableLabelParent(stack, node, labelsWithControl) {
250602
250607
  const parent = stack[stack.length - 1];
250603
250608
  return stack.length === 1 &&
@@ -250613,9 +250618,27 @@ const rule$B = createRule({
250613
250618
  create(context) {
250614
250619
  const interactiveStack = [];
250615
250620
  const labelsWithControl = new WeakSet();
250621
+ const savedStackByNode = new WeakMap();
250622
+ function saveAndReset(node) {
250623
+ savedStackByNode.set(node, [...interactiveStack]);
250624
+ interactiveStack.length = 0;
250625
+ }
250626
+ function restore(node) {
250627
+ const saved = savedStackByNode.get(node);
250628
+ if (saved === undefined) {
250629
+ return;
250630
+ }
250631
+ savedStackByNode.delete(node);
250632
+ interactiveStack.length = 0;
250633
+ interactiveStack.push(...saved);
250634
+ }
250616
250635
  return {
250617
250636
  Element(rawNode) {
250618
250637
  const node = rawNode;
250638
+ if (PORTAL_ELEMENTS.has(node.name.toLowerCase())) {
250639
+ saveAndReset(node);
250640
+ return;
250641
+ }
250619
250642
  if (!isInteractiveElement(node)) {
250620
250643
  return;
250621
250644
  }
@@ -250635,10 +250658,23 @@ const rule$B = createRule({
250635
250658
  },
250636
250659
  'Element:exit'(rawNode) {
250637
250660
  const node = rawNode;
250661
+ restore(node);
250638
250662
  if (interactiveStack[interactiveStack.length - 1] === node) {
250639
250663
  interactiveStack.pop();
250640
250664
  }
250641
250665
  },
250666
+ Template(rawNode) {
250667
+ const node = rawNode;
250668
+ const isPortalBoundary = node.tagName === 'ng-template' ||
250669
+ node.templateAttrs.some((attr) => PORTAL_STRUCTURAL_DIRECTIVES.has(attr.name));
250670
+ if (isPortalBoundary) {
250671
+ saveAndReset(node);
250672
+ }
250673
+ },
250674
+ 'Template:exit'(rawNode) {
250675
+ const node = rawNode;
250676
+ restore(node);
250677
+ },
250642
250678
  };
250643
250679
  },
250644
250680
  meta: {
@@ -250850,6 +250886,7 @@ const rule$A = createRule({
250850
250886
  rule: {
250851
250887
  create(context) {
250852
250888
  const { sourceCode } = context;
250889
+ const boundTextStack = [];
250853
250890
  const conditionalStack = [];
250854
250891
  const containerStack = [];
250855
250892
  const letNames = collectTemplateIdentifiers(sourceCode.ast);
@@ -250858,18 +250895,22 @@ const rule$A = createRule({
250858
250895
  function reportNestedConditional(node, options) {
250859
250896
  const container = containerStack[containerStack.length - 1];
250860
250897
  const attribute = getContainingBoundAttribute(container, node);
250898
+ const boundText = boundTextStack[boundTextStack.length - 1];
250861
250899
  const baseName = attribute?.name;
250862
250900
  const fixable = options.allowFix &&
250863
250901
  boundEventDepth === 0 &&
250864
250902
  letDeclarationDepth === 0 &&
250865
- baseName &&
250866
- isIdentifier(baseName);
250903
+ ((baseName !== undefined && isIdentifier(baseName)) ||
250904
+ boundText !== undefined);
250867
250905
  context.report({
250868
250906
  ...(fixable
250869
250907
  ? {
250870
250908
  fix(fixer) {
250871
- const result = createLetFixes(node, baseName, letNames, sourceCode.text);
250872
- const insertOffset = container?.startSourceSpan.start.offset;
250909
+ const effectiveName = baseName ?? 'text';
250910
+ const result = createLetFixes(node, effectiveName, letNames, sourceCode.text);
250911
+ const insertOffset = baseName === undefined
250912
+ ? boundText?.sourceSpan.start.offset
250913
+ : container?.startSourceSpan.start.offset;
250873
250914
  if (insertOffset === undefined) {
250874
250915
  return null;
250875
250916
  }
@@ -250898,6 +250939,14 @@ const rule$A = createRule({
250898
250939
  'BoundEvent:exit'() {
250899
250940
  boundEventDepth--;
250900
250941
  },
250942
+ BoundText(rawNode) {
250943
+ boundTextStack.push(rawNode);
250944
+ },
250945
+ 'BoundText:exit'(rawNode) {
250946
+ if (boundTextStack[boundTextStack.length - 1] === rawNode) {
250947
+ boundTextStack.pop();
250948
+ }
250949
+ },
250901
250950
  Conditional(rawNode) {
250902
250951
  const node = rawNode;
250903
250952
  if (conditionalStack.length > 0) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@taiga-ui/eslint-plugin-experience-next",
3
- "version": "0.518.0",
3
+ "version": "0.519.0",
4
4
  "description": "An ESLint plugin to enforce a consistent code styles across taiga-ui projects",
5
5
  "homepage": "https://github.com/taiga-family/toolkit#readme",
6
6
  "bugs": {