@c-code/c-code-fw 1.1.9 → 1.3.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 (31) hide show
  1. package/README.md +104 -0
  2. package/fesm2022/c-code-c-code-fw-ui.mjs +815 -0
  3. package/fesm2022/c-code-c-code-fw-ui.mjs.map +1 -0
  4. package/fesm2022/c-code-c-code-fw.mjs +37 -30
  5. package/fesm2022/c-code-c-code-fw.mjs.map +1 -1
  6. package/lib/screen_width-event.service.d.ts +8 -8
  7. package/package.json +9 -2
  8. package/public-api.d.ts +1 -1
  9. package/ui/index.d.ts +5 -0
  10. package/ui/lib/components/category-menu/category-menu.component.d.ts +19 -0
  11. package/ui/lib/components/faq/faq.component.d.ts +16 -0
  12. package/ui/lib/components/gallery/gallery.component.d.ts +27 -0
  13. package/ui/lib/components/info-item/info-item.component.d.ts +18 -0
  14. package/ui/lib/components/lightbox/lightbox.component.d.ts +26 -0
  15. package/ui/lib/components/page-banner/page-banner.component.d.ts +23 -0
  16. package/ui/lib/components/plan-card/plan-card.component.d.ts +23 -0
  17. package/ui/lib/components/plan-catalog/plan-catalog.component.d.ts +78 -0
  18. package/ui/lib/components/plan-details/plan-details.component.d.ts +44 -0
  19. package/ui/lib/components/plan-filter-form/plan-filter-form.component.d.ts +28 -0
  20. package/ui/lib/components/promo-modal/promo-modal.component.d.ts +24 -0
  21. package/ui/lib/components/search-box/search-box.component.d.ts +18 -0
  22. package/ui/lib/components/social-links/social-links.component.d.ts +17 -0
  23. package/ui/lib/components/whatsapp-button/whatsapp-button.component.d.ts +19 -0
  24. package/ui/lib/models/plan.models.d.ts +50 -0
  25. package/ui/lib/models/ui.models.d.ts +24 -0
  26. package/ui/lib/services/plan-catalog.service.d.ts +43 -0
  27. package/ui/lib/services/seo.service.d.ts +39 -0
  28. package/ui/lib/utils/plan.utils.d.ts +16 -0
  29. package/ui/lib/utils/text.utils.d.ts +15 -0
  30. package/ui/public-api.d.ts +20 -0
  31. package/ui/theme/tokens.css +45 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"c-code-c-code-fw-ui.mjs","sources":["../../../projects/core/ui/src/lib/models/plan.models.ts","../../../projects/core/ui/src/lib/utils/text.utils.ts","../../../projects/core/ui/src/lib/utils/plan.utils.ts","../../../projects/core/ui/src/lib/services/plan-catalog.service.ts","../../../projects/core/ui/src/lib/services/seo.service.ts","../../../projects/core/ui/src/lib/components/whatsapp-button/whatsapp-button.component.ts","../../../projects/core/ui/src/lib/components/whatsapp-button/whatsapp-button.component.html","../../../projects/core/ui/src/lib/components/promo-modal/promo-modal.component.ts","../../../projects/core/ui/src/lib/components/promo-modal/promo-modal.component.html","../../../projects/core/ui/src/lib/components/page-banner/page-banner.component.ts","../../../projects/core/ui/src/lib/components/page-banner/page-banner.component.html","../../../projects/core/ui/src/lib/components/info-item/info-item.component.ts","../../../projects/core/ui/src/lib/components/info-item/info-item.component.html","../../../projects/core/ui/src/lib/components/faq/faq.component.ts","../../../projects/core/ui/src/lib/components/faq/faq.component.html","../../../projects/core/ui/src/lib/components/social-links/social-links.component.ts","../../../projects/core/ui/src/lib/components/social-links/social-links.component.html","../../../projects/core/ui/src/lib/components/plan-card/plan-card.component.ts","../../../projects/core/ui/src/lib/components/plan-card/plan-card.component.html","../../../projects/core/ui/src/lib/components/category-menu/category-menu.component.ts","../../../projects/core/ui/src/lib/components/category-menu/category-menu.component.html","../../../projects/core/ui/src/lib/components/search-box/search-box.component.ts","../../../projects/core/ui/src/lib/components/search-box/search-box.component.html","../../../projects/core/ui/src/lib/components/plan-filter-form/plan-filter-form.component.ts","../../../projects/core/ui/src/lib/components/plan-filter-form/plan-filter-form.component.html","../../../projects/core/ui/src/lib/components/plan-catalog/plan-catalog.component.ts","../../../projects/core/ui/src/lib/components/plan-catalog/plan-catalog.component.html","../../../projects/core/ui/src/lib/components/plan-details/plan-details.component.ts","../../../projects/core/ui/src/lib/components/plan-details/plan-details.component.html","../../../projects/core/ui/src/lib/components/lightbox/lightbox.component.ts","../../../projects/core/ui/src/lib/components/lightbox/lightbox.component.html","../../../projects/core/ui/src/lib/components/gallery/gallery.component.ts","../../../projects/core/ui/src/lib/components/gallery/gallery.component.html","../../../projects/core/ui/src/public-api.ts","../../../projects/core/ui/src/c-code-c-code-fw-ui.ts"],"sourcesContent":["/**\n * Plan category. The numeric values match the `category` field stored in the sites' `plans.json`.\n */\nexport enum PlanCategory {\n Individual = 0,\n Couple = 1,\n Group = 2,\n None = 3,\n}\n\n/** Add-on service that a plan includes (an entry in `additionals.json`). */\nexport interface AdditionalService {\n id: number;\n iconPath: string;\n name: string;\n}\n\n/** A spa plan (an entry in `plans.json`). */\nexport interface Plan {\n id: number;\n name: string;\n description: string;\n duration: string;\n price: number;\n /** Number of people the plan is for. The spelling matches the existing JSON files. */\n cuantity: number;\n imgPath: string;\n category: PlanCategory | number;\n additionalServicesId: number[];\n /** Filled in by `PlanCatalogService` by joining `additionalServicesId` with `additionals.json`. */\n additionalServices?: AdditionalService[];\n}\n\n/** Price range option for the filter form (an entry in `priceRanges.json`). */\nexport interface PriceRange {\n description: string;\n min: number;\n max: number;\n}\n\n/** Filter produced by `cc-plan-filter-form`. Empty fields are not applied. */\nexport interface PlanFilter {\n service?: AdditionalService | null;\n priceRange?: PriceRange | null;\n}\n\n/** Entry in `cc-category-menu`. */\nexport interface CategoryOption<T = PlanCategory | number> {\n value: T;\n label: string;\n /** Number shown next to the label. Leave it empty to hide it. */\n count?: number;\n}\n\n/** Default Spanish labels for the plan categories. */\nexport const DEFAULT_PLAN_CATEGORIES: CategoryOption[] = [\n { value: PlanCategory.Individual, label: 'Individual' },\n { value: PlanCategory.Couple, label: 'Pareja' },\n { value: PlanCategory.Group, label: 'Grupal' },\n];\n","/**\n * Turns a text into a URL-safe slug: \"PLAN FLOR DE LOTTO 3\" -> \"plan-flor-de-lotto-3\".\n * Accents are removed, so \"Jacuzzi Mágico\" -> \"jacuzzi-magico\".\n */\nexport function slugify(text: string): string {\n return text\n .normalize('NFD')\n .replace(/[̀-ͯ]/g, '')\n .toLowerCase()\n .trim()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-+|-+$/g, '');\n}\n\n/** \"PLAN GARDENIA\" -> \"Plan Gardenia\". */\nexport function titleCase(text: string): string {\n return text.toLowerCase().replace(/(^|\\s)\\S/g, (c) => c.toUpperCase());\n}\n\n/** Cuts a text at the last whole word that fits in `max` characters and adds \"…\". */\nexport function truncateText(text: string, max = 160): string {\n if (text.length <= max) return text;\n const cut = text.lastIndexOf(' ', max - 1);\n return text.slice(0, cut > 0 ? cut : max - 1) + '…';\n}\n\n/**\n * Builds a WhatsApp chat link.\n * @param phone Number with country code, with or without \"+\" and spaces: \"57 310 494 8884\".\n * @param message Pre-filled message, optional.\n */\nexport function whatsappUrl(phone: string, message?: string): string {\n const params = new URLSearchParams({ phone: phone.replace(/\\D/g, '') });\n if (message) params.set('text', message);\n params.set('type', 'phone_number');\n params.set('app_absent', '0');\n return `https://api.whatsapp.com/send/?${params.toString()}`;\n}\n","import {\n AdditionalService,\n CategoryOption,\n Plan,\n PlanCategory,\n PlanFilter,\n} from '../models/plan.models';\nimport { slugify } from './text.utils';\n\n/** Fills `plan.additionalServices` from `additionalServicesId`. Unknown ids are skipped. */\nexport function joinAdditionalServices(\n plans: Plan[],\n additionals: AdditionalService[]\n): Plan[] {\n const byId = new Map<number, AdditionalService>();\n // First entry wins, so a repeated id in the JSON keeps the original behavior of `Array.find`.\n for (const service of additionals) {\n if (!byId.has(service.id)) byId.set(service.id, service);\n }\n return plans.map((plan) => ({\n ...plan,\n additionalServices: plan.additionalServicesId\n .map((id) => byId.get(id))\n .filter((s): s is AdditionalService => !!s),\n }));\n}\n\n/** URL slug of a plan, derived from its name. */\nexport function planSlug(plan: Plan | string): string {\n return slugify(typeof plan === 'string' ? plan : plan.name);\n}\n\nexport function findPlanBySlug(plans: Plan[], slug: string): Plan | undefined {\n return plans.find((plan) => planSlug(plan) === slug);\n}\n\nexport function filterPlansByCategory(\n plans: Plan[],\n category: PlanCategory | number\n): Plan[] {\n return plans.filter((plan) => plan.category === category);\n}\n\n/** Case- and accent-insensitive search on the plan name. An empty query returns every plan. */\nexport function searchPlansByName(plans: Plan[], query: string): Plan[] {\n const q = slugify(query);\n if (!q) return plans;\n return plans.filter((plan) => planSlug(plan).includes(q));\n}\n\n/**\n * Applies a `PlanFilter`. Price uses `min < price <= max`, the same rule the sites had,\n * except that `min = 0` also includes free plans.\n */\nexport function filterPlans(plans: Plan[], filter: PlanFilter): Plan[] {\n const { service, priceRange } = filter;\n return plans.filter((plan) => {\n const matchesService =\n !service ||\n (plan.additionalServices ?? []).some((s) => s.id === service.id) ||\n plan.additionalServicesId.includes(service.id);\n const matchesPrice =\n !priceRange ||\n (plan.price <= priceRange.max &&\n (plan.price > priceRange.min || (priceRange.min === 0 && plan.price === 0)));\n return matchesService && matchesPrice;\n });\n}\n\n/** Returns the options with `count` set to the number of plans in each category. */\nexport function withCategoryCounts<T extends PlanCategory | number>(\n options: CategoryOption<T>[],\n plans: Plan[]\n): CategoryOption<T>[] {\n return options.map((option) => ({\n ...option,\n count: plans.filter((plan) => plan.category === option.value).length,\n }));\n}\n","import { HttpClient } from '@angular/common/http';\nimport {\n EnvironmentProviders,\n inject,\n Injectable,\n InjectionToken,\n makeEnvironmentProviders,\n} from '@angular/core';\nimport { forkJoin, map, Observable, of, shareReplay } from 'rxjs';\nimport {\n AdditionalService,\n Plan,\n PlanCategory,\n PlanFilter,\n PriceRange,\n} from '../models/plan.models';\nimport {\n filterPlans,\n filterPlansByCategory,\n findPlanBySlug,\n joinAdditionalServices,\n searchPlansByName,\n} from '../utils/plan.utils';\n\n/** Where `PlanCatalogService` loads the JSON files from. */\nexport interface PlanCatalogConfig {\n plansUrl: string;\n additionalsUrl: string;\n /** Leave it empty if the site has no `priceRanges.json`; `getPriceRanges()` then returns `[]`. */\n priceRangesUrl?: string | null;\n}\n\nexport const DEFAULT_PLAN_CATALOG_CONFIG: PlanCatalogConfig = {\n plansUrl: 'assets/data/plans.json',\n additionalsUrl: 'assets/data/additionals.json',\n priceRangesUrl: 'assets/data/priceRanges.json',\n};\n\nexport const PLAN_CATALOG_CONFIG = new InjectionToken<PlanCatalogConfig>(\n 'PLAN_CATALOG_CONFIG',\n { providedIn: 'root', factory: () => DEFAULT_PLAN_CATALOG_CONFIG }\n);\n\n/**\n * Overrides the JSON locations. Without it, the service reads `assets/data/*.json`.\n *\n * ```ts\n * providers: [provideHttpClient(withFetch()), providePlanCatalog({ priceRangesUrl: null })]\n * ```\n */\nexport function providePlanCatalog(\n config: Partial<PlanCatalogConfig> = {}\n): EnvironmentProviders {\n return makeEnvironmentProviders([\n {\n provide: PLAN_CATALOG_CONFIG,\n useValue: { ...DEFAULT_PLAN_CATALOG_CONFIG, ...config },\n },\n ]);\n}\n\n/**\n * Reads plans, add-on services and price ranges from static JSON.\n * Each file is requested once and cached; filtering happens in memory.\n * Needs `provideHttpClient()` in the app.\n */\n@Injectable({ providedIn: 'root' })\nexport class PlanCatalogService {\n private http = inject(HttpClient);\n private config = inject(PLAN_CATALOG_CONFIG);\n\n private additionals$ = this.http\n .get<AdditionalService[]>(this.config.additionalsUrl)\n .pipe(shareReplay(1));\n\n private plans$ = forkJoin({\n plans: this.http.get<Plan[]>(this.config.plansUrl),\n additionals: this.additionals$,\n }).pipe(\n map(({ plans, additionals }) => joinAdditionalServices(plans, additionals)),\n shareReplay(1)\n );\n\n private priceRanges$ = (\n this.config.priceRangesUrl\n ? this.http.get<PriceRange[]>(this.config.priceRangesUrl)\n : of<PriceRange[]>([])\n ).pipe(shareReplay(1));\n\n /** Every plan, with `additionalServices` filled in. */\n getPlans(): Observable<Plan[]> {\n return this.plans$;\n }\n\n getAdditionalServices(): Observable<AdditionalService[]> {\n return this.additionals$;\n }\n\n getPriceRanges(): Observable<PriceRange[]> {\n return this.priceRanges$;\n }\n\n getPlansByCategory(category: PlanCategory | number): Observable<Plan[]> {\n return this.plans$.pipe(map((plans) => filterPlansByCategory(plans, category)));\n }\n\n getPlansByFilter(filter: PlanFilter): Observable<Plan[]> {\n return this.plans$.pipe(map((plans) => filterPlans(plans, filter)));\n }\n\n getPlansByName(name: string): Observable<Plan[]> {\n return this.plans$.pipe(map((plans) => searchPlansByName(plans, name)));\n }\n\n getPlanBySlug(slug: string): Observable<Plan | undefined> {\n return this.plans$.pipe(map((plans) => findPlanBySlug(plans, slug)));\n }\n}\n","import { DOCUMENT } from '@angular/common';\nimport {\n EnvironmentProviders,\n inject,\n Injectable,\n InjectionToken,\n makeEnvironmentProviders,\n} from '@angular/core';\nimport { Meta, Title } from '@angular/platform-browser';\n\nexport interface SeoConfig {\n /** Production domain without a trailing slash: \"https://www.laurelspamedellin.com\". */\n siteUrl: string;\n /** Image used when a page does not set one. Relative paths are resolved against `siteUrl`. */\n defaultImage?: string;\n}\n\nexport interface SeoData {\n title: string;\n description: string;\n /** Page path, for example \"/planes\". */\n path: string;\n /** Image for the share preview. Defaults to `SeoConfig.defaultImage`. */\n image?: string;\n}\n\nexport const SEO_CONFIG = new InjectionToken<SeoConfig>('SEO_CONFIG');\n\n/** Registers the site data `SeoService` needs. */\nexport function provideSeo(config: SeoConfig): EnvironmentProviders {\n return makeEnvironmentProviders([\n {\n provide: SEO_CONFIG,\n useValue: { ...config, siteUrl: config.siteUrl.replace(/\\/+$/, '') },\n },\n ]);\n}\n\n/**\n * Sets the title, description, canonical URL, Open Graph and Twitter tags, and JSON-LD blocks.\n * Works during SSR and prerendering. Requires `provideSeo()`.\n */\n@Injectable({ providedIn: 'root' })\nexport class SeoService {\n private title = inject(Title);\n private meta = inject(Meta);\n private document = inject(DOCUMENT);\n private config = inject(SEO_CONFIG);\n\n get siteUrl(): string {\n return this.config.siteUrl;\n }\n\n /** Turns a site path or relative asset into an absolute URL. Absolute URLs are returned unchanged. */\n absoluteUrl(pathOrUrl: string): string {\n if (/^https?:\\/\\//.test(pathOrUrl)) return pathOrUrl;\n return this.config.siteUrl + (pathOrUrl.startsWith('/') ? pathOrUrl : '/' + pathOrUrl);\n }\n\n update({ title, description, path, image }: SeoData): void {\n const url = this.absoluteUrl(path);\n const imageSrc = image ?? this.config.defaultImage;\n\n this.title.setTitle(title);\n this.meta.updateTag({ name: 'description', content: description });\n\n this.meta.updateTag({ property: 'og:title', content: title });\n this.meta.updateTag({ property: 'og:description', content: description });\n this.meta.updateTag({ property: 'og:url', content: url });\n\n this.meta.updateTag({ name: 'twitter:title', content: title });\n this.meta.updateTag({ name: 'twitter:description', content: description });\n\n if (imageSrc) {\n const imageUrl = this.absoluteUrl(imageSrc);\n this.meta.updateTag({ property: 'og:image', content: imageUrl });\n this.meta.updateTag({ name: 'twitter:image', content: imageUrl });\n }\n\n this.setCanonical(url);\n }\n\n /** Adds or replaces a `<script type=\"application/ld+json\">` with the given id. */\n setJsonLd(id: string, data: object): void {\n let script = this.document.getElementById(id);\n if (!script) {\n script = this.document.createElement('script');\n script.id = id;\n script.setAttribute('type', 'application/ld+json');\n this.document.head.appendChild(script);\n }\n script.textContent = JSON.stringify(data);\n }\n\n removeJsonLd(id: string): void {\n this.document.getElementById(id)?.remove();\n }\n\n private setCanonical(url: string): void {\n let link = this.document.head.querySelector<HTMLLinkElement>('link[rel=\"canonical\"]');\n if (!link) {\n link = this.document.createElement('link');\n link.setAttribute('rel', 'canonical');\n this.document.head.appendChild(link);\n }\n link.setAttribute('href', url);\n }\n}\n","import { ChangeDetectionStrategy, Component, input } from '@angular/core';\n\n/**\n * Floating WhatsApp button, fixed to a corner of the screen.\n *\n * ```html\n * <cc-whatsapp-button [href]=\"whatsappLink\" />\n * <cc-whatsapp-button [href]=\"whatsappLink\" iconSrc=\"assets/icons/whatsapp.png\" position=\"left\" />\n * ```\n */\n@Component({\n selector: 'cc-whatsapp-button',\n changeDetection: ChangeDetectionStrategy.OnPush,\n templateUrl: './whatsapp-button.component.html',\n styleUrl: './whatsapp-button.component.css',\n})\nexport class WhatsappButtonComponent {\n /** WhatsApp link. Build it with `whatsappUrl(phone, message)`. */\n readonly href = input.required<string>();\n /** Custom icon. Without it, the WhatsApp logo is drawn as SVG. */\n readonly iconSrc = input<string>('');\n readonly label = input<string>('Escríbenos por WhatsApp');\n readonly position = input<'right' | 'left'>('right');\n}\n","<a\n class=\"cc-wa\"\n [class.cc-wa--left]=\"position() === 'left'\"\n [href]=\"href()\"\n target=\"_blank\"\n rel=\"noopener\"\n [attr.aria-label]=\"label()\"\n>\n @if (iconSrc()) {\n <img [src]=\"iconSrc()\" alt=\"\" class=\"cc-wa__img\" />\n } @else {\n <svg class=\"cc-wa__svg\" viewBox=\"0 0 32 32\" aria-hidden=\"true\">\n <circle cx=\"16\" cy=\"16\" r=\"16\" fill=\"#25D366\" />\n <path\n fill=\"#fff\"\n d=\"M23.3 8.7A10.3 10.3 0 0 0 7 21.1L5.6 26.4l5.4-1.4a10.3 10.3 0 0 0 4.9 1.3 10.3 10.3 0 0 0 7.4-17.6Zm-7.3 15.8a8.5 8.5 0 0 1-4.3-1.2l-.3-.2-3.2.8.9-3.1-.2-.3a8.5 8.5 0 1 1 7.1 4Zm4.7-6.4c-.3-.1-1.5-.7-1.8-.8-.2-.1-.4-.1-.6.1l-.8 1c-.2.2-.3.2-.6.1a7 7 0 0 1-3.5-3c-.3-.5.3-.4.7-1.4.1-.2 0-.3 0-.4l-.8-2c-.2-.5-.4-.4-.6-.4h-.5a1 1 0 0 0-.7.3 3 3 0 0 0-.9 2.2 5.2 5.2 0 0 0 1.1 2.8 11.9 11.9 0 0 0 4.6 4c1.7.7 2.4.8 3.2.7a2.8 2.8 0 0 0 1.8-1.3 2.3 2.3 0 0 0 .2-1.3c-.1-.1-.3-.2-.6-.3Z\"\n />\n </svg>\n }\n</a>\n","import {\n ChangeDetectionStrategy,\n Component,\n input,\n model,\n output,\n} from '@angular/core';\n\n/**\n * Modal over the page, for example a promotion shown when the site opens.\n * Shows `imageSrc`, or the projected content when there is no image.\n * Closes with the ✕ button, a backdrop click or the Escape key.\n *\n * ```html\n * <cc-promo-modal [(open)]=\"showPromo\" imageSrc=\"assets/images/pop.jpeg\" imageAlt=\"Promoción\" />\n * ```\n */\n@Component({\n selector: 'cc-promo-modal',\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: { '(document:keydown.escape)': 'open() && close()' },\n templateUrl: './promo-modal.component.html',\n styleUrl: './promo-modal.component.css',\n})\nexport class PromoModalComponent {\n /** Whether the modal is visible. Use `[(open)]` to bind both ways. */\n readonly open = model<boolean>(true);\n readonly imageSrc = input<string>('');\n readonly imageAlt = input<string>('');\n /** Makes the image a link, for example to WhatsApp. */\n readonly link = input<string>('');\n readonly closeOnBackdrop = input<boolean>(true);\n readonly closeLabel = input<string>('Cerrar');\n readonly closed = output<void>();\n\n close(): void {\n this.open.set(false);\n this.closed.emit();\n }\n}\n","@if (open()) {\n <div class=\"cc-modal\" (click)=\"closeOnBackdrop() && close()\">\n <div\n class=\"cc-modal__box\"\n role=\"dialog\"\n aria-modal=\"true\"\n [attr.aria-label]=\"imageAlt() || null\"\n (click)=\"$event.stopPropagation()\"\n >\n <button type=\"button\" class=\"cc-modal__close\" [attr.aria-label]=\"closeLabel()\" (click)=\"close()\">\n ✕\n </button>\n @if (imageSrc()) {\n @if (link()) {\n <a [href]=\"link()\" target=\"_blank\" rel=\"noopener\">\n <img [src]=\"imageSrc()\" [alt]=\"imageAlt()\" class=\"cc-modal__img\" />\n </a>\n } @else {\n <img [src]=\"imageSrc()\" [alt]=\"imageAlt()\" class=\"cc-modal__img\" />\n }\n } @else {\n <ng-content />\n }\n </div>\n </div>\n}\n","import { ChangeDetectionStrategy, Component, input } from '@angular/core';\nimport { RouterLink } from '@angular/router';\nimport { LinkTarget } from '../../models/ui.models';\n\n/**\n * Title strip at the top of a page, with an optional back link and icon.\n * Renders the page's `<h1>`.\n *\n * ```html\n * <cc-page-banner title=\"Reserva tu plan - Pareja\" />\n * <cc-page-banner [title]=\"plan.name\" backLink=\"/planes\" iconSrc=\"assets/icons/hoja.png\" variant=\"plain\" />\n * ```\n */\n@Component({\n selector: 'cc-page-banner',\n imports: [RouterLink],\n changeDetection: ChangeDetectionStrategy.OnPush,\n templateUrl: './page-banner.component.html',\n styleUrl: './page-banner.component.css',\n})\nexport class PageBannerComponent {\n readonly title = input.required<string>();\n /** `band` uses the surface color; `plain` uses the page background. */\n readonly variant = input<'band' | 'plain'>('band');\n readonly iconSrc = input<string>('');\n /** Shows a back arrow that links here. */\n readonly backLink = input<LinkTarget | null>(null);\n readonly backIconSrc = input<string>('');\n readonly backLabel = input<string>('Volver');\n}\n","<div class=\"cc-banner\" [class.cc-banner--plain]=\"variant() === 'plain'\" [class.cc-banner--split]=\"!!backLink()\">\n @if (backLink()) {\n <a class=\"cc-banner__back\" [routerLink]=\"backLink()\" [attr.aria-label]=\"backLabel()\">\n @if (backIconSrc()) {\n <img [src]=\"backIconSrc()\" alt=\"\" />\n } @else {\n <svg viewBox=\"0 0 24 24\" aria-hidden=\"true\">\n <path d=\"M15 18l-6-6 6-6\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n }\n </a>\n }\n <div class=\"cc-banner__title\">\n <h1>{{ title() }}</h1>\n @if (iconSrc()) {\n <img [src]=\"iconSrc()\" alt=\"\" class=\"cc-banner__icon\" />\n }\n </div>\n @if (backLink()) {\n <span class=\"cc-banner__spacer\"></span>\n }\n</div>\n","import { ChangeDetectionStrategy, Component, input } from '@angular/core';\n\n/**\n * Title with a paragraph, used for policy sections.\n * Extra content (lists, notes) can be projected under the text.\n *\n * ```html\n * <cc-info-item title=\"Pagos\" text=\"Aceptamos Nequi, Daviplata y efectivo.\" />\n * <cc-info-item title=\"Reservaciones\" [text]=\"texto\">\n * <ul><li>…</li></ul>\n * </cc-info-item>\n * ```\n */\n@Component({\n selector: 'cc-info-item',\n changeDetection: ChangeDetectionStrategy.OnPush,\n templateUrl: './info-item.component.html',\n styleUrl: './info-item.component.css',\n})\nexport class InfoItemComponent {\n readonly title = input.required<string>();\n readonly text = input<string>('');\n}\n","<h2 class=\"cc-info__title\">{{ title() }}</h2>\n@if (text()) {\n <p class=\"cc-info__text\">{{ text() }}</p>\n}\n<ng-content />\n","import { ChangeDetectionStrategy, Component, input } from '@angular/core';\nimport { FaqItem } from '../../models/ui.models';\n\n/**\n * Frequently asked questions as native `<details>` elements, so the answers\n * stay in the prerendered HTML for search engines.\n *\n * ```html\n * <cc-faq title=\"PREGUNTAS FRECUENTES\" [items]=\"faq\" />\n * ```\n */\n@Component({\n selector: 'cc-faq',\n changeDetection: ChangeDetectionStrategy.OnPush,\n templateUrl: './faq.component.html',\n styleUrl: './faq.component.css',\n})\nexport class FaqComponent {\n readonly items = input.required<FaqItem[]>();\n readonly title = input<string>('');\n}\n","@if (title()) {\n <h2 class=\"cc-faq__title\">{{ title() }}</h2>\n}\n@for (item of items(); track item.question) {\n <details class=\"cc-faq__item\">\n <summary>{{ item.question }}</summary>\n <p>{{ item.answer }}</p>\n </details>\n}\n","import { ChangeDetectionStrategy, Component, input } from '@angular/core';\nimport { SocialLink } from '../../models/ui.models';\n\n/**\n * Row of social network icons that open in a new tab.\n *\n * ```html\n * <cc-social-links [links]=\"socials\" size=\"1.25rem\" />\n * ```\n */\n@Component({\n selector: 'cc-social-links',\n changeDetection: ChangeDetectionStrategy.OnPush,\n templateUrl: './social-links.component.html',\n styleUrl: './social-links.component.css',\n})\nexport class SocialLinksComponent {\n readonly links = input.required<SocialLink[]>();\n /** Icon width, any CSS length. */\n readonly size = input<string>('1rem');\n readonly gap = input<string>('1.25rem');\n}\n","<ul class=\"cc-social\" [style.gap]=\"gap()\">\n @for (link of links(); track link.href) {\n <li>\n <a [href]=\"link.href\" target=\"_blank\" rel=\"noopener\" [attr.aria-label]=\"link.label\">\n <img [src]=\"link.iconSrc\" alt=\"\" [style.width]=\"size()\" />\n </a>\n </li>\n }\n</ul>\n","import { ChangeDetectionStrategy, Component, input, output } from '@angular/core';\nimport { RouterLink } from '@angular/router';\nimport { LinkTarget } from '../../models/ui.models';\n\n/**\n * Plan card: image, name and a button.\n * With `link` the button navigates with the router; without it, it emits `ctaClick`.\n *\n * ```html\n * <cc-plan-card [name]=\"plan.name\" [imageSrc]=\"plan.imgPath\" [link]=\"['/planes', slug]\" />\n * ```\n */\n@Component({\n selector: 'cc-plan-card',\n imports: [RouterLink],\n changeDetection: ChangeDetectionStrategy.OnPush,\n templateUrl: './plan-card.component.html',\n styleUrl: './plan-card.component.css',\n})\nexport class PlanCardComponent {\n readonly name = input.required<string>();\n readonly imageSrc = input.required<string>();\n /** Defaults to `name`. */\n readonly imageAlt = input<string>('');\n /** Optional line under the name, for example the formatted price. */\n readonly subtitle = input<string>('');\n readonly link = input<LinkTarget | null>(null);\n readonly ctaLabel = input<string>('Saber más');\n readonly ctaClick = output<void>();\n}\n","<article class=\"cc-card\">\n <img\n class=\"cc-card__img\"\n [src]=\"imageSrc()\"\n [alt]=\"imageAlt() || name()\"\n loading=\"lazy\"\n decoding=\"async\"\n />\n <h2 class=\"cc-card__name\">{{ name() }}</h2>\n @if (subtitle()) {\n <p class=\"cc-card__subtitle\">{{ subtitle() }}</p>\n }\n @if (link()) {\n <a class=\"cc-card__cta\" [routerLink]=\"link()\" (click)=\"ctaClick.emit()\">{{ ctaLabel() }}</a>\n } @else {\n <button type=\"button\" class=\"cc-card__cta\" (click)=\"ctaClick.emit()\">{{ ctaLabel() }}</button>\n }\n</article>\n","import { ChangeDetectionStrategy, Component, input, model } from '@angular/core';\nimport { CategoryOption } from '../../models/plan.models';\n\n/**\n * Vertical category list with a single selected option.\n * Replaces the `appElementActive` markup the sites used for plan categories.\n *\n * ```html\n * <cc-category-menu [options]=\"categories\" [(selected)]=\"category\" />\n * ```\n */\n@Component({\n selector: 'cc-category-menu',\n changeDetection: ChangeDetectionStrategy.OnPush,\n templateUrl: './category-menu.component.html',\n styleUrl: './category-menu.component.css',\n})\nexport class CategoryMenuComponent<T = unknown> {\n readonly options = input.required<CategoryOption<T>[]>();\n /** Selected value. Use `[(selected)]` to bind both ways. */\n readonly selected = model<T | null>(null);\n readonly title = input<string>('CATEGORÍA DE PLANES');\n\n select(value: T): void {\n this.selected.set(value);\n }\n}\n","<ul class=\"cc-cat\" role=\"listbox\" [attr.aria-label]=\"title() || null\">\n @if (title()) {\n <li class=\"cc-cat__title\" role=\"presentation\">{{ title() }}</li>\n }\n @for (option of options(); track option.value) {\n <li\n class=\"cc-cat__item\"\n role=\"option\"\n tabindex=\"0\"\n [class.cc-cat__item--active]=\"option.value === selected()\"\n [attr.aria-selected]=\"option.value === selected()\"\n (click)=\"select(option.value)\"\n (keydown.enter)=\"select(option.value)\"\n (keydown.space)=\"$event.preventDefault(); select(option.value)\"\n >\n <span>{{ option.label }}</span>\n @if (option.count !== undefined && option.count !== null) {\n <small>{{ option.count }}</small>\n }\n </li>\n }\n</ul>\n","import { ChangeDetectionStrategy, Component, input, model, output } from '@angular/core';\n\n/**\n * Text field with a search button. Emits `search` on Enter or on the button.\n *\n * ```html\n * <cc-search-box placeholder=\"Buscar plan\" [(value)]=\"query\" (search)=\"onSearch($event)\" />\n * ```\n */\n@Component({\n selector: 'cc-search-box',\n changeDetection: ChangeDetectionStrategy.OnPush,\n templateUrl: './search-box.component.html',\n styleUrl: './search-box.component.css',\n})\nexport class SearchBoxComponent {\n readonly value = model<string>('');\n readonly placeholder = input<string>('Buscar plan');\n readonly buttonLabel = input<string>('Buscar');\n readonly iconSrc = input<string>('');\n readonly search = output<string>();\n\n onInput(event: Event): void {\n this.value.set((event.target as HTMLInputElement).value);\n }\n}\n","<form class=\"cc-search\" role=\"search\" (submit)=\"$event.preventDefault(); search.emit(value())\">\n <input\n type=\"search\"\n class=\"cc-search__input\"\n [placeholder]=\"placeholder()\"\n [attr.aria-label]=\"placeholder()\"\n [value]=\"value()\"\n (input)=\"onInput($event)\"\n />\n <button type=\"submit\" class=\"cc-search__btn\" [attr.aria-label]=\"buttonLabel()\">\n @if (iconSrc()) {\n <img [src]=\"iconSrc()\" alt=\"\" />\n } @else {\n <svg viewBox=\"0 0 24 24\" aria-hidden=\"true\">\n <circle cx=\"11\" cy=\"11\" r=\"7\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" />\n <path d=\"m20 20-3.5-3.5\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" />\n </svg>\n }\n </button>\n</form>\n","import { ChangeDetectionStrategy, Component, input, output, signal } from '@angular/core';\nimport { AdditionalService, PlanFilter, PriceRange } from '../../models/plan.models';\n\n/**\n * Filter by included service and price range. The options come in as inputs,\n * so the form does not load data by itself.\n *\n * ```html\n * <cc-plan-filter-form [services]=\"services\" [priceRanges]=\"ranges\" (filterChange)=\"apply($event)\" />\n * ```\n */\n@Component({\n selector: 'cc-plan-filter-form',\n changeDetection: ChangeDetectionStrategy.OnPush,\n templateUrl: './plan-filter-form.component.html',\n styleUrl: './plan-filter-form.component.css',\n})\nexport class PlanFilterFormComponent {\n readonly services = input<AdditionalService[]>([]);\n readonly priceRanges = input<PriceRange[]>([]);\n readonly serviceLabel = input<string>('Servicio incluido');\n readonly priceLabel = input<string>('Rango de precio');\n readonly anyLabel = input<string>('Todos');\n readonly submitLabel = input<string>('Filtrar');\n readonly resetLabel = input<string>('Limpiar');\n /** Emits on submit, and with an empty filter on reset. */\n readonly filterChange = output<PlanFilter>();\n\n protected serviceIndex = signal(-1);\n protected rangeIndex = signal(-1);\n\n protected toIndex(event: Event): number {\n return Number((event.target as HTMLSelectElement).value);\n }\n\n submit(): void {\n this.filterChange.emit({\n service: this.services()[this.serviceIndex()] ?? null,\n priceRange: this.priceRanges()[this.rangeIndex()] ?? null,\n });\n }\n\n reset(): void {\n this.serviceIndex.set(-1);\n this.rangeIndex.set(-1);\n this.filterChange.emit({ service: null, priceRange: null });\n }\n}\n","<form class=\"cc-filter\" (submit)=\"$event.preventDefault(); submit()\">\n @if (services().length) {\n <label class=\"cc-filter__field\">\n <span>{{ serviceLabel() }}</span>\n <select (change)=\"serviceIndex.set(toIndex($event))\">\n <option value=\"-1\" [selected]=\"serviceIndex() === -1\">{{ anyLabel() }}</option>\n @for (service of services(); track $index) {\n <option [value]=\"$index\" [selected]=\"serviceIndex() === $index\">{{ service.name }}</option>\n }\n </select>\n </label>\n }\n @if (priceRanges().length) {\n <label class=\"cc-filter__field\">\n <span>{{ priceLabel() }}</span>\n <select (change)=\"rangeIndex.set(toIndex($event))\">\n <option value=\"-1\" [selected]=\"rangeIndex() === -1\">{{ anyLabel() }}</option>\n @for (range of priceRanges(); track $index) {\n <option [value]=\"$index\" [selected]=\"rangeIndex() === $index\">{{ range.description }}</option>\n }\n </select>\n </label>\n }\n <div class=\"cc-filter__actions\">\n <button type=\"submit\" class=\"cc-filter__submit\">{{ submitLabel() }}</button>\n <button type=\"button\" class=\"cc-filter__reset\" (click)=\"reset()\">{{ resetLabel() }}</button>\n </div>\n</form>\n","import { NgTemplateOutlet } from '@angular/common';\nimport {\n ChangeDetectionStrategy,\n Component,\n computed,\n contentChild,\n Directive,\n effect,\n input,\n output,\n signal,\n TemplateRef,\n untracked,\n} from '@angular/core';\nimport {\n AdditionalService,\n CategoryOption,\n DEFAULT_PLAN_CATEGORIES,\n Plan,\n PlanCategory,\n PlanFilter,\n PriceRange,\n} from '../../models/plan.models';\nimport { LinkTarget } from '../../models/ui.models';\nimport {\n filterPlans,\n filterPlansByCategory,\n planSlug,\n searchPlansByName,\n withCategoryCounts,\n} from '../../utils/plan.utils';\nimport { CategoryMenuComponent } from '../category-menu/category-menu.component';\nimport { PageBannerComponent } from '../page-banner/page-banner.component';\nimport { PlanCardComponent } from '../plan-card/plan-card.component';\nimport { PlanFilterFormComponent } from '../plan-filter-form/plan-filter-form.component';\nimport { SearchBoxComponent } from '../search-box/search-box.component';\n\n/** Context of a custom card template: `<ng-template ccPlanCard let-plan let-link=\"link\">`. */\nexport interface PlanCardContext {\n $implicit: Plan;\n link: LinkTarget;\n}\n\n/** Marks an `<ng-template>` inside `cc-plan-catalog` as the card to render for each plan. */\n@Directive({ selector: 'ng-template[ccPlanCard]' })\nexport class PlanCardTemplateDirective {\n static ngTemplateContextGuard(_dir: PlanCardTemplateDirective, ctx: unknown): ctx is PlanCardContext {\n return true;\n }\n}\n\n/**\n * Full plan list page: title, name search, category menu, filter and card grid.\n * It only needs the plans; the rest has Spanish defaults you can override.\n *\n * Selecting a category shows its plans. Searching by name or applying the filter\n * looks across every category, as the sites already did.\n *\n * ```html\n * <cc-plan-catalog\n * [plans]=\"plans()\"\n * [services]=\"services()\"\n * [priceRanges]=\"ranges()\"\n * imageAltSuffix=\" - Laurel Spa Medellín\"\n * />\n * ```\n */\n@Component({\n selector: 'cc-plan-catalog',\n imports: [\n NgTemplateOutlet,\n PageBannerComponent,\n SearchBoxComponent,\n CategoryMenuComponent,\n PlanFilterFormComponent,\n PlanCardComponent,\n ],\n changeDetection: ChangeDetectionStrategy.OnPush,\n templateUrl: './plan-catalog.component.html',\n styleUrl: './plan-catalog.component.css',\n})\nexport class PlanCatalogComponent {\n readonly plans = input.required<Plan[]>();\n readonly categories = input<CategoryOption[]>(DEFAULT_PLAN_CATEGORIES);\n readonly initialCategory = input<PlanCategory | number>(PlanCategory.Individual);\n /** Shows how many plans each category has, counted from `plans`. */\n readonly showCounts = input<boolean>(true);\n /** Options for the filter form. The filter is hidden when both are empty. */\n readonly services = input<AdditionalService[]>([]);\n readonly priceRanges = input<PriceRange[]>([]);\n /** Where each card links to. Defaults to `/planes/<slug>`. */\n readonly detailsLink = input<(plan: Plan) => LinkTarget>((plan) => ['/planes', planSlug(plan)]);\n\n readonly showBanner = input<boolean>(true);\n readonly showSearch = input<boolean>(true);\n readonly titlePrefix = input<string>('Reserva tu plan');\n readonly resultsTitle = input<string>('Resultados');\n readonly categoriesTitle = input<string>('CATEGORÍA DE PLANES');\n readonly searchPlaceholder = input<string>('Buscar plan');\n readonly searchIconSrc = input<string>('');\n readonly filterTitle = input<string>('Filtrar');\n readonly filterIconSrc = input<string>('');\n readonly ctaLabel = input<string>('Saber más');\n /** Added after the plan name in each image's alt text. */\n readonly imageAltSuffix = input<string>('');\n readonly emptyMessage = input<string>('No encontramos planes con esos criterios.');\n\n readonly categoryChange = output<PlanCategory | number>();\n\n protected readonly cardTemplate = contentChild(PlanCardTemplateDirective, { read: TemplateRef });\n\n protected readonly category = signal<PlanCategory | number | null>(null);\n protected readonly query = signal('');\n protected readonly filter = signal<PlanFilter | null>(null);\n protected readonly filterOpen = signal(false);\n /** Set when the user searched or filtered; results then cover every category. */\n protected readonly searching = signal(false);\n /** Category that was open before searching, to return to it when the search is cleared. */\n private lastCategory: PlanCategory | number | null = null;\n\n constructor() {\n // Apply `initialCategory` until the user picks one.\n effect(() => {\n const initial = this.initialCategory();\n untracked(() => {\n if (!this.searching()) this.category.set(initial);\n });\n });\n }\n\n protected readonly categoryOptions = computed(() =>\n this.showCounts() ? withCategoryCounts(this.categories(), this.plans()) : this.categories()\n );\n\n protected readonly hasFilter = computed(\n () => this.services().length > 0 || this.priceRanges().length > 0\n );\n\n protected readonly visiblePlans = computed(() => {\n const plans = this.plans();\n if (!this.searching()) {\n const category = this.category();\n return category === null ? plans : filterPlansByCategory(plans, category);\n }\n const byName = searchPlansByName(plans, this.query());\n const filter = this.filter();\n return filter ? filterPlans(byName, filter) : byName;\n });\n\n protected readonly title = computed(() => {\n if (this.searching()) return `${this.titlePrefix()} - ${this.resultsTitle()}`;\n const option = this.categories().find((c) => c.value === this.category());\n return option ? `${this.titlePrefix()} - ${option.label}` : this.titlePrefix();\n });\n\n protected selectCategory(value: PlanCategory | number | null): void {\n if (value === null) return;\n this.searching.set(false);\n this.query.set('');\n this.filter.set(null);\n this.category.set(value);\n this.categoryChange.emit(value);\n }\n\n protected onSearch(query: string): void {\n this.query.set(query);\n if (!query.trim() && !this.filter()) {\n this.selectCategory(this.lastCategory ?? this.initialCategory());\n return;\n }\n this.startSearch();\n }\n\n protected onFilter(filter: PlanFilter): void {\n const empty = !filter.service && !filter.priceRange;\n this.filter.set(empty ? null : filter);\n if (empty && !this.query().trim()) {\n this.selectCategory(this.lastCategory ?? this.initialCategory());\n return;\n }\n this.startSearch();\n }\n\n protected linkFor(plan: Plan): LinkTarget {\n return this.detailsLink()(plan);\n }\n\n private startSearch(): void {\n if (!this.searching()) this.lastCategory = this.category();\n this.searching.set(true);\n this.category.set(null);\n }\n}\n","@if (showBanner()) {\n <cc-page-banner [title]=\"title()\" />\n}\n\n<div class=\"cc-catalog\">\n <aside class=\"cc-catalog__side\">\n @if (showSearch()) {\n <cc-search-box\n [placeholder]=\"searchPlaceholder()\"\n [iconSrc]=\"searchIconSrc()\"\n [(value)]=\"query\"\n (search)=\"onSearch($event)\"\n />\n }\n\n <div class=\"cc-catalog__panel\">\n <cc-category-menu\n [title]=\"categoriesTitle()\"\n [options]=\"categoryOptions()\"\n [selected]=\"category()\"\n (selectedChange)=\"selectCategory($event)\"\n />\n\n @if (hasFilter()) {\n <hr class=\"cc-catalog__rule\" />\n <button\n type=\"button\"\n class=\"cc-catalog__filter-toggle\"\n [attr.aria-expanded]=\"filterOpen()\"\n (click)=\"filterOpen.set(!filterOpen())\"\n >\n <span>{{ filterTitle() }}</span>\n @if (filterIconSrc()) {\n <img [src]=\"filterIconSrc()\" alt=\"\" />\n } @else {\n <svg viewBox=\"0 0 24 24\" aria-hidden=\"true\">\n <path d=\"M3 5h18l-7 8v6l-4-2v-4L3 5Z\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linejoin=\"round\" />\n </svg>\n }\n </button>\n @if (filterOpen()) {\n <cc-plan-filter-form\n [services]=\"services()\"\n [priceRanges]=\"priceRanges()\"\n (filterChange)=\"onFilter($event)\"\n />\n }\n }\n </div>\n </aside>\n\n @if (visiblePlans().length) {\n <div class=\"cc-catalog__grid\">\n @for (plan of visiblePlans(); track plan.id) {\n @if (cardTemplate(); as tpl) {\n <ng-container *ngTemplateOutlet=\"tpl; context: { $implicit: plan, link: linkFor(plan) }\" />\n } @else {\n <cc-plan-card\n [name]=\"plan.name\"\n [imageSrc]=\"plan.imgPath\"\n [imageAlt]=\"plan.name + imageAltSuffix()\"\n [link]=\"linkFor(plan)\"\n [ctaLabel]=\"ctaLabel()\"\n />\n }\n }\n </div>\n } @else {\n <p class=\"cc-catalog__empty\">{{ emptyMessage() }}</p>\n }\n</div>\n","import { CurrencyPipe } from '@angular/common';\nimport { ChangeDetectionStrategy, Component, computed, input } from '@angular/core';\nimport { Plan } from '../../models/plan.models';\nimport { LinkTarget } from '../../models/ui.models';\nimport { PageBannerComponent } from '../page-banner/page-banner.component';\n\n/**\n * Plan detail view: title with a back link, photo, price, description, duration,\n * number of people, included services, and a gift box with the booking button.\n * It only renders; the page loads the plan and handles SEO.\n *\n * ```html\n * <cc-plan-details [plan]=\"plan\" [bookingUrl]=\"whatsappLink\" imageAltSuffix=\" en Laurel Spa Medellín\" />\n * ```\n */\n@Component({\n selector: 'cc-plan-details',\n imports: [CurrencyPipe, PageBannerComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n templateUrl: './plan-details.component.html',\n styleUrl: './plan-details.component.css',\n})\nexport class PlanDetailsComponent {\n readonly plan = input.required<Plan>();\n /** Link of the booking button, usually WhatsApp. */\n readonly bookingUrl = input.required<string>();\n readonly bookingLabel = input<string>('¡RESERVAR AHORA!');\n\n readonly showBanner = input<boolean>(true);\n readonly backLink = input<LinkTarget | null>('/planes');\n readonly backLabel = input<string>('Volver a los planes');\n readonly backIconSrc = input<string>('');\n readonly titleIconSrc = input<string>('');\n /** Added after the plan name in the photo's alt text. */\n readonly imageAltSuffix = input<string>('');\n\n /** Arguments of Angular's `currency` pipe. */\n readonly currencyCode = input<string>('COP');\n readonly currencyDisplay = input<string>('COP$ ');\n readonly currencyDigits = input<string>('1.0-0');\n\n readonly durationIconSrc = input<string>('');\n readonly personIconSrc = input<string>('');\n readonly peopleIconSrc = input<string>('');\n readonly personLabel = input<string>('persona');\n readonly peopleLabel = input<string>('Personas');\n readonly includesLabel = input<string>('Incluye:');\n\n /** Gift box. It is hidden when `perks` is empty. */\n readonly perksTitle = input<string>('Recibe con nuestro plan');\n readonly perks = input<string[]>([\n 'Gift Card de invitación en PDF para regalo.',\n 'Decoración según la ocasión que celebres.',\n ]);\n readonly perksImageSrc = input<string>('');\n readonly perksImageAlt = input<string>('Gift card de regalo');\n\n protected readonly people = computed(() => Math.max(this.plan().cuantity || 1, 1));\n protected readonly services = computed(() => this.plan().additionalServices ?? []);\n}\n","@if (showBanner()) {\n <cc-page-banner\n variant=\"plain\"\n [title]=\"plan().name\"\n [iconSrc]=\"titleIconSrc()\"\n [backLink]=\"backLink()\"\n [backLabel]=\"backLabel()\"\n [backIconSrc]=\"backIconSrc()\"\n />\n}\n\n<div class=\"cc-details\">\n <div class=\"cc-details__media\">\n <img class=\"cc-details__photo\" [src]=\"plan().imgPath\" [alt]=\"plan().name + imageAltSuffix()\" />\n <ng-content select=\"[ccDetailsMedia]\" />\n </div>\n\n <div class=\"cc-details__panel\">\n <div class=\"cc-details__info\">\n <div class=\"cc-details__price\">\n <p>{{ plan().price | currency: currencyCode() : currencyDisplay() : currencyDigits() }}</p>\n </div>\n\n <p class=\"cc-details__description\">{{ plan().description }}</p>\n\n <div class=\"cc-details__facts\">\n <div class=\"cc-details__fact\">\n @if (durationIconSrc()) {\n <img [src]=\"durationIconSrc()\" alt=\"Duración\" />\n } @else {\n <svg viewBox=\"0 0 24 24\" role=\"img\" aria-label=\"Duración\">\n <circle cx=\"12\" cy=\"12\" r=\"9\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" />\n <path d=\"M12 7v5l3 2\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" />\n </svg>\n }\n <small>{{ plan().duration }}</small>\n </div>\n\n <div class=\"cc-details__fact\">\n @if (people() > 1) {\n @if (peopleIconSrc()) {\n <img [src]=\"peopleIconSrc()\" alt=\"\" />\n } @else {\n <svg viewBox=\"0 0 24 24\" aria-hidden=\"true\">\n <circle cx=\"9\" cy=\"8\" r=\"3.5\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" />\n <circle cx=\"17\" cy=\"9\" r=\"2.5\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" />\n <path d=\"M2.5 20a6.5 6.5 0 0 1 13 0M15 14.5a5 5 0 0 1 6.5 4.5\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" />\n </svg>\n }\n <small>{{ people() }} {{ peopleLabel() }}</small>\n } @else {\n @if (personIconSrc()) {\n <img [src]=\"personIconSrc()\" alt=\"\" />\n } @else {\n <svg viewBox=\"0 0 24 24\" aria-hidden=\"true\">\n <circle cx=\"12\" cy=\"8\" r=\"4\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" />\n <path d=\"M4.5 20a7.5 7.5 0 0 1 15 0\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" />\n </svg>\n }\n <small>1 {{ personLabel() }}</small>\n }\n </div>\n </div>\n\n @if (services().length) {\n <h2 class=\"cc-details__includes\">{{ includesLabel() }}</h2>\n <ul class=\"cc-details__services\">\n @for (service of services(); track $index) {\n <li>\n <img [src]=\"service.iconPath\" alt=\"\" />\n <small>{{ service.name }}</small>\n </li>\n }\n </ul>\n }\n\n <ng-content />\n\n <div class=\"cc-details__gift\" [class.cc-details__gift--solo]=\"!perks().length\">\n @if (perks().length) {\n @if (perksImageSrc()) {\n <img class=\"cc-details__gift-img\" [src]=\"perksImageSrc()\" [alt]=\"perksImageAlt()\" loading=\"lazy\" />\n }\n <div class=\"cc-details__perks\">\n <h2>{{ perksTitle() }}</h2>\n <ul>\n @for (perk of perks(); track $index) {\n <li>{{ perk }}</li>\n }\n </ul>\n </div>\n }\n <div class=\"cc-details__cta-wrap\">\n <a class=\"cc-details__cta\" [href]=\"bookingUrl()\" target=\"_blank\" rel=\"noopener\">{{ bookingLabel() }}</a>\n </div>\n </div>\n </div>\n </div>\n</div>\n","import { DOCUMENT } from '@angular/common';\nimport {\n ChangeDetectionStrategy,\n Component,\n computed,\n effect,\n inject,\n input,\n model,\n} from '@angular/core';\nimport { GalleryImage } from '../../models/ui.models';\n\n/**\n * Full-screen image viewer. It is open while `index` is not null.\n * Arrow keys move between images and Escape closes it.\n *\n * ```html\n * <cc-lightbox [images]=\"images\" [(index)]=\"openIndex\" />\n * ```\n */\n@Component({\n selector: 'cc-lightbox',\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n '(document:keydown.escape)': 'close()',\n '(document:keydown.arrowright)': 'next()',\n '(document:keydown.arrowleft)': 'prev()',\n },\n templateUrl: './lightbox.component.html',\n styleUrl: './lightbox.component.css',\n})\nexport class LightboxComponent {\n readonly images = input.required<GalleryImage[]>();\n /** Index of the open image, or null when closed. Use `[(index)]`. */\n readonly index = model<number | null>(null);\n readonly closeLabel = input<string>('Cerrar');\n readonly prevLabel = input<string>('Imagen anterior');\n readonly nextLabel = input<string>('Imagen siguiente');\n\n protected readonly current = computed(() => {\n const i = this.index();\n return i === null ? null : (this.images()[i] ?? null);\n });\n\n private document = inject(DOCUMENT);\n\n constructor() {\n // Stop the page behind from scrolling while the viewer is open.\n effect((onCleanup) => {\n if (this.current() === null) return;\n const body = this.document.body;\n const previous = body.style.overflow;\n body.style.overflow = 'hidden';\n onCleanup(() => (body.style.overflow = previous));\n });\n }\n\n close(): void {\n if (this.index() !== null) this.index.set(null);\n }\n\n next(): void {\n const i = this.index();\n const total = this.images().length;\n if (i !== null && total) this.index.set((i + 1) % total);\n }\n\n prev(): void {\n const i = this.index();\n const total = this.images().length;\n if (i !== null && total) this.index.set((i - 1 + total) % total);\n }\n}\n","@if (current(); as image) {\n <div class=\"cc-lb\" role=\"dialog\" aria-modal=\"true\" [attr.aria-label]=\"image.caption || image.alt || null\" (click)=\"close()\">\n <button type=\"button\" class=\"cc-lb__btn cc-lb__close\" [attr.aria-label]=\"closeLabel()\" (click)=\"close()\">✕</button>\n @if (images().length > 1) {\n <button type=\"button\" class=\"cc-lb__btn cc-lb__prev\" [attr.aria-label]=\"prevLabel()\" (click)=\"$event.stopPropagation(); prev()\">‹</button>\n }\n <img class=\"cc-lb__img\" [src]=\"image.src\" [alt]=\"image.alt ?? image.caption ?? ''\" (click)=\"$event.stopPropagation()\" />\n @if (images().length > 1) {\n <button type=\"button\" class=\"cc-lb__btn cc-lb__next\" [attr.aria-label]=\"nextLabel()\" (click)=\"$event.stopPropagation(); next()\">›</button>\n }\n @if (image.caption) {\n <p class=\"cc-lb__caption\">{{ image.caption }}</p>\n }\n </div>\n}\n","import { ChangeDetectionStrategy, Component, input, signal } from '@angular/core';\nimport { GalleryImage } from '../../models/ui.models';\nimport { LightboxComponent } from '../lightbox/lightbox.component';\n\n/**\n * Thumbnail grid that opens a lightbox on click.\n *\n * ```html\n * <cc-gallery [images]=\"images\" />\n * ```\n *\n * `numberedImages()` builds the list for folders named 1.jpeg, 2.jpeg, …\n */\n@Component({\n selector: 'cc-gallery',\n imports: [LightboxComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n templateUrl: './gallery.component.html',\n styleUrl: './gallery.component.css',\n})\nexport class GalleryComponent {\n readonly images = input.required<GalleryImage[]>();\n readonly backgroundImage = input<string>('');\n readonly openLabel = input<string>('Ver imagen');\n\n protected readonly open = signal<number | null>(null);\n}\n\n/**\n * Builds a gallery list for numbered files.\n *\n * ```ts\n * numberedImages(18, (i) => `assets/images/galery/${i}.jpeg`, (i) => `Instalaciones - foto ${i}`)\n * ```\n */\nexport function numberedImages(\n count: number,\n src: (n: number) => string,\n caption?: (n: number) => string\n): GalleryImage[] {\n return Array.from({ length: count }, (_, i) => {\n const n = i + 1;\n return { src: src(n), caption: caption?.(n) };\n });\n}\n","<ul class=\"cc-gallery\" [style.background-image]=\"backgroundImage() ? 'url(' + backgroundImage() + ')' : null\">\n @for (image of images(); track image.src; let i = $index) {\n <li>\n <button type=\"button\" class=\"cc-gallery__item\" [attr.aria-label]=\"openLabel() + ': ' + (image.alt ?? image.caption ?? i + 1)\" (click)=\"open.set(i)\">\n <img [src]=\"image.thumb ?? image.src\" [alt]=\"image.alt ?? image.caption ?? ''\" loading=\"lazy\" decoding=\"async\" />\n </button>\n </li>\n }\n</ul>\n<cc-lightbox [images]=\"images()\" [(index)]=\"open\" />\n","/*\n * Public API Surface of @c-code/c-code-fw/ui\n */\n\n// Models\nexport * from './lib/models/plan.models';\nexport * from './lib/models/ui.models';\n\n// Utilities\nexport * from './lib/utils/text.utils';\nexport * from './lib/utils/plan.utils';\n\n// Services\nexport * from './lib/services/plan-catalog.service';\nexport * from './lib/services/seo.service';\n\n// Components\nexport * from './lib/components/whatsapp-button/whatsapp-button.component';\nexport * from './lib/components/promo-modal/promo-modal.component';\nexport * from './lib/components/page-banner/page-banner.component';\nexport * from './lib/components/info-item/info-item.component';\nexport * from './lib/components/faq/faq.component';\nexport * from './lib/components/social-links/social-links.component';\nexport * from './lib/components/plan-card/plan-card.component';\nexport * from './lib/components/category-menu/category-menu.component';\nexport * from './lib/components/search-box/search-box.component';\nexport * from './lib/components/plan-filter-form/plan-filter-form.component';\nexport * from './lib/components/plan-catalog/plan-catalog.component';\nexport * from './lib/components/plan-details/plan-details.component';\nexport * from './lib/components/lightbox/lightbox.component';\nexport * from './lib/components/gallery/gallery.component';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  import * as i0 from '@angular/core';
2
- import { Injectable, HostListener, Input, Directive, signal, inject, PLATFORM_ID, DestroyRef } from '@angular/core';
2
+ import { Injectable, HostListener, Input, Directive, signal } from '@angular/core';
3
3
  import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
4
4
  import { fromEvent, debounceTime } from 'rxjs';
5
5
  import { isPlatformBrowser } from '@angular/common';
@@ -137,16 +137,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.6", ngImpor
137
137
  type: Injectable
138
138
  }] });
139
139
 
140
- var ScreenWidthType;
141
- (function (ScreenWidthType) {
142
- ScreenWidthType[ScreenWidthType["XS"] = 640] = "XS";
143
- ScreenWidthType[ScreenWidthType["SM"] = 768] = "SM";
144
- ScreenWidthType[ScreenWidthType["MD"] = 1024] = "MD";
145
- ScreenWidthType[ScreenWidthType["LG"] = 1280] = "LG";
146
- ScreenWidthType[ScreenWidthType["XL"] = 1536] = "XL";
147
- ScreenWidthType[ScreenWidthType["XXL"] = 1920] = "XXL";
148
- })(ScreenWidthType || (ScreenWidthType = {}));
149
-
150
140
  /**
151
141
  * Tailwind CSS Breakpoints:
152
142
  * - xs: < 640px (Extra small, below Tailwind's `sm`)
@@ -157,25 +147,29 @@ var ScreenWidthType;
157
147
  * - 2xl: 1536px (2x Extra large screens)
158
148
  */
159
149
  // @Service: ScreenWidthEventService
160
- class ScreenWidthEventService {
150
+ class ScreenWidthEventService2 {
161
151
  // @Property: Stores the current screen width
162
- screenWidth = window.innerWidth;
152
+ screenWidth;
163
153
  // @Property: Stores the current screen height
164
- screenHeight = window.innerHeight;
154
+ screenHeight;
165
155
  // @Property: Platform ID for browser/server detection
166
- platformId = inject(PLATFORM_ID);
156
+ platformId;
167
157
  // @Property: DestroyRef for managing subscriptions
168
- destroyRef = inject(DestroyRef);
169
- /**
170
- * @Constructor
171
- * @Description: Initializes the screen width and height if running in a browser environment
172
- */
173
- constructor() {
158
+ destroyRef;
159
+ currentWindow;
160
+ setWindows(currentWindow) {
174
161
  if (isPlatformBrowser(this.platformId)) {
175
- this.screenWidth = window.innerWidth;
176
- this.screenHeight = window.innerHeight;
162
+ this.currentWindow = currentWindow;
163
+ this.screenWidth = currentWindow.innerWidth;
164
+ this.screenHeight = currentWindow.innerHeight;
177
165
  }
178
166
  }
167
+ setPlatformId(platformId) {
168
+ this.platformId = platformId;
169
+ }
170
+ setDestroyRef(destroyRef) {
171
+ this.destroyRef = destroyRef;
172
+ }
179
173
  /**
180
174
  * @Method: getScreenWidth
181
175
  * @Description: Returns the current screen width
@@ -215,7 +209,10 @@ class ScreenWidthEventService {
215
209
  */
216
210
  onResize(func, debounceTimeValue = 200) {
217
211
  if (isPlatformBrowser(this.platformId)) {
218
- fromEvent(window, 'resize')
212
+ if (this.currentWindow === undefined) {
213
+ throw new Error('The current window is not set. Please call setWindows() first.');
214
+ }
215
+ fromEvent(this.currentWindow, 'resize')
219
216
  .pipe(debounceTime(debounceTimeValue), takeUntilDestroyed(this.destroyRef))
220
217
  .subscribe(() => {
221
218
  this.screenWidth = window.innerWidth;
@@ -227,15 +224,25 @@ class ScreenWidthEventService {
227
224
  throw new Error('onResize can only be called in a browser environment.');
228
225
  }
229
226
  }
230
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.6", ngImport: i0, type: ScreenWidthEventService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
231
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.6", ngImport: i0, type: ScreenWidthEventService, providedIn: 'root' });
227
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.6", ngImport: i0, type: ScreenWidthEventService2, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
228
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.6", ngImport: i0, type: ScreenWidthEventService2, providedIn: 'root' });
232
229
  }
233
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.6", ngImport: i0, type: ScreenWidthEventService, decorators: [{
230
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.6", ngImport: i0, type: ScreenWidthEventService2, decorators: [{
234
231
  type: Injectable,
235
232
  args: [{
236
- providedIn: 'root',
233
+ providedIn: 'root'
237
234
  }]
238
- }], ctorParameters: () => [] });
235
+ }] });
236
+
237
+ var ScreenWidthType;
238
+ (function (ScreenWidthType) {
239
+ ScreenWidthType[ScreenWidthType["XS"] = 640] = "XS";
240
+ ScreenWidthType[ScreenWidthType["SM"] = 768] = "SM";
241
+ ScreenWidthType[ScreenWidthType["MD"] = 1024] = "MD";
242
+ ScreenWidthType[ScreenWidthType["LG"] = 1280] = "LG";
243
+ ScreenWidthType[ScreenWidthType["XL"] = 1536] = "XL";
244
+ ScreenWidthType[ScreenWidthType["XXL"] = 1920] = "XXL";
245
+ })(ScreenWidthType || (ScreenWidthType = {}));
239
246
 
240
247
  /*
241
248
  * Public API Surface of core
@@ -245,5 +252,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.6", ngImpor
245
252
  * Generated bundle index. Do not edit.
246
253
  */
247
254
 
248
- export { ElementActiveDirective, ElementActiveService, ElementStatusType, ElementToggleService, ScreenWidthEventService, ScreenWidthType };
255
+ export { ElementActiveDirective, ElementActiveService, ElementStatusType, ElementToggleService, ScreenWidthEventService2, ScreenWidthType };
249
256
  //# sourceMappingURL=c-code-c-code-fw.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"c-code-c-code-fw.mjs","sources":["../../../projects/core/src/lib/element-active.service.ts","../../../projects/core/src/lib/element-active.directive.ts","../../../projects/core/src/lib/types/element_status-type.ts","../../../projects/core/src/lib/element_toggle.service.ts","../../../projects/core/src/lib/types/screen_width-type.ts","../../../projects/core/src/lib/screen_width-event.service.ts","../../../projects/core/src/public-api.ts","../../../projects/core/src/c-code-c-code-fw.ts"],"sourcesContent":["import { Injectable } from '@angular/core';\r\n\r\n@Injectable(\r\n \r\n)\r\nexport class ElementActiveService {\r\n private currentActiveElement: HTMLElement | null = null;\r\n private elementsClickedRegister: HTMLElement[] = [];\r\n setActiveElement(element: HTMLElement, classActiveName: string) {\r\n this.deactivateElementsOtherThanOneClicked(classActiveName,element);\r\n\r\n this.currentActiveElement = element;\r\n this.currentActiveElement.classList.add(classActiveName);\r\n\r\n if(!this.elementsClickedRegister.includes(element)){\r\n this.elementsClickedRegister.push(element);\r\n }\r\n }\r\n\r\n private deactivateElementsOtherThanOneClicked(classActiveName: string, excludeElement: HTMLElement) {\r\n this.elementsClickedRegister.forEach(element => {\r\n if (element !== excludeElement) {\r\n element.classList.remove(classActiveName);\r\n }\r\n });\r\n}\r\n}\r\n","import {\r\n Directive,\r\n ElementRef,\r\n HostListener,\r\n Input,\r\n Renderer2,\r\n } from '@angular/core';\r\nimport { ElementActiveService } from './element-active.service';\r\n \r\n @Directive({\r\n selector: '[appElementActive]',\r\n standalone: true,\r\n })\r\n export class ElementActiveDirective {\r\n @Input() activeClass:string = \"active\"\r\n constructor(\r\n private el: ElementRef,\r\n private render: Renderer2,\r\n private elementService: ElementActiveService\r\n ) {}\r\n @HostListener('click') onClick() {\r\n this.elementService.setActiveElement(this.el.nativeElement,this.activeClass);\r\n this.render.addClass(this.el.nativeElement, this.activeClass)\r\n }\r\n }\r\n ","export enum ElementStatusType{\r\n SHOW,\r\n HIDDEN,\r\n DEFAULT\r\n}","import {Injectable, signal } from '@angular/core';\r\nimport { ElementStatusType } from './types/element_status-type';\r\n\r\n/**\r\n * Service to manage the state and classes of HTML elements,\r\n * used in menus and buttons to show or hide content.\r\n *\r\n */\r\n@Injectable()\r\nexport class ElementToggleService {\r\n private elementStatus = signal<ElementStatusType>(ElementStatusType.DEFAULT);\r\n private elementsHistory: HTMLElement[] = [];\r\n private currentToggleClass: string = '';\r\n /**\r\n * Gets the current state of the element.\r\n * @returns Signal with the current state.\r\n */\r\n get elementStatusToggle() {\r\n if (this.elementStatus() === ElementStatusType.DEFAULT) {\r\n console.warn(\r\n 'The element state is default. A different value should be set.'\r\n );\r\n }\r\n return this.elementStatus;\r\n }\r\n\r\n /**\r\n * Changes the state of the element to a specific one. If the state is already SHOW, it changes to HIDDEN.\r\n * @param status New state of type ElementStatusType.\r\n * @throws Error if the state is DEFAULT.\r\n */\r\n toggleByElementStatusType(status: ElementStatusType) {\r\n if (status === ElementStatusType.DEFAULT) {\r\n throw Error('The element state cannot be default.');\r\n }\r\n if (\r\n this.elementStatus() === ElementStatusType.SHOW &&\r\n status === ElementStatusType.SHOW\r\n ) {\r\n this.elementStatus.set(ElementStatusType.HIDDEN);\r\n } else {\r\n this.elementStatus.set(status);\r\n }\r\n }\r\n\r\n /**\r\n * Toggles a CSS class on an element and saves it in the history.\r\n * @param element HTML element to toggle the class on.\r\n * @param className Name of the class to toggle.\r\n * @throws Error if the class name is null or empty.\r\n */\r\n toggleByClassName(element: HTMLElement, className: string) {\r\n if (!className.trim()) {\r\n throw Error('The class name cannot be null or empty.');\r\n }\r\n\r\n element.classList.toggle(className);\r\n this.currentToggleClass = className;\r\n if (!this.elementsHistory.includes(element)) {\r\n this.elementsHistory.push(element);\r\n }\r\n }\r\n\r\n /**\r\n * Removes the active class from all elements stored in the history.\r\n * @throws Error if the history is empty.\r\n */\r\n removeActiveClassToAllElements() {\r\n if (this.elementsHistory.length <= 0) {\r\n throw Error('The element history is empty.');\r\n }\r\n\r\n this.elementsHistory.forEach((element) => {\r\n element.classList.remove(this.currentToggleClass);\r\n });\r\n }\r\n}\r\n","export enum ScreenWidthType{\r\n XS = 640,\r\n SM = 768,\r\n MD = 1024, \r\n LG = 1280,\r\n XL = 1536,\r\n XXL = 1920\r\n}","import { DestroyRef, inject, Injectable, PLATFORM_ID } from '@angular/core';\r\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\r\nimport { debounceTime, fromEvent } from 'rxjs';\r\nimport { ScreenWidthType } from './types/screen_width-type';\r\nimport { isPlatformBrowser } from '@angular/common';\r\n\r\n/**\r\n * Tailwind CSS Breakpoints:\r\n * - xs: < 640px (Extra small, below Tailwind's `sm`)\r\n * - sm: 640px (Small screens)\r\n * - md: 768px (Medium screens)\r\n * - lg: 1024px (Large screens)\r\n * - xl: 1280px (Extra large screens)\r\n * - 2xl: 1536px (2x Extra large screens)\r\n */\r\n\r\n// @Service: ScreenWidthEventService\r\n@Injectable({\r\n providedIn: 'root',\r\n})\r\nexport class ScreenWidthEventService {\r\n // @Property: Stores the current screen width\r\n private screenWidth: number = window.innerWidth;\r\n\r\n // @Property: Stores the current screen height\r\n private screenHeight: number = window.innerHeight;\r\n\r\n // @Property: Platform ID for browser/server detection\r\n private platformId = inject(PLATFORM_ID);\r\n\r\n // @Property: DestroyRef for managing subscriptions\r\n private destroyRef = inject(DestroyRef);\r\n\r\n /**\r\n * @Constructor\r\n * @Description: Initializes the screen width and height if running in a browser environment\r\n */\r\n constructor() {\r\n if (isPlatformBrowser(this.platformId)) {\r\n this.screenWidth = window.innerWidth;\r\n this.screenHeight = window.innerHeight;\r\n }\r\n }\r\n\r\n /**\r\n * @Method: getScreenWidth\r\n * @Description: Returns the current screen width\r\n * @Returns: number - The current screen width\r\n * @Throws: Error if called outside of a browser environment\r\n */\r\n public getScreenWidth(): number {\r\n if (isPlatformBrowser(this.platformId)) {\r\n return this.screenWidth;\r\n }\r\n throw new Error(\r\n 'getScreenWidth can only be called in a browser environment.'\r\n );\r\n }\r\n\r\n /**\r\n * @Method: getScreenHeight\r\n * @Description: Returns the current screen height\r\n * @Returns: number - The current screen height\r\n * @Throws: Error if called outside of a browser environment\r\n */\r\n public getScreenHeight(): number {\r\n if (isPlatformBrowser(this.platformId)) {\r\n return this.screenHeight;\r\n }\r\n throw new Error(\r\n 'getScreenHeight can only be called in a browser environment.'\r\n );\r\n }\r\n\r\n /**\r\n * @Method: executeFuncByScreenWidth\r\n * @Description: Executes a function if the screen width is less than or equal to the specified width\r\n * @Param: func - The function to execute\r\n * @Param: width - The maximum screen width to trigger the function (can be a ScreenWidthType or a number)\r\n */\r\n public executeFuncByScreenWidth(\r\n func: () => void,\r\n width: ScreenWidthType\r\n ): void;\r\n\r\n public executeFuncByScreenWidth(func: () => void, width: number): void;\r\n\r\n public executeFuncByScreenWidth(\r\n func: () => void,\r\n width: ScreenWidthType | number\r\n ): void {\r\n if (this.screenWidth <= width) {\r\n // Calls the function immediately only to pass tests, as onResize requires a browser to trigger fromEvent(window, 'resize').\r\n this.onResize(func);\r\n }\r\n }\r\n\r\n /**\r\n * @Method: onResize\r\n * @Description: Subscribes to the window resize event and executes the provided function after a debounce period\r\n * @Param: func - The function to execute on resize\r\n * @Param: debounceTimeValue - The debounce time in milliseconds (default: 200ms)\r\n * @Throws: Error if called outside of a browser environment\r\n */\r\n private onResize(func: () => void, debounceTimeValue: number = 200): void {\r\n if (isPlatformBrowser(this.platformId)) {\r\n fromEvent(window, 'resize')\r\n .pipe(\r\n debounceTime(debounceTimeValue),\r\n takeUntilDestroyed(this.destroyRef)\r\n )\r\n .subscribe(() => {\r\n this.screenWidth = window.innerWidth;\r\n this.screenHeight = window.innerHeight;\r\n func();\r\n });\r\n } else {\r\n throw new Error('onResize can only be called in a browser environment.');\r\n }\r\n }\r\n}\r\n","/*\r\n * Public API Surface of core\r\n */\r\n\r\nexport * from './lib/element-active.directive';\r\nexport * from './lib/element-active.service';\r\nexport * from './lib/element_toggle.service';\r\nexport * from './lib/types/element_status-type'\r\nexport * from './lib/types/screen_width-type';\r\nexport * from './lib/screen_width-event.service';","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["i1.ElementActiveService"],"mappings":"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"}
1
+ {"version":3,"file":"c-code-c-code-fw.mjs","sources":["../../../projects/core/src/lib/element-active.service.ts","../../../projects/core/src/lib/element-active.directive.ts","../../../projects/core/src/lib/types/element_status-type.ts","../../../projects/core/src/lib/element_toggle.service.ts","../../../projects/core/src/lib/screen_width-event.service.ts","../../../projects/core/src/lib/types/screen_width-type.ts","../../../projects/core/src/public-api.ts","../../../projects/core/src/c-code-c-code-fw.ts"],"sourcesContent":["import { Injectable } from '@angular/core';\r\n\r\n@Injectable(\r\n \r\n)\r\nexport class ElementActiveService {\r\n private currentActiveElement: HTMLElement | null = null;\r\n private elementsClickedRegister: HTMLElement[] = [];\r\n setActiveElement(element: HTMLElement, classActiveName: string) {\r\n this.deactivateElementsOtherThanOneClicked(classActiveName,element);\r\n\r\n this.currentActiveElement = element;\r\n this.currentActiveElement.classList.add(classActiveName);\r\n\r\n if(!this.elementsClickedRegister.includes(element)){\r\n this.elementsClickedRegister.push(element);\r\n }\r\n }\r\n\r\n private deactivateElementsOtherThanOneClicked(classActiveName: string, excludeElement: HTMLElement) {\r\n this.elementsClickedRegister.forEach(element => {\r\n if (element !== excludeElement) {\r\n element.classList.remove(classActiveName);\r\n }\r\n });\r\n}\r\n}\r\n","import {\r\n Directive,\r\n ElementRef,\r\n HostListener,\r\n Input,\r\n Renderer2,\r\n } from '@angular/core';\r\nimport { ElementActiveService } from './element-active.service';\r\n \r\n @Directive({\r\n selector: '[appElementActive]',\r\n standalone: true,\r\n })\r\n export class ElementActiveDirective {\r\n @Input() activeClass:string = \"active\"\r\n constructor(\r\n private el: ElementRef,\r\n private render: Renderer2,\r\n private elementService: ElementActiveService\r\n ) {}\r\n @HostListener('click') onClick() {\r\n this.elementService.setActiveElement(this.el.nativeElement,this.activeClass);\r\n this.render.addClass(this.el.nativeElement, this.activeClass)\r\n }\r\n }\r\n ","export enum ElementStatusType{\r\n SHOW,\r\n HIDDEN,\r\n DEFAULT\r\n}","import {Injectable, signal } from '@angular/core';\r\nimport { ElementStatusType } from './types/element_status-type';\r\n\r\n/**\r\n * Service to manage the state and classes of HTML elements,\r\n * used in menus and buttons to show or hide content.\r\n *\r\n */\r\n@Injectable()\r\nexport class ElementToggleService {\r\n private elementStatus = signal<ElementStatusType>(ElementStatusType.DEFAULT);\r\n private elementsHistory: HTMLElement[] = [];\r\n private currentToggleClass: string = '';\r\n /**\r\n * Gets the current state of the element.\r\n * @returns Signal with the current state.\r\n */\r\n get elementStatusToggle() {\r\n if (this.elementStatus() === ElementStatusType.DEFAULT) {\r\n console.warn(\r\n 'The element state is default. A different value should be set.'\r\n );\r\n }\r\n return this.elementStatus;\r\n }\r\n\r\n /**\r\n * Changes the state of the element to a specific one. If the state is already SHOW, it changes to HIDDEN.\r\n * @param status New state of type ElementStatusType.\r\n * @throws Error if the state is DEFAULT.\r\n */\r\n toggleByElementStatusType(status: ElementStatusType) {\r\n if (status === ElementStatusType.DEFAULT) {\r\n throw Error('The element state cannot be default.');\r\n }\r\n if (\r\n this.elementStatus() === ElementStatusType.SHOW &&\r\n status === ElementStatusType.SHOW\r\n ) {\r\n this.elementStatus.set(ElementStatusType.HIDDEN);\r\n } else {\r\n this.elementStatus.set(status);\r\n }\r\n }\r\n\r\n /**\r\n * Toggles a CSS class on an element and saves it in the history.\r\n * @param element HTML element to toggle the class on.\r\n * @param className Name of the class to toggle.\r\n * @throws Error if the class name is null or empty.\r\n */\r\n toggleByClassName(element: HTMLElement, className: string) {\r\n if (!className.trim()) {\r\n throw Error('The class name cannot be null or empty.');\r\n }\r\n\r\n element.classList.toggle(className);\r\n this.currentToggleClass = className;\r\n if (!this.elementsHistory.includes(element)) {\r\n this.elementsHistory.push(element);\r\n }\r\n }\r\n\r\n /**\r\n * Removes the active class from all elements stored in the history.\r\n * @throws Error if the history is empty.\r\n */\r\n removeActiveClassToAllElements() {\r\n if (this.elementsHistory.length <= 0) {\r\n throw Error('The element history is empty.');\r\n }\r\n\r\n this.elementsHistory.forEach((element) => {\r\n element.classList.remove(this.currentToggleClass);\r\n });\r\n }\r\n}\r\n","import { DestroyRef, Injectable } from '@angular/core';\r\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\r\nimport { debounceTime, fromEvent } from 'rxjs';\r\nimport { isPlatformBrowser } from '@angular/common';\r\nimport { ScreenWidthType } from './types/screen_width-type';\r\n\r\n/**\r\n * Tailwind CSS Breakpoints:\r\n * - xs: < 640px (Extra small, below Tailwind's `sm`)\r\n * - sm: 640px (Small screens)\r\n * - md: 768px (Medium screens)\r\n * - lg: 1024px (Large screens)\r\n * - xl: 1280px (Extra large screens)\r\n * - 2xl: 1536px (2x Extra large screens)\r\n */\r\n\r\n// @Service: ScreenWidthEventService\r\n@Injectable({\r\n providedIn:'root'\r\n})\r\nexport class ScreenWidthEventService2 {\r\n // @Property: Stores the current screen width\r\n private screenWidth!: number\r\n\r\n // @Property: Stores the current screen height\r\n private screenHeight!: number\r\n\r\n // @Property: Platform ID for browser/server detection\r\n private platformId!: Object;\r\n\r\n // @Property: DestroyRef for managing subscriptions\r\n private destroyRef!: DestroyRef;\r\n private currentWindow!: Window;\r\n\r\n setWindows(currentWindow: Window): void {\r\n if (isPlatformBrowser(this.platformId)) {\r\n this.currentWindow = currentWindow;\r\n this.screenWidth = currentWindow.innerWidth;\r\n this.screenHeight = currentWindow.innerHeight;\r\n }\r\n }\r\n\r\n setPlatformId(platformId: Object): void {\r\n this.platformId = platformId;\r\n }\r\n setDestroyRef(destroyRef: DestroyRef): void {\r\n this.destroyRef = destroyRef;\r\n }\r\n\r\n /**\r\n * @Method: getScreenWidth\r\n * @Description: Returns the current screen width\r\n * @Returns: number - The current screen width\r\n * @Throws: Error if called outside of a browser environment\r\n */\r\n public getScreenWidth(): number {\r\n if (isPlatformBrowser(this.platformId)) {\r\n return this.screenWidth;\r\n }\r\n throw new Error(\r\n 'getScreenWidth can only be called in a browser environment.'\r\n );\r\n }\r\n\r\n /**\r\n * @Method: getScreenHeight\r\n * @Description: Returns the current screen height\r\n * @Returns: number - The current screen height\r\n * @Throws: Error if called outside of a browser environment\r\n */\r\n public getScreenHeight(): number {\r\n if (isPlatformBrowser(this.platformId)) {\r\n return this.screenHeight;\r\n }\r\n throw new Error(\r\n 'getScreenHeight can only be called in a browser environment.'\r\n );\r\n }\r\n\r\n /**\r\n * @Method: executeFuncByScreenWidth\r\n * @Description: Executes a function if the screen width is less than or equal to the specified width\r\n * @Param: func - The function to execute\r\n * @Param: width - The maximum screen width to trigger the function (can be a ScreenWidthType or a number)\r\n */\r\n public executeFuncByScreenWidth(\r\n func: () => void,\r\n width: ScreenWidthType\r\n ): void;\r\n\r\n public executeFuncByScreenWidth(func: () => void, width: number): void;\r\n\r\n public executeFuncByScreenWidth(\r\n func: () => void,\r\n width: ScreenWidthType | number\r\n ): void {\r\n if (this.screenWidth <= width) {\r\n // Calls the function immediately only to pass tests, as onResize requires a browser to trigger fromEvent(window, 'resize').\r\n this.onResize(func);\r\n }\r\n }\r\n\r\n /**\r\n * @Method: onResize\r\n * @Description: Subscribes to the window resize event and executes the provided function after a debounce period\r\n * @Param: func - The function to execute on resize\r\n * @Param: debounceTimeValue - The debounce time in milliseconds (default: 200ms)\r\n * @Throws: Error if called outside of a browser environment\r\n */\r\n private onResize(func: () => void, debounceTimeValue: number = 200): void {\r\n if (isPlatformBrowser(this.platformId)) {\r\n if(this.currentWindow === undefined){\r\n throw new Error('The current window is not set. Please call setWindows() first.');\r\n }\r\n fromEvent(this.currentWindow, 'resize')\r\n .pipe(\r\n debounceTime(debounceTimeValue),\r\n takeUntilDestroyed(this.destroyRef)\r\n )\r\n .subscribe(() => {\r\n this.screenWidth = window.innerWidth;\r\n this.screenHeight = window.innerHeight;\r\n func();\r\n });\r\n } else {\r\n throw new Error('onResize can only be called in a browser environment.');\r\n }\r\n }\r\n}\r\n","export enum ScreenWidthType{\r\n XS = 640,\r\n SM = 768,\r\n MD = 1024, \r\n LG = 1280,\r\n XL = 1536,\r\n XXL = 1920\r\n}","/*\r\n * Public API Surface of core\r\n */\r\n\r\nexport * from './lib/element-active.directive';\r\nexport * from './lib/element-active.service';\r\nexport * from './lib/element_toggle.service';\r\nexport * from './lib/screen_width-event.service';\r\nexport * from './lib/types/element_status-type'\r\nexport * from './lib/types/screen_width-type';\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["i1.ElementActiveService"],"mappings":"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"}
@@ -1,3 +1,4 @@
1
+ import { DestroyRef } from '@angular/core';
1
2
  import { ScreenWidthType } from './types/screen_width-type';
2
3
  import * as i0 from "@angular/core";
3
4
  /**
@@ -9,16 +10,15 @@ import * as i0 from "@angular/core";
9
10
  * - xl: 1280px (Extra large screens)
10
11
  * - 2xl: 1536px (2x Extra large screens)
11
12
  */
12
- export declare class ScreenWidthEventService {
13
+ export declare class ScreenWidthEventService2 {
13
14
  private screenWidth;
14
15
  private screenHeight;
15
16
  private platformId;
16
17
  private destroyRef;
17
- /**
18
- * @Constructor
19
- * @Description: Initializes the screen width and height if running in a browser environment
20
- */
21
- constructor();
18
+ private currentWindow;
19
+ setWindows(currentWindow: Window): void;
20
+ setPlatformId(platformId: Object): void;
21
+ setDestroyRef(destroyRef: DestroyRef): void;
22
22
  /**
23
23
  * @Method: getScreenWidth
24
24
  * @Description: Returns the current screen width
@@ -49,6 +49,6 @@ export declare class ScreenWidthEventService {
49
49
  * @Throws: Error if called outside of a browser environment
50
50
  */
51
51
  private onResize;
52
- static ɵfac: i0.ɵɵFactoryDeclaration<ScreenWidthEventService, never>;
53
- static ɵprov: i0.ɵɵInjectableDeclaration<ScreenWidthEventService>;
52
+ static ɵfac: i0.ɵɵFactoryDeclaration<ScreenWidthEventService2, never>;
53
+ static ɵprov: i0.ɵɵInjectableDeclaration<ScreenWidthEventService2>;
54
54
  }
package/package.json CHANGED
@@ -1,9 +1,12 @@
1
1
  {
2
2
  "name": "@c-code/c-code-fw",
3
- "version": "1.1.9",
3
+ "version": "1.3.0",
4
4
  "peerDependencies": {
5
5
  "@angular/common": "^19.2.0",
6
- "@angular/core": "^19.2.0"
6
+ "@angular/core": "^19.2.0",
7
+ "@angular/platform-browser": "^19.2.0",
8
+ "@angular/router": "^19.2.0",
9
+ "rxjs": "^7.8.0"
7
10
  },
8
11
  "dependencies": {
9
12
  "tslib": "^2.3.0"
@@ -18,6 +21,10 @@
18
21
  ".": {
19
22
  "types": "./index.d.ts",
20
23
  "default": "./fesm2022/c-code-c-code-fw.mjs"
24
+ },
25
+ "./ui": {
26
+ "types": "./ui/index.d.ts",
27
+ "default": "./fesm2022/c-code-c-code-fw-ui.mjs"
21
28
  }
22
29
  }
23
30
  }
package/public-api.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  export * from './lib/element-active.directive';
2
2
  export * from './lib/element-active.service';
3
3
  export * from './lib/element_toggle.service';
4
+ export * from './lib/screen_width-event.service';
4
5
  export * from './lib/types/element_status-type';
5
6
  export * from './lib/types/screen_width-type';
6
- export * from './lib/screen_width-event.service';
package/ui/index.d.ts ADDED
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Generated bundle index. Do not edit.
3
+ */
4
+ /// <amd-module name="@c-code/c-code-fw/ui" />
5
+ export * from './public-api';
@@ -0,0 +1,19 @@
1
+ import { CategoryOption } from '../../models/plan.models';
2
+ import * as i0 from "@angular/core";
3
+ /**
4
+ * Vertical category list with a single selected option.
5
+ * Replaces the `appElementActive` markup the sites used for plan categories.
6
+ *
7
+ * ```html
8
+ * <cc-category-menu [options]="categories" [(selected)]="category" />
9
+ * ```
10
+ */
11
+ export declare class CategoryMenuComponent<T = unknown> {
12
+ readonly options: import("@angular/core").InputSignal<CategoryOption<T>[]>;
13
+ /** Selected value. Use `[(selected)]` to bind both ways. */
14
+ readonly selected: import("@angular/core").ModelSignal<T | null>;
15
+ readonly title: import("@angular/core").InputSignal<string>;
16
+ select(value: T): void;
17
+ static ɵfac: i0.ɵɵFactoryDeclaration<CategoryMenuComponent<any>, never>;
18
+ static ɵcmp: i0.ɵɵComponentDeclaration<CategoryMenuComponent<any>, "cc-category-menu", never, { "options": { "alias": "options"; "required": true; "isSignal": true; }; "selected": { "alias": "selected"; "required": false; "isSignal": true; }; "title": { "alias": "title"; "required": false; "isSignal": true; }; }, { "selected": "selectedChange"; }, never, never, true, never>;
19
+ }
@@ -0,0 +1,16 @@
1
+ import { FaqItem } from '../../models/ui.models';
2
+ import * as i0 from "@angular/core";
3
+ /**
4
+ * Frequently asked questions as native `<details>` elements, so the answers
5
+ * stay in the prerendered HTML for search engines.
6
+ *
7
+ * ```html
8
+ * <cc-faq title="PREGUNTAS FRECUENTES" [items]="faq" />
9
+ * ```
10
+ */
11
+ export declare class FaqComponent {
12
+ readonly items: import("@angular/core").InputSignal<FaqItem[]>;
13
+ readonly title: import("@angular/core").InputSignal<string>;
14
+ static ɵfac: i0.ɵɵFactoryDeclaration<FaqComponent, never>;
15
+ static ɵcmp: i0.ɵɵComponentDeclaration<FaqComponent, "cc-faq", never, { "items": { "alias": "items"; "required": true; "isSignal": true; }; "title": { "alias": "title"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
16
+ }
@@ -0,0 +1,27 @@
1
+ import { GalleryImage } from '../../models/ui.models';
2
+ import * as i0 from "@angular/core";
3
+ /**
4
+ * Thumbnail grid that opens a lightbox on click.
5
+ *
6
+ * ```html
7
+ * <cc-gallery [images]="images" />
8
+ * ```
9
+ *
10
+ * `numberedImages()` builds the list for folders named 1.jpeg, 2.jpeg, …
11
+ */
12
+ export declare class GalleryComponent {
13
+ readonly images: import("@angular/core").InputSignal<GalleryImage[]>;
14
+ readonly backgroundImage: import("@angular/core").InputSignal<string>;
15
+ readonly openLabel: import("@angular/core").InputSignal<string>;
16
+ protected readonly open: import("@angular/core").WritableSignal<number | null>;
17
+ static ɵfac: i0.ɵɵFactoryDeclaration<GalleryComponent, never>;
18
+ static ɵcmp: i0.ɵɵComponentDeclaration<GalleryComponent, "cc-gallery", never, { "images": { "alias": "images"; "required": true; "isSignal": true; }; "backgroundImage": { "alias": "backgroundImage"; "required": false; "isSignal": true; }; "openLabel": { "alias": "openLabel"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
19
+ }
20
+ /**
21
+ * Builds a gallery list for numbered files.
22
+ *
23
+ * ```ts
24
+ * numberedImages(18, (i) => `assets/images/galery/${i}.jpeg`, (i) => `Instalaciones - foto ${i}`)
25
+ * ```
26
+ */
27
+ export declare function numberedImages(count: number, src: (n: number) => string, caption?: (n: number) => string): GalleryImage[];
@@ -0,0 +1,18 @@
1
+ import * as i0 from "@angular/core";
2
+ /**
3
+ * Title with a paragraph, used for policy sections.
4
+ * Extra content (lists, notes) can be projected under the text.
5
+ *
6
+ * ```html
7
+ * <cc-info-item title="Pagos" text="Aceptamos Nequi, Daviplata y efectivo." />
8
+ * <cc-info-item title="Reservaciones" [text]="texto">
9
+ * <ul><li>…</li></ul>
10
+ * </cc-info-item>
11
+ * ```
12
+ */
13
+ export declare class InfoItemComponent {
14
+ readonly title: import("@angular/core").InputSignal<string>;
15
+ readonly text: import("@angular/core").InputSignal<string>;
16
+ static ɵfac: i0.ɵɵFactoryDeclaration<InfoItemComponent, never>;
17
+ static ɵcmp: i0.ɵɵComponentDeclaration<InfoItemComponent, "cc-info-item", never, { "title": { "alias": "title"; "required": true; "isSignal": true; }; "text": { "alias": "text"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
18
+ }