{"version":3,"file":"koobiq-components-dynamic-translation.mjs","sources":["../../../packages/components/dynamic-translation/dynamic-translation.ts","../../../packages/components/dynamic-translation/module.ts","../../../packages/components/dynamic-translation/koobiq-components-dynamic-translation.ts"],"sourcesContent":["import { NgTemplateOutlet } from '@angular/common';\nimport {\n    afterNextRender,\n    ChangeDetectionStrategy,\n    Component,\n    computed,\n    contentChildren,\n    Directive,\n    effect,\n    ElementRef,\n    inject,\n    input,\n    Renderer2,\n    Signal,\n    TemplateRef,\n    viewChildren\n} from '@angular/core';\n\n/**\n * @docs-private\n */\ntype KbqDynamicTranslationParsedSlot = {\n    type: 'text' | 'slot';\n    template: TemplateRef<unknown> | null;\n    context?: { $implicit: unknown };\n    text?: string;\n};\n\n/**\n * @docs-private\n */\nexport interface KbqDynamicTranslationHelperSlot {\n    name: string;\n    tag: string;\n    attributes?: { key: string; value: string }[];\n    content?: string;\n}\n\n/**\n * Directive for defining a dynamic translation slot.\n */\n@Directive({\n    selector: '[kbqDynamicTranslationSlot]'\n})\nexport class KbqDynamicTranslationSlot {\n    /**\n     * The name of the dynamic translation slot.\n     */\n    readonly name = input.required<string>({ alias: 'kbqDynamicTranslationSlot' });\n\n    /**\n     * @docs-private\n     */\n    readonly templateRef = inject(TemplateRef);\n}\n\n/**\n * Component for dynamic translation.\n */\n@Component({\n    selector: 'kbq-dynamic-translation',\n    imports: [NgTemplateOutlet],\n    template: `\n        @for (slot of parsedSlots(); track $index) {\n            @switch (slot.type) {\n                @case ('slot') {\n                    <ng-container *ngTemplateOutlet=\"slot.template; context: slot.context\" />\n                }\n                @default {\n                    <ng-container>{{ slot.text }}</ng-container>\n                }\n            }\n        }\n    `,\n    changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class KbqDynamicTranslation {\n    private readonly slots = contentChildren(KbqDynamicTranslationSlot);\n\n    /**\n     * The text which will be translated.\n     */\n    readonly text = input.required<string>();\n\n    /**\n     * @docs-private\n     */\n    protected readonly parsedSlots: Signal<KbqDynamicTranslationParsedSlot[]> = computed(() =>\n        this.parseSlots(this.text(), this.slots())\n    );\n\n    private parseSlots(\n        text: string,\n        slots: ReadonlyArray<KbqDynamicTranslationSlot>\n    ): KbqDynamicTranslationParsedSlot[] {\n        const slotTemplatesByName = slots.reduce<Record<string, TemplateRef<unknown>>>((map, { name, templateRef }) => {\n            const slotName = name();\n\n            if (slotName) map[slotName] = templateRef;\n\n            return map;\n        }, {});\n        const parsedSlots: KbqDynamicTranslationParsedSlot[] = [];\n        const slotSelector = new RegExp(`\\\\[\\\\[(${Object.keys(slotTemplatesByName).join('|')})(?::(.+?))?\\\\]\\\\]`, 'g');\n        let match: RegExpExecArray | null;\n        let lastIndex = 0;\n\n        while ((match = slotSelector.exec(text)) !== null) {\n            const [slotMatch, slotName, slotText] = match;\n            const [listMatch, listString] = new RegExp('^\\\\((.*?)\\\\)$', 'g').exec(slotText) ?? [];\n            const textBeforeSlot = text.substring(lastIndex, +match.index);\n\n            if (textBeforeSlot) {\n                parsedSlots.push({ type: 'text', text: textBeforeSlot, template: null });\n            }\n\n            parsedSlots.push({\n                type: 'slot',\n                template: slotTemplatesByName[slotName] || null,\n                context: { $implicit: listMatch && listString ? listString.split(',') : slotText }\n            });\n\n            lastIndex = match.index + slotMatch.length;\n        }\n\n        const textAfterLastSlot = text.substring(lastIndex);\n\n        if (textAfterLastSlot) {\n            parsedSlots.push({ type: 'text', text: textAfterLastSlot, template: null });\n        }\n\n        return parsedSlots;\n    }\n}\n\n/**\n * @docs-private\n */\n@Component({\n    selector: 'kbq-dynamic-translation-with-dynamic-component-creation',\n    imports: [KbqDynamicTranslation, KbqDynamicTranslationSlot],\n    template: `\n        <kbq-dynamic-translation [text]=\"text()\">\n            @for (slot of slots(); track $index) {\n                <ng-container *kbqDynamicTranslationSlot=\"slot.name; let content\">\n                    <span\n                        #replaceableSlotContainer\n                        [attr.data-slot-name]=\"slot.name\"\n                        [attr.data-slot-content]=\"slot.content || content\"\n                    ></span>\n                </ng-container>\n            }\n        </kbq-dynamic-translation>\n    `,\n    changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class KbqDynamicTranslationHelper {\n    private readonly renderer = inject(Renderer2);\n    private readonly replaceableSlotContainers = viewChildren<ElementRef<HTMLElement>>('replaceableSlotContainer');\n    private readonly slotsByName = new Map<string, KbqDynamicTranslationHelperSlot>();\n\n    readonly text = input.required<string>();\n\n    readonly slots = input.required<KbqDynamicTranslationHelperSlot[]>();\n\n    constructor() {\n        effect(() => {\n            this.slotsByName.clear();\n            this.slots().forEach((slot) => this.slotsByName.set(slot.name, slot));\n        });\n\n        afterNextRender(() => {\n            this.replaceSlots();\n        });\n    }\n\n    private replaceSlots(): void {\n        this.replaceableSlotContainers().forEach(({ nativeElement }: ElementRef<HTMLElement>) => {\n            const slotName = nativeElement.getAttribute('data-slot-name')!;\n            const slotContent = nativeElement.getAttribute('data-slot-content')!;\n            const { tag, attributes } = this.slotsByName.get(slotName)!;\n            const elementToRender = this.renderer.createElement(tag);\n\n            this.renderer.appendChild(elementToRender, this.renderer.createText(slotContent));\n\n            attributes?.forEach(({ key, value }) => this.renderer.setAttribute(elementToRender, key, value));\n\n            nativeElement.replaceWith(elementToRender);\n        });\n    }\n}\n","import { NgModule } from '@angular/core';\nimport { KbqDynamicTranslation, KbqDynamicTranslationHelper, KbqDynamicTranslationSlot } from './dynamic-translation';\n\nconst COMPONENTS = [\n    KbqDynamicTranslationSlot,\n    KbqDynamicTranslationHelper,\n    KbqDynamicTranslation\n];\n\n@NgModule({\n    imports: COMPONENTS,\n    exports: COMPONENTS\n})\nexport class KbqDynamicTranslationModule {}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}