{"version":3,"file":"contentside-v2.mjs","sources":["../../../../src/contentside/v2/contentside.ts"],"sourcesContent":["import { html, unsafeCSS, type CSSResult, type TemplateResult, type PropertyValues } from 'lit';\nimport { customElement, property, state } from 'lit/decorators.js';\nimport { BaseOrganism } from '../../base-organism/base-organism';\nimport { appendStylesheet } from '../../core/utils';\nimport styles from './contentside.scss?inline';\nimport slotStyles from './contentside.slot.scss?inline';\nimport '../../text-content';\n\n@customElement('pips-v2-contentside')\nexport class ContentSideV2 extends BaseOrganism {\n  static override styles: CSSResult[] = [...BaseOrganism.styles, unsafeCSS(styles)];\n\n  @property({ type: Boolean, reflect: true }) fullWidth = false;\n  @property({ type: String, reflect: true }) side: 'right' | 'left' = 'right';\n  @property({ type: String, reflect: true }) mediaShape: 'default' | 'round' = 'default';\n  @property({ type: String, reflect: true }) imageSize: 'default' | 'small' = 'default';\n  @property({ type: String, reflect: true }) headingVisualSize: 'lg' | 'xl' | '2xl' | '' = '';\n\n  @state() private _hasMedia = false;\n\n  // Reactive: effectiveSide (used in renderContent()) reads this, so a\n  // restricted<->unrestricted media swap must trigger a re-render even when\n  // _hasMedia doesn't change (e.g. accordion -> image, both \"has media\").\n  @state() private _restrictedMedia = false;\n\n  // Public so contentside.stories.ts can derive its Controls-locking logic\n  // from this same list instead of hand-duplicating it.\n  static readonly RESTRICTED_MEDIA_TAGS = new Set(['pips-v1-accordion', 'pips-v1-link-list']);\n\n  // Mirrors $cq-xl from src/styles/_variables.scss (container-max-widths xl minus gutter).\n  private static readonly CQ_XL_PX = 1116;\n\n  private resizeObserver?: ResizeObserver;\n\n  override connectedCallback(): void {\n    super.connectedCallback();\n    this.updateMediaState();\n    appendStylesheet({\n      target: this,\n      styles: slotStyles,\n      name: 'pips-v2-contentside-slot',\n    });\n  }\n\n  protected override firstUpdated(): void {\n    super.firstUpdated();\n    this.resizeObserver = new ResizeObserver(() => this.onResize());\n    this.resizeObserver.observe(this);\n  }\n\n  override disconnectedCallback(): void {\n    super.disconnectedCallback();\n    this.resizeObserver?.disconnect();\n  }\n\n  private onResize(): void {\n    const container = this.shadowRoot?.querySelector('.layout-container') as HTMLElement | null;\n    const width = container?.clientWidth ?? this.clientWidth;\n    const ctaSlot = this.shadowRoot?.querySelector('slot[name=\"cta\"]') as HTMLSlotElement;\n    const assigned = ctaSlot?.assignedElements({ flatten: true }) ?? [];\n    const link = assigned.length > 1 ? assigned[1] : undefined;\n    if (link) {\n      const size = width < ContentSideV2.CQ_XL_PX ? 'c11n-text-sm' : 'c11n-text-md';\n      const otherSize = size === 'c11n-text-sm' ? 'c11n-text-md' : 'c11n-text-sm';\n      link.classList.add(size);\n      link.classList.remove(otherSize);\n    }\n  }\n\n  private onMediaSlotChange(): void {\n    this.updateMediaState();\n  }\n\n  // Doesn't call warnIfRestrictedMediaMisconfigured() directly — updated()\n  // below reacts to `_restrictedMedia` changing too, so it covers this in\n  // the same render cycle without a second, duplicate warning. On initial\n  // connect (slotted media present in the starting HTML), the slotchange\n  // event that calls this can fire within the very first render, by which\n  // point `changedProperties` in updated() already reflects this same\n  // toggle — calling the warn here as well would fire it twice.\n  private updateMediaState(): void {\n    const mediaEls = Array.from(this.querySelectorAll(':scope > [slot=\"media\"], :scope > [slot=\"image\"]'));\n    this._hasMedia = mediaEls.length > 0;\n    this._restrictedMedia = mediaEls.some((el) => this.isRestrictedMediaElement(el));\n    this.toggleAttribute('has-media', this._hasMedia);\n    this.toggleAttribute('restricted-media', this._restrictedMedia);\n  }\n\n  private isRestrictedMediaElement(el: Element): boolean {\n    return ContentSideV2.RESTRICTED_MEDIA_TAGS.has(el.tagName.toLowerCase());\n  }\n\n  // `side=\"left\"` is the one thing Accordion/Link List media can't do — side-by-side\n  // on the right (the default) and stacking on mobile both work as normal.\n  private get effectiveSide(): 'right' | 'left' {\n    return this._restrictedMedia && this.side === 'left' ? 'right' : this.side;\n  }\n\n  private warnIfRestrictedMediaMisconfigured(): void {\n    if (!this._restrictedMedia) return;\n\n    const ignored: string[] = [];\n    if (this.side === 'left') ignored.push(`side=\"${this.side}\" (falls back to \"right\")`);\n    if (this.background && this.background !== 'white') ignored.push(`background=\"${this.background}\" (forced to white)`);\n    if (this.mediaShape === 'round') ignored.push(`mediaShape=\"${this.mediaShape}\" (forced to \"default\")`);\n    if (ignored.length === 0) return;\n\n    console.warn(\n      `[pips-v2-contentside] Accordion and Link List media can't sit on the left, take a colored background, or clip to a circle — ${ignored.join(', ')}. This is a dev-time warning only.`\n    );\n  }\n\n  // Single source of truth for the warning: fires when restricted media is\n  // present and either the misconfigurable properties (side/background/\n  // mediaShape) changed, or `_restrictedMedia` itself just became true (a\n  // slot swap or the initial connect) — covers every case (initial connect,\n  // slot changes, and side/background/mediaShape mutated post-connect by a\n  // framework re-binding) from this one lifecycle hook, so nothing else\n  // needs to call warnIfRestrictedMediaMisconfigured() and risk a duplicate.\n  //\n  // The default value keeps this override's signature compatible with\n  // BaseOrganism's own `updated(): void` (no params) for override-safety —\n  // and `super.updated()` is called without forwarding the argument for the\n  // same reason: BaseOrganism's real signature takes none, so forwarding one\n  // would be a \"too many arguments\" compile error, not a \"convention\".\n  protected override updated(changedProperties: PropertyValues = new Map()): void {\n    super.updated();\n\n    if (\n      this._restrictedMedia &&\n      (changedProperties.has('side') ||\n        changedProperties.has('background') ||\n        changedProperties.has('mediaShape') ||\n        changedProperties.has('_restrictedMedia'))\n    ) {\n      this.warnIfRestrictedMediaMisconfigured();\n    }\n  }\n\n  protected override renderContent(): TemplateResult {\n    const side = this.effectiveSide;\n    const isSmall = this.imageSize === 'small';\n    const layoutClass = isSmall ? ` layout--col7-col4-gap1-${side}` : '';\n    const contentColClass = isSmall ? ' layout--col7' : '';\n    const mediaColClass = isSmall ? ' layout--col4' : '';\n\n    return html`\n      <div class=\"contentside contentside--${side}${this._hasMedia ? '' : ' contentside--no-media'}${layoutClass}\">\n        <div class=\"contentside-content${contentColClass}\">\n          <slot name=\"icon\"></slot>\n          <slot name=\"heading\"></slot>\n          <slot name=\"body\"></slot>\n          <slot name=\"cta\"></slot>\n        </div>\n        <div class=\"contentside-image-container${mediaColClass}\">\n          <slot name=\"media\" @slotchange=\"${this.onMediaSlotChange}\"></slot>\n          <slot name=\"image\" @slotchange=\"${this.onMediaSlotChange}\"></slot>\n        </div>\n      </div>\n    `;\n  }\n}\n"],"names":["ContentSideV2","BaseOrganism","super","arguments","this","fullWidth","side","mediaShape","imageSize","headingVisualSize","_hasMedia","_restrictedMedia","connectedCallback","updateMediaState","appendStylesheet","target","styles","name","firstUpdated","resizeObserver","ResizeObserver","onResize","observe","disconnectedCallback","disconnect","container","shadowRoot","querySelector","width","clientWidth","ctaSlot","assigned","assignedElements","flatten","link","length","size","CQ_XL_PX","otherSize","classList","add","remove","onMediaSlotChange","mediaEls","Array","from","querySelectorAll","some","el","isRestrictedMediaElement","toggleAttribute","RESTRICTED_MEDIA_TAGS","has","tagName","toLowerCase","effectiveSide","warnIfRestrictedMediaMisconfigured","ignored","push","background","console","warn","join","changedProperties","Map","updated","renderContent","isSmall","layoutClass","contentColClass","mediaColClass","html","unsafeCSS","Set","__decorateClass","property","type","Boolean","reflect","prototype","String","state","customElement"],"mappings":"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"}