Skip to content

feat(sdk/skyux-eslint)!: add no-barrel-exports rule#4268

Merged
johnhwhite merged 8 commits intomainfrom
lint-no-barrel-exports
Mar 5, 2026
Merged

feat(sdk/skyux-eslint)!: add no-barrel-exports rule#4268
johnhwhite merged 8 commits intomainfrom
lint-no-barrel-exports

Conversation

@johnhwhite
Copy link
Copy Markdown
Member

@johnhwhite johnhwhite commented Mar 4, 2026

AB#3614172

Summary by CodeRabbit

  • New Features

    • Added an ESLint rule that flags wildcard ("export *") re-exports and offers automatic fixes when target modules can be resolved.
  • Documentation

    • Added a documentation page describing the rule, examples, messages, and fix behavior.
  • Tests

    • Added comprehensive tests covering the rule and utilities for resolving and extracting named exports.
  • Chores

    • Declared a TypeScript peer dependency (^5.9.3).

@johnhwhite johnhwhite added the risk level (author): 1 No additional bugs expected from this change label Mar 4, 2026
@johnhwhite johnhwhite temporarily deployed to e2e-team-members March 4, 2026 20:24 — with GitHub Actions Inactive
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 4, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds a new SkyUX ESLint rule no-barrel-exports, its implementation and tests, utilities to resolve and extract named exports, documentation, registers the rule in TS configs, and adds TypeScript as a peer dependency.

Changes

Cohort / File(s) Summary
Documentation & Configs
libs/sdk/skyux-eslint/docs/rules/no-barrel-exports.md, libs/sdk/skyux-eslint/src/configs/ts-all.ts, libs/sdk/skyux-eslint/src/configs/ts-recommended.ts
Adds rule docs and enables skyux-eslint/no-barrel-exports as error in TS "all" and "recommended" configs.
Rule Implementation & Plugin
libs/sdk/skyux-eslint/src/rules/no-barrel-exports.ts, libs/sdk/skyux-eslint/src/plugins/ts-plugin.ts
New no-barrel-exports rule detecting export * / export * as forms, reporting namespace/barrel exports; provides fixes for resolvable relative barrels and registers the rule in the TS plugin.
Resolution & Extraction Utilities
libs/sdk/skyux-eslint/src/rules/utils/resolve-exports.ts
Adds resolveModulePath, extractNamedExports, and getNamedExportsFromFile to resolve relative specifiers and statically extract/deduplicate/sort value and type named exports.
Tests
libs/sdk/skyux-eslint/src/rules/no-barrel-exports.spec.ts, libs/sdk/skyux-eslint/src/rules/utils/resolve-exports.spec.ts
Adds comprehensive tests for the rule (valid/invalid cases, fixer outputs, namespace reports) and extensive tests for resolution/extraction across many export syntaxes and resolution scenarios.
Package Manifest
libs/sdk/skyux-eslint/package.json
Adds typescript (^5.9.3) to peerDependencies alongside @typescript-eslint/utils.

Sequence Diagram(s)

sequenceDiagram
    participant ESLint as ESLint Engine
    participant Rule as no-barrel-exports Rule
    participant Resolver as resolveModulePath
    participant Extractor as getNamedExportsFromFile
    participant Fixer as Fix Generator

    ESLint->>Rule: Provide ExportAllDeclaration node
    Rule->>Rule: Is namespace re-export?
    alt Namespace re-export
        Rule-->>ESLint: Report noNamespaceReExports
    else Plain wildcard export
        Rule->>Resolver: Resolve specifier (relative?)
        Resolver-->>Rule: file path or undefined
        alt Resolved
            Rule->>Extractor: Read & extract named exports
            Extractor-->>Rule: valueExports / typeExports or undefined
            alt Exports found
                Rule->>Fixer: Build explicit export statements
                Fixer-->>Rule: replacement code
                Rule-->>ESLint: Report noBarrelExports with fix
            else No exports
                Rule-->>ESLint: Report noBarrelExports (no fix)
            end
        else Not resolved
            Rule-->>ESLint: Report noBarrelExports (no fix)
        end
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

Suggested reviewers

  • Blackbaud-SteveBrush
  • Blackbaud-SandhyaRajasabeson

Poem

🐰 I hopped through files and chased each star,
Turned wild barrels into names with care,
Values and types now tidy and clear,
Exports listed plainly, nothing to fear.
A rabbit’s nibble for code made fair 🥕

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat(sdk/skyux-eslint)!: add no-barrel-exports rule' directly and accurately describes the main change—adding a new ESLint rule called no-barrel-exports to the sdk/skyux-eslint package.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch lint-no-barrel-exports

Comment @coderabbitai help to get the list of available commands and usage tips.

@nx-cloud
Copy link
Copy Markdown

nx-cloud bot commented Mar 4, 2026

View your CI Pipeline Execution ↗ for commit d46106b

Command Status Duration Result
nx build code-examples-playground --baseHref=ht... ✅ Succeeded 2m 12s View ↗
nx build integration --baseHref=https://blackba... ✅ Succeeded 5s View ↗
nx build playground --baseHref=https://blackbau... ✅ Succeeded 7s View ↗

☁️ Nx Cloud last updated this comment at 2026-03-05 17:30:33 UTC

@blackbaud-sky-build-user
Copy link
Copy Markdown
Collaborator

Storybook preview

Component Storybooks:

  • (no component storybooks affected in this pr)

Apps:

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new skyux-eslint/no-barrel-exports TypeScript rule to discourage export * (including export * as ns) so library/public API surfaces stay explicit, and wires it into the SKY UX TS plugin + recommended/all presets with accompanying docs and snapshots.

Changes:

  • Introduces no-barrel-exports rule (with an auto-fix attempt for relative export * from cases).
  • Adds export-resolution utilities (+ unit tests) to support the rule’s fixer.
  • Enables the rule in ts-recommended and ts-all, and adds rule documentation + snapshot updates.

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
libs/sdk/skyux-eslint/src/rules/utils/resolve-exports.ts Adds filesystem/path helpers and regex-based export extraction used by the rule fixer.
libs/sdk/skyux-eslint/src/rules/utils/resolve-exports.spec.ts Adds unit tests for module path resolution and export extraction.
libs/sdk/skyux-eslint/src/rules/no-barrel-exports.ts Implements the new rule and fixer for wildcard re-exports.
libs/sdk/skyux-eslint/src/rules/no-barrel-exports.spec.ts Adds RuleTester coverage including fixer behavior via mocks.
libs/sdk/skyux-eslint/src/plugins/ts-plugin.ts Registers the new rule in the TS plugin.
libs/sdk/skyux-eslint/src/configs/ts-recommended.ts Enables the rule in the recommended TS preset.
libs/sdk/skyux-eslint/src/configs/ts-all.ts Enables the rule in the “all” TS preset.
libs/sdk/skyux-eslint/docs/rules/no-barrel-exports.md Adds end-user documentation for the new rule.
libs/sdk/eslint-config-skyux/src/snapshots/index.test.ts.snap Updates snapshots to include the new rule + preset changes.

You can also share your feedback on Copilot code review. Take the survey.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@libs/sdk/skyux-eslint/docs/rules/no-barrel-exports.md`:
- Around line 18-44: The markdown headings under the "Usage Examples" section
use fourth-level headings (e.g., "#### Default Config", "#### :x: Invalid Code",
"#### :white_check_mark: Valid Code") which breaks the heading hierarchy; change
those subsection headings from "####" to "###" so they are peer-level
subsections under the parent "Usage Examples" heading to satisfy markdownlint
MD001.

In `@libs/sdk/skyux-eslint/src/rules/no-barrel-exports.ts`:
- Around line 52-60: The autofixer currently emits a single value re-export for
everything returned by getNamedExportsFromFile, which incorrectly treats
type-only symbols as value exports; update the fixer logic around
node/moduleSpecifier to split the returned names into two arrays (valueExports
vs typeOnlyExports) by using the same logic as extractNamedExports or by
enhancing getNamedExportsFromFile to indicate kind, then generate appropriate
replacement text: emit "export { ... } from '<moduleSpecifier>';" for
valueExports and "export type { ... } from '<moduleSpecifier>';" for
typeOnlyExports (emit one or both statements depending on which arrays are
non-empty), and use fixer.replaceText(node, ...) with that combined string.
Ensure you reference the existing functions getNamedExportsFromFile and
extractNamedExports (or augment getNamedExportsFromFile to return kind info) and
keep node and moduleSpecifier usage intact.

In `@libs/sdk/skyux-eslint/src/rules/utils/resolve-exports.ts`:
- Around line 39-44: The current declarationRegex in resolve-exports.ts only
captures the first identifier (match[1]) which loses subsequent declarators in
statements like `export const a = 1, b = 2;`; update the logic that iterates
over declarationRegex.exec(fileContent) to detect when the matched kind is a
variable declaration (const|let|var), then parse the full declarator list from
the matched text (split on commas outside brackets/strings or use a simple split
for typical patterns) and push each identifier into the exports array; keep
existing behavior for class/interface/type/function/enum by continuing to push
match[1] for those kinds and ensure the variables-handling code references the
declarationRegex match group and fileContent to extract the entire declaration
text before splitting.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 97a92598-eeb2-4924-862f-12b8c247bf19

📥 Commits

Reviewing files that changed from the base of the PR and between d026f28 and 5547de8.

⛔ Files ignored due to path filters (1)
  • libs/sdk/eslint-config-skyux/src/__snapshots__/index.test.ts.snap is excluded by !**/*.snap
📒 Files selected for processing (8)
  • libs/sdk/skyux-eslint/docs/rules/no-barrel-exports.md
  • libs/sdk/skyux-eslint/src/configs/ts-all.ts
  • libs/sdk/skyux-eslint/src/configs/ts-recommended.ts
  • libs/sdk/skyux-eslint/src/plugins/ts-plugin.ts
  • libs/sdk/skyux-eslint/src/rules/no-barrel-exports.spec.ts
  • libs/sdk/skyux-eslint/src/rules/no-barrel-exports.ts
  • libs/sdk/skyux-eslint/src/rules/utils/resolve-exports.spec.ts
  • libs/sdk/skyux-eslint/src/rules/utils/resolve-exports.ts

…fixer (#4269)

The `no-barrel-exports` auto-fixer always emitted `export { ... }` for
all symbols, which is invalid under `isolatedModules: true` for
type-only exports (interfaces, type aliases). This splits the fixer
output into separate `export { ... }` and `export type { ... }`
statements.

## `resolve-exports.ts`
- Introduces `ExtractedNamedExports` interface with `valueExports:
string[]` and `typeExports: string[]`
- Rewrites `extractNamedExports` to categorize by kind:
- **Value**: `class`, `abstract class`, `function`, `async function`,
`enum`, `const`/`let`/`var` (including `declare` variants)
- **Type-only**: `interface`, `type` alias, `export type { ... }`
blocks, inline `type` specifiers in `export { type Foo, Bar }`
- Adds multi-declarator variable support: `export const a = 1, b = 2` →
`['a', 'b']`
- Uses `[^;\n]+` in variable regex to prevent greedy cross-statement
capture in semicolon-free files
- Updates `getNamedExportsFromFile` return type to
`ExtractedNamedExports | undefined`

## `no-barrel-exports.ts`
- Fixer now emits one or both statements depending on what's present:

```ts
// Before (always emitted as values — broken for interfaces/types):
export { FooComponent, FooConfig, FooType } from './foo';

// After:
export { FooComponent } from './foo';
export type { FooConfig, FooType } from './foo';
```
- Updates `meta.docs.description` to mention `export * as ns from`
alongside `export * from`

## Tests & docs
- Updates all `extractNamedExports` expectations to `{ valueExports,
typeExports }` shape
- Adds tests for type-only re-exports, mixed exports, multi-declarator
variables, inline `type` specifiers, and trailing-comma specifiers
- Replaces `require('node:fs').mkdirSync` with the already-imported
`mkdirSync`
- Fixes `no-barrel-exports.md` heading levels (`####` → `###`) per
markdownlint MD001

> [!WARNING]
>
> <details>
> <summary>Firewall rules blocked me from connecting to one or more
addresses (expand for details)</summary>
>
> #### I tried to connect to the following addresses, but was blocked by
firewall rules:
>
> - `download.cypress.io`
> - Triggering command:
`/home/REDACTED/work/_temp/ghcca-node/node/bin/node node dist/index.js
--exec install -test` (dns block)
>
> If you need me to access, download, or install something from one of
these locations, you can either:
>
> - Configure [Actions setup
steps](https://gh.io/copilot/actions-setup-steps) to set up my
environment, which run before the firewall is enabled
> - Add the appropriate URLs or hosts to the custom allowlist in this
repository's [Copilot coding agent
settings](https://github.com/blackbaud/skyux/settings/copilot/coding_agent)
(admins only)
>
> </details>

<!-- START COPILOT CODING AGENT TIPS -->
---

💬 We'd love your input! Share your thoughts on Copilot coding agent in
our [2 minute survey](https://gh.io/copilot-coding-agent-survey).

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: johnhwhite <750350+johnhwhite@users.noreply.github.com>
@johnhwhite johnhwhite temporarily deployed to e2e-team-members March 4, 2026 21:16 — with GitHub Actions Inactive
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@libs/sdk/skyux-eslint/src/rules/utils/resolve-exports.ts`:
- Around line 64-69: The current export variable parsing
(variableDeclarationRegex / fileContent and the names extraction) wrongly splits
on every comma and stops at newlines, mis-parsing declarations with nested
commas or multiline initializers; change the approach to capture the full
declaration up to the semicolon (e.g. adjust the regex to consume everything
until the next semicolon rather than stopping at newlines) and replace the naive
.split(',') with a small stateful splitter that iterates the captured
declaration and ignores commas inside parentheses/brackets/braces and inside
strings/comments, then apply the identifier extraction (/^([A-Za-z_$][\w$]*)/)
to each top-level segment to build names so variableDeclarationRegex, the names
mapping logic, and downstream code get correct symbols.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 5cf22840-63c5-45f7-856a-bb945db66909

📥 Commits

Reviewing files that changed from the base of the PR and between 5547de8 and ef3bf13.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (5)
  • libs/sdk/skyux-eslint/docs/rules/no-barrel-exports.md
  • libs/sdk/skyux-eslint/src/rules/no-barrel-exports.spec.ts
  • libs/sdk/skyux-eslint/src/rules/no-barrel-exports.ts
  • libs/sdk/skyux-eslint/src/rules/utils/resolve-exports.spec.ts
  • libs/sdk/skyux-eslint/src/rules/utils/resolve-exports.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • libs/sdk/skyux-eslint/docs/rules/no-barrel-exports.md
  • libs/sdk/skyux-eslint/src/rules/no-barrel-exports.spec.ts

@johnhwhite johnhwhite temporarily deployed to e2e-team-members March 4, 2026 21:28 — with GitHub Actions Inactive
@johnhwhite johnhwhite changed the title feat(sdk/skyux-eslint): add no-barrel-exports rule feat(sdk/skyux-eslint)!: add no-barrel-exports rule Mar 4, 2026
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 10 out of 10 changed files in this pull request and generated 2 comments.


You can also share your feedback on Copilot code review. Take the survey.

@johnhwhite johnhwhite temporarily deployed to e2e-team-members March 5, 2026 16:01 — with GitHub Actions Inactive
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
libs/sdk/skyux-eslint/src/rules/utils/resolve-exports.spec.ts (1)

12-20: Deduplicate temp-dir lifecycle setup to reduce test maintenance.

The beforeEach/afterEach temp-dir setup is repeated in both suites; extracting a shared helper (or using outer hooks) would keep setup changes in one place.

Also applies to: 52-58

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@libs/sdk/skyux-eslint/src/rules/utils/resolve-exports.spec.ts` around lines
12 - 20, Extract the duplicated temp-dir lifecycle into a single shared setup so
both test suites reuse it: move the tempDir declaration and the
mkdtempSync/rmSync beforeEach/afterEach into an outer scope or helper function
and have both inner describe blocks use that shared hook; specifically
consolidate the existing tempDir variable and the beforeEach
(mkdtempSync(join(tmpdir(), 'resolve-exports-'))) and afterEach (rmSync(tempDir,
{ recursive: true })) logic so you only maintain it once (referencing tempDir,
mkdtempSync, rmSync, and the beforeEach/afterEach hooks in
resolve-exports.spec.ts).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@libs/sdk/skyux-eslint/src/rules/utils/resolve-exports.ts`:
- Around line 9-15: The resolveModulePath function currently resolves any
moduleSpecifier as a filesystem path; add an early guard in resolveModulePath to
enforce the "relative specifier" contract by returning undefined unless
moduleSpecifier begins with "./" or "../" (so only relative paths are
processed), then continue with the existing dirname/resolve logic; refer to the
resolveModulePath function to locate where to insert this check.

---

Nitpick comments:
In `@libs/sdk/skyux-eslint/src/rules/utils/resolve-exports.spec.ts`:
- Around line 12-20: Extract the duplicated temp-dir lifecycle into a single
shared setup so both test suites reuse it: move the tempDir declaration and the
mkdtempSync/rmSync beforeEach/afterEach into an outer scope or helper function
and have both inner describe blocks use that shared hook; specifically
consolidate the existing tempDir variable and the beforeEach
(mkdtempSync(join(tmpdir(), 'resolve-exports-'))) and afterEach (rmSync(tempDir,
{ recursive: true })) logic so you only maintain it once (referencing tempDir,
mkdtempSync, rmSync, and the beforeEach/afterEach hooks in
resolve-exports.spec.ts).

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: dacb5c4a-5b36-4c92-bd60-eebcc098fbb1

📥 Commits

Reviewing files that changed from the base of the PR and between 6b9c27c and fe31ddd.

📒 Files selected for processing (5)
  • libs/sdk/skyux-eslint/docs/rules/no-barrel-exports.md
  • libs/sdk/skyux-eslint/src/rules/no-barrel-exports.spec.ts
  • libs/sdk/skyux-eslint/src/rules/no-barrel-exports.ts
  • libs/sdk/skyux-eslint/src/rules/utils/resolve-exports.spec.ts
  • libs/sdk/skyux-eslint/src/rules/utils/resolve-exports.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • libs/sdk/skyux-eslint/src/rules/no-barrel-exports.ts
  • libs/sdk/skyux-eslint/src/rules/no-barrel-exports.spec.ts

@johnhwhite johnhwhite merged commit d7a8332 into main Mar 5, 2026
24 checks passed
@johnhwhite johnhwhite deleted the lint-no-barrel-exports branch March 5, 2026 23:06
johnhwhite pushed a commit that referenced this pull request Mar 6, 2026
##
[14.0.0-alpha.5](14.0.0-alpha.4...14.0.0-alpha.5)
(2026-03-05)


### ⚠ BREAKING CHANGES

* **sdk/skyux-eslint:** add no-barrel-exports rule (#4268)

### Features

* **components/ag-grid:** use datepicker component for column filter
([#4249](#4249))
([d026f28](d026f28)),
closes
[AB#3648062](https://dev.azure.com/blackbaud/Products/_workitems/edit/3648062)
* **sdk/skyux-eslint:** add no-barrel-exports rule
([#4268](#4268))
([d7a8332](d7a8332))


### Bug Fixes

* update to `@angular/build@21.2.0`
([#4266](#4266))
([e2c8ec0](e2c8ec0))

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Breaking Changes**
  * New ESLint rule added (no-barrel-exports)

* **New Features**
  * Integrated datepicker component for ag-grid column filtering
  * Added new ESLint rule for code organization

* **Bug Fixes**
  * Updated Angular build version

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
johnhwhite added a commit that referenced this pull request Mar 6, 2026
…-and-libphonenumber

* origin/main:
  chore: release 14.0.0-alpha.5 (#4267)
  feat(sdk/skyux-eslint)!: add no-barrel-exports rule (#4268)
johnhwhite added a commit that referenced this pull request Mar 18, 2026
[AB#3614172](https://dev.azure.com/blackbaud/f565481a-7bc9-4083-95d5-4f953da6d499/_workitems/edit/3614172)

Reverts #4268 

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Chores**
* Removed the no-barrel-exports ESLint rule from configs and the plugin
* Deleted the rule implementation, related utility module, tests, and
documentation
* Removed the TypeScript peer dependency declaration from the package
configuration
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
johnhwhite pushed a commit that referenced this pull request Mar 18, 2026
##
[14.0.0-alpha.10](14.0.0-alpha.9...14.0.0-alpha.10)
(2026-03-18)


### ⚠ BREAKING CHANGES

* **components/layout:** replace `@angular/animations` in text expand
repeater component with CSS transitions (#4317)
* **components/layout:** replace `@angular/animations` in text expand
component with CSS transitions (#4308)
* **components/inline-form:** replace `@angular/animations` with CSS
transitions (#4315)
* **components/popovers:** replace `@angular/animations` with CSS
transitions (#4313)

### Features

* **components/modals:** modal header close button is shown in modern
theme ([#4265](#4265))
([db2a615](db2a615))


### Bug Fixes

* **components/core:** animationend and transitionend handlers detect
suppressed animations via `getComputedStyle`
([#4310](#4310))
([88d7b0f](88d7b0f))
* **components/inline-form:** replace `@angular/animations` with CSS
transitions ([#4315](#4315))
([5254dbb](5254dbb))
* **components/layout:** replace `@angular/animations` in text expand
component with CSS transitions
([#4308](#4308))
([bbde359](bbde359))
* **components/layout:** replace `@angular/animations` in text expand
repeater component with CSS transitions
([#4317](#4317))
([bb4a3c7](bb4a3c7))
* **components/popovers:** replace `@angular/animations` with CSS
transitions ([#4313](#4313))
([28088aa](28088aa))
* **sdk/skyux-eslint:** remove `no-barrel-exports` rule
([#4320](#4320))
([73dafd6](73dafd6)),
closes
[AB#3614172](https://dev.azure.com/blackbaud/Products/_workitems/edit/3614172)
[#4268](#4268)

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Breaking Changes**
  * Animation behavior updated across multiple components

* **New Features**
  * Added close button to modal headers in the modern theme

* **Bug Fixes**
  * Resolved animation handling issues affecting multiple components
  * Fixed related stability issues across components

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

risk level (author): 1 No additional bugs expected from this change

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants