Repository: prettier/prettier (JavaScript)

Issue:
Angular inline styles are not formatted if specified as single string (new in v17)
**Prettier 3.2.2**
[Playground link](https://prettier.io/playground/#N4Igxg9gdgLgprEAuEBLAtgBwgJxgAmAGEItoEYBffAMx1PwHIABAQygHMBXAG1ZwD0kHHEYBuADpQpzEmSgUAFMCn58AZzg84YGLiRNWmTAFp6EGIwA0q-PCx94BgAYAJLTwjObUNepgAntrqLrZqSAAWEP4qvmrxkJ44SABGPFxwYpS23lKUAJRScAAe2Hj4YHzq6vgAgsZy2AqwhNlQIFYgEJgwqNDqyKD89ADuAAr8CAMorDwjrAEDnSk4rGAA1nAwAMqs6HAAMqgKyDSzmsurG1vbmGvHHMgwOBmdmuioTy9wnSWYcDgMBRZgAVAFQfioODTM48C4gdQPbQARS4Fjgp3OPxAACt1MVtki4Kj0Zi4diAI5o+BjeiYaYgVjqEwKOAAE3ZHRAz1YqB4Dzk6FYyEZPB4XMRnG0tRgz1QKS4NIBRxOSFh8IiMHQPAA6hFUPB1HcwHBtlMDagAG4GgIisDVLmWjIASSgHNg2zAgJ6tTd20C2jJ8Mw9E0OtWmBFIehAMtGM6x00eFprA4QqD2LuOCTIpSrBSWi5IeOMB1qDZMAiyAAHAAGToiKmoEQptPCtVYzowfNlitVpAAJk6XE0IPzMM7IDg6ALbI5bIO7G4qbgADFcELZQ8RaxFRAQJRKEA)
<!-- prettier-ignore -->
```sh
--parser babel
```

**Input:**
<!-- prettier-ignore -->
```jsx
import {Component} from '@angular/core';

@Component({
  selector: 'app-root',
  template: `Hello`,
  styles: `
    :host{
      color:blue;}
  `,
})
export class AppComponent {}

```

**Output:**
<!-- prettier-ignore -->
```jsx
import { Component } from "@angular/core";

@Component({
  selector: "app-root",
  template: `Hello`,
  styles: `
    :host{
      color:blue;}
  `,
})
export class AppComponent {}

```

**Expected output:**
<!-- prettier-ignore -->
```jsx

```

**Why?**

Since Angular v17 it is possible to specify an inline style with a single string rather than an array of strings. If specified as array prettier formats the css. If specified as string prettier does nothing with the css.


Hints:

Patch:
diff --git a/src/language-js/embed/utils.js b/src/language-js/embed/utils.js
--- a/src/language-js/embed/utils.js
+++ b/src/language-js/embed/utils.js
@@ -30,15 +30,25 @@ const angularComponentObjectExpressionPredicates = [
  * })
  */
 function isAngularComponentStyles(path) {
-  return path.match(
-    (node) => node.type === "TemplateLiteral",
-    (node, name) => isArrayOrTupleExpression(node) && name === "elements",
-    (node, name) =>
-      isObjectProperty(node) &&
-      node.key.type === "Identifier" &&
-      node.key.name === "styles" &&
-      name === "value",
-    ...angularComponentObjectExpressionPredicates,
+  const isTemplateLiteral = (node) => node.type === "TemplateLiteral";
+  const isObjectPropertyNamedStyles = (node, key) =>
+    isObjectProperty(node) &&
+    !node.computed &&
+    node.key.type === "Identifier" &&
+    node.key.name === "styles" &&
+    key === "value";
+  return (
+    path.match(
+      isTemplateLiteral,
+      (node, name) => isArrayOrTupleExpression(node) && name === "elements",
+      isObjectPropertyNamedStyles,
+      ...angularComponentObjectExpressionPredicates,
+    ) ||
+    path.match(
+      isTemplateLiteral,
+      isObjectPropertyNamedStyles,
+      ...angularComponentObjectExpressionPredicates,
+    )
   );
 }
 function isAngularComponentTemplate(path) {


Test patch:
diff --git a/tests/format/typescript/angular-component-examples/15934-computed.component.ts b/tests/format/typescript/angular-component-examples/15934-computed.component.ts
new file mode 100644
--- /dev/null
+++ b/tests/format/typescript/angular-component-examples/15934-computed.component.ts
@@ -0,0 +1,13 @@
+import { Component } from '@angular/core';
+
+const styles = "foobar";
+
+@Component({
+    selector: 'app-root',
+    template: `
+        <h1>My App</h1>
+        <app-todo-list></app-todo-list>
+    `,
+    [styles]: `h1 { color: blue }`
+})
+export class AppComponent {}
diff --git a/tests/format/typescript/angular-component-examples/15934.component.ts b/tests/format/typescript/angular-component-examples/15934.component.ts
new file mode 100644
--- /dev/null
+++ b/tests/format/typescript/angular-component-examples/15934.component.ts
@@ -0,0 +1,11 @@
+import { Component } from '@angular/core';
+
+@Component({
+    selector: 'app-root',
+    template: `
+        <h1>My App</h1>
+        <app-todo-list></app-todo-list>
+    `,
+    styles: `h1 { color: blue }`
+})
+export class AppComponent {}
diff --git a/tests/format/typescript/angular-component-examples/__snapshots__/jsfmt.spec.js.snap b/tests/format/typescript/angular-component-examples/__snapshots__/jsfmt.spec.js.snap
--- a/tests/format/typescript/angular-component-examples/__snapshots__/jsfmt.spec.js.snap
+++ b/tests/format/typescript/angular-component-examples/__snapshots__/jsfmt.spec.js.snap
@@ -1,5 +1,161 @@
 // Jest Snapshot v1, https://goo.gl/fbAQLP
 
+exports[`15934.component.ts - {"trailingComma":"es5"} format 1`] = `
+====================================options=====================================
+parsers: ["typescript"]
+printWidth: 80
+trailingComma: "es5"
+                                                                                | printWidth
+=====================================input======================================
+import { Component } from '@angular/core';
+
+@Component({
+    selector: 'app-root',
+    template: \`
+        <h1>My App</h1>
+        <app-todo-list></app-todo-list>
+    \`,
+    styles: \`h1 { color: blue }\`
+})
+export class AppComponent {}
+
+=====================================output=====================================
+import { Component } from "@angular/core";
+
+@Component({
+  selector: "app-root",
+  template: \`
+    <h1>My App</h1>
+    <app-todo-list></app-todo-list>
+  \`,
+  styles: \`
+    h1 {
+      color: blue;
+    }
+  \`,
+})
+export class AppComponent {}
+
+================================================================================
+`;
+
+exports[`15934.component.ts - {"trailingComma":"none"} format 1`] = `
+====================================options=====================================
+parsers: ["typescript"]
+printWidth: 80
+trailingComma: "none"
+                                                                                | printWidth
+=====================================input======================================
+import { Component } from '@angular/core';
+
+@Component({
+    selector: 'app-root',
+    template: \`
+        <h1>My App</h1>
+        <app-todo-list></app-todo-list>
+    \`,
+    styles: \`h1 { color: blue }\`
+})
+export class AppComponent {}
+
+=====================================output=====================================
+import { Component } from "@angular/core";
+
+@Component({
+  selector: "app-root",
+  template: \`
+    <h1>My App</h1>
+    <app-todo-list></app-todo-list>
+  \`,
+  styles: \`
+    h1 {
+      color: blue;
+    }
+  \`
+})
+export class AppComponent {}
+
+================================================================================
+`;
+
+exports[`15934-computed.component.ts - {"trailingComma":"es5"} format 1`] = `
+====================================options=====================================
+parsers: ["typescript"]
+printWidth: 80
+trailingComma: "es5"
+                                                                                | printWidth
+=====================================input======================================
+import { Component } from '@angular/core';
+
+const styles = "foobar";
+
+@Component({
+    selector: 'app-root',
+    template: \`
+        <h1>My App</h1>
+        <app-todo-list></app-todo-list>
+    \`,
+    [styles]: \`h1 { color: blue }\`
+})
+export class AppComponent {}
+
+=====================================output=====================================
+import { Component } from "@angular/core";
+
+const styles = "foobar";
+
+@Component({
+  selector: "app-root",
+  template: \`
+    <h1>My App</h1>
+    <app-todo-list></app-todo-list>
+  \`,
+  [styles]: \`h1 { color: blue }\`,
+})
+export class AppComponent {}
+
+================================================================================
+`;
+
+exports[`15934-computed.component.ts - {"trailingComma":"none"} format 1`] = `
+====================================options=====================================
+parsers: ["typescript"]
+printWidth: 80
+trailingComma: "none"
+                                                                                | printWidth
+=====================================input======================================
+import { Component } from '@angular/core';
+
+const styles = "foobar";
+
+@Component({
+    selector: 'app-root',
+    template: \`
+        <h1>My App</h1>
+        <app-todo-list></app-todo-list>
+    \`,
+    [styles]: \`h1 { color: blue }\`
+})
+export class AppComponent {}
+
+=====================================output=====================================
+import { Component } from "@angular/core";
+
+const styles = "foobar";
+
+@Component({
+  selector: "app-root",
+  template: \`
+    <h1>My App</h1>
+    <app-todo-list></app-todo-list>
+  \`,
+  [styles]: \`h1 { color: blue }\`
+})
+export class AppComponent {}
+
+================================================================================
+`;
+
 exports[`test.component.ts - {"trailingComma":"es5"} format 1`] = `
 ====================================options=====================================
 parsers: ["typescript"]