From 0a5f455070184639ed4194f02c9edbc492d9c58b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aliz=C3=A9=20Debray?= Date: Fri, 5 Apr 2024 16:46:54 +0200 Subject: [PATCH] Update migrations --- packages/migrations/src/migrations.json | 6 +- .../src/migrations/v7/badge/index.ts | 106 ++++++++++++++++++ 2 files changed, 109 insertions(+), 3 deletions(-) create mode 100644 packages/migrations/src/migrations/v7/badge/index.ts diff --git a/packages/migrations/src/migrations.json b/packages/migrations/src/migrations.json index 9fd7f27714..2c0eb03364 100644 --- a/packages/migrations/src/migrations.json +++ b/packages/migrations/src/migrations.json @@ -101,10 +101,10 @@ "description": "Improves the post stepper accessibility.", "factory": "./migrations/post/stepper" }, - "migration-bootstrap-chip": { + "migration-badge-to-chip-or-tag": { "version": "7.0.0", - "description": "Renames badges to chips.", - "factory": "./migrations/bootstrap/chip" + "description": "Migrates badges to chip or tag depending on the content.", + "factory": "./migrations/v7/badge" } } } diff --git a/packages/migrations/src/migrations/v7/badge/index.ts b/packages/migrations/src/migrations/v7/badge/index.ts new file mode 100644 index 0000000000..bb10137f16 --- /dev/null +++ b/packages/migrations/src/migrations/v7/badge/index.ts @@ -0,0 +1,106 @@ +import { Rule } from '@angular-devkit/schematics'; +import type { AnyNode, Cheerio, CheerioAPI } from 'cheerio'; +import { DomUpdate, getDomMigrationRule } from '../../../utils/dom-migration'; +import { themeColors } from '../../../utils/constants'; + +export default function (): Rule { + return getDomMigrationRule( + new BadgeCheckToChipFilterUpdate(), + new BadgeToChipDismissibleUpdate(), + new BadgeToTagUpdate(), + ); +} + +class BadgeCheckToChipFilterUpdate implements DomUpdate { + selector = '.badge-check'; + + update($elements: Cheerio, $: CheerioAPI) { + $elements.each((_i, element) => { + const $element = $(element); + + $element.removeClass('badge-check').addClass('chip-filter'); + + const $input = $element.children('.badge-check-input'); + if ($input) $input.removeClass('badge-check-input').addClass('chip-filter-input'); + + const $label = $element.children('.badge-check-label'); + if ($label) $label.removeClass('badge-check-label').addClass('chip-filter-label'); + + addChipTextClass($label); + }); + } +} + +class BadgeToChipDismissibleUpdate implements DomUpdate { + selector = '.badge'; + + update($elements: Cheerio, $: CheerioAPI) { + $elements.each((_i, element) => { + const $element = $(element); + + // only update badge with close button + const $closeBtn = $element.children('.btn-close'); + if (!$closeBtn.length) { + return; + } + + addChipTextClass($element); + + $closeBtn.removeAttr('class').addClass('chip chip-dismissible'); + + const ariaLabel = $closeBtn.attr('aria-label'); + if (ariaLabel) { + $closeBtn.removeAttr('aria-label'); + $closeBtn.append(`${ariaLabel}`); + } + + $closeBtn.append($element.children()).data($element.data()); + + $element.replaceWith($closeBtn); + }); + } +} + +class BadgeToTagUpdate implements DomUpdate { + selector = '.badge'; + + bgClassRegex: RegExp = new RegExp(`^bg-(${themeColors.join('|')})$`); + + update($elements: Cheerio, $: CheerioAPI) { + $elements.each((_i, element) => { + const $element = $(element); + + // do not update nested badges + const $parent = $element.parent(); + if ($parent.hasClass('tag')) { + return; + } + + $element.removeClass('badge').addClass('tag'); + + if ($element.hasClass('badge-sm')) $element.removeClass('badge-sm').addClass('tag-sm'); + + $element + .attr('class') + ?.split(' ') + .forEach(cssClass => { + const [_, bgColor] = cssClass.match(this.bgClassRegex) ?? []; + + if (!bgColor) return; + + if (bgColor === 'active' || bgColor === 'yellow') $element.addClass('tag-yellow'); + if (bgColor === 'white') $element.addClass('tag-white'); + if (bgColor === 'info') $element.addClass('tag-info'); + if (bgColor === 'success') $element.addClass('tag-success'); + if (bgColor === 'danger') $element.addClass('tag-danger'); + if (bgColor === 'warning') $element.addClass('tag-warning'); + + $element.removeClass(cssClass); + }); + }); + } +} + +function addChipTextClass($element: Cheerio) { + $element.children('span:not(.badge)').addClass('chip-text'); +}