@vadem/ui 0.1.0 → 0.2.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.
- package/fesm2022/vadem-ui-kanban.mjs +1021 -0
- package/fesm2022/vadem-ui-kanban.mjs.map +1 -0
- package/fesm2022/vadem-ui-locale.mjs +78 -0
- package/fesm2022/vadem-ui-locale.mjs.map +1 -1
- package/fesm2022/vadem-ui-schedule.mjs +1836 -0
- package/fesm2022/vadem-ui-schedule.mjs.map +1 -0
- package/fesm2022/vadem-ui.mjs +1 -1
- package/fesm2022/vadem-ui.mjs.map +1 -1
- package/package.json +9 -1
- package/styles/components/index.css +2 -0
- package/styles/components/kanban.css +220 -0
- package/styles/components/schedule.css +604 -0
- package/types/vadem-ui-kanban.d.ts +222 -0
- package/types/vadem-ui-locale.d.ts +31 -0
- package/types/vadem-ui-schedule.d.ts +402 -0
- package/types/vadem-ui.d.ts +1 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vadem-ui-kanban.mjs","names":[],"sources":["../../../projects/ui/kanban/src/core/kanban.ts","../../../projects/ui/kanban/src/kanban.ts"],"sourcesContent":["/** Framework-agnostic board logic: validation, drop targets and immutable moves. */\n\nexport interface VdKanbanCardData {\n readonly id: string;\n /** Plain text used in announcements and the move menu's accessible name. */\n readonly label: string;\n}\n\nexport interface VdKanbanColumn<T extends VdKanbanCardData = VdKanbanCardData> {\n readonly id: string;\n readonly title: string;\n readonly cards: readonly T[];\n}\n\n/** A requested move. `toIndex` is the card's index in the target column after the move. */\nexport interface VdKanbanMove {\n readonly cardId: string;\n readonly fromColumnId: string;\n readonly toColumnId: string;\n readonly fromIndex: number;\n readonly toIndex: number;\n readonly method: 'menu' | 'pointer';\n}\n\nexport interface VdKanbanPosition {\n readonly columnId: string;\n readonly index: number;\n}\n\n/** Column and card IDs must be non-empty and unique across the whole board. */\nexport function vdKanbanValid(columns: readonly VdKanbanColumn[]): boolean {\n const columnIds = new Set<string>();\n const cardIds = new Set<string>();\n for (const column of columns) {\n if (!isId(column.id) || columnIds.has(column.id)) return false;\n columnIds.add(column.id);\n for (const card of column.cards) {\n if (!isId(card.id) || cardIds.has(card.id)) return false;\n cardIds.add(card.id);\n }\n }\n return true;\n}\n\nexport function vdKanbanFind(\n columns: readonly VdKanbanColumn[],\n cardId: string,\n): VdKanbanPosition | null {\n for (const column of columns) {\n const index = column.cards.findIndex((card) => card.id === cardId);\n if (index >= 0) return { columnId: column.id, index };\n }\n return null;\n}\n\n/**\n * Builds a move request, or null when it changes nothing or is out of range.\n * `toIndex` is clamped to the target column (after removing the card from its source).\n */\nexport function vdKanbanMoveRequest(\n columns: readonly VdKanbanColumn[],\n cardId: string,\n to: VdKanbanPosition,\n method: VdKanbanMove['method'],\n): VdKanbanMove | null {\n const from = vdKanbanFind(columns, cardId);\n const target = columns.find((column) => column.id === to.columnId);\n if (!from || !target || !Number.isInteger(to.index)) return null;\n const size = target.cards.length - (target.id === from.columnId ? 1 : 0);\n const index = Math.max(0, Math.min(to.index, size));\n if (target.id === from.columnId && index === from.index) return null;\n return {\n cardId,\n fromColumnId: from.columnId,\n toColumnId: target.id,\n fromIndex: from.index,\n toIndex: index,\n method,\n };\n}\n\n/**\n * Applies a move immutably: untouched columns keep their identity. Returns the same array when\n * the move no longer matches the board (stale request), so callers can detect a no-op.\n */\nexport function vdKanbanApplyMove<T extends VdKanbanCardData, C extends VdKanbanColumn<T>>(\n columns: readonly C[],\n move: Pick<VdKanbanMove, 'cardId' | 'toColumnId' | 'toIndex'>,\n): readonly C[] {\n const from = vdKanbanFind(columns, move.cardId);\n if (!from || !columns.some((column) => column.id === move.toColumnId)) return columns;\n const card = columns.find((column) => column.id === from.columnId)!.cards[from.index];\n return columns.map((column) => {\n if (column.id !== from.columnId && column.id !== move.toColumnId) return column;\n const cards = column.cards.filter((c) => c.id !== move.cardId);\n if (column.id === move.toColumnId) {\n cards.splice(Math.max(0, Math.min(move.toIndex, cards.length)), 0, card);\n }\n return { ...column, cards };\n });\n}\n\n/**\n * Insertion index for a pointer at `y` among the other cards of a column (the dragged card's own\n * rectangle excluded): the number of cards whose vertical middle lies above the pointer.\n */\nexport function vdKanbanInsertIndex(\n y: number,\n cards: readonly { top: number; bottom: number }[],\n): number {\n if (!Number.isFinite(y)) return 0;\n let index = 0;\n for (const rect of cards) if (y > (rect.top + rect.bottom) / 2) index++;\n return index;\n}\n\n/** The column under a horizontal pointer position, or -1 outside every column. */\nexport function vdKanbanColumnAt(\n x: number,\n columns: readonly { left: number; right: number }[],\n): number {\n if (!Number.isFinite(x)) return -1;\n return columns.findIndex((rect) => x >= rect.left && x <= rect.right);\n}\n\nfunction isId(id: unknown): id is string {\n return typeof id === 'string' && id.trim().length > 0;\n}\n","import { NgTemplateOutlet } from '@angular/common';\nimport {\n ChangeDetectionStrategy,\n Component,\n DestroyRef,\n Directive,\n ElementRef,\n TemplateRef,\n ViewEncapsulation,\n afterNextRender,\n afterRenderEffect,\n booleanAttribute,\n computed,\n contentChild,\n effect,\n inject,\n input,\n output,\n signal,\n} from '@angular/core';\nimport { VdButton } from '@vadem/ui/button';\nimport { vdUniqueId } from '@vadem/ui/field';\nimport { VdIcon } from '@vadem/ui/icon';\nimport { vdTexts } from '@vadem/ui/locale';\nimport { VD_MENU } from '@vadem/ui/menu';\nimport {\n VdKanbanCardData,\n VdKanbanColumn,\n VdKanbanMove,\n vdKanbanColumnAt,\n vdKanbanFind,\n vdKanbanInsertIndex,\n vdKanbanMoveRequest,\n vdKanbanValid,\n} from './core/kanban';\n\n/** Template context for `ng-template[vdKanbanCard]` and `ng-template[vdKanbanColumnHeader]`. */\nexport interface VdKanbanCardContext<T extends VdKanbanCardData = VdKanbanCardData> {\n $implicit: T;\n column: VdKanbanColumn<T>;\n index: number;\n}\nexport interface VdKanbanColumnContext<T extends VdKanbanCardData = VdKanbanCardData> {\n $implicit: VdKanbanColumn<T>;\n}\n\n/** Card content. Without it, a card shows its `label`. */\n@Directive({ selector: 'ng-template[vdKanbanCard]' })\nexport class VdKanbanCard {\n readonly template = inject<TemplateRef<VdKanbanCardContext>>(TemplateRef);\n}\n\n/** Extra column header content after the title and count (for example a total). */\n@Directive({ selector: 'ng-template[vdKanbanColumnHeader]' })\nexport class VdKanbanColumnHeader {\n readonly template = inject<TemplateRef<VdKanbanColumnContext>>(TemplateRef);\n}\n\ninterface Drag {\n pointer: number;\n element: HTMLElement;\n columns: readonly VdKanbanColumn[];\n cardId: string;\n label: string;\n touch: boolean;\n x: number;\n y: number;\n lastX: number;\n lastY: number;\n active: boolean;\n /** Long-press timer for touch. */\n timer: ReturnType<typeof setTimeout> | null;\n ghost: HTMLElement | null;\n offsetX: number;\n offsetY: number;\n /** Horizontal auto-scroll direction while the pointer rests near a board edge. */\n scroll: -1 | 0 | 1;\n frame: number | null;\n}\ninterface Drop {\n columnId: string;\n index: number;\n cardId: string | null;\n edge: 'before' | 'after' | null;\n}\n\n/** Elements inside a card that keep their own pointer behavior (no drag starts there). */\nconst INTERACTIVE = 'a, button, input, select, textarea, label, [contenteditable], [tabindex]';\nconst INTERACTIVE_TOUCH = 'button, input, select, textarea, label, [contenteditable]';\n/** Touch: hold still this long to pick a card up; moving earlier scrolls instead. */\nconst LONG_PRESS_MS = 400;\nconst TOUCH_SLOP = 8;\nconst EDGE = 48;\nconst EDGE_STEP = 14;\n\n/**\n * A board of columns and cards. The application owns the data: the board never changes\n * `columns` itself, it emits `cardMove` requests (from the Move menu or a pointer drag) and the\n * application applies them (for example with `vdKanbanApplyMove`). Spec: specs/kanban.md\n */\n@Component({\n selector: 'vd-kanban',\n imports: [NgTemplateOutlet, VdButton, VdIcon, VD_MENU],\n template: `\n <p class=\"vd-visually-hidden\" [id]=\"instructionsId\">{{ t().instructions }}</p>\n @if (!valid()) {\n <p class=\"vd-kanban__invalid\">{{ t().invalidText }}</p>\n } @else {\n <div\n class=\"vd-kanban__columns\"\n role=\"group\"\n [attr.aria-label]=\"t().label\"\n [attr.aria-describedby]=\"instructionsId\"\n >\n @for (column of columns(); track column.id; let c = $index) {\n <section\n class=\"vd-kanban__column\"\n [attr.aria-labelledby]=\"baseId + '-title-' + c\"\n [attr.data-column-id]=\"column.id\"\n [attr.data-drop-target]=\"drop()?.columnId === column.id ? '' : null\"\n >\n <header class=\"vd-kanban__header\">\n <p class=\"vd-kanban__title\" [id]=\"baseId + '-title-' + c\">\n <bdi>{{ column.title }}</bdi>\n <span class=\"vd-kanban__count\" aria-hidden=\"true\">{{ column.cards.length }}</span>\n <span class=\"vd-visually-hidden\">, {{ t().countText(column.cards.length) }}</span>\n </p>\n @if (columnHeader(); as header) {\n <div class=\"vd-kanban__header-extra\">\n <ng-container\n [ngTemplateOutlet]=\"header.template\"\n [ngTemplateOutletContext]=\"{ $implicit: column }\"\n />\n </div>\n }\n </header>\n <ul\n class=\"vd-kanban__cards\"\n role=\"list\"\n [attr.aria-labelledby]=\"baseId + '-title-' + c\"\n >\n @for (card of column.cards; track card.id; let i = $index, last = $last) {\n <li\n class=\"vd-kanban__card\"\n tabindex=\"-1\"\n [attr.data-card-id]=\"card.id\"\n [attr.data-dragging]=\"draggingId() === card.id ? '' : null\"\n [attr.data-drop]=\"drop()?.cardId === card.id ? drop()?.edge : null\"\n (pointerdown)=\"start($event, card)\"\n (pointermove)=\"pointerMove($event)\"\n (pointerup)=\"end($event)\"\n (pointercancel)=\"pointerCancel($event)\"\n (lostpointercapture)=\"pointerCancel($event)\"\n >\n <div class=\"vd-kanban__content\">\n @if (cardTemplate(); as tpl) {\n <ng-container\n [ngTemplateOutlet]=\"tpl.template\"\n [ngTemplateOutletContext]=\"{ $implicit: card, column, index: i }\"\n />\n } @else {\n <bdi>{{ card.label }}</bdi>\n }\n </div>\n <button\n vdButton\n class=\"vd-kanban__move\"\n variant=\"ghost\"\n size=\"sm\"\n iconOnly\n type=\"button\"\n [disabled]=\"disabled()\"\n [attr.aria-label]=\"t().moveLabel(card.label)\"\n [vdMenuTrigger]=\"menu\"\n >\n <vd-icon name=\"more-horizontal\" />\n </button>\n <div vdMenu #menu=\"vdMenu\">\n <button\n vdMenuItem\n [disabled]=\"i === 0\"\n (click)=\"moveTo(card.id, column.id, i - 1)\"\n >\n <vd-icon name=\"arrow-up\" />{{ t().upText }}\n </button>\n <button\n vdMenuItem\n [disabled]=\"last\"\n (click)=\"moveTo(card.id, column.id, i + 1)\"\n >\n <vd-icon name=\"arrow-down\" />{{ t().downText }}\n </button>\n @if (columns().length > 1) {\n <div vdMenuSeparator></div>\n <p vdMenuLabel>{{ t().moveToText }}</p>\n @for (target of columns(); track target.id) {\n @if (target.id !== column.id) {\n <button\n vdMenuItem\n (click)=\"moveTo(card.id, target.id, target.cards.length)\"\n >\n <bdi>{{ target.title }}</bdi>\n </button>\n }\n }\n }\n </div>\n </li>\n } @empty {\n <li class=\"vd-kanban__empty\">{{ t().emptyText }}</li>\n }\n </ul>\n </section>\n }\n </div>\n }\n <p class=\"vd-visually-hidden\" role=\"status\" aria-atomic=\"true\">\n @for (message of messages(); track message.serial) {\n <span>{{ message.text }}</span>\n }\n </p>\n `,\n host: {\n class: 'vd-kanban',\n '[attr.data-state]':\n '!valid() ? \"invalid\" : disabled() ? \"disabled\" : draggingId() ? \"dragging\" : \"idle\"',\n '(keydown)': 'key($event)',\n },\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n})\nexport class VdKanban<T extends VdKanbanCardData = VdKanbanCardData> {\n readonly columns = input<readonly VdKanbanColumn<T>[]>([]);\n /** Disables every move (menus and dragging). Card content stays interactive. */\n readonly disabled = input(false, { transform: booleanAttribute });\n readonly label = input<string>();\n readonly instructions = input<string>();\n readonly emptyText = input<string>();\n readonly invalidText = input<string>();\n readonly countText = input<(count: number) => string>();\n readonly moveLabel = input<(card: string) => string>();\n readonly upText = input<string>();\n readonly downText = input<string>();\n readonly moveToText = input<string>();\n readonly movedText =\n input<(card: string, column: string, position: number, total: number) => string>();\n readonly canceledText = input<(card: string) => string>();\n /** A move request. Apply it to `columns` to make it happen; ignore it to reject it. */\n readonly cardMove = output<VdKanbanMove>();\n\n protected readonly t = vdTexts('kanban', {\n label: this.label,\n instructions: this.instructions,\n emptyText: this.emptyText,\n invalidText: this.invalidText,\n countText: this.countText,\n moveLabel: this.moveLabel,\n upText: this.upText,\n downText: this.downText,\n moveToText: this.moveToText,\n movedText: this.movedText,\n canceledText: this.canceledText,\n });\n protected readonly cardTemplate = contentChild(VdKanbanCard);\n protected readonly columnHeader = contentChild(VdKanbanColumnHeader);\n protected readonly valid = computed(() => vdKanbanValid(this.columns()));\n protected readonly baseId = vdUniqueId('vd-kanban');\n protected readonly instructionsId = this.baseId + '-instructions';\n protected readonly draggingId = signal<string | null>(null);\n protected readonly drop = signal<Drop | null>(null);\n protected readonly messages = signal<readonly { serial: number; text: string }[]>([]);\n private readonly host: HTMLElement = inject(ElementRef).nativeElement;\n private drag: Drag | null = null;\n /** Card whose Move button should get focus once the moved card renders in its new place. */\n private pendingFocus: string | null = null;\n /** The click that follows a finished drag must not follow a link or activate content. */\n private suppressClick = false;\n private serial = 0;\n\n constructor() {\n effect(() => {\n const columns = this.columns(),\n disabled = this.disabled();\n if (this.drag && (disabled || columns !== this.drag.columns)) this.finish(true);\n });\n afterRenderEffect(() => {\n this.columns();\n const id = this.pendingFocus;\n if (!id) return;\n const card = this.cardElement(id);\n if (!card) return;\n this.pendingFocus = null;\n const active = this.host.ownerDocument.activeElement;\n const lost = !active || active === this.host.ownerDocument.body || !active.isConnected;\n if (!lost && !this.host.contains(active)) return;\n if (card.contains(active)) return;\n const target = card.querySelector<HTMLElement>('.vd-kanban__move:not(:disabled)') ?? card;\n target.focus({ preventScroll: true });\n target.scrollIntoView({ block: 'nearest', inline: 'nearest', behavior: 'instant' });\n });\n const destroyRef = inject(DestroyRef);\n destroyRef.onDestroy(() => this.finish(false));\n afterNextRender(() => {\n // Non-passive so a lifted card stops the page from scrolling under the finger; the\n // long-press context menu is suppressed while a touch drag is pending or active.\n const touchMove = (event: TouchEvent) => {\n if (this.drag?.touch && this.drag.active) event.preventDefault();\n };\n const contextMenu = (event: Event) => {\n if (this.drag?.touch) event.preventDefault();\n };\n const click = (event: Event) => {\n if (!this.suppressClick) return;\n this.suppressClick = false;\n event.preventDefault();\n event.stopPropagation();\n };\n this.host.addEventListener('touchmove', touchMove, { passive: false });\n this.host.addEventListener('contextmenu', contextMenu);\n this.host.addEventListener('click', click, true);\n destroyRef.onDestroy(() => {\n this.host.removeEventListener('touchmove', touchMove);\n this.host.removeEventListener('contextmenu', contextMenu);\n this.host.removeEventListener('click', click, true);\n });\n });\n }\n\n protected moveTo(cardId: string, columnId: string, index: number): void {\n if (this.disabled() || !this.valid() || this.drag) return;\n this.request(vdKanbanMoveRequest(this.columns(), cardId, { columnId, index }, 'menu'));\n }\n\n private request(move: VdKanbanMove | null): void {\n if (!move) return;\n const columns = this.columns();\n const target = columns.find((column) => column.id === move.toColumnId)!;\n const card = columns.find((c) => c.id === move.fromColumnId)!.cards[move.fromIndex];\n const total = target.cards.length + (move.fromColumnId === move.toColumnId ? 0 : 1);\n this.pendingFocus = move.cardId;\n this.announce(this.t().movedText(card.label, target.title, move.toIndex + 1, total));\n this.cardMove.emit(move);\n }\n\n protected start(event: PointerEvent, card: T): void {\n this.suppressClick = false;\n if (!event.isPrimary || event.button !== 0 || this.disabled() || !this.valid() || this.drag)\n return;\n const element = event.currentTarget as HTMLElement;\n // Links, buttons and fields inside the card keep their own behavior (the card itself\n // matches [tabindex], so it is excluded).\n const touch = event.pointerType === 'touch';\n // On touch a long press may start on a link too: a short tap still follows it.\n const hit = (event.target as Element | null)?.closest(touch ? INTERACTIVE_TOUCH : INTERACTIVE);\n if (hit && hit !== element && element.contains(hit)) return;\n if (typeof element.setPointerCapture !== 'function') return;\n this.drag = {\n pointer: event.pointerId,\n element,\n columns: this.columns(),\n cardId: card.id,\n label: card.label,\n touch,\n x: event.clientX,\n y: event.clientY,\n lastX: event.clientX,\n lastY: event.clientY,\n active: false,\n timer: null,\n ghost: null,\n offsetX: 0,\n offsetY: 0,\n scroll: 0,\n frame: null,\n };\n if (touch) {\n // No preventDefault: a swipe must still scroll. Holding still picks the card up.\n const drag = this.drag;\n drag.timer = setTimeout(() => {\n drag.timer = null;\n if (this.drag !== drag) return;\n try {\n element.setPointerCapture(drag.pointer);\n } catch {\n this.finish(false);\n return;\n }\n this.activate(drag);\n }, LONG_PRESS_MS);\n return;\n }\n try {\n element.setPointerCapture(event.pointerId);\n } catch {\n this.drag = null;\n return;\n }\n event.preventDefault();\n }\n\n protected pointerMove(event: PointerEvent): void {\n const drag = this.drag;\n if (!drag || drag.pointer !== event.pointerId) return;\n drag.lastX = event.clientX;\n drag.lastY = event.clientY;\n const distance = Math.hypot(event.clientX - drag.x, event.clientY - drag.y);\n if (!drag.active) {\n // Touch moving before the long press is a scroll; mouse needs a small dead zone.\n if (drag.touch) {\n if (distance > TOUCH_SLOP) this.finish(false);\n return;\n }\n if (event.buttons === 0) {\n this.finish(false);\n return;\n }\n if (distance < 4) return;\n this.activate(drag);\n }\n this.track(drag);\n }\n\n protected end(event: PointerEvent): void {\n const drag = this.drag;\n if (!drag || drag.pointer !== event.pointerId) return;\n const drop = drag.active ? this.target(event.clientX, event.clientY) : null;\n this.suppressClick = drag.active;\n this.finish(drag.active && !drop);\n if (drop) {\n this.request(vdKanbanMoveRequest(this.columns(), drag.cardId, drop, 'pointer'));\n }\n }\n\n protected pointerCancel(event: PointerEvent): void {\n if (event.pointerId === this.drag?.pointer) this.finish(!!this.drag?.active);\n }\n\n protected key(event: KeyboardEvent): void {\n if (!this.drag || event.isComposing) return;\n if (event.key === 'Escape' || event.key === 'Tab') {\n if (event.key === 'Escape') {\n event.preventDefault();\n event.stopPropagation();\n }\n this.finish(true);\n }\n }\n\n /** Lifts the card: a floating copy follows the pointer, the card itself becomes a slot. */\n private activate(drag: Drag): void {\n drag.active = true;\n const { element } = drag;\n // Focus lets Escape/Tab reach the board (pointerdown was prevented for mouse).\n if (!element.contains(this.host.ownerDocument.activeElement))\n element.focus({ preventScroll: true });\n const rect = element.getBoundingClientRect();\n drag.offsetX = drag.x - rect.left;\n drag.offsetY = drag.y - rect.top;\n const ghost = element.cloneNode(true) as HTMLElement;\n ghost.querySelectorAll('[popover]').forEach((node) => node.remove());\n ghost.querySelectorAll('[id]').forEach((node) => node.removeAttribute('id'));\n for (const name of ['data-card-id', 'data-dragging', 'data-drop', 'tabindex'])\n ghost.removeAttribute(name);\n ghost.className = 'vd-kanban__card vd-kanban__ghost';\n ghost.setAttribute('aria-hidden', 'true');\n ghost.inert = true;\n ghost.style.setProperty('inline-size', `${rect.width}px`);\n ghost.setAttribute('popover', 'manual');\n this.host.append(ghost);\n ghost.showPopover?.();\n drag.ghost = ghost;\n this.draggingId.set(drag.cardId);\n this.track(drag);\n }\n\n /** Moves the floating copy, updates the drop marker and edge auto-scroll. */\n private track(drag: Drag): void {\n const ghost = drag.ghost;\n if (ghost) {\n // Physical viewport coordinates; the copy is anchored at the inline start, so RTL\n // measures from the right edge.\n const rtl =\n this.host.ownerDocument.defaultView?.getComputedStyle(this.host).direction === 'rtl';\n const left = drag.lastX - drag.offsetX;\n const x = rtl\n ? left + ghost.offsetWidth - this.host.ownerDocument.documentElement.clientWidth\n : left;\n ghost.style.setProperty('--vd-kanban-ghost-x', `${x}px`);\n ghost.style.setProperty('--vd-kanban-ghost-y', `${drag.lastY - drag.offsetY}px`);\n }\n this.drop.set(this.target(drag.lastX, drag.lastY));\n const scroller = this.host.querySelector<HTMLElement>('.vd-kanban__columns');\n if (!scroller) return;\n const rect = scroller.getBoundingClientRect();\n drag.scroll = drag.lastX < rect.left + EDGE ? -1 : drag.lastX > rect.right - EDGE ? 1 : 0;\n if (drag.scroll && drag.frame === null) {\n const view = this.host.ownerDocument.defaultView;\n const step = () => {\n if (this.drag !== drag || !drag.scroll || !view) {\n drag.frame = null;\n return;\n }\n scroller.scrollBy({ left: drag.scroll * EDGE_STEP, behavior: 'instant' });\n this.drop.set(this.target(drag.lastX, drag.lastY));\n drag.frame = view.requestAnimationFrame(step);\n };\n drag.frame = view?.requestAnimationFrame(step) ?? null;\n }\n }\n\n /** Column and insertion index under the pointer, with the card that shows the marker. */\n private target(x: number, y: number): Drop | null {\n const drag = this.drag;\n if (!drag) return null;\n const sections = Array.from(\n this.host.querySelectorAll<HTMLElement>('.vd-kanban__column[data-column-id]'),\n );\n const index = vdKanbanColumnAt(\n x,\n sections.map((s) => s.getBoundingClientRect()),\n );\n if (index < 0) return null;\n const section = sections[index];\n const rect = section.getBoundingClientRect();\n if (y < rect.top || y > rect.bottom) return null;\n const others = Array.from(\n section.querySelectorAll<HTMLElement>('.vd-kanban__card[data-card-id]'),\n ).filter((el) => el.dataset['cardId'] !== drag.cardId);\n const at = vdKanbanInsertIndex(\n y,\n others.map((el) => el.getBoundingClientRect()),\n );\n const columnId = section.dataset['columnId']!;\n const from = vdKanbanFind(this.columns(), drag.cardId);\n if (from && from.columnId === columnId && from.index === at) return null;\n const marker = others[at] ?? others[others.length - 1] ?? null;\n return {\n columnId,\n index: at,\n cardId: marker?.dataset['cardId'] ?? null,\n edge: marker ? (others[at] ? 'before' : 'after') : null,\n };\n }\n\n private finish(announce: boolean): void {\n const drag = this.drag;\n this.drag = null;\n this.draggingId.set(null);\n this.drop.set(null);\n if (!drag) return;\n if (drag.timer !== null) clearTimeout(drag.timer);\n if (drag.frame !== null) this.host.ownerDocument.defaultView?.cancelAnimationFrame(drag.frame);\n drag.ghost?.remove();\n if (drag.element.hasPointerCapture?.(drag.pointer))\n drag.element.releasePointerCapture(drag.pointer);\n if (announce && drag.active) this.announce(this.t().canceledText(drag.label));\n }\n\n private announce(text: string): void {\n this.messages.set([{ serial: ++this.serial, text }]);\n }\n\n private cardElement(id: string): HTMLElement | null {\n return (\n Array.from(this.host.querySelectorAll<HTMLElement>('.vd-kanban__card[data-card-id]')).find(\n (el) => el.dataset['cardId'] === id,\n ) ?? null\n );\n }\n}\n\nexport const VD_KANBAN = [VdKanban, VdKanbanCard, VdKanbanColumnHeader] as const;\n"],"mappings":"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"}
|
|
@@ -122,6 +122,22 @@ const vdLocaleEn = {
|
|
|
122
122
|
title: "Check the form",
|
|
123
123
|
description: "Correct the following fields before continuing."
|
|
124
124
|
},
|
|
125
|
+
kanban: {
|
|
126
|
+
label: "Board",
|
|
127
|
+
instructions: "Each card has a Move menu to change its position or column. With a mouse, drag a card; Escape cancels dragging.",
|
|
128
|
+
emptyText: "No cards",
|
|
129
|
+
invalidText: "This board cannot be shown.",
|
|
130
|
+
countText: (count) => vdPlural("en", count, {
|
|
131
|
+
one: "# card",
|
|
132
|
+
other: "# cards"
|
|
133
|
+
}),
|
|
134
|
+
moveLabel: (card) => `Move ${card}`,
|
|
135
|
+
upText: "Move up",
|
|
136
|
+
downText: "Move down",
|
|
137
|
+
moveToText: "Move to",
|
|
138
|
+
movedText: (card, column, position, total) => `${card} moved to ${column}. Position ${position} of ${total}.`,
|
|
139
|
+
canceledText: (card) => `Move canceled: ${card}.`
|
|
140
|
+
},
|
|
125
141
|
kbd: { thenLabel: "then" },
|
|
126
142
|
navigationList: { label: "Navigation" },
|
|
127
143
|
numberInput: {
|
|
@@ -158,6 +174,27 @@ const vdLocaleEn = {
|
|
|
158
174
|
movedText: (label, position, total) => `${label}. Position ${position} of ${total}.`,
|
|
159
175
|
canceledText: (label) => `Reordering canceled: ${label}.`
|
|
160
176
|
},
|
|
177
|
+
schedule: {
|
|
178
|
+
label: "Schedule",
|
|
179
|
+
todayText: "Today",
|
|
180
|
+
previousLabel: "Previous period",
|
|
181
|
+
nextLabel: "Next period",
|
|
182
|
+
viewLabel: "View",
|
|
183
|
+
monthText: "Month",
|
|
184
|
+
weekText: "Week",
|
|
185
|
+
dayText: "Day",
|
|
186
|
+
agendaText: "Agenda",
|
|
187
|
+
allDayText: "All day",
|
|
188
|
+
emptyText: "No events in this period",
|
|
189
|
+
invalidText: "These events cannot be shown.",
|
|
190
|
+
moreText: (count) => `+${count} more`,
|
|
191
|
+
eventsText: (count) => vdPlural("en", count, {
|
|
192
|
+
one: "# event",
|
|
193
|
+
other: "# events"
|
|
194
|
+
}),
|
|
195
|
+
changedText: (title, when) => `${title} moved to ${when}.`,
|
|
196
|
+
canceledText: (title) => `Change canceled: ${title}.`
|
|
197
|
+
},
|
|
161
198
|
searchInput: {
|
|
162
199
|
clearLabel: "Clear search",
|
|
163
200
|
loadingLabel: "Searching"
|
|
@@ -331,6 +368,24 @@ const vdLocaleUk = {
|
|
|
331
368
|
title: "Перевірте форму",
|
|
332
369
|
description: "Виправте ці поля, перш ніж продовжити."
|
|
333
370
|
},
|
|
371
|
+
kanban: {
|
|
372
|
+
label: "Дошка",
|
|
373
|
+
instructions: "Кожна картка має меню «Перемістити» для зміни позиції або колонки. Мишею перетягніть картку; Escape скасовує перетягування.",
|
|
374
|
+
emptyText: "Немає карток",
|
|
375
|
+
invalidText: "Не вдалося показати дошку.",
|
|
376
|
+
countText: (count) => vdPlural("uk", count, {
|
|
377
|
+
one: "# картка",
|
|
378
|
+
few: "# картки",
|
|
379
|
+
many: "# карток",
|
|
380
|
+
other: "# картки"
|
|
381
|
+
}),
|
|
382
|
+
moveLabel: (card) => `Перемістити ${card}`,
|
|
383
|
+
upText: "Вище",
|
|
384
|
+
downText: "Нижче",
|
|
385
|
+
moveToText: "Перемістити в",
|
|
386
|
+
movedText: (card, column, position, total) => `${card} переміщено в «${column}». Позиція ${position} з ${total}.`,
|
|
387
|
+
canceledText: (card) => `Переміщення скасовано: ${card}.`
|
|
388
|
+
},
|
|
334
389
|
kbd: { thenLabel: "потім" },
|
|
335
390
|
navigationList: { label: "Навігація" },
|
|
336
391
|
numberInput: {
|
|
@@ -368,6 +423,29 @@ const vdLocaleUk = {
|
|
|
368
423
|
movedText: (label, position, total) => `${label}. Позиція ${position} з ${total}.`,
|
|
369
424
|
canceledText: (label) => `Переміщення скасовано: ${label}.`
|
|
370
425
|
},
|
|
426
|
+
schedule: {
|
|
427
|
+
label: "Розклад",
|
|
428
|
+
todayText: "Сьогодні",
|
|
429
|
+
previousLabel: "Попередній період",
|
|
430
|
+
nextLabel: "Наступний період",
|
|
431
|
+
viewLabel: "Вигляд",
|
|
432
|
+
monthText: "Місяць",
|
|
433
|
+
weekText: "Тиждень",
|
|
434
|
+
dayText: "День",
|
|
435
|
+
agendaText: "Список",
|
|
436
|
+
allDayText: "Весь день",
|
|
437
|
+
emptyText: "Немає подій у цьому періоді",
|
|
438
|
+
invalidText: "Не вдалося показати ці події.",
|
|
439
|
+
moreText: (count) => `ще ${count}`,
|
|
440
|
+
eventsText: (count) => vdPlural("uk", count, {
|
|
441
|
+
one: "# подія",
|
|
442
|
+
few: "# події",
|
|
443
|
+
many: "# подій",
|
|
444
|
+
other: "# події"
|
|
445
|
+
}),
|
|
446
|
+
changedText: (title, when) => `${title}: перенесено на ${when}.`,
|
|
447
|
+
canceledText: (title) => `Зміну скасовано: ${title}.`
|
|
448
|
+
},
|
|
371
449
|
searchInput: {
|
|
372
450
|
clearLabel: "Очистити пошук",
|
|
373
451
|
loadingLabel: "Пошук"
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vadem-ui-locale.mjs","names":[],"sources":["../../../projects/ui/locale/src/core/locale.ts","../../../projects/ui/locale/src/locale.ts"],"sourcesContent":["/**\n * Default user-facing strings of every component, grouped by component. Framework-agnostic:\n * adapters provide one of these objects; a component input always overrides its entry.\n */\n\nexport interface VdLocale {\n /** BCP 47 language tag, also used for plural rules. */\n code: string;\n activeFilters: {\n label: string;\n clearText: string;\n emptyText: string;\n invalidText: string;\n removeLabel: (label: string, value: string) => string;\n };\n alert: { dismissLabel: string };\n alertDialog: {\n confirmLabel: string;\n cancelLabel: string;\n pendingText: string;\n errorText: string;\n };\n autocomplete: {\n label: string;\n loadingText: string;\n emptyText: string;\n resultsText: (count: number) => string;\n };\n breadcrumbs: { label: string };\n calendar: { previousLabel: string; nextLabel: string };\n characterCount: {\n countText: (used: number, limit: number | null) => string;\n remainingText: (remaining: number) => string;\n overText: (excess: number) => string;\n limitText: string;\n };\n chart: {\n tableLabel: string;\n categoryLabel: string;\n /** Spoken summary of a sparkline: values arrive already formatted. */\n trendSummary: (first: string, last: string, min: string, max: string) => string;\n };\n datePicker: { openLabel: string; dialogLabel: string; previousLabel: string; nextLabel: string };\n colorPicker: {\n placeholder: string;\n pickerLabel: string;\n hexLabel: string;\n paletteLabel: string;\n applyLabel: string;\n errorLabel: string;\n };\n command: { label: string; placeholder: string; emptyText: string; loadingText: string };\n contextMenu: { label: string };\n copyButton: {\n label: string;\n copyingLabel: string;\n copiedLabel: string;\n errorLabel: string;\n errorMessage: string;\n };\n dateRangePicker: {\n groupLabel: string;\n startLabel: string;\n endLabel: string;\n openLabel: string;\n pickerLabel: string;\n previousLabel: string;\n nextLabel: string;\n startInstruction: string;\n endInstruction: string;\n errorLabel: string;\n };\n editableText: {\n emptyText: string;\n editLabel: (label: string, value: string) => string;\n saveLabel: string;\n cancelLabel: string;\n savingText: string;\n savedText: string;\n saveErrorText: string;\n requiredText: string;\n tooLongText: (limit: number) => string;\n };\n fileSize: { unknownText: string };\n filePreview: {\n title: string;\n closeLabel: string;\n downloadLabel: string;\n loadingText: string;\n errorText: string;\n emptyText: string;\n unsupportedText: string;\n pdfText: string;\n };\n expandableText: { expandLabel: string; collapseLabel: string };\n formErrorSummary: { title: string; description: string };\n kbd: { thenLabel: string };\n navigationList: { label: string };\n numberInput: { decreaseLabel: string; increaseLabel: string };\n pagination: {\n label: string;\n previousLabel: string;\n nextLabel: string;\n pageLabel: (page: number) => string;\n };\n passwordInput: { revealLabel: string };\n progressRing: { label: string };\n rangeSlider: { lowerLabel: string; upperLabel: string };\n rating: { starLabel: (value: number) => string };\n relativeTime: { justNowText: string; unknownText: string };\n reorderList: {\n label: string;\n instructions: string;\n upText: string;\n downText: string;\n emptyText: string;\n invalidText: string;\n movedText: (label: string, position: number, total: number) => string;\n canceledText: (label: string) => string;\n };\n searchInput: { clearLabel: string; loadingLabel: string };\n select: { emptyText: string };\n multiSelect: {\n removeLabel: (label: string) => string;\n selectionLabel: (count: number) => string;\n };\n sidebar: { label: string; closeLabel: string };\n stat: { increaseLabel: string; decreaseLabel: string; unchangedLabel: string };\n stepper: { label: string; completedLabel: string; errorLabel: string };\n tagInput: {\n addLabel: string;\n tagsLabel: string;\n removeLabel: (tag: string) => string;\n addedMessage: (tag: string) => string;\n removedMessage: (tag: string) => string;\n duplicateMessage: (tag: string) => string;\n };\n timeInput: { pickerLabel: string; hoursLabel: string; minutesLabel: string; emptyLabel: string };\n timeline: { label: string };\n toast: { label: string; closeLabel: string };\n toolbar: { label: string };\n tree: { label: string };\n uploadList: { label: string };\n}\n\n/** Picks a plural form with the platform's CLDR rules (\"one\", \"few\", \"many\", \"other\"...). */\nexport function vdPlural(\n code: string,\n count: number,\n forms: Partial<Record<Intl.LDMLPluralRule, string>> & { other: string },\n): string {\n const rule = new Intl.PluralRules(code).select(count);\n return (forms[rule] ?? forms.other).replace('#', String(count));\n}\n\nexport const vdLocaleEn: VdLocale = {\n code: 'en',\n activeFilters: {\n label: 'Active filters',\n clearText: 'Clear all',\n emptyText: 'No filters applied.',\n invalidText: 'These filters could not be displayed.',\n removeLabel: (label, value) => `Remove ${label}: ${value}`,\n },\n alert: { dismissLabel: 'Dismiss' },\n alertDialog: {\n confirmLabel: 'Confirm',\n cancelLabel: 'Cancel',\n pendingText: 'Working… Please wait.',\n errorText: 'The action could not be completed. Try again or cancel.',\n },\n autocomplete: {\n label: 'Suggestions',\n loadingText: 'Loading suggestions…',\n emptyText: 'No suggestions. You can enter your own text.',\n resultsText: (count) =>\n vdPlural('en', count, {\n one: '# suggestion available.',\n other: '# suggestions available.',\n }),\n },\n breadcrumbs: { label: 'Breadcrumb' },\n calendar: { previousLabel: 'Previous month', nextLabel: 'Next month' },\n characterCount: {\n countText: (used, limit) =>\n limit === null\n ? vdPlural('en', used, { one: `${used} character`, other: `${used} characters` })\n : `${used} / ${limit}`,\n remainingText: (count) =>\n vdPlural('en', count, {\n one: `${count} character remaining.`,\n other: `${count} characters remaining.`,\n }),\n overText: (count) =>\n vdPlural('en', count, {\n one: `${count} character over the limit.`,\n other: `${count} characters over the limit.`,\n }),\n limitText: 'Character limit reached.',\n },\n chart: {\n tableLabel: 'Data table',\n categoryLabel: 'Category',\n trendSummary: (first, last, min, max) => `from ${first} to ${last}, low ${min}, high ${max}`,\n },\n datePicker: {\n openLabel: 'Choose date',\n dialogLabel: 'Choose date',\n previousLabel: 'Previous month',\n nextLabel: 'Next month',\n },\n colorPicker: {\n placeholder: 'Choose color',\n pickerLabel: 'Choose color',\n hexLabel: 'HEX color',\n paletteLabel: 'Palette',\n applyLabel: 'Apply color',\n errorLabel: 'Enter a HEX color, such as #6D4BD3',\n },\n contextMenu: { label: 'Actions' },\n command: {\n label: 'Search commands',\n placeholder: 'Search commands…',\n emptyText: 'No commands found',\n loadingText: 'Loading commands…',\n },\n copyButton: {\n label: 'Copy',\n copyingLabel: 'Copying…',\n copiedLabel: 'Copied',\n errorLabel: 'Try again',\n errorMessage: 'Could not copy. Select the text and copy it manually.',\n },\n dateRangePicker: {\n groupLabel: 'Date range',\n startLabel: 'Start date',\n endLabel: 'End date',\n openLabel: 'Choose date range',\n pickerLabel: 'Choose date range',\n previousLabel: 'Previous month',\n nextLabel: 'Next month',\n startInstruction: 'Choose the start date',\n endInstruction: 'Choose the end date',\n errorLabel: 'Enter a valid range, with the end on or after the start',\n },\n editableText: {\n emptyText: 'Add a value',\n editLabel: (label, value) => `Edit ${label}: ${value}`,\n saveLabel: 'Save',\n cancelLabel: 'Cancel',\n savingText: 'Saving…',\n savedText: 'Saved.',\n saveErrorText: 'Could not save. Your text is kept; try again.',\n requiredText: 'Enter a value.',\n tooLongText: (limit) => `Use at most ${limit} characters.`,\n },\n fileSize: { unknownText: 'Unknown size' },\n filePreview: {\n title: 'File preview',\n closeLabel: 'Close',\n downloadLabel: 'Download',\n loadingText: 'Loading preview…',\n errorText: 'The image could not be displayed. Download the file to open it.',\n emptyText: 'Choose a file to preview.',\n unsupportedText: 'Preview is not available for this file type. Download it to open it.',\n pdfText:\n 'PDF preview depends on your browser. If it is unavailable, download the file to open it.',\n },\n expandableText: { expandLabel: 'Show more', collapseLabel: 'Show less' },\n formErrorSummary: {\n title: 'Check the form',\n description: 'Correct the following fields before continuing.',\n },\n kbd: { thenLabel: 'then' },\n navigationList: { label: 'Navigation' },\n numberInput: { decreaseLabel: 'Decrease value', increaseLabel: 'Increase value' },\n pagination: {\n label: 'Pagination',\n previousLabel: 'Previous page',\n nextLabel: 'Next page',\n pageLabel: (page) => `Page ${page}`,\n },\n passwordInput: { revealLabel: 'Show password' },\n progressRing: { label: 'Loading' },\n rangeSlider: { lowerLabel: 'Minimum', upperLabel: 'Maximum' },\n rating: {\n starLabel: (value) =>\n vdPlural('en', value, { one: '# out of 5 stars', other: '# out of 5 stars' }),\n },\n relativeTime: { justNowText: 'Just now', unknownText: 'Unknown time' },\n reorderList: {\n label: 'Item order',\n instructions:\n 'Move items with Up and Down buttons or drag the handle. Escape cancels dragging.',\n upText: 'Up',\n downText: 'Down',\n emptyText: 'There are no items to reorder.',\n invalidText: 'This list cannot be reordered.',\n movedText: (label, position, total) => `${label}. Position ${position} of ${total}.`,\n canceledText: (label) => `Reordering canceled: ${label}.`,\n },\n searchInput: { clearLabel: 'Clear search', loadingLabel: 'Searching' },\n select: { emptyText: 'No options' },\n multiSelect: {\n removeLabel: (label) => `Remove ${label}`,\n selectionLabel: (count) => `${count} selected`,\n },\n sidebar: { label: 'Navigation', closeLabel: 'Close' },\n stat: { increaseLabel: 'Increase', decreaseLabel: 'Decrease', unchangedLabel: 'No change' },\n stepper: { label: 'Steps', completedLabel: 'Completed', errorLabel: 'Needs attention' },\n tagInput: {\n addLabel: 'Add tag',\n tagsLabel: 'Tags',\n removeLabel: (tag) => `Remove ${tag}`,\n addedMessage: (tag) => `Added ${tag}.`,\n removedMessage: (tag) => `Removed ${tag}.`,\n duplicateMessage: (tag) => `${tag} is already added.`,\n },\n timeInput: {\n pickerLabel: 'Choose time',\n hoursLabel: 'Hours',\n minutesLabel: 'Minutes',\n emptyLabel: 'No available times',\n },\n timeline: { label: 'Activity timeline' },\n toast: { label: 'Notifications', closeLabel: 'Close' },\n toolbar: { label: 'Toolbar' },\n tree: { label: 'Tree' },\n uploadList: { label: 'Uploads' },\n};\n\nexport const vdLocaleUk: VdLocale = {\n code: 'uk',\n activeFilters: {\n label: 'Застосовані фільтри',\n clearText: 'Очистити всі',\n emptyText: 'Фільтри не застосовано.',\n invalidText: 'Не вдалося показати ці фільтри.',\n removeLabel: (label, value) => `Прибрати фільтр ${label}: ${value}`,\n },\n alert: { dismissLabel: 'Закрити повідомлення' },\n alertDialog: {\n confirmLabel: 'Підтвердити',\n cancelLabel: 'Скасувати',\n pendingText: 'Виконуємо дію… Зачекайте.',\n errorText: 'Не вдалося виконати дію. Спробуйте ще раз або скасуйте.',\n },\n autocomplete: {\n label: 'Підказки',\n loadingText: 'Завантаження підказок…',\n emptyText: 'Підказок немає. Можна ввести власний текст.',\n resultsText: (count) =>\n vdPlural('uk', count, {\n one: 'Доступна # підказка.',\n few: 'Доступні # підказки.',\n other: 'Доступно # підказок.',\n }),\n },\n breadcrumbs: { label: 'Навігаційний ланцюжок' },\n calendar: { previousLabel: 'Попередній місяць', nextLabel: 'Наступний місяць' },\n characterCount: {\n countText: (used, limit) =>\n limit === null\n ? vdPlural('uk', used, {\n one: `${used} символ`,\n few: `${used} символи`,\n many: `${used} символів`,\n other: `${used} символу`,\n })\n : `${used} / ${limit}`,\n remainingText: (count) =>\n `Залишилось ${vdPlural('uk', count, { one: `${count} символ`, few: `${count} символи`, many: `${count} символів`, other: `${count} символу` })}.`,\n overText: (count) =>\n `Перевищення на ${vdPlural('uk', count, { one: `${count} символ`, few: `${count} символи`, many: `${count} символів`, other: `${count} символу` })}.`,\n limitText: 'Ліміт символів досягнуто.',\n },\n chart: {\n tableLabel: 'Таблиця даних',\n categoryLabel: 'Категорія',\n trendSummary: (first, last, min, max) =>\n `від ${first} до ${last}, мінімум ${min}, максимум ${max}`,\n },\n datePicker: {\n openLabel: 'Обрати дату',\n dialogLabel: 'Обрати дату',\n previousLabel: 'Попередній місяць',\n nextLabel: 'Наступний місяць',\n },\n colorPicker: {\n placeholder: 'Оберіть колір',\n pickerLabel: 'Обрати колір',\n hexLabel: 'Колір HEX',\n paletteLabel: 'Палітра',\n applyLabel: 'Застосувати колір',\n errorLabel: 'Введіть колір у форматі HEX, наприклад #6D4BD3',\n },\n contextMenu: { label: 'Дії' },\n command: {\n label: 'Пошук команд',\n placeholder: 'Пошук команд…',\n emptyText: 'Команд не знайдено',\n loadingText: 'Завантаження команд…',\n },\n copyButton: {\n label: 'Копіювати',\n copyingLabel: 'Копіювання…',\n copiedLabel: 'Скопійовано',\n errorLabel: 'Спробувати ще раз',\n errorMessage: 'Не вдалося скопіювати. Виділіть текст і скопіюйте вручну.',\n },\n dateRangePicker: {\n groupLabel: 'Діапазон дат',\n startLabel: 'Дата початку',\n endLabel: 'Дата завершення',\n openLabel: 'Обрати діапазон дат',\n pickerLabel: 'Обрати діапазон дат',\n previousLabel: 'Попередній місяць',\n nextLabel: 'Наступний місяць',\n startInstruction: 'Оберіть дату початку',\n endInstruction: 'Оберіть дату завершення',\n errorLabel: 'Введіть коректний діапазон: кінець не раніше за початок',\n },\n editableText: {\n emptyText: 'Додати значення',\n editLabel: (label, value) => `Редагувати ${label}: ${value}`,\n saveLabel: 'Зберегти',\n cancelLabel: 'Скасувати',\n savingText: 'Зберігаємо…',\n savedText: 'Збережено.',\n saveErrorText: 'Не вдалося зберегти. Текст збережено в полі; спробуйте ще раз.',\n requiredText: 'Введіть значення.',\n tooLongText: (limit) => `Використайте не більше ${limit} символів.`,\n },\n fileSize: { unknownText: 'Розмір невідомий' },\n filePreview: {\n title: 'Перегляд файлу',\n closeLabel: 'Закрити',\n downloadLabel: 'Завантажити',\n loadingText: 'Завантажуємо перегляд…',\n errorText: 'Не вдалося показати зображення. Завантажте файл, щоб відкрити його.',\n emptyText: 'Виберіть файл для перегляду.',\n unsupportedText: 'Перегляд цього типу файлів недоступний. Завантажте файл, щоб відкрити його.',\n pdfText:\n 'Перегляд PDF залежить від браузера. Якщо документ не відображається, завантажте файл.',\n },\n expandableText: { expandLabel: 'Показати більше', collapseLabel: 'Згорнути' },\n formErrorSummary: {\n title: 'Перевірте форму',\n description: 'Виправте ці поля, перш ніж продовжити.',\n },\n kbd: { thenLabel: 'потім' },\n navigationList: { label: 'Навігація' },\n numberInput: { decreaseLabel: 'Зменшити значення', increaseLabel: 'Збільшити значення' },\n pagination: {\n label: 'Сторінки',\n previousLabel: 'Попередня сторінка',\n nextLabel: 'Наступна сторінка',\n pageLabel: (page) => `Сторінка ${page}`,\n },\n passwordInput: { revealLabel: 'Показати пароль' },\n progressRing: { label: 'Завантаження' },\n rangeSlider: { lowerLabel: 'Мінімум', upperLabel: 'Максимум' },\n rating: {\n starLabel: (value) =>\n vdPlural('uk', value, {\n one: '# зірка з 5',\n few: '# зірки з 5',\n other: '# зірок з 5',\n }),\n },\n relativeTime: { justNowText: 'Щойно', unknownText: 'Час невідомий' },\n reorderList: {\n label: 'Порядок елементів',\n instructions:\n 'Змінюйте порядок кнопками «Вище» та «Нижче» або перетягніть за маркер. Escape скасовує перетягування.',\n upText: 'Вище',\n downText: 'Нижче',\n emptyText: 'Немає елементів для впорядкування.',\n invalidText: 'Не вдалося впорядкувати цей список.',\n movedText: (label, position, total) => `${label}. Позиція ${position} з ${total}.`,\n canceledText: (label) => `Переміщення скасовано: ${label}.`,\n },\n searchInput: { clearLabel: 'Очистити пошук', loadingLabel: 'Пошук' },\n select: { emptyText: 'Немає варіантів' },\n multiSelect: {\n removeLabel: (label) => `Вилучити ${label}`,\n selectionLabel: (count) => `Обрано: ${count}`,\n },\n sidebar: { label: 'Навігація', closeLabel: 'Закрити' },\n stat: { increaseLabel: 'Зростання', decreaseLabel: 'Падіння', unchangedLabel: 'Без змін' },\n stepper: { label: 'Кроки', completedLabel: 'Завершено', errorLabel: 'Потребує уваги' },\n tagInput: {\n addLabel: 'Додати тег',\n tagsLabel: 'Теги',\n removeLabel: (tag) => `Вилучити ${tag}`,\n addedMessage: (tag) => `Додано ${tag}.`,\n removedMessage: (tag) => `Вилучено ${tag}.`,\n duplicateMessage: (tag) => `${tag} вже додано.`,\n },\n timeInput: {\n pickerLabel: 'Обрати час',\n hoursLabel: 'Години',\n minutesLabel: 'Хвилини',\n emptyLabel: 'Немає доступного часу',\n },\n timeline: { label: 'Хронологія подій' },\n toast: { label: 'Сповіщення', closeLabel: 'Закрити' },\n toolbar: { label: 'Панель інструментів' },\n tree: { label: 'Дерево' },\n uploadList: { label: 'Завантаження' },\n};\n","import {\n type EnvironmentProviders,\n InjectionToken,\n type Provider,\n type Signal,\n computed,\n inject,\n makeEnvironmentProviders,\n} from '@angular/core';\nimport { type VdLocale, vdLocaleEn } from './core/locale';\n\n/** Active strings for Vadem components. English unless the application provides another. */\nexport const VD_LOCALE = new InjectionToken<VdLocale>('VD_LOCALE', {\n providedIn: 'root',\n factory: () => vdLocaleEn,\n});\n\n/** Application-wide component strings: `provideVdLocale(vdLocaleUk)` in bootstrap providers. */\nexport function provideVdLocale(locale: VdLocale): EnvironmentProviders {\n return makeEnvironmentProviders([{ provide: VD_LOCALE, useValue: locale }]);\n}\n\n/** The same, for one component subtree: `providers: [vdLocaleProvider(vdLocaleUk)]`. */\nexport function vdLocaleProvider(locale: VdLocale): Provider {\n return { provide: VD_LOCALE, useValue: locale };\n}\n\ntype Section = Exclude<keyof VdLocale, 'code'>;\n\n/**\n * Resolves a component's text inputs against the active locale: an input that is set wins,\n * otherwise the locale entry of the same name. Call in a field initializer (injection context).\n */\nexport function vdTexts<S extends Section, K extends keyof VdLocale[S]>(\n section: S,\n inputs: { [P in K]: Signal<VdLocale[S][P] | undefined> },\n): Signal<Pick<VdLocale[S], K>> {\n const locale = inject(VD_LOCALE)[section];\n return computed(() => {\n const resolved = {} as Pick<VdLocale[S], K>;\n for (const key of Object.keys(inputs) as K[]) {\n resolved[key] = inputs[key]() ?? locale[key];\n }\n return resolved;\n });\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"vadem-ui-locale.mjs","names":[],"sources":["../../../projects/ui/locale/src/core/locale.ts","../../../projects/ui/locale/src/locale.ts"],"sourcesContent":["/**\n * Default user-facing strings of every component, grouped by component. Framework-agnostic:\n * adapters provide one of these objects; a component input always overrides its entry.\n */\n\nexport interface VdLocale {\n /** BCP 47 language tag, also used for plural rules. */\n code: string;\n activeFilters: {\n label: string;\n clearText: string;\n emptyText: string;\n invalidText: string;\n removeLabel: (label: string, value: string) => string;\n };\n alert: { dismissLabel: string };\n alertDialog: {\n confirmLabel: string;\n cancelLabel: string;\n pendingText: string;\n errorText: string;\n };\n autocomplete: {\n label: string;\n loadingText: string;\n emptyText: string;\n resultsText: (count: number) => string;\n };\n breadcrumbs: { label: string };\n calendar: { previousLabel: string; nextLabel: string };\n characterCount: {\n countText: (used: number, limit: number | null) => string;\n remainingText: (remaining: number) => string;\n overText: (excess: number) => string;\n limitText: string;\n };\n chart: {\n tableLabel: string;\n categoryLabel: string;\n /** Spoken summary of a sparkline: values arrive already formatted. */\n trendSummary: (first: string, last: string, min: string, max: string) => string;\n };\n datePicker: { openLabel: string; dialogLabel: string; previousLabel: string; nextLabel: string };\n colorPicker: {\n placeholder: string;\n pickerLabel: string;\n hexLabel: string;\n paletteLabel: string;\n applyLabel: string;\n errorLabel: string;\n };\n command: { label: string; placeholder: string; emptyText: string; loadingText: string };\n contextMenu: { label: string };\n copyButton: {\n label: string;\n copyingLabel: string;\n copiedLabel: string;\n errorLabel: string;\n errorMessage: string;\n };\n dateRangePicker: {\n groupLabel: string;\n startLabel: string;\n endLabel: string;\n openLabel: string;\n pickerLabel: string;\n previousLabel: string;\n nextLabel: string;\n startInstruction: string;\n endInstruction: string;\n errorLabel: string;\n };\n editableText: {\n emptyText: string;\n editLabel: (label: string, value: string) => string;\n saveLabel: string;\n cancelLabel: string;\n savingText: string;\n savedText: string;\n saveErrorText: string;\n requiredText: string;\n tooLongText: (limit: number) => string;\n };\n fileSize: { unknownText: string };\n filePreview: {\n title: string;\n closeLabel: string;\n downloadLabel: string;\n loadingText: string;\n errorText: string;\n emptyText: string;\n unsupportedText: string;\n pdfText: string;\n };\n expandableText: { expandLabel: string; collapseLabel: string };\n formErrorSummary: { title: string; description: string };\n kanban: {\n label: string;\n instructions: string;\n emptyText: string;\n invalidText: string;\n countText: (count: number) => string;\n moveLabel: (card: string) => string;\n upText: string;\n downText: string;\n moveToText: string;\n movedText: (card: string, column: string, position: number, total: number) => string;\n canceledText: (card: string) => string;\n };\n kbd: { thenLabel: string };\n navigationList: { label: string };\n numberInput: { decreaseLabel: string; increaseLabel: string };\n pagination: {\n label: string;\n previousLabel: string;\n nextLabel: string;\n pageLabel: (page: number) => string;\n };\n passwordInput: { revealLabel: string };\n progressRing: { label: string };\n rangeSlider: { lowerLabel: string; upperLabel: string };\n rating: { starLabel: (value: number) => string };\n relativeTime: { justNowText: string; unknownText: string };\n reorderList: {\n label: string;\n instructions: string;\n upText: string;\n downText: string;\n emptyText: string;\n invalidText: string;\n movedText: (label: string, position: number, total: number) => string;\n canceledText: (label: string) => string;\n };\n schedule: {\n label: string;\n todayText: string;\n previousLabel: string;\n nextLabel: string;\n viewLabel: string;\n monthText: string;\n weekText: string;\n dayText: string;\n agendaText: string;\n allDayText: string;\n emptyText: string;\n invalidText: string;\n moreText: (count: number) => string;\n eventsText: (count: number) => string;\n changedText: (title: string, when: string) => string;\n canceledText: (title: string) => string;\n };\n searchInput: { clearLabel: string; loadingLabel: string };\n select: { emptyText: string };\n multiSelect: {\n removeLabel: (label: string) => string;\n selectionLabel: (count: number) => string;\n };\n sidebar: { label: string; closeLabel: string };\n stat: { increaseLabel: string; decreaseLabel: string; unchangedLabel: string };\n stepper: { label: string; completedLabel: string; errorLabel: string };\n tagInput: {\n addLabel: string;\n tagsLabel: string;\n removeLabel: (tag: string) => string;\n addedMessage: (tag: string) => string;\n removedMessage: (tag: string) => string;\n duplicateMessage: (tag: string) => string;\n };\n timeInput: { pickerLabel: string; hoursLabel: string; minutesLabel: string; emptyLabel: string };\n timeline: { label: string };\n toast: { label: string; closeLabel: string };\n toolbar: { label: string };\n tree: { label: string };\n uploadList: { label: string };\n}\n\n/** Picks a plural form with the platform's CLDR rules (\"one\", \"few\", \"many\", \"other\"...). */\nexport function vdPlural(\n code: string,\n count: number,\n forms: Partial<Record<Intl.LDMLPluralRule, string>> & { other: string },\n): string {\n const rule = new Intl.PluralRules(code).select(count);\n return (forms[rule] ?? forms.other).replace('#', String(count));\n}\n\nexport const vdLocaleEn: VdLocale = {\n code: 'en',\n activeFilters: {\n label: 'Active filters',\n clearText: 'Clear all',\n emptyText: 'No filters applied.',\n invalidText: 'These filters could not be displayed.',\n removeLabel: (label, value) => `Remove ${label}: ${value}`,\n },\n alert: { dismissLabel: 'Dismiss' },\n alertDialog: {\n confirmLabel: 'Confirm',\n cancelLabel: 'Cancel',\n pendingText: 'Working… Please wait.',\n errorText: 'The action could not be completed. Try again or cancel.',\n },\n autocomplete: {\n label: 'Suggestions',\n loadingText: 'Loading suggestions…',\n emptyText: 'No suggestions. You can enter your own text.',\n resultsText: (count) =>\n vdPlural('en', count, {\n one: '# suggestion available.',\n other: '# suggestions available.',\n }),\n },\n breadcrumbs: { label: 'Breadcrumb' },\n calendar: { previousLabel: 'Previous month', nextLabel: 'Next month' },\n characterCount: {\n countText: (used, limit) =>\n limit === null\n ? vdPlural('en', used, { one: `${used} character`, other: `${used} characters` })\n : `${used} / ${limit}`,\n remainingText: (count) =>\n vdPlural('en', count, {\n one: `${count} character remaining.`,\n other: `${count} characters remaining.`,\n }),\n overText: (count) =>\n vdPlural('en', count, {\n one: `${count} character over the limit.`,\n other: `${count} characters over the limit.`,\n }),\n limitText: 'Character limit reached.',\n },\n chart: {\n tableLabel: 'Data table',\n categoryLabel: 'Category',\n trendSummary: (first, last, min, max) => `from ${first} to ${last}, low ${min}, high ${max}`,\n },\n datePicker: {\n openLabel: 'Choose date',\n dialogLabel: 'Choose date',\n previousLabel: 'Previous month',\n nextLabel: 'Next month',\n },\n colorPicker: {\n placeholder: 'Choose color',\n pickerLabel: 'Choose color',\n hexLabel: 'HEX color',\n paletteLabel: 'Palette',\n applyLabel: 'Apply color',\n errorLabel: 'Enter a HEX color, such as #6D4BD3',\n },\n contextMenu: { label: 'Actions' },\n command: {\n label: 'Search commands',\n placeholder: 'Search commands…',\n emptyText: 'No commands found',\n loadingText: 'Loading commands…',\n },\n copyButton: {\n label: 'Copy',\n copyingLabel: 'Copying…',\n copiedLabel: 'Copied',\n errorLabel: 'Try again',\n errorMessage: 'Could not copy. Select the text and copy it manually.',\n },\n dateRangePicker: {\n groupLabel: 'Date range',\n startLabel: 'Start date',\n endLabel: 'End date',\n openLabel: 'Choose date range',\n pickerLabel: 'Choose date range',\n previousLabel: 'Previous month',\n nextLabel: 'Next month',\n startInstruction: 'Choose the start date',\n endInstruction: 'Choose the end date',\n errorLabel: 'Enter a valid range, with the end on or after the start',\n },\n editableText: {\n emptyText: 'Add a value',\n editLabel: (label, value) => `Edit ${label}: ${value}`,\n saveLabel: 'Save',\n cancelLabel: 'Cancel',\n savingText: 'Saving…',\n savedText: 'Saved.',\n saveErrorText: 'Could not save. Your text is kept; try again.',\n requiredText: 'Enter a value.',\n tooLongText: (limit) => `Use at most ${limit} characters.`,\n },\n fileSize: { unknownText: 'Unknown size' },\n filePreview: {\n title: 'File preview',\n closeLabel: 'Close',\n downloadLabel: 'Download',\n loadingText: 'Loading preview…',\n errorText: 'The image could not be displayed. Download the file to open it.',\n emptyText: 'Choose a file to preview.',\n unsupportedText: 'Preview is not available for this file type. Download it to open it.',\n pdfText:\n 'PDF preview depends on your browser. If it is unavailable, download the file to open it.',\n },\n expandableText: { expandLabel: 'Show more', collapseLabel: 'Show less' },\n formErrorSummary: {\n title: 'Check the form',\n description: 'Correct the following fields before continuing.',\n },\n kanban: {\n label: 'Board',\n instructions:\n 'Each card has a Move menu to change its position or column. With a mouse, drag a card; Escape cancels dragging.',\n emptyText: 'No cards',\n invalidText: 'This board cannot be shown.',\n countText: (count) => vdPlural('en', count, { one: '# card', other: '# cards' }),\n moveLabel: (card) => `Move ${card}`,\n upText: 'Move up',\n downText: 'Move down',\n moveToText: 'Move to',\n movedText: (card, column, position, total) =>\n `${card} moved to ${column}. Position ${position} of ${total}.`,\n canceledText: (card) => `Move canceled: ${card}.`,\n },\n kbd: { thenLabel: 'then' },\n navigationList: { label: 'Navigation' },\n numberInput: { decreaseLabel: 'Decrease value', increaseLabel: 'Increase value' },\n pagination: {\n label: 'Pagination',\n previousLabel: 'Previous page',\n nextLabel: 'Next page',\n pageLabel: (page) => `Page ${page}`,\n },\n passwordInput: { revealLabel: 'Show password' },\n progressRing: { label: 'Loading' },\n rangeSlider: { lowerLabel: 'Minimum', upperLabel: 'Maximum' },\n rating: {\n starLabel: (value) =>\n vdPlural('en', value, { one: '# out of 5 stars', other: '# out of 5 stars' }),\n },\n relativeTime: { justNowText: 'Just now', unknownText: 'Unknown time' },\n reorderList: {\n label: 'Item order',\n instructions:\n 'Move items with Up and Down buttons or drag the handle. Escape cancels dragging.',\n upText: 'Up',\n downText: 'Down',\n emptyText: 'There are no items to reorder.',\n invalidText: 'This list cannot be reordered.',\n movedText: (label, position, total) => `${label}. Position ${position} of ${total}.`,\n canceledText: (label) => `Reordering canceled: ${label}.`,\n },\n schedule: {\n label: 'Schedule',\n todayText: 'Today',\n previousLabel: 'Previous period',\n nextLabel: 'Next period',\n viewLabel: 'View',\n monthText: 'Month',\n weekText: 'Week',\n dayText: 'Day',\n agendaText: 'Agenda',\n allDayText: 'All day',\n emptyText: 'No events in this period',\n invalidText: 'These events cannot be shown.',\n moreText: (count) => `+${count} more`,\n eventsText: (count) => vdPlural('en', count, { one: '# event', other: '# events' }),\n changedText: (title, when) => `${title} moved to ${when}.`,\n canceledText: (title) => `Change canceled: ${title}.`,\n },\n searchInput: { clearLabel: 'Clear search', loadingLabel: 'Searching' },\n select: { emptyText: 'No options' },\n multiSelect: {\n removeLabel: (label) => `Remove ${label}`,\n selectionLabel: (count) => `${count} selected`,\n },\n sidebar: { label: 'Navigation', closeLabel: 'Close' },\n stat: { increaseLabel: 'Increase', decreaseLabel: 'Decrease', unchangedLabel: 'No change' },\n stepper: { label: 'Steps', completedLabel: 'Completed', errorLabel: 'Needs attention' },\n tagInput: {\n addLabel: 'Add tag',\n tagsLabel: 'Tags',\n removeLabel: (tag) => `Remove ${tag}`,\n addedMessage: (tag) => `Added ${tag}.`,\n removedMessage: (tag) => `Removed ${tag}.`,\n duplicateMessage: (tag) => `${tag} is already added.`,\n },\n timeInput: {\n pickerLabel: 'Choose time',\n hoursLabel: 'Hours',\n minutesLabel: 'Minutes',\n emptyLabel: 'No available times',\n },\n timeline: { label: 'Activity timeline' },\n toast: { label: 'Notifications', closeLabel: 'Close' },\n toolbar: { label: 'Toolbar' },\n tree: { label: 'Tree' },\n uploadList: { label: 'Uploads' },\n};\n\nexport const vdLocaleUk: VdLocale = {\n code: 'uk',\n activeFilters: {\n label: 'Застосовані фільтри',\n clearText: 'Очистити всі',\n emptyText: 'Фільтри не застосовано.',\n invalidText: 'Не вдалося показати ці фільтри.',\n removeLabel: (label, value) => `Прибрати фільтр ${label}: ${value}`,\n },\n alert: { dismissLabel: 'Закрити повідомлення' },\n alertDialog: {\n confirmLabel: 'Підтвердити',\n cancelLabel: 'Скасувати',\n pendingText: 'Виконуємо дію… Зачекайте.',\n errorText: 'Не вдалося виконати дію. Спробуйте ще раз або скасуйте.',\n },\n autocomplete: {\n label: 'Підказки',\n loadingText: 'Завантаження підказок…',\n emptyText: 'Підказок немає. Можна ввести власний текст.',\n resultsText: (count) =>\n vdPlural('uk', count, {\n one: 'Доступна # підказка.',\n few: 'Доступні # підказки.',\n other: 'Доступно # підказок.',\n }),\n },\n breadcrumbs: { label: 'Навігаційний ланцюжок' },\n calendar: { previousLabel: 'Попередній місяць', nextLabel: 'Наступний місяць' },\n characterCount: {\n countText: (used, limit) =>\n limit === null\n ? vdPlural('uk', used, {\n one: `${used} символ`,\n few: `${used} символи`,\n many: `${used} символів`,\n other: `${used} символу`,\n })\n : `${used} / ${limit}`,\n remainingText: (count) =>\n `Залишилось ${vdPlural('uk', count, { one: `${count} символ`, few: `${count} символи`, many: `${count} символів`, other: `${count} символу` })}.`,\n overText: (count) =>\n `Перевищення на ${vdPlural('uk', count, { one: `${count} символ`, few: `${count} символи`, many: `${count} символів`, other: `${count} символу` })}.`,\n limitText: 'Ліміт символів досягнуто.',\n },\n chart: {\n tableLabel: 'Таблиця даних',\n categoryLabel: 'Категорія',\n trendSummary: (first, last, min, max) =>\n `від ${first} до ${last}, мінімум ${min}, максимум ${max}`,\n },\n datePicker: {\n openLabel: 'Обрати дату',\n dialogLabel: 'Обрати дату',\n previousLabel: 'Попередній місяць',\n nextLabel: 'Наступний місяць',\n },\n colorPicker: {\n placeholder: 'Оберіть колір',\n pickerLabel: 'Обрати колір',\n hexLabel: 'Колір HEX',\n paletteLabel: 'Палітра',\n applyLabel: 'Застосувати колір',\n errorLabel: 'Введіть колір у форматі HEX, наприклад #6D4BD3',\n },\n contextMenu: { label: 'Дії' },\n command: {\n label: 'Пошук команд',\n placeholder: 'Пошук команд…',\n emptyText: 'Команд не знайдено',\n loadingText: 'Завантаження команд…',\n },\n copyButton: {\n label: 'Копіювати',\n copyingLabel: 'Копіювання…',\n copiedLabel: 'Скопійовано',\n errorLabel: 'Спробувати ще раз',\n errorMessage: 'Не вдалося скопіювати. Виділіть текст і скопіюйте вручну.',\n },\n dateRangePicker: {\n groupLabel: 'Діапазон дат',\n startLabel: 'Дата початку',\n endLabel: 'Дата завершення',\n openLabel: 'Обрати діапазон дат',\n pickerLabel: 'Обрати діапазон дат',\n previousLabel: 'Попередній місяць',\n nextLabel: 'Наступний місяць',\n startInstruction: 'Оберіть дату початку',\n endInstruction: 'Оберіть дату завершення',\n errorLabel: 'Введіть коректний діапазон: кінець не раніше за початок',\n },\n editableText: {\n emptyText: 'Додати значення',\n editLabel: (label, value) => `Редагувати ${label}: ${value}`,\n saveLabel: 'Зберегти',\n cancelLabel: 'Скасувати',\n savingText: 'Зберігаємо…',\n savedText: 'Збережено.',\n saveErrorText: 'Не вдалося зберегти. Текст збережено в полі; спробуйте ще раз.',\n requiredText: 'Введіть значення.',\n tooLongText: (limit) => `Використайте не більше ${limit} символів.`,\n },\n fileSize: { unknownText: 'Розмір невідомий' },\n filePreview: {\n title: 'Перегляд файлу',\n closeLabel: 'Закрити',\n downloadLabel: 'Завантажити',\n loadingText: 'Завантажуємо перегляд…',\n errorText: 'Не вдалося показати зображення. Завантажте файл, щоб відкрити його.',\n emptyText: 'Виберіть файл для перегляду.',\n unsupportedText: 'Перегляд цього типу файлів недоступний. Завантажте файл, щоб відкрити його.',\n pdfText:\n 'Перегляд PDF залежить від браузера. Якщо документ не відображається, завантажте файл.',\n },\n expandableText: { expandLabel: 'Показати більше', collapseLabel: 'Згорнути' },\n formErrorSummary: {\n title: 'Перевірте форму',\n description: 'Виправте ці поля, перш ніж продовжити.',\n },\n kanban: {\n label: 'Дошка',\n instructions:\n 'Кожна картка має меню «Перемістити» для зміни позиції або колонки. Мишею перетягніть картку; Escape скасовує перетягування.',\n emptyText: 'Немає карток',\n invalidText: 'Не вдалося показати дошку.',\n countText: (count) =>\n vdPlural('uk', count, {\n one: '# картка',\n few: '# картки',\n many: '# карток',\n other: '# картки',\n }),\n moveLabel: (card) => `Перемістити ${card}`,\n upText: 'Вище',\n downText: 'Нижче',\n moveToText: 'Перемістити в',\n movedText: (card, column, position, total) =>\n `${card} переміщено в «${column}». Позиція ${position} з ${total}.`,\n canceledText: (card) => `Переміщення скасовано: ${card}.`,\n },\n kbd: { thenLabel: 'потім' },\n navigationList: { label: 'Навігація' },\n numberInput: { decreaseLabel: 'Зменшити значення', increaseLabel: 'Збільшити значення' },\n pagination: {\n label: 'Сторінки',\n previousLabel: 'Попередня сторінка',\n nextLabel: 'Наступна сторінка',\n pageLabel: (page) => `Сторінка ${page}`,\n },\n passwordInput: { revealLabel: 'Показати пароль' },\n progressRing: { label: 'Завантаження' },\n rangeSlider: { lowerLabel: 'Мінімум', upperLabel: 'Максимум' },\n rating: {\n starLabel: (value) =>\n vdPlural('uk', value, {\n one: '# зірка з 5',\n few: '# зірки з 5',\n other: '# зірок з 5',\n }),\n },\n relativeTime: { justNowText: 'Щойно', unknownText: 'Час невідомий' },\n reorderList: {\n label: 'Порядок елементів',\n instructions:\n 'Змінюйте порядок кнопками «Вище» та «Нижче» або перетягніть за маркер. Escape скасовує перетягування.',\n upText: 'Вище',\n downText: 'Нижче',\n emptyText: 'Немає елементів для впорядкування.',\n invalidText: 'Не вдалося впорядкувати цей список.',\n movedText: (label, position, total) => `${label}. Позиція ${position} з ${total}.`,\n canceledText: (label) => `Переміщення скасовано: ${label}.`,\n },\n schedule: {\n label: 'Розклад',\n todayText: 'Сьогодні',\n previousLabel: 'Попередній період',\n nextLabel: 'Наступний період',\n viewLabel: 'Вигляд',\n monthText: 'Місяць',\n weekText: 'Тиждень',\n dayText: 'День',\n agendaText: 'Список',\n allDayText: 'Весь день',\n emptyText: 'Немає подій у цьому періоді',\n invalidText: 'Не вдалося показати ці події.',\n moreText: (count) => `ще ${count}`,\n eventsText: (count) =>\n vdPlural('uk', count, { one: '# подія', few: '# події', many: '# подій', other: '# події' }),\n changedText: (title, when) => `${title}: перенесено на ${when}.`,\n canceledText: (title) => `Зміну скасовано: ${title}.`,\n },\n searchInput: { clearLabel: 'Очистити пошук', loadingLabel: 'Пошук' },\n select: { emptyText: 'Немає варіантів' },\n multiSelect: {\n removeLabel: (label) => `Вилучити ${label}`,\n selectionLabel: (count) => `Обрано: ${count}`,\n },\n sidebar: { label: 'Навігація', closeLabel: 'Закрити' },\n stat: { increaseLabel: 'Зростання', decreaseLabel: 'Падіння', unchangedLabel: 'Без змін' },\n stepper: { label: 'Кроки', completedLabel: 'Завершено', errorLabel: 'Потребує уваги' },\n tagInput: {\n addLabel: 'Додати тег',\n tagsLabel: 'Теги',\n removeLabel: (tag) => `Вилучити ${tag}`,\n addedMessage: (tag) => `Додано ${tag}.`,\n removedMessage: (tag) => `Вилучено ${tag}.`,\n duplicateMessage: (tag) => `${tag} вже додано.`,\n },\n timeInput: {\n pickerLabel: 'Обрати час',\n hoursLabel: 'Години',\n minutesLabel: 'Хвилини',\n emptyLabel: 'Немає доступного часу',\n },\n timeline: { label: 'Хронологія подій' },\n toast: { label: 'Сповіщення', closeLabel: 'Закрити' },\n toolbar: { label: 'Панель інструментів' },\n tree: { label: 'Дерево' },\n uploadList: { label: 'Завантаження' },\n};\n","import {\n type EnvironmentProviders,\n InjectionToken,\n type Provider,\n type Signal,\n computed,\n inject,\n makeEnvironmentProviders,\n} from '@angular/core';\nimport { type VdLocale, vdLocaleEn } from './core/locale';\n\n/** Active strings for Vadem components. English unless the application provides another. */\nexport const VD_LOCALE = new InjectionToken<VdLocale>('VD_LOCALE', {\n providedIn: 'root',\n factory: () => vdLocaleEn,\n});\n\n/** Application-wide component strings: `provideVdLocale(vdLocaleUk)` in bootstrap providers. */\nexport function provideVdLocale(locale: VdLocale): EnvironmentProviders {\n return makeEnvironmentProviders([{ provide: VD_LOCALE, useValue: locale }]);\n}\n\n/** The same, for one component subtree: `providers: [vdLocaleProvider(vdLocaleUk)]`. */\nexport function vdLocaleProvider(locale: VdLocale): Provider {\n return { provide: VD_LOCALE, useValue: locale };\n}\n\ntype Section = Exclude<keyof VdLocale, 'code'>;\n\n/**\n * Resolves a component's text inputs against the active locale: an input that is set wins,\n * otherwise the locale entry of the same name. Call in a field initializer (injection context).\n */\nexport function vdTexts<S extends Section, K extends keyof VdLocale[S]>(\n section: S,\n inputs: { [P in K]: Signal<VdLocale[S][P] | undefined> },\n): Signal<Pick<VdLocale[S], K>> {\n const locale = inject(VD_LOCALE)[section];\n return computed(() => {\n const resolved = {} as Pick<VdLocale[S], K>;\n for (const key of Object.keys(inputs) as K[]) {\n resolved[key] = inputs[key]() ?? locale[key];\n }\n return resolved;\n });\n}\n"],"mappings":";AAiLA,SAAgB,SACd,MACA,OACA,OAAuE;CAGvE,QAAQ,MADK,IAAI,KAAK,YAAY,IAAI,CAAC,CAAC,OAAO,KACjC,MAAS,MAAM,MAAA,CAAO,QAAQ,KAAK,OAAO,KAAK,CAAC;AAChE;AAEA,MAAa,aAAuB;CAClC,MAAM;CACN,eAAe;EACb,OAAO;EACP,WAAW;EACX,WAAW;EACX,aAAa;EACb,cAAc,OAAO,UAAU,UAAU,MAAK,IAAK;CACpD;CACD,OAAO,EAAE,cAAc,UAAS;CAChC,aAAa;EACX,cAAc;EACd,aAAa;EACb,aAAa;EACb,WAAW;CACZ;CACD,cAAc;EACZ,OAAO;EACP,aAAa;EACb,WAAW;EACX,cAAc,UACZ,SAAS,MAAM,OAAO;GACpB,KAAK;GACL,OAAO;EACR,CAAA;CACJ;CACD,aAAa,EAAE,OAAO,aAAY;CAClC,UAAU;EAAE,eAAe;EAAkB,WAAW;CAAY;CACpE,gBAAgB;EACd,YAAY,MAAM,UAChB,UAAU,OACN,SAAS,MAAM,MAAM;GAAE,KAAK,GAAG,KAAI;GAAc,OAAO,GAAG,KAAI;EAAa,CAAE,IAC9E,GAAG,KAAI,KAAM;EACnB,gBAAgB,UACd,SAAS,MAAM,OAAO;GACpB,KAAK,GAAG,MAAK;GACb,OAAO,GAAG,MAAK;EAChB,CAAA;EACH,WAAW,UACT,SAAS,MAAM,OAAO;GACpB,KAAK,GAAG,MAAK;GACb,OAAO,GAAG,MAAK;EAChB,CAAA;EACH,WAAW;CACZ;CACD,OAAO;EACL,YAAY;EACZ,eAAe;EACf,eAAe,OAAO,MAAM,KAAK,QAAQ,QAAQ,MAAK,MAAO,KAAI,QAAS,IAAG,SAAU;CACxF;CACD,YAAY;EACV,WAAW;EACX,aAAa;EACb,eAAe;EACf,WAAW;CACZ;CACD,aAAa;EACX,aAAa;EACb,aAAa;EACb,UAAU;EACV,cAAc;EACd,YAAY;EACZ,YAAY;CACb;CACD,aAAa,EAAE,OAAO,UAAS;CAC/B,SAAS;EACP,OAAO;EACP,aAAa;EACb,WAAW;EACX,aAAa;CACd;CACD,YAAY;EACV,OAAO;EACP,cAAc;EACd,aAAa;EACb,YAAY;EACZ,cAAc;CACf;CACD,iBAAiB;EACf,YAAY;EACZ,YAAY;EACZ,UAAU;EACV,WAAW;EACX,aAAa;EACb,eAAe;EACf,WAAW;EACX,kBAAkB;EAClB,gBAAgB;EAChB,YAAY;CACb;CACD,cAAc;EACZ,WAAW;EACX,YAAY,OAAO,UAAU,QAAQ,MAAK,IAAK;EAC/C,WAAW;EACX,aAAa;EACb,YAAY;EACZ,WAAW;EACX,eAAe;EACf,cAAc;EACd,cAAc,UAAU,eAAe,MAAK;CAC7C;CACD,UAAU,EAAE,aAAa,eAAc;CACvC,aAAa;EACX,OAAO;EACP,YAAY;EACZ,eAAe;EACf,aAAa;EACb,WAAW;EACX,WAAW;EACX,iBAAiB;EACjB,SACE;CACH;CACD,gBAAgB;EAAE,aAAa;EAAa,eAAe;CAAW;CACtE,kBAAkB;EAChB,OAAO;EACP,aAAa;CACd;CACD,QAAQ;EACN,OAAO;EACP,cACE;EACF,WAAW;EACX,aAAa;EACb,YAAY,UAAU,SAAS,MAAM,OAAO;GAAE,KAAK;GAAU,OAAO;EAAS,CAAE;EAC/E,YAAY,SAAS,QAAQ;EAC7B,QAAQ;EACR,UAAU;EACV,YAAY;EACZ,YAAY,MAAM,QAAQ,UAAU,UAClC,GAAG,KAAI,YAAa,OAAM,aAAc,SAAQ,MAAO,MAAK;EAC9D,eAAe,SAAS,kBAAkB,KAAI;CAC/C;CACD,KAAK,EAAE,WAAW,OAAM;CACxB,gBAAgB,EAAE,OAAO,aAAY;CACrC,aAAa;EAAE,eAAe;EAAkB,eAAe;CAAgB;CAC/E,YAAY;EACV,OAAO;EACP,eAAe;EACf,WAAW;EACX,YAAY,SAAS,QAAQ;CAC9B;CACD,eAAe,EAAE,aAAa,gBAAe;CAC7C,cAAc,EAAE,OAAO,UAAS;CAChC,aAAa;EAAE,YAAY;EAAW,YAAY;CAAS;CAC3D,QAAQ,EACN,YAAY,UACV,SAAS,MAAM,OAAO;EAAE,KAAK;EAAoB,OAAO;CAAkB,CAAE,EAC/E;CACD,cAAc;EAAE,aAAa;EAAY,aAAa;CAAc;CACpE,aAAa;EACX,OAAO;EACP,cACE;EACF,QAAQ;EACR,UAAU;EACV,WAAW;EACX,aAAa;EACb,YAAY,OAAO,UAAU,UAAU,GAAG,MAAK,aAAc,SAAQ,MAAO,MAAK;EACjF,eAAe,UAAU,wBAAwB,MAAK;CACvD;CACD,UAAU;EACR,OAAO;EACP,WAAW;EACX,eAAe;EACf,WAAW;EACX,WAAW;EACX,WAAW;EACX,UAAU;EACV,SAAS;EACT,YAAY;EACZ,YAAY;EACZ,WAAW;EACX,aAAa;EACb,WAAW,UAAU,IAAI,MAAK;EAC9B,aAAa,UAAU,SAAS,MAAM,OAAO;GAAE,KAAK;GAAW,OAAO;EAAU,CAAE;EAClF,cAAc,OAAO,SAAS,GAAG,MAAK,YAAa,KAAI;EACvD,eAAe,UAAU,oBAAoB,MAAK;CACnD;CACD,aAAa;EAAE,YAAY;EAAgB,cAAc;CAAW;CACpE,QAAQ,EAAE,WAAW,aAAY;CACjC,aAAa;EACX,cAAc,UAAU,UAAU;EAClC,iBAAiB,UAAU,GAAG,MAAK;CACpC;CACD,SAAS;EAAE,OAAO;EAAc,YAAY;CAAO;CACnD,MAAM;EAAE,eAAe;EAAY,eAAe;EAAY,gBAAgB;CAAW;CACzF,SAAS;EAAE,OAAO;EAAS,gBAAgB;EAAa,YAAY;CAAiB;CACrF,UAAU;EACR,UAAU;EACV,WAAW;EACX,cAAc,QAAQ,UAAU;EAChC,eAAe,QAAQ,SAAS,IAAG;EACnC,iBAAiB,QAAQ,WAAW,IAAG;EACvC,mBAAmB,QAAQ,GAAG,IAAG;CAClC;CACD,WAAW;EACT,aAAa;EACb,YAAY;EACZ,cAAc;EACd,YAAY;CACb;CACD,UAAU,EAAE,OAAO,oBAAmB;CACtC,OAAO;EAAE,OAAO;EAAiB,YAAY;CAAO;CACpD,SAAS,EAAE,OAAO,UAAS;CAC3B,MAAM,EAAE,OAAO,OAAM;CACrB,YAAY,EAAE,OAAO,UAAS;AAC/B;AAED,MAAa,aAAuB;CAClC,MAAM;CACN,eAAe;EACb,OAAO;EACP,WAAW;EACX,WAAW;EACX,aAAa;EACb,cAAc,OAAO,UAAU,mBAAmB,MAAK,IAAK;CAC7D;CACD,OAAO,EAAE,cAAc,uBAAsB;CAC7C,aAAa;EACX,cAAc;EACd,aAAa;EACb,aAAa;EACb,WAAW;CACZ;CACD,cAAc;EACZ,OAAO;EACP,aAAa;EACb,WAAW;EACX,cAAc,UACZ,SAAS,MAAM,OAAO;GACpB,KAAK;GACL,KAAK;GACL,OAAO;EACR,CAAA;CACJ;CACD,aAAa,EAAE,OAAO,wBAAuB;CAC7C,UAAU;EAAE,eAAe;EAAqB,WAAW;CAAkB;CAC7E,gBAAgB;EACd,YAAY,MAAM,UAChB,UAAU,OACN,SAAS,MAAM,MAAM;GACnB,KAAK,GAAG,KAAI;GACZ,KAAK,GAAG,KAAI;GACZ,MAAM,GAAG,KAAI;GACb,OAAO,GAAG,KAAI;EACf,CAAA,IACD,GAAG,KAAI,KAAM;EACnB,gBAAgB,UACd,cAAc,SAAS,MAAM,OAAO;GAAE,KAAK,GAAG,MAAK;GAAW,KAAK,GAAG,MAAK;GAAY,MAAM,GAAG,MAAK;GAAa,OAAO,GAAG,MAAK;EAAU,CAAE,EAAC;EAChJ,WAAW,UACT,kBAAkB,SAAS,MAAM,OAAO;GAAE,KAAK,GAAG,MAAK;GAAW,KAAK,GAAG,MAAK;GAAY,MAAM,GAAG,MAAK;GAAa,OAAO,GAAG,MAAK;EAAU,CAAE,EAAC;EACpJ,WAAW;CACZ;CACD,OAAO;EACL,YAAY;EACZ,eAAe;EACf,eAAe,OAAO,MAAM,KAAK,QAC/B,OAAO,MAAK,MAAO,KAAI,YAAa,IAAG,aAAc;CACxD;CACD,YAAY;EACV,WAAW;EACX,aAAa;EACb,eAAe;EACf,WAAW;CACZ;CACD,aAAa;EACX,aAAa;EACb,aAAa;EACb,UAAU;EACV,cAAc;EACd,YAAY;EACZ,YAAY;CACb;CACD,aAAa,EAAE,OAAO,MAAK;CAC3B,SAAS;EACP,OAAO;EACP,aAAa;EACb,WAAW;EACX,aAAa;CACd;CACD,YAAY;EACV,OAAO;EACP,cAAc;EACd,aAAa;EACb,YAAY;EACZ,cAAc;CACf;CACD,iBAAiB;EACf,YAAY;EACZ,YAAY;EACZ,UAAU;EACV,WAAW;EACX,aAAa;EACb,eAAe;EACf,WAAW;EACX,kBAAkB;EAClB,gBAAgB;EAChB,YAAY;CACb;CACD,cAAc;EACZ,WAAW;EACX,YAAY,OAAO,UAAU,cAAc,MAAK,IAAK;EACrD,WAAW;EACX,aAAa;EACb,YAAY;EACZ,WAAW;EACX,eAAe;EACf,cAAc;EACd,cAAc,UAAU,0BAA0B,MAAK;CACxD;CACD,UAAU,EAAE,aAAa,mBAAkB;CAC3C,aAAa;EACX,OAAO;EACP,YAAY;EACZ,eAAe;EACf,aAAa;EACb,WAAW;EACX,WAAW;EACX,iBAAiB;EACjB,SACE;CACH;CACD,gBAAgB;EAAE,aAAa;EAAmB,eAAe;CAAU;CAC3E,kBAAkB;EAChB,OAAO;EACP,aAAa;CACd;CACD,QAAQ;EACN,OAAO;EACP,cACE;EACF,WAAW;EACX,aAAa;EACb,YAAY,UACV,SAAS,MAAM,OAAO;GACpB,KAAK;GACL,KAAK;GACL,MAAM;GACN,OAAO;EACR,CAAA;EACH,YAAY,SAAS,eAAe;EACpC,QAAQ;EACR,UAAU;EACV,YAAY;EACZ,YAAY,MAAM,QAAQ,UAAU,UAClC,GAAG,KAAI,iBAAkB,OAAM,aAAc,SAAQ,KAAM,MAAK;EAClE,eAAe,SAAS,0BAA0B,KAAI;CACvD;CACD,KAAK,EAAE,WAAW,QAAO;CACzB,gBAAgB,EAAE,OAAO,YAAW;CACpC,aAAa;EAAE,eAAe;EAAqB,eAAe;CAAoB;CACtF,YAAY;EACV,OAAO;EACP,eAAe;EACf,WAAW;EACX,YAAY,SAAS,YAAY;CAClC;CACD,eAAe,EAAE,aAAa,kBAAiB;CAC/C,cAAc,EAAE,OAAO,eAAc;CACrC,aAAa;EAAE,YAAY;EAAW,YAAY;CAAU;CAC5D,QAAQ,EACN,YAAY,UACV,SAAS,MAAM,OAAO;EACpB,KAAK;EACL,KAAK;EACL,OAAO;CACR,CAAA,EACJ;CACD,cAAc;EAAE,aAAa;EAAS,aAAa;CAAe;CAClE,aAAa;EACX,OAAO;EACP,cACE;EACF,QAAQ;EACR,UAAU;EACV,WAAW;EACX,aAAa;EACb,YAAY,OAAO,UAAU,UAAU,GAAG,MAAK,YAAa,SAAQ,KAAM,MAAK;EAC/E,eAAe,UAAU,0BAA0B,MAAK;CACzD;CACD,UAAU;EACR,OAAO;EACP,WAAW;EACX,eAAe;EACf,WAAW;EACX,WAAW;EACX,WAAW;EACX,UAAU;EACV,SAAS;EACT,YAAY;EACZ,YAAY;EACZ,WAAW;EACX,aAAa;EACb,WAAW,UAAU,MAAM;EAC3B,aAAa,UACX,SAAS,MAAM,OAAO;GAAE,KAAK;GAAW,KAAK;GAAW,MAAM;GAAW,OAAO;EAAS,CAAE;EAC7F,cAAc,OAAO,SAAS,GAAG,MAAK,kBAAmB,KAAI;EAC7D,eAAe,UAAU,oBAAoB,MAAK;CACnD;CACD,aAAa;EAAE,YAAY;EAAkB,cAAc;CAAO;CAClE,QAAQ,EAAE,WAAW,kBAAiB;CACtC,aAAa;EACX,cAAc,UAAU,YAAY;EACpC,iBAAiB,UAAU,WAAW;CACvC;CACD,SAAS;EAAE,OAAO;EAAa,YAAY;CAAS;CACpD,MAAM;EAAE,eAAe;EAAa,eAAe;EAAW,gBAAgB;CAAU;CACxF,SAAS;EAAE,OAAO;EAAS,gBAAgB;EAAa,YAAY;CAAgB;CACpF,UAAU;EACR,UAAU;EACV,WAAW;EACX,cAAc,QAAQ,YAAY;EAClC,eAAe,QAAQ,UAAU,IAAG;EACpC,iBAAiB,QAAQ,YAAY,IAAG;EACxC,mBAAmB,QAAQ,GAAG,IAAG;CAClC;CACD,WAAW;EACT,aAAa;EACb,YAAY;EACZ,cAAc;EACd,YAAY;CACb;CACD,UAAU,EAAE,OAAO,mBAAkB;CACrC,OAAO;EAAE,OAAO;EAAc,YAAY;CAAS;CACnD,SAAS,EAAE,OAAO,sBAAqB;CACvC,MAAM,EAAE,OAAO,SAAQ;CACvB,YAAY,EAAE,OAAO,eAAc;AACpC;AC1lBD,MAAa,YAAY,IAAI,eAAyB,aAAa;CACjE,YAAY;CACZ,eAAe;AAChB,CAAA;AAGD,SAAgB,gBAAgB,QAAgB;CAC9C,OAAO,yBAAyB,CAAC;EAAE,SAAS;EAAW,UAAU;CAAM,CAAE,CAAC;AAC5E;AAGA,SAAgB,iBAAiB,QAAgB;CAC/C,OAAO;EAAE,SAAS;EAAW,UAAU;CAAM;AAC/C;AAQA,SAAgB,QACd,SACA,QAAwD;CAExD,MAAM,SAAS,OAAO,SAAS,CAAC,CAAC;CACjC,OAAO,eAAc;EACnB,MAAM,WAAW,CAAA;EACjB,KAAK,MAAM,OAAO,OAAO,KAAK,MAAM,GAClC,SAAS,OAAO,OAAO,IAAI,CAAA,KAAM,OAAO;EAE1C,OAAO;CACT,CAAC;AACH"}
|