@lifecorner/angular-ui-kit 3.25.1 → 3.27.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/lifecorner-angular-ui-kit-button.mjs +18 -2
- package/fesm2022/lifecorner-angular-ui-kit-button.mjs.map +1 -1
- package/fesm2022/lifecorner-angular-ui-kit-callout.mjs +2 -2
- package/fesm2022/lifecorner-angular-ui-kit-callout.mjs.map +1 -1
- package/fesm2022/lifecorner-angular-ui-kit-chat.mjs +2 -2
- package/fesm2022/lifecorner-angular-ui-kit-chat.mjs.map +1 -1
- package/fesm2022/lifecorner-angular-ui-kit-choice-prompt.mjs +1 -0
- package/fesm2022/lifecorner-angular-ui-kit-choice-prompt.mjs.map +1 -1
- package/fesm2022/lifecorner-angular-ui-kit-color-picker.mjs +2 -2
- package/fesm2022/lifecorner-angular-ui-kit-color-picker.mjs.map +1 -1
- package/fesm2022/lifecorner-angular-ui-kit-confirm-dialog.mjs +1 -0
- package/fesm2022/lifecorner-angular-ui-kit-confirm-dialog.mjs.map +1 -1
- package/fesm2022/lifecorner-angular-ui-kit-copy-field.mjs +1 -0
- package/fesm2022/lifecorner-angular-ui-kit-copy-field.mjs.map +1 -1
- package/fesm2022/lifecorner-angular-ui-kit-date-range-picker.mjs +2 -2
- package/fesm2022/lifecorner-angular-ui-kit-date-range-picker.mjs.map +1 -1
- package/fesm2022/lifecorner-angular-ui-kit-datepicker.mjs +2 -2
- package/fesm2022/lifecorner-angular-ui-kit-datepicker.mjs.map +1 -1
- package/fesm2022/lifecorner-angular-ui-kit-dependency-viewer.mjs +47 -9
- package/fesm2022/lifecorner-angular-ui-kit-dependency-viewer.mjs.map +1 -1
- package/fesm2022/lifecorner-angular-ui-kit-description-list.mjs +2 -2
- package/fesm2022/lifecorner-angular-ui-kit-description-list.mjs.map +1 -1
- package/fesm2022/lifecorner-angular-ui-kit-document-viewer.mjs +2 -2
- package/fesm2022/lifecorner-angular-ui-kit-document-viewer.mjs.map +1 -1
- package/fesm2022/lifecorner-angular-ui-kit-file-upload.mjs +8 -4
- package/fesm2022/lifecorner-angular-ui-kit-file-upload.mjs.map +1 -1
- package/fesm2022/lifecorner-angular-ui-kit-filter-bar.mjs +2 -2
- package/fesm2022/lifecorner-angular-ui-kit-filter-bar.mjs.map +1 -1
- package/fesm2022/lifecorner-angular-ui-kit-gallery.mjs +2 -2
- package/fesm2022/lifecorner-angular-ui-kit-gallery.mjs.map +1 -1
- package/fesm2022/lifecorner-angular-ui-kit-gantt-chart.mjs +2 -2
- package/fesm2022/lifecorner-angular-ui-kit-gantt-chart.mjs.map +1 -1
- package/fesm2022/lifecorner-angular-ui-kit-header.mjs +3 -2
- package/fesm2022/lifecorner-angular-ui-kit-header.mjs.map +1 -1
- package/fesm2022/lifecorner-angular-ui-kit-input.mjs +2 -2
- package/fesm2022/lifecorner-angular-ui-kit-input.mjs.map +1 -1
- package/fesm2022/lifecorner-angular-ui-kit-kanban-board.mjs +2 -2
- package/fesm2022/lifecorner-angular-ui-kit-kanban-board.mjs.map +1 -1
- package/fesm2022/lifecorner-angular-ui-kit-list.mjs +1 -0
- package/fesm2022/lifecorner-angular-ui-kit-list.mjs.map +1 -1
- package/fesm2022/lifecorner-angular-ui-kit-log-viewer.mjs +2 -2
- package/fesm2022/lifecorner-angular-ui-kit-log-viewer.mjs.map +1 -1
- package/fesm2022/lifecorner-angular-ui-kit-next-step-card.mjs +1 -0
- package/fesm2022/lifecorner-angular-ui-kit-next-step-card.mjs.map +1 -1
- package/fesm2022/lifecorner-angular-ui-kit-notification-center.mjs +2 -2
- package/fesm2022/lifecorner-angular-ui-kit-notification-center.mjs.map +1 -1
- package/fesm2022/lifecorner-angular-ui-kit-number-input.mjs +2 -2
- package/fesm2022/lifecorner-angular-ui-kit-number-input.mjs.map +1 -1
- package/fesm2022/lifecorner-angular-ui-kit-rich-text-editor.mjs +2 -2
- package/fesm2022/lifecorner-angular-ui-kit-rich-text-editor.mjs.map +1 -1
- package/fesm2022/lifecorner-angular-ui-kit-scatter-plot.mjs +2 -2
- package/fesm2022/lifecorner-angular-ui-kit-scatter-plot.mjs.map +1 -1
- package/fesm2022/lifecorner-angular-ui-kit-search-input.mjs +2 -2
- package/fesm2022/lifecorner-angular-ui-kit-search-input.mjs.map +1 -1
- package/fesm2022/lifecorner-angular-ui-kit-select.mjs +2 -2
- package/fesm2022/lifecorner-angular-ui-kit-select.mjs.map +1 -1
- package/fesm2022/lifecorner-angular-ui-kit-split-pane.mjs +2 -2
- package/fesm2022/lifecorner-angular-ui-kit-split-pane.mjs.map +1 -1
- package/fesm2022/lifecorner-angular-ui-kit-table.mjs +3 -2
- package/fesm2022/lifecorner-angular-ui-kit-table.mjs.map +1 -1
- package/fesm2022/lifecorner-angular-ui-kit-tabs.mjs +2 -2
- package/fesm2022/lifecorner-angular-ui-kit-tabs.mjs.map +1 -1
- package/fesm2022/lifecorner-angular-ui-kit-tag-input.mjs +2 -2
- package/fesm2022/lifecorner-angular-ui-kit-tag-input.mjs.map +1 -1
- package/fesm2022/lifecorner-angular-ui-kit-textarea.mjs +2 -2
- package/fesm2022/lifecorner-angular-ui-kit-textarea.mjs.map +1 -1
- package/fesm2022/lifecorner-angular-ui-kit-toggle-group.mjs +2 -2
- package/fesm2022/lifecorner-angular-ui-kit-toggle-group.mjs.map +1 -1
- package/package.json +1 -1
- package/src/styles/_reset.scss +4 -2
- package/src/styles/focus-indicators.spec.ts +199 -0
- package/types/lifecorner-angular-ui-kit-button.d.ts +20 -0
- package/types/lifecorner-angular-ui-kit-dependency-viewer.d.ts +33 -4
- package/types/lifecorner-angular-ui-kit-description-list.d.ts +4 -0
- package/types/lifecorner-angular-ui-kit-file-upload.d.ts +11 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lifecorner-angular-ui-kit-split-pane.mjs","names":[],"sources":["../../../../libs/angular-ui-kit/src/lib/split-pane/split-pane.component.ts","../../../../libs/angular-ui-kit/src/lib/split-pane/split-pane.component.html"],"sourcesContent":["import {\n ChangeDetectionStrategy,\n Component,\n DestroyRef,\n ElementRef,\n OnInit,\n computed,\n effect,\n inject,\n input,\n output,\n signal,\n} from '@angular/core';\n\n/**\n * Resizable two-pane layout container.\n *\n * Projects two panes (`slot=\"start\"`, `slot=\"end\"`) side by side with a\n * draggable separator in between. The start pane has a fixed, user-adjustable\n * width; the end pane fills the remaining space.\n *\n * Features:\n * - Drag the separator with mouse / touch (pointer capture), bounded by\n * `minSize` / `maxSize` (px or percentage of the container)\n * - Double-click the separator to restore `initialSize`\n * - Keyboard resizing: focusable separator, ←/→ adjust by `step`,\n * Home/End jump to min/max (`role=\"separator\"`, `aria-valuenow`)\n * - Optional persistence: with `storageKey`, the width survives a reload\n * - Below the `stackBelow` viewport breakpoint the panes stack vertically\n * and the resizer is disabled\n *\n * @example\n * ```html\n * <lc-split-pane\n * [initialSize]=\"360\"\n * [minSize]=\"280\"\n * [maxSize]=\"'55%'\"\n * storageKey=\"sidebar-width\"\n * (sizeChange)=\"onWidthChange($event)\"\n * >\n * <div slot=\"start\">…</div>\n * <div slot=\"end\">…</div>\n * </lc-split-pane>\n * ```\n */\n@Component({\n selector: 'lc-split-pane',\n standalone: true,\n templateUrl: './split-pane.component.html',\n styleUrl: './split-pane.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class SplitPaneComponent implements OnInit {\n /** Initial width of the start pane in px. Restored on separator double-click. */\n readonly initialSize = input<number>(320);\n\n /** Minimum width of the start pane in px. */\n readonly minSize = input<number>(0);\n\n /**\n * Maximum width of the start pane: a number (px) or a percentage string\n * such as `'55%'` (relative to the container width). `null` = no limit\n * beyond the container itself.\n */\n readonly maxSize = input<number | string | null>(null);\n\n /**\n * When set, the current width is persisted to localStorage under this key\n * and restored on the next init.\n */\n readonly storageKey = input<string>();\n\n /** Step in px for keyboard resizing (←/→ on the focused separator). */\n readonly step = input<number>(16);\n\n /**\n * Viewport width in px below which the panes stack vertically and the\n * resizer is disabled. `0` disables stacking.\n */\n readonly stackBelow = input<number>(0);\n\n /** Accessible label for the separator. */\n readonly separatorLabel = input('Resize panel');\n\n /** Emitted whenever the start-pane width changes (drag, keyboard, reset). */\n readonly sizeChange = output<number>();\n\n private readonly host = inject<ElementRef<HTMLElement>>(ElementRef);\n private readonly destroyRef = inject(DestroyRef);\n\n /** Requested start-pane width; clamped to min/max for rendering. */\n private readonly size = signal(0);\n\n /** Container width, tracked so percentage `maxSize` stays responsive. */\n private readonly containerWidth = signal(0);\n\n /** Whether the panes are stacked (viewport below `stackBelow`). */\n protected readonly stacked = signal(false);\n\n private dragPointerId: number | null = null;\n private dragStartX = 0;\n private dragStartSize = 0;\n\n /** Clamped width actually applied to the start pane. */\n protected readonly effectiveSize = computed(() => this.clamp(this.size()));\n\n /** Resolved max in px for aria-valuemax; null when unbounded. */\n protected readonly ariaMax = computed(() => {\n const max = this.resolveMaxPx();\n return Number.isFinite(max) && max < Number.MAX_SAFE_INTEGER\n ? Math.round(max)\n : null;\n });\n\n constructor() {\n // Track the stacking breakpoint reactively; re-subscribes when the\n // `stackBelow` input changes.\n effect((onCleanup) => {\n const breakpoint = this.stackBelow();\n if (\n !breakpoint ||\n typeof window === 'undefined' ||\n typeof window.matchMedia !== 'function'\n ) {\n this.stacked.set(false);\n return;\n }\n const query = window.matchMedia(`(max-width: ${breakpoint - 0.02}px)`);\n this.stacked.set(query.matches);\n const onChange = (event: MediaQueryListEvent) =>\n this.stacked.set(event.matches);\n query.addEventListener('change', onChange);\n onCleanup(() => query.removeEventListener('change', onChange));\n });\n }\n\n ngOnInit(): void {\n this.size.set(this.restoreSize() ?? this.initialSize());\n this.observeContainer();\n }\n\n /** Restore the initial width (also wired to separator double-click). */\n reset(): void {\n this.applySize(this.initialSize());\n this.persist();\n }\n\n protected onPointerDown(event: PointerEvent): void {\n const separator = event.currentTarget as HTMLElement;\n try {\n separator.setPointerCapture?.(event.pointerId);\n } catch {\n // Synthetic events carry no active pointer — dragging still works as\n // long as the pointer stays over the separator.\n }\n this.dragPointerId = event.pointerId;\n this.dragStartX = event.clientX;\n this.dragStartSize = this.effectiveSize();\n event.preventDefault();\n }\n\n protected onPointerMove(event: PointerEvent): void {\n if (this.dragPointerId !== event.pointerId) return;\n this.applySize(this.dragStartSize + (event.clientX - this.dragStartX));\n }\n\n protected onPointerUp(event: PointerEvent): void {\n if (this.dragPointerId !== event.pointerId) return;\n this.dragPointerId = null;\n try {\n (event.currentTarget as HTMLElement).releasePointerCapture?.(\n event.pointerId,\n );\n } catch {\n // No capture to release — nothing to do.\n }\n this.persist();\n }\n\n protected onKeydown(event: KeyboardEvent): void {\n let next: number;\n switch (event.key) {\n case 'ArrowLeft':\n next = this.effectiveSize() - this.step();\n break;\n case 'ArrowRight':\n next = this.effectiveSize() + this.step();\n break;\n case 'Home':\n next = this.minSize();\n break;\n case 'End':\n next = this.resolveMaxPx();\n break;\n default:\n return;\n }\n event.preventDefault();\n this.applySize(next);\n this.persist();\n }\n\n // ── internals ──────────────────────────────────────────────────────────────\n\n private applySize(px: number): void {\n const clamped = this.clamp(px);\n const previous = this.effectiveSize();\n // Always store the clamped value so deltas can't accumulate off-limits.\n this.size.set(clamped);\n if (clamped !== previous) {\n this.sizeChange.emit(clamped);\n }\n }\n\n private clamp(px: number): number {\n const min = this.minSize();\n const max = Math.max(min, this.resolveMaxPx());\n return Math.min(Math.max(px, min), max);\n }\n\n private resolveMaxPx(): number {\n const raw = this.maxSize();\n const width = this.containerWidth();\n if (raw == null) {\n return width > 0 ? width : Number.MAX_SAFE_INTEGER;\n }\n if (typeof raw === 'number') return raw;\n const trimmed = raw.trim();\n const value = parseFloat(trimmed);\n if (Number.isNaN(value)) return Number.MAX_SAFE_INTEGER;\n if (trimmed.endsWith('%')) {\n return width > 0 ? (width * value) / 100 : Number.MAX_SAFE_INTEGER;\n }\n return value;\n }\n\n private observeContainer(): void {\n const element = this.host.nativeElement;\n this.containerWidth.set(element.clientWidth || 0);\n if (typeof ResizeObserver === 'undefined') return;\n const observer = new ResizeObserver((entries) => {\n const width = entries[0]?.contentRect.width ?? 0;\n this.containerWidth.set(width);\n });\n observer.observe(element);\n this.destroyRef.onDestroy(() => observer.disconnect());\n }\n\n private storageId(): string | null {\n const key = this.storageKey();\n return key ? `lc-split-pane:${key}` : null;\n }\n\n private restoreSize(): number | null {\n const id = this.storageId();\n if (!id) return null;\n try {\n const raw = globalThis.localStorage?.getItem(id);\n const parsed = raw == null ? NaN : parseFloat(raw);\n return Number.isFinite(parsed) ? parsed : null;\n } catch {\n return null;\n }\n }\n\n private persist(): void {\n const id = this.storageId();\n if (!id) return;\n try {\n globalThis.localStorage?.setItem(id, String(this.effectiveSize()));\n } catch {\n // Storage unavailable (SSR, private mode) — width simply won't persist.\n }\n }\n}\n","<div class=\"lc-split-pane\" [class.lc-split-pane--stacked]=\"stacked()\">\n <div\n class=\"lc-split-pane__pane lc-split-pane__pane--start\"\n [style.flex-basis.px]=\"stacked() ? null : effectiveSize()\"\n >\n <ng-content select=\"[slot=start]\" />\n </div>\n\n @if (!stacked()) {\n <div\n class=\"lc-split-pane__separator\"\n role=\"separator\"\n tabindex=\"0\"\n aria-orientation=\"vertical\"\n [attr.aria-label]=\"separatorLabel()\"\n [attr.aria-valuenow]=\"effectiveSize()\"\n [attr.aria-valuemin]=\"minSize()\"\n [attr.aria-valuemax]=\"ariaMax()\"\n (pointerdown)=\"onPointerDown($event)\"\n (pointermove)=\"onPointerMove($event)\"\n (pointerup)=\"onPointerUp($event)\"\n (pointercancel)=\"onPointerUp($event)\"\n (dblclick)=\"reset()\"\n (keydown)=\"onKeydown($event)\"\n ></div>\n }\n\n <div class=\"lc-split-pane__pane lc-split-pane__pane--end\">\n <ng-content select=\"[slot=end]\" />\n </div>\n</div>\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"lifecorner-angular-ui-kit-split-pane.mjs","names":[],"sources":["../../../../libs/angular-ui-kit/src/lib/split-pane/split-pane.component.ts","../../../../libs/angular-ui-kit/src/lib/split-pane/split-pane.component.html"],"sourcesContent":["import {\n ChangeDetectionStrategy,\n Component,\n DestroyRef,\n ElementRef,\n OnInit,\n computed,\n effect,\n inject,\n input,\n output,\n signal,\n} from '@angular/core';\n\n/**\n * Resizable two-pane layout container.\n *\n * Projects two panes (`slot=\"start\"`, `slot=\"end\"`) side by side with a\n * draggable separator in between. The start pane has a fixed, user-adjustable\n * width; the end pane fills the remaining space.\n *\n * Features:\n * - Drag the separator with mouse / touch (pointer capture), bounded by\n * `minSize` / `maxSize` (px or percentage of the container)\n * - Double-click the separator to restore `initialSize`\n * - Keyboard resizing: focusable separator, ←/→ adjust by `step`,\n * Home/End jump to min/max (`role=\"separator\"`, `aria-valuenow`)\n * - Optional persistence: with `storageKey`, the width survives a reload\n * - Below the `stackBelow` viewport breakpoint the panes stack vertically\n * and the resizer is disabled\n *\n * @example\n * ```html\n * <lc-split-pane\n * [initialSize]=\"360\"\n * [minSize]=\"280\"\n * [maxSize]=\"'55%'\"\n * storageKey=\"sidebar-width\"\n * (sizeChange)=\"onWidthChange($event)\"\n * >\n * <div slot=\"start\">…</div>\n * <div slot=\"end\">…</div>\n * </lc-split-pane>\n * ```\n */\n@Component({\n selector: 'lc-split-pane',\n standalone: true,\n templateUrl: './split-pane.component.html',\n styleUrl: './split-pane.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class SplitPaneComponent implements OnInit {\n /** Initial width of the start pane in px. Restored on separator double-click. */\n readonly initialSize = input<number>(320);\n\n /** Minimum width of the start pane in px. */\n readonly minSize = input<number>(0);\n\n /**\n * Maximum width of the start pane: a number (px) or a percentage string\n * such as `'55%'` (relative to the container width). `null` = no limit\n * beyond the container itself.\n */\n readonly maxSize = input<number | string | null>(null);\n\n /**\n * When set, the current width is persisted to localStorage under this key\n * and restored on the next init.\n */\n readonly storageKey = input<string>();\n\n /** Step in px for keyboard resizing (←/→ on the focused separator). */\n readonly step = input<number>(16);\n\n /**\n * Viewport width in px below which the panes stack vertically and the\n * resizer is disabled. `0` disables stacking.\n */\n readonly stackBelow = input<number>(0);\n\n /** Accessible label for the separator. */\n readonly separatorLabel = input('Resize panel');\n\n /** Emitted whenever the start-pane width changes (drag, keyboard, reset). */\n readonly sizeChange = output<number>();\n\n private readonly host = inject<ElementRef<HTMLElement>>(ElementRef);\n private readonly destroyRef = inject(DestroyRef);\n\n /** Requested start-pane width; clamped to min/max for rendering. */\n private readonly size = signal(0);\n\n /** Container width, tracked so percentage `maxSize` stays responsive. */\n private readonly containerWidth = signal(0);\n\n /** Whether the panes are stacked (viewport below `stackBelow`). */\n protected readonly stacked = signal(false);\n\n private dragPointerId: number | null = null;\n private dragStartX = 0;\n private dragStartSize = 0;\n\n /** Clamped width actually applied to the start pane. */\n protected readonly effectiveSize = computed(() => this.clamp(this.size()));\n\n /** Resolved max in px for aria-valuemax; null when unbounded. */\n protected readonly ariaMax = computed(() => {\n const max = this.resolveMaxPx();\n return Number.isFinite(max) && max < Number.MAX_SAFE_INTEGER\n ? Math.round(max)\n : null;\n });\n\n constructor() {\n // Track the stacking breakpoint reactively; re-subscribes when the\n // `stackBelow` input changes.\n effect((onCleanup) => {\n const breakpoint = this.stackBelow();\n if (\n !breakpoint ||\n typeof window === 'undefined' ||\n typeof window.matchMedia !== 'function'\n ) {\n this.stacked.set(false);\n return;\n }\n const query = window.matchMedia(`(max-width: ${breakpoint - 0.02}px)`);\n this.stacked.set(query.matches);\n const onChange = (event: MediaQueryListEvent) =>\n this.stacked.set(event.matches);\n query.addEventListener('change', onChange);\n onCleanup(() => query.removeEventListener('change', onChange));\n });\n }\n\n ngOnInit(): void {\n this.size.set(this.restoreSize() ?? this.initialSize());\n this.observeContainer();\n }\n\n /** Restore the initial width (also wired to separator double-click). */\n reset(): void {\n this.applySize(this.initialSize());\n this.persist();\n }\n\n protected onPointerDown(event: PointerEvent): void {\n const separator = event.currentTarget as HTMLElement;\n try {\n separator.setPointerCapture?.(event.pointerId);\n } catch {\n // Synthetic events carry no active pointer — dragging still works as\n // long as the pointer stays over the separator.\n }\n this.dragPointerId = event.pointerId;\n this.dragStartX = event.clientX;\n this.dragStartSize = this.effectiveSize();\n event.preventDefault();\n }\n\n protected onPointerMove(event: PointerEvent): void {\n if (this.dragPointerId !== event.pointerId) return;\n this.applySize(this.dragStartSize + (event.clientX - this.dragStartX));\n }\n\n protected onPointerUp(event: PointerEvent): void {\n if (this.dragPointerId !== event.pointerId) return;\n this.dragPointerId = null;\n try {\n (event.currentTarget as HTMLElement).releasePointerCapture?.(\n event.pointerId,\n );\n } catch {\n // No capture to release — nothing to do.\n }\n this.persist();\n }\n\n protected onKeydown(event: KeyboardEvent): void {\n let next: number;\n switch (event.key) {\n case 'ArrowLeft':\n next = this.effectiveSize() - this.step();\n break;\n case 'ArrowRight':\n next = this.effectiveSize() + this.step();\n break;\n case 'Home':\n next = this.minSize();\n break;\n case 'End':\n next = this.resolveMaxPx();\n break;\n default:\n return;\n }\n event.preventDefault();\n this.applySize(next);\n this.persist();\n }\n\n // ── internals ──────────────────────────────────────────────────────────────\n\n private applySize(px: number): void {\n const clamped = this.clamp(px);\n const previous = this.effectiveSize();\n // Always store the clamped value so deltas can't accumulate off-limits.\n this.size.set(clamped);\n if (clamped !== previous) {\n this.sizeChange.emit(clamped);\n }\n }\n\n private clamp(px: number): number {\n const min = this.minSize();\n const max = Math.max(min, this.resolveMaxPx());\n return Math.min(Math.max(px, min), max);\n }\n\n private resolveMaxPx(): number {\n const raw = this.maxSize();\n const width = this.containerWidth();\n if (raw == null) {\n return width > 0 ? width : Number.MAX_SAFE_INTEGER;\n }\n if (typeof raw === 'number') return raw;\n const trimmed = raw.trim();\n const value = parseFloat(trimmed);\n if (Number.isNaN(value)) return Number.MAX_SAFE_INTEGER;\n if (trimmed.endsWith('%')) {\n return width > 0 ? (width * value) / 100 : Number.MAX_SAFE_INTEGER;\n }\n return value;\n }\n\n private observeContainer(): void {\n const element = this.host.nativeElement;\n this.containerWidth.set(element.clientWidth || 0);\n if (typeof ResizeObserver === 'undefined') return;\n const observer = new ResizeObserver((entries) => {\n const width = entries[0]?.contentRect.width ?? 0;\n this.containerWidth.set(width);\n });\n observer.observe(element);\n this.destroyRef.onDestroy(() => observer.disconnect());\n }\n\n private storageId(): string | null {\n const key = this.storageKey();\n return key ? `lc-split-pane:${key}` : null;\n }\n\n private restoreSize(): number | null {\n const id = this.storageId();\n if (!id) return null;\n try {\n const raw = globalThis.localStorage?.getItem(id);\n const parsed = raw == null ? NaN : parseFloat(raw);\n return Number.isFinite(parsed) ? parsed : null;\n } catch {\n return null;\n }\n }\n\n private persist(): void {\n const id = this.storageId();\n if (!id) return;\n try {\n globalThis.localStorage?.setItem(id, String(this.effectiveSize()));\n } catch {\n // Storage unavailable (SSR, private mode) — width simply won't persist.\n }\n }\n}\n","<div class=\"lc-split-pane\" [class.lc-split-pane--stacked]=\"stacked()\">\n <div\n class=\"lc-split-pane__pane lc-split-pane__pane--start\"\n [style.flex-basis.px]=\"stacked() ? null : effectiveSize()\"\n >\n <ng-content select=\"[slot=start]\" />\n </div>\n\n @if (!stacked()) {\n <div\n class=\"lc-split-pane__separator\"\n role=\"separator\"\n tabindex=\"0\"\n aria-orientation=\"vertical\"\n [attr.aria-label]=\"separatorLabel()\"\n [attr.aria-valuenow]=\"effectiveSize()\"\n [attr.aria-valuemin]=\"minSize()\"\n [attr.aria-valuemax]=\"ariaMax()\"\n (pointerdown)=\"onPointerDown($event)\"\n (pointermove)=\"onPointerMove($event)\"\n (pointerup)=\"onPointerUp($event)\"\n (pointercancel)=\"onPointerUp($event)\"\n (dblclick)=\"reset()\"\n (keydown)=\"onKeydown($event)\"\n ></div>\n }\n\n <div class=\"lc-split-pane__pane lc-split-pane__pane--end\">\n <ng-content select=\"[slot=end]\" />\n </div>\n</div>\n"],"mappings":"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"}
|
|
@@ -991,7 +991,7 @@ var TableComponent = class TableComponent {
|
|
|
991
991
|
}],
|
|
992
992
|
ngImport: i0,
|
|
993
993
|
template: "<div [class]=\"wrapperClasses()\">\n <table [class]=\"tableClasses()\" [attr.role]=\"treeMode() ? 'treegrid' : 'table'\">\n @if (caption()) {\n <!-- First child of the table, so it names the table (and the treegrid). -->\n <caption class=\"lc-table__caption\" [class.lc-table__caption--hidden]=\"!showCaption()\">{{ caption() }}</caption>\n }\n <thead>\n <!-- Filter row -->\n @if (filterable()) {\n <tr class=\"lc-table__filter-row\">\n @if (selectable()) {\n <th class=\"lc-table__select-cell\"></th>\n }\n @for (column of columns(); track column.key) {\n <th>\n @if (column.filterable !== false) {\n <lc-input\n class=\"lc-table__filter-input\"\n size=\"xs\"\n [placeholder]=\"filterPlaceholderLabel() + ' ' + column.label\"\n [ariaLabel]=\"filterAriaLabel() + ' ' + column.label\"\n [ngModel]=\"getFilterValue(column.key)\"\n (ngModelChange)=\"onFilterChange(column.key, $event)\"\n />\n }\n </th>\n }\n @if (hasActions()) {\n <th class=\"lc-table__actions-cell\"></th>\n }\n </tr>\n }\n <!-- Header row -->\n <tr>\n @if (selectable()) {\n <th class=\"lc-table__select-cell\" scope=\"col\">\n <input\n type=\"checkbox\"\n class=\"lc-table__checkbox\"\n [checked]=\"allSelected()\"\n [indeterminate]=\"someSelected()\"\n (change)=\"toggleSelectAll()\"\n [attr.aria-label]=\"selectAllAriaLabel()\"\n />\n </th>\n }\n @for (column of columns(); track column.key) {\n <!-- A sortable header is a keyboard stop too: Enter/Space sort like a click. -->\n <th\n scope=\"col\"\n [class]=\"getHeaderClasses(column) + (column.cssClass ? ' ' + column.cssClass : '')\"\n [attr.aria-sort]=\"getAriaSort(column.key)\"\n [attr.tabindex]=\"column.sortable ? 0 : null\"\n [style.width]=\"column.width\"\n [title]=\"column.tooltip || ''\"\n (click)=\"handleSort(column.key)\"\n (keydown)=\"column.sortable ? onHeaderKeydown($event, column.key) : null\">\n @if (column.align === 'end') {\n <!-- 3.17: the arrow is placed before the label (CSS), so the label stays\n flush with the figures; in the DOM it still follows the label. No\n whitespace between the label and the arrow. -->\n <span class=\"lc-table__sort-label\">{{ column.label }}@if (column.sortable && getSortState(column.key)) {<span class=\"sort-indicator\" [attr.aria-label]=\"getSortState(column.key) === 'asc' ? sortedAscendingLabel() : sortedDescendingLabel()\">\n @if (getSortState(column.key) === 'asc') {\n ↑\n } @else {\n ↓\n }\n </span>}</span>\n } @else {\n {{ column.label }}\n @if (column.sortable && getSortState(column.key)) {\n <span class=\"sort-indicator\" [attr.aria-label]=\"getSortState(column.key) === 'asc' ? sortedAscendingLabel() : sortedDescendingLabel()\">\n @if (getSortState(column.key) === 'asc') {\n ↑\n } @else {\n ↓\n }\n </span>\n }\n }\n </th>\n }\n @if (hasActions()) {\n <th\n scope=\"col\"\n class=\"lc-table__actions-cell\"\n [class]=\"'lc-table__actions-cell--' + actionsAlign()\"\n [style.width]=\"actionsWidth()\"\n >\n {{ actionsLabel() }}\n </th>\n }\n </tr>\n </thead>\n <tbody>\n @if (displayRows().length === 0) {\n <tr>\n <td [attr.colspan]=\"columns().length + (selectable() ? 1 : 0) + (hasActions() ? 1 : 0)\" class=\"lc-table__empty\">\n {{ emptyText() }}\n </td>\n </tr>\n } @else {\n @for (dr of displayRows(); track dr.key) {\n <!-- In tree mode the rows form the treegrid's keyboard model: a roving\n tab stop plus Arrow/Home/End/Enter/Space handling (see the\n component). Flat mode keeps plain table rows. -->\n <tr\n #dataRow\n [class.lc-table__row--selected]=\"selectable() && isRowSelected(dr.row)\"\n [class.lc-table__row--group]=\"dr.hasChildren\"\n [attr.role]=\"treeMode() ? 'row' : null\"\n [attr.tabindex]=\"rowTabindex(dr)\"\n [attr.aria-level]=\"treeMode() ? dr.level : null\"\n [attr.aria-expanded]=\"treeMode() && dr.hasChildren ? dr.expanded : null\"\n [attr.aria-posinset]=\"treeMode() ? dr.posInSet : null\"\n [attr.aria-setsize]=\"treeMode() ? dr.setSize : null\"\n [attr.aria-selected]=\"treeMode() && selectable() ? isRowSelected(dr.row) : null\"\n (click)=\"onRowClick(dr.row, $event)\"\n (focus)=\"onRowFocus(dr)\"\n (keydown)=\"onRowKeydown($event, dr)\"\n >\n @if (selectable()) {\n <td class=\"lc-table__select-cell\" [attr.role]=\"treeMode() ? 'gridcell' : null\">\n <input\n type=\"checkbox\"\n class=\"lc-table__checkbox\"\n [checked]=\"isRowSelected(dr.row)\"\n (change)=\"toggleRowSelect(dr.row)\"\n (click)=\"$event.stopPropagation()\"\n [attr.aria-label]=\"selectRowAriaLabel() + ' ' + (dr.absIndex + 1)\"\n />\n </td>\n }\n @for (column of columns(); track column.key) {\n <td\n [class]=\"getCellClasses(dr.row, column, dr.absIndex)\"\n [ngStyle]=\"getCellStyles(dr.row, column, dr.absIndex)\"\n [attr.role]=\"treeMode() ? 'gridcell' : null\"\n (dblclick)=\"editable() ? startEdit(dr.row, column.key, getCellValue(dr.row, column.key)) : null\"\n >\n @if (isTreeColumn(column.key)) {\n <span class=\"lc-table__tree-cell\">\n @for (lvl of indentLevels(dr.depth); track lvl) {\n <span class=\"lc-table__tree-indent\" [style.width.px]=\"indentSize()\"></span>\n }\n <span class=\"lc-table__tree-chevron\" [style.width.px]=\"indentSize()\">\n @if (dr.hasChildren) {\n <button\n type=\"button\"\n class=\"lc-table__chevron-btn\"\n [class.lc-table__chevron-btn--expanded]=\"dr.expanded\"\n [attr.aria-label]=\"(dr.expanded ? collapseRowAriaLabel() : expandRowAriaLabel()) + ' ' + treeCellLabel(dr.row)\"\n [attr.aria-expanded]=\"dr.expanded\"\n (click)=\"onChevronClick(dr, $event)\"\n >\n <lc-icon name=\"chevron-right\" size=\"xs\" [decorative]=\"true\" />\n </button>\n }\n </span>\n <span class=\"lc-table__tree-content\">\n <ng-container\n *ngTemplateOutlet=\"cellContent; context: { row: dr.row, column: column, absIndex: dr.absIndex }\"\n ></ng-container>\n </span>\n </span>\n } @else {\n <ng-container\n *ngTemplateOutlet=\"cellContent; context: { row: dr.row, column: column, absIndex: dr.absIndex }\"\n ></ng-container>\n }\n </td>\n }\n @if (hasActions()) {\n <td\n class=\"lc-table__actions-cell\"\n [class]=\"'lc-table__actions-cell--' + actionsAlign()\"\n [attr.role]=\"treeMode() ? 'gridcell' : null\"\n (click)=\"$event.stopPropagation()\"\n >\n <div class=\"lc-table__actions\">\n @for (action of actions(); track action.key) {\n @if (!isActionHidden(action, dr.row, dr.absIndex)) {\n <lc-button\n [variant]=\"action.variant ?? 'ghost'\"\n size=\"xs\"\n [iconOnly]=\"!action.label\"\n [disabled]=\"isActionDisabled(action, dr.row, dr.absIndex)\"\n [ariaLabel]=\"action.tooltip ?? action.label ?? action.key\"\n (clicked)=\"onActionClick(action, dr.row, dr.absIndex)\"\n >\n @if (action.icon) {\n <lc-icon [name]=\"action.icon\" size=\"sm\" [decorative]=\"true\" />\n }\n @if (action.label) {\n {{ action.label }}\n }\n </lc-button>\n }\n }\n </div>\n </td>\n }\n </tr>\n }\n }\n </tbody>\n </table>\n</div>\n\n<!-- Shared cell content (edit input / custom template / formatted value) -->\n<ng-template #cellContent let-row=\"row\" let-column=\"column\" let-absIndex=\"absIndex\">\n @if (isEditing(row, column.key)) {\n <input\n #editInput\n type=\"text\"\n class=\"lc-table__edit-input\"\n [value]=\"editValue()\"\n (input)=\"editValue.set(getInputValue($event))\"\n (blur)=\"commitEdit(row, column.key)\"\n (keydown)=\"onEditKeydown($event, row, column.key)\"\n />\n } @else if (hasCustomTemplate(column.key)) {\n <ng-container *ngTemplateOutlet=\"getCellTemplate(column.key)!.template; context: { $implicit: row }\"></ng-container>\n } @else {\n {{ getFormattedCellValue(row, column, absIndex) }}\n }\n</ng-template>\n\n<!-- Pagination -->\n@if (paginate()) {\n <div [class]=\"'lc-table-pagination lc-table-pagination--' + paginationSize()\">\n <div class=\"lc-table-pagination__info\">\n {{ paginationStart }}–{{ paginationEnd }} {{ rangeOfLabel() }} {{ totalRows() }}\n </div>\n <div class=\"lc-table-pagination__controls\">\n <lc-select\n class=\"lc-table-pagination__size\"\n [size]=\"paginationSize()\"\n [options]=\"pageSizeSelectOptions()\"\n [ngModel]=\"internalPageSize()\"\n [ariaLabel]=\"rowsPerPageAriaLabel()\"\n (ngModelChange)=\"onPageSizeModelChange($event)\"\n />\n <div class=\"lc-table-pagination__pager\">\n <button\n type=\"button\"\n class=\"lc-table-pagination__btn\"\n [disabled]=\"currentPage() === 0\"\n (click)=\"goToPage(currentPage() - 1)\"\n [attr.aria-label]=\"previousPageAriaLabel()\"\n >‹</button>\n <span class=\"lc-table-pagination__page\">\n {{ currentPage() + 1 }} / {{ totalPages() }}\n </span>\n <button\n type=\"button\"\n class=\"lc-table-pagination__btn\"\n [disabled]=\"currentPage() >= totalPages() - 1\"\n (click)=\"goToPage(currentPage() + 1)\"\n [attr.aria-label]=\"nextPageAriaLabel()\"\n >›</button>\n </div>\n </div>\n </div>\n}\n",
|
|
994
|
-
styles: [".lc-table-wrapper{width:100%}.lc-table-wrapper--responsive{overflow-x:auto;-webkit-overflow-scrolling:touch}@media(max-width:768px){.lc-table-wrapper--responsive::-webkit-scrollbar{height:8px}.lc-table-wrapper--responsive::-webkit-scrollbar-thumb{background-color:var(--color-border);border-radius:var(--border-radius-sm)}}.lc-table{width:100%;border-collapse:collapse;border-spacing:0;background-color:var(--color-surface);color:var(--color-text-primary);font-family:var(--typography-font-family)}.lc-table thead{background-color:var(--color-surface-2);border-bottom:2px solid var(--color-border-strong)}.lc-table thead tr th{padding:var(--lc-density-padding-sm, var(--spacing-3)) var(--lc-density-padding-md, var(--spacing-4));text-align:left;font-weight:var(--typography-font-weight-semibold);font-size:var(--typography-font-size-sm);text-transform:uppercase;letter-spacing:.04em;color:var(--color-text-secondary);white-space:nowrap;-webkit-user-select:none;user-select:none}.lc-table thead tr th.sortable{cursor:pointer;position:relative;padding-right:var(--spacing-8);transition:background-color .2s ease}.lc-table thead tr th.sortable:focus-visible{outline:2px solid var(--color-primary-500);outline-offset:-2px}.lc-table thead tr th.sortable:hover{background-color:var(--color-surface-hover);color:var(--color-text-primary)}.lc-table thead tr th.sortable .sort-indicator{position:absolute;right:var(--spacing-3);top:50%;transform:translateY(-50%);font-size:var(--typography-font-size-xs);color:var(--color-primary)}.lc-table thead tr th.sorted-asc,.lc-table thead tr th.sorted-desc{background-color:var(--color-surface-hover);color:var(--color-text-primary)}.lc-table tbody tr{border-bottom:1px solid var(--color-divider)}.lc-table tbody tr:focus-visible{outline:2px solid var(--color-primary-500);outline-offset:-2px}.lc-table tbody tr:last-child{border-bottom:none}.lc-table tbody tr td{padding:var(--lc-density-padding-sm, var(--spacing-3)) var(--lc-density-padding-md, var(--spacing-4))}.lc-table__empty{text-align:center;padding:var(--spacing-8) var(--spacing-4)!important;font-style:italic}.lc-table--striped tbody tr:nth-child(2n){background-color:var(--color-surface-2)}.lc-table--bordered{border:1px solid var(--color-border)}.lc-table--bordered thead tr th,.lc-table--bordered tbody tr td{border-right:1px solid var(--color-divider)}.lc-table--bordered thead tr th:last-child,.lc-table--bordered tbody tr td:last-child{border-right:none}.lc-table--bordered tbody tr{border-bottom:1px solid var(--color-border)}.lc-table--hoverable tbody tr,.lc-table--clickable tbody tr{transition:background-color .15s ease;cursor:pointer}.lc-table--hoverable tbody tr:hover,.lc-table--clickable tbody tr:hover{background-color:var(--color-surface-hover)}.lc-table--sm thead tr th,.lc-table--sm tbody tr td{padding:var(--lc-density-padding-xs, var(--spacing-2)) var(--lc-density-padding-sm, var(--spacing-3))}.lc-table--sm thead tr th{font-size:var(--typography-font-size-xs)}.lc-table--lg thead tr th,.lc-table--lg tbody tr td{padding:var(--lc-density-padding-md, var(--spacing-4)) var(--spacing-5)}.lc-table--lg thead tr th{font-size:var(--typography-font-size-base)}:where(.lc-table tbody tr td){font-size:var(--typography-font-size-sm);color:var(--color-text-primary)}:where(.lc-table--sm tbody tr td){font-size:var(--typography-font-size-xs)}:where(.lc-table--lg tbody tr td){font-size:var(--typography-font-size-base)}.lc-table thead tr th.lc-table__cell--end,.lc-table tbody tr td.lc-table__cell--end{text-align:end;font-variant-numeric:tabular-nums}.lc-table thead tr th.sortable.lc-table__cell--end{padding-inline-start:var(--spacing-8);padding-inline-end:var(--lc-density-padding-md, var(--spacing-4))}.lc-table thead tr th.sortable.lc-table__cell--end .sort-indicator{right:auto;inset-inline-end:calc(100% + var(--spacing-2))}.lc-table--sm thead tr th.sortable.lc-table__cell--end{padding-inline-end:var(--lc-density-padding-sm, var(--spacing-3))}.lc-table--lg thead tr th.sortable.lc-table__cell--end{padding-inline-end:var(--spacing-5)}.lc-table__sort-label{position:relative;display:inline-block}.lc-table__cell--end .lc-table__edit-input{text-align:end;font-variant-numeric:tabular-nums}.lc-table__caption{caption-side:top;padding:0 0 var(--spacing-3);text-align:start;font-family:var(--typography-font-family);font-size:var(--typography-font-size-base);font-weight:var(--typography-font-weight-semibold);line-height:var(--typography-line-height-normal);color:var(--color-text-primary)}.lc-table__caption--hidden{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}@media(forced-colors:active){.lc-table tbody tr:focus-visible{outline:2px solid Highlight}}.lc-table__filter-row th{padding:var(--spacing-2) var(--spacing-4)!important;background-color:var(--color-surface)!important;border-bottom:1px solid var(--color-divider)!important}.lc-table__filter-input{width:100%;display:block}.lc-table__filter-input .input-field{font-size:var(--typography-font-size-xs)}.lc-table__select-cell{width:40px;text-align:center!important;padding:var(--spacing-2)!important}.lc-table__checkbox{width:16px;height:16px;cursor:pointer;accent-color:var(--color-primary)}.lc-table__row--selected{background-color:var(--color-surface-selected)!important}.lc-table__actions-cell{white-space:nowrap}.lc-table thead tr th.lc-table__actions-cell--start,.lc-table tbody tr td.lc-table__actions-cell--start{text-align:left}.lc-table thead tr th.lc-table__actions-cell--center,.lc-table tbody tr td.lc-table__actions-cell--center{text-align:center}.lc-table thead tr th.lc-table__actions-cell--end,.lc-table tbody tr td.lc-table__actions-cell--end{text-align:right}.lc-table__actions{display:flex;align-items:center;gap:var(--spacing-2);justify-content:flex-start}.lc-table__actions-cell--center .lc-table__actions{justify-content:center}.lc-table__actions-cell--end .lc-table__actions{justify-content:flex-end}.lc-table__tree-cell{display:flex;align-items:center;min-width:0}.lc-table__tree-indent{flex:0 0 auto;align-self:stretch;position:relative}.lc-table__tree-indent:before{content:\"\";position:absolute;left:50%;top:0;bottom:0;width:1px;background-color:var(--color-border)}.lc-table__tree-chevron{flex:0 0 auto;display:inline-flex;align-items:center;justify-content:center}.lc-table__chevron-btn{display:inline-flex;align-items:center;justify-content:center;width:20px;height:20px;padding:0;border:none;background:transparent;color:var(--color-text-secondary);cursor:pointer;border-radius:var(--border-radius-sm);transition:transform .2s ease,background-color .15s ease,color .15s ease}.lc-table__chevron-btn:hover{background-color:var(--color-surface-hover);color:var(--color-text-primary)}.lc-table__chevron-btn:focus-visible{outline:2px solid var(--color-primary);outline-offset:1px}.lc-table__chevron-btn--expanded{transform:rotate(90deg)}.lc-table__tree-content{flex:1 1 auto;min-width:0}.lc-table__row--group .lc-table__tree-content{font-weight:var(--typography-font-weight-semibold)}.lc-table__edit-input{width:100%;padding:var(--spacing-1) var(--spacing-2);border:2px solid var(--color-primary);border-radius:var(--border-radius-sm);font-size:inherit;background-color:var(--color-surface-2);color:var(--color-text-primary);outline:none}.lc-table-pagination{--_lc-table-pagination-btn: var(--size-interactive-md-height);display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:var(--spacing-2) var(--spacing-4);padding:var(--spacing-3) var(--spacing-1);font-size:var(--typography-font-size-sm);color:var(--color-text-secondary)}.lc-table-pagination--sm{--_lc-table-pagination-btn: var(--size-interactive-sm-height)}.lc-table-pagination--lg{--_lc-table-pagination-btn: var(--size-interactive-lg-height)}.lc-table-pagination__info{white-space:nowrap}.lc-table-pagination__controls{display:flex;flex-wrap:wrap;align-items:center;justify-content:flex-end;gap:var(--spacing-2);margin-inline-start:auto}.lc-table-pagination__pager{display:flex;align-items:center;gap:var(--spacing-2)}.lc-table-pagination__size{--lc-select-clear-display: none;display:block;min-width:110px}.lc-table-pagination__btn{position:relative;appearance:none;border:1px solid var(--color-field-border);background-color:var(--color-surface-2);color:var(--color-text-primary);width:var(--_lc-table-pagination-btn);height:var(--_lc-table-pagination-btn);display:flex;align-items:center;justify-content:center;padding:0;border-radius:var(--border-radius-md);font-size:var(--typography-font-size-xl);line-height:1;cursor:pointer;transition:background-color .15s ease,border-color .15s ease}.lc-table-pagination__btn:before{content:\"\";position:absolute;inset:min(0px,(100% - var(--size-min-touch-height, 2.75rem)) / 2)}.lc-table-pagination__btn:hover:not(:disabled){background-color:var(--color-surface-hover);border-color:var(--color-text-secondary)}.lc-table-pagination__btn:focus-visible{outline:2px solid var(--color-primary-500);outline-offset:2px}.lc-table-pagination__btn:disabled{opacity:.4;cursor:not-allowed}.lc-table-pagination__page{white-space:nowrap;min-width:60px;text-align:center}@media(max-width:640px){.lc-table-wrapper--stack .lc-table thead{display:none}.lc-table-wrapper--stack .lc-table tbody tr{display:block;margin-bottom:var(--spacing-4);border:1px solid var(--color-border);border-radius:var(--border-radius-md)}.lc-table-wrapper--stack .lc-table tbody tr td{display:block;text-align:right;padding:var(--spacing-2) var(--spacing-4);border-bottom:1px solid var(--color-divider)}.lc-table-wrapper--stack .lc-table tbody tr td:last-child{border-bottom:none}.lc-table-wrapper--stack .lc-table tbody tr td:before{content:attr(data-label);float:left;font-weight:var(--typography-font-weight-semibold);color:var(--color-text-secondary)}}\n"],
|
|
994
|
+
styles: [".lc-table-wrapper{width:100%}.lc-table-wrapper--responsive{overflow-x:auto;-webkit-overflow-scrolling:touch}@media(max-width:768px){.lc-table-wrapper--responsive::-webkit-scrollbar{height:8px}.lc-table-wrapper--responsive::-webkit-scrollbar-thumb{background-color:var(--color-border);border-radius:var(--border-radius-sm)}}.lc-table{width:100%;border-collapse:collapse;border-spacing:0;background-color:var(--color-surface);color:var(--color-text-primary);font-family:var(--typography-font-family)}.lc-table thead{background-color:var(--color-surface-2);border-bottom:2px solid var(--color-border-strong)}.lc-table thead tr th{padding:var(--lc-density-padding-sm, var(--spacing-3)) var(--lc-density-padding-md, var(--spacing-4));text-align:left;font-weight:var(--typography-font-weight-semibold);font-size:var(--typography-font-size-sm);text-transform:uppercase;letter-spacing:.04em;color:var(--color-text-secondary);white-space:nowrap;-webkit-user-select:none;user-select:none}.lc-table thead tr th.sortable{cursor:pointer;position:relative;padding-right:var(--spacing-8);transition:background-color .2s ease}.lc-table thead tr th.sortable:focus-visible{outline:2px solid var(--color-primary-500);outline-offset:-2px}.lc-table thead tr th.sortable:hover{background-color:var(--color-surface-hover);color:var(--color-text-primary)}.lc-table thead tr th.sortable .sort-indicator{position:absolute;right:var(--spacing-3);top:50%;transform:translateY(-50%);font-size:var(--typography-font-size-xs);color:var(--color-primary)}.lc-table thead tr th.sorted-asc,.lc-table thead tr th.sorted-desc{background-color:var(--color-surface-hover);color:var(--color-text-primary)}.lc-table tbody tr{border-bottom:1px solid var(--color-divider)}.lc-table tbody tr:focus-visible{outline:2px solid var(--color-primary-500);outline-offset:-2px}.lc-table tbody tr:last-child{border-bottom:none}.lc-table tbody tr td{padding:var(--lc-density-padding-sm, var(--spacing-3)) var(--lc-density-padding-md, var(--spacing-4))}.lc-table__empty{text-align:center;padding:var(--spacing-8) var(--spacing-4)!important;font-style:italic}.lc-table--striped tbody tr:nth-child(2n){background-color:var(--color-surface-2)}.lc-table--bordered{border:1px solid var(--color-border)}.lc-table--bordered thead tr th,.lc-table--bordered tbody tr td{border-right:1px solid var(--color-divider)}.lc-table--bordered thead tr th:last-child,.lc-table--bordered tbody tr td:last-child{border-right:none}.lc-table--bordered tbody tr{border-bottom:1px solid var(--color-border)}.lc-table--hoverable tbody tr,.lc-table--clickable tbody tr{transition:background-color .15s ease;cursor:pointer}.lc-table--hoverable tbody tr:hover,.lc-table--clickable tbody tr:hover{background-color:var(--color-surface-hover)}.lc-table--sm thead tr th,.lc-table--sm tbody tr td{padding:var(--lc-density-padding-xs, var(--spacing-2)) var(--lc-density-padding-sm, var(--spacing-3))}.lc-table--sm thead tr th{font-size:var(--typography-font-size-xs)}.lc-table--lg thead tr th,.lc-table--lg tbody tr td{padding:var(--lc-density-padding-md, var(--spacing-4)) var(--spacing-5)}.lc-table--lg thead tr th{font-size:var(--typography-font-size-base)}:where(.lc-table tbody tr td){font-size:var(--typography-font-size-sm);color:var(--color-text-primary)}:where(.lc-table--sm tbody tr td){font-size:var(--typography-font-size-xs)}:where(.lc-table--lg tbody tr td){font-size:var(--typography-font-size-base)}.lc-table thead tr th.lc-table__cell--end,.lc-table tbody tr td.lc-table__cell--end{text-align:end;font-variant-numeric:tabular-nums}.lc-table thead tr th.sortable.lc-table__cell--end{padding-inline-start:var(--spacing-8);padding-inline-end:var(--lc-density-padding-md, var(--spacing-4))}.lc-table thead tr th.sortable.lc-table__cell--end .sort-indicator{right:auto;inset-inline-end:calc(100% + var(--spacing-2))}.lc-table--sm thead tr th.sortable.lc-table__cell--end{padding-inline-end:var(--lc-density-padding-sm, var(--spacing-3))}.lc-table--lg thead tr th.sortable.lc-table__cell--end{padding-inline-end:var(--spacing-5)}.lc-table__sort-label{position:relative;display:inline-block}.lc-table__cell--end .lc-table__edit-input{text-align:end;font-variant-numeric:tabular-nums}.lc-table__caption{caption-side:top;padding:0 0 var(--spacing-3);text-align:start;font-family:var(--typography-font-family);font-size:var(--typography-font-size-base);font-weight:var(--typography-font-weight-semibold);line-height:var(--typography-line-height-normal);color:var(--color-text-primary)}.lc-table__caption--hidden{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}@media(forced-colors:active){.lc-table tbody tr:focus-visible{outline:2px solid Highlight}}.lc-table__filter-row th{padding:var(--spacing-2) var(--spacing-4)!important;background-color:var(--color-surface)!important;border-bottom:1px solid var(--color-divider)!important}.lc-table__filter-input{width:100%;display:block}.lc-table__filter-input .input-field{font-size:var(--typography-font-size-xs)}.lc-table__select-cell{width:40px;text-align:center!important;padding:var(--spacing-2)!important}.lc-table__checkbox{width:16px;height:16px;cursor:pointer;accent-color:var(--color-primary)}.lc-table__checkbox:focus-visible{outline:2px solid var(--color-primary-500);outline-offset:2px}.lc-table__row--selected{background-color:var(--color-surface-selected)!important}.lc-table__actions-cell{white-space:nowrap}.lc-table thead tr th.lc-table__actions-cell--start,.lc-table tbody tr td.lc-table__actions-cell--start{text-align:left}.lc-table thead tr th.lc-table__actions-cell--center,.lc-table tbody tr td.lc-table__actions-cell--center{text-align:center}.lc-table thead tr th.lc-table__actions-cell--end,.lc-table tbody tr td.lc-table__actions-cell--end{text-align:right}.lc-table__actions{display:flex;align-items:center;gap:var(--spacing-2);justify-content:flex-start}.lc-table__actions-cell--center .lc-table__actions{justify-content:center}.lc-table__actions-cell--end .lc-table__actions{justify-content:flex-end}.lc-table__tree-cell{display:flex;align-items:center;min-width:0}.lc-table__tree-indent{flex:0 0 auto;align-self:stretch;position:relative}.lc-table__tree-indent:before{content:\"\";position:absolute;left:50%;top:0;bottom:0;width:1px;background-color:var(--color-border)}.lc-table__tree-chevron{flex:0 0 auto;display:inline-flex;align-items:center;justify-content:center}.lc-table__chevron-btn{display:inline-flex;align-items:center;justify-content:center;width:20px;height:20px;padding:0;border:none;background:transparent;color:var(--color-text-secondary);cursor:pointer;border-radius:var(--border-radius-sm);transition:transform .2s ease,background-color .15s ease,color .15s ease}.lc-table__chevron-btn:hover{background-color:var(--color-surface-hover);color:var(--color-text-primary)}.lc-table__chevron-btn:focus-visible{outline:2px solid var(--color-primary);outline-offset:1px}.lc-table__chevron-btn--expanded{transform:rotate(90deg)}.lc-table__tree-content{flex:1 1 auto;min-width:0}.lc-table__row--group .lc-table__tree-content{font-weight:var(--typography-font-weight-semibold)}.lc-table__edit-input{width:100%;padding:var(--spacing-1) var(--spacing-2);border:2px solid var(--color-primary);border-radius:var(--border-radius-sm);font-size:inherit;background-color:var(--color-surface-2);color:var(--color-text-primary);outline:none}.lc-table-pagination{--_lc-table-pagination-btn: var(--size-interactive-md-height);display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:var(--spacing-2) var(--spacing-4);padding:var(--spacing-3) var(--spacing-1);font-size:var(--typography-font-size-sm);color:var(--color-text-secondary)}.lc-table-pagination--sm{--_lc-table-pagination-btn: var(--size-interactive-sm-height)}.lc-table-pagination--lg{--_lc-table-pagination-btn: var(--size-interactive-lg-height)}.lc-table-pagination__info{white-space:nowrap}.lc-table-pagination__controls{display:flex;flex-wrap:wrap;align-items:center;justify-content:flex-end;gap:var(--spacing-2);margin-inline-start:auto}.lc-table-pagination__pager{display:flex;align-items:center;gap:var(--spacing-2)}.lc-table-pagination__size{--lc-select-clear-display: none;display:block;min-width:110px}.lc-table-pagination__btn{position:relative;appearance:none;border:1px solid var(--color-field-border);background-color:var(--color-surface-2);color:var(--color-text-primary);width:var(--_lc-table-pagination-btn);height:var(--_lc-table-pagination-btn);display:flex;align-items:center;justify-content:center;padding:0;border-radius:var(--border-radius-md);font-size:var(--typography-font-size-xl);line-height:1;cursor:pointer;transition:background-color .15s ease,border-color .15s ease}.lc-table-pagination__btn:before{content:\"\";position:absolute;inset:min(0px,(100% - var(--size-min-touch-height, 2.75rem)) / 2)}.lc-table-pagination__btn:hover:not(:disabled){background-color:var(--color-surface-hover);border-color:var(--color-text-secondary)}.lc-table-pagination__btn:focus-visible{outline:2px solid var(--color-primary-500);outline-offset:2px}.lc-table-pagination__btn:disabled{opacity:.4;cursor:not-allowed}.lc-table-pagination__page{white-space:nowrap;min-width:60px;text-align:center}@media(max-width:640px){.lc-table-wrapper--stack .lc-table thead{display:none}.lc-table-wrapper--stack .lc-table tbody tr{display:block;margin-bottom:var(--spacing-4);border:1px solid var(--color-border);border-radius:var(--border-radius-md)}.lc-table-wrapper--stack .lc-table tbody tr td{display:block;text-align:right;padding:var(--spacing-2) var(--spacing-4);border-bottom:1px solid var(--color-divider)}.lc-table-wrapper--stack .lc-table tbody tr td:last-child{border-bottom:none}.lc-table-wrapper--stack .lc-table tbody tr td:before{content:attr(data-label);float:left;font-weight:var(--typography-font-weight-semibold);color:var(--color-text-secondary)}}@media(forced-colors:active){.lc-table__checkbox:focus-visible{outline-color:Highlight}}\n"],
|
|
995
995
|
dependencies: [
|
|
996
996
|
{
|
|
997
997
|
kind: "directive",
|
|
@@ -1113,6 +1113,7 @@ var TableComponent = class TableComponent {
|
|
|
1113
1113
|
"iconOnly",
|
|
1114
1114
|
"fullWidth",
|
|
1115
1115
|
"ariaLabel",
|
|
1116
|
+
"ariaDescribedBy",
|
|
1116
1117
|
"type",
|
|
1117
1118
|
"title",
|
|
1118
1119
|
"disabledReason",
|
|
@@ -1166,7 +1167,7 @@ i0.ɵɵngDeclareClassMetadata({
|
|
|
1166
1167
|
viewProviders: [ɵprovideKitIcons([ICON_CHEVRON_RIGHT])],
|
|
1167
1168
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
1168
1169
|
template: "<div [class]=\"wrapperClasses()\">\n <table [class]=\"tableClasses()\" [attr.role]=\"treeMode() ? 'treegrid' : 'table'\">\n @if (caption()) {\n <!-- First child of the table, so it names the table (and the treegrid). -->\n <caption class=\"lc-table__caption\" [class.lc-table__caption--hidden]=\"!showCaption()\">{{ caption() }}</caption>\n }\n <thead>\n <!-- Filter row -->\n @if (filterable()) {\n <tr class=\"lc-table__filter-row\">\n @if (selectable()) {\n <th class=\"lc-table__select-cell\"></th>\n }\n @for (column of columns(); track column.key) {\n <th>\n @if (column.filterable !== false) {\n <lc-input\n class=\"lc-table__filter-input\"\n size=\"xs\"\n [placeholder]=\"filterPlaceholderLabel() + ' ' + column.label\"\n [ariaLabel]=\"filterAriaLabel() + ' ' + column.label\"\n [ngModel]=\"getFilterValue(column.key)\"\n (ngModelChange)=\"onFilterChange(column.key, $event)\"\n />\n }\n </th>\n }\n @if (hasActions()) {\n <th class=\"lc-table__actions-cell\"></th>\n }\n </tr>\n }\n <!-- Header row -->\n <tr>\n @if (selectable()) {\n <th class=\"lc-table__select-cell\" scope=\"col\">\n <input\n type=\"checkbox\"\n class=\"lc-table__checkbox\"\n [checked]=\"allSelected()\"\n [indeterminate]=\"someSelected()\"\n (change)=\"toggleSelectAll()\"\n [attr.aria-label]=\"selectAllAriaLabel()\"\n />\n </th>\n }\n @for (column of columns(); track column.key) {\n <!-- A sortable header is a keyboard stop too: Enter/Space sort like a click. -->\n <th\n scope=\"col\"\n [class]=\"getHeaderClasses(column) + (column.cssClass ? ' ' + column.cssClass : '')\"\n [attr.aria-sort]=\"getAriaSort(column.key)\"\n [attr.tabindex]=\"column.sortable ? 0 : null\"\n [style.width]=\"column.width\"\n [title]=\"column.tooltip || ''\"\n (click)=\"handleSort(column.key)\"\n (keydown)=\"column.sortable ? onHeaderKeydown($event, column.key) : null\">\n @if (column.align === 'end') {\n <!-- 3.17: the arrow is placed before the label (CSS), so the label stays\n flush with the figures; in the DOM it still follows the label. No\n whitespace between the label and the arrow. -->\n <span class=\"lc-table__sort-label\">{{ column.label }}@if (column.sortable && getSortState(column.key)) {<span class=\"sort-indicator\" [attr.aria-label]=\"getSortState(column.key) === 'asc' ? sortedAscendingLabel() : sortedDescendingLabel()\">\n @if (getSortState(column.key) === 'asc') {\n ↑\n } @else {\n ↓\n }\n </span>}</span>\n } @else {\n {{ column.label }}\n @if (column.sortable && getSortState(column.key)) {\n <span class=\"sort-indicator\" [attr.aria-label]=\"getSortState(column.key) === 'asc' ? sortedAscendingLabel() : sortedDescendingLabel()\">\n @if (getSortState(column.key) === 'asc') {\n ↑\n } @else {\n ↓\n }\n </span>\n }\n }\n </th>\n }\n @if (hasActions()) {\n <th\n scope=\"col\"\n class=\"lc-table__actions-cell\"\n [class]=\"'lc-table__actions-cell--' + actionsAlign()\"\n [style.width]=\"actionsWidth()\"\n >\n {{ actionsLabel() }}\n </th>\n }\n </tr>\n </thead>\n <tbody>\n @if (displayRows().length === 0) {\n <tr>\n <td [attr.colspan]=\"columns().length + (selectable() ? 1 : 0) + (hasActions() ? 1 : 0)\" class=\"lc-table__empty\">\n {{ emptyText() }}\n </td>\n </tr>\n } @else {\n @for (dr of displayRows(); track dr.key) {\n <!-- In tree mode the rows form the treegrid's keyboard model: a roving\n tab stop plus Arrow/Home/End/Enter/Space handling (see the\n component). Flat mode keeps plain table rows. -->\n <tr\n #dataRow\n [class.lc-table__row--selected]=\"selectable() && isRowSelected(dr.row)\"\n [class.lc-table__row--group]=\"dr.hasChildren\"\n [attr.role]=\"treeMode() ? 'row' : null\"\n [attr.tabindex]=\"rowTabindex(dr)\"\n [attr.aria-level]=\"treeMode() ? dr.level : null\"\n [attr.aria-expanded]=\"treeMode() && dr.hasChildren ? dr.expanded : null\"\n [attr.aria-posinset]=\"treeMode() ? dr.posInSet : null\"\n [attr.aria-setsize]=\"treeMode() ? dr.setSize : null\"\n [attr.aria-selected]=\"treeMode() && selectable() ? isRowSelected(dr.row) : null\"\n (click)=\"onRowClick(dr.row, $event)\"\n (focus)=\"onRowFocus(dr)\"\n (keydown)=\"onRowKeydown($event, dr)\"\n >\n @if (selectable()) {\n <td class=\"lc-table__select-cell\" [attr.role]=\"treeMode() ? 'gridcell' : null\">\n <input\n type=\"checkbox\"\n class=\"lc-table__checkbox\"\n [checked]=\"isRowSelected(dr.row)\"\n (change)=\"toggleRowSelect(dr.row)\"\n (click)=\"$event.stopPropagation()\"\n [attr.aria-label]=\"selectRowAriaLabel() + ' ' + (dr.absIndex + 1)\"\n />\n </td>\n }\n @for (column of columns(); track column.key) {\n <td\n [class]=\"getCellClasses(dr.row, column, dr.absIndex)\"\n [ngStyle]=\"getCellStyles(dr.row, column, dr.absIndex)\"\n [attr.role]=\"treeMode() ? 'gridcell' : null\"\n (dblclick)=\"editable() ? startEdit(dr.row, column.key, getCellValue(dr.row, column.key)) : null\"\n >\n @if (isTreeColumn(column.key)) {\n <span class=\"lc-table__tree-cell\">\n @for (lvl of indentLevels(dr.depth); track lvl) {\n <span class=\"lc-table__tree-indent\" [style.width.px]=\"indentSize()\"></span>\n }\n <span class=\"lc-table__tree-chevron\" [style.width.px]=\"indentSize()\">\n @if (dr.hasChildren) {\n <button\n type=\"button\"\n class=\"lc-table__chevron-btn\"\n [class.lc-table__chevron-btn--expanded]=\"dr.expanded\"\n [attr.aria-label]=\"(dr.expanded ? collapseRowAriaLabel() : expandRowAriaLabel()) + ' ' + treeCellLabel(dr.row)\"\n [attr.aria-expanded]=\"dr.expanded\"\n (click)=\"onChevronClick(dr, $event)\"\n >\n <lc-icon name=\"chevron-right\" size=\"xs\" [decorative]=\"true\" />\n </button>\n }\n </span>\n <span class=\"lc-table__tree-content\">\n <ng-container\n *ngTemplateOutlet=\"cellContent; context: { row: dr.row, column: column, absIndex: dr.absIndex }\"\n ></ng-container>\n </span>\n </span>\n } @else {\n <ng-container\n *ngTemplateOutlet=\"cellContent; context: { row: dr.row, column: column, absIndex: dr.absIndex }\"\n ></ng-container>\n }\n </td>\n }\n @if (hasActions()) {\n <td\n class=\"lc-table__actions-cell\"\n [class]=\"'lc-table__actions-cell--' + actionsAlign()\"\n [attr.role]=\"treeMode() ? 'gridcell' : null\"\n (click)=\"$event.stopPropagation()\"\n >\n <div class=\"lc-table__actions\">\n @for (action of actions(); track action.key) {\n @if (!isActionHidden(action, dr.row, dr.absIndex)) {\n <lc-button\n [variant]=\"action.variant ?? 'ghost'\"\n size=\"xs\"\n [iconOnly]=\"!action.label\"\n [disabled]=\"isActionDisabled(action, dr.row, dr.absIndex)\"\n [ariaLabel]=\"action.tooltip ?? action.label ?? action.key\"\n (clicked)=\"onActionClick(action, dr.row, dr.absIndex)\"\n >\n @if (action.icon) {\n <lc-icon [name]=\"action.icon\" size=\"sm\" [decorative]=\"true\" />\n }\n @if (action.label) {\n {{ action.label }}\n }\n </lc-button>\n }\n }\n </div>\n </td>\n }\n </tr>\n }\n }\n </tbody>\n </table>\n</div>\n\n<!-- Shared cell content (edit input / custom template / formatted value) -->\n<ng-template #cellContent let-row=\"row\" let-column=\"column\" let-absIndex=\"absIndex\">\n @if (isEditing(row, column.key)) {\n <input\n #editInput\n type=\"text\"\n class=\"lc-table__edit-input\"\n [value]=\"editValue()\"\n (input)=\"editValue.set(getInputValue($event))\"\n (blur)=\"commitEdit(row, column.key)\"\n (keydown)=\"onEditKeydown($event, row, column.key)\"\n />\n } @else if (hasCustomTemplate(column.key)) {\n <ng-container *ngTemplateOutlet=\"getCellTemplate(column.key)!.template; context: { $implicit: row }\"></ng-container>\n } @else {\n {{ getFormattedCellValue(row, column, absIndex) }}\n }\n</ng-template>\n\n<!-- Pagination -->\n@if (paginate()) {\n <div [class]=\"'lc-table-pagination lc-table-pagination--' + paginationSize()\">\n <div class=\"lc-table-pagination__info\">\n {{ paginationStart }}–{{ paginationEnd }} {{ rangeOfLabel() }} {{ totalRows() }}\n </div>\n <div class=\"lc-table-pagination__controls\">\n <lc-select\n class=\"lc-table-pagination__size\"\n [size]=\"paginationSize()\"\n [options]=\"pageSizeSelectOptions()\"\n [ngModel]=\"internalPageSize()\"\n [ariaLabel]=\"rowsPerPageAriaLabel()\"\n (ngModelChange)=\"onPageSizeModelChange($event)\"\n />\n <div class=\"lc-table-pagination__pager\">\n <button\n type=\"button\"\n class=\"lc-table-pagination__btn\"\n [disabled]=\"currentPage() === 0\"\n (click)=\"goToPage(currentPage() - 1)\"\n [attr.aria-label]=\"previousPageAriaLabel()\"\n >‹</button>\n <span class=\"lc-table-pagination__page\">\n {{ currentPage() + 1 }} / {{ totalPages() }}\n </span>\n <button\n type=\"button\"\n class=\"lc-table-pagination__btn\"\n [disabled]=\"currentPage() >= totalPages() - 1\"\n (click)=\"goToPage(currentPage() + 1)\"\n [attr.aria-label]=\"nextPageAriaLabel()\"\n >›</button>\n </div>\n </div>\n </div>\n}\n",
|
|
1169
|
-
styles: [".lc-table-wrapper{width:100%}.lc-table-wrapper--responsive{overflow-x:auto;-webkit-overflow-scrolling:touch}@media(max-width:768px){.lc-table-wrapper--responsive::-webkit-scrollbar{height:8px}.lc-table-wrapper--responsive::-webkit-scrollbar-thumb{background-color:var(--color-border);border-radius:var(--border-radius-sm)}}.lc-table{width:100%;border-collapse:collapse;border-spacing:0;background-color:var(--color-surface);color:var(--color-text-primary);font-family:var(--typography-font-family)}.lc-table thead{background-color:var(--color-surface-2);border-bottom:2px solid var(--color-border-strong)}.lc-table thead tr th{padding:var(--lc-density-padding-sm, var(--spacing-3)) var(--lc-density-padding-md, var(--spacing-4));text-align:left;font-weight:var(--typography-font-weight-semibold);font-size:var(--typography-font-size-sm);text-transform:uppercase;letter-spacing:.04em;color:var(--color-text-secondary);white-space:nowrap;-webkit-user-select:none;user-select:none}.lc-table thead tr th.sortable{cursor:pointer;position:relative;padding-right:var(--spacing-8);transition:background-color .2s ease}.lc-table thead tr th.sortable:focus-visible{outline:2px solid var(--color-primary-500);outline-offset:-2px}.lc-table thead tr th.sortable:hover{background-color:var(--color-surface-hover);color:var(--color-text-primary)}.lc-table thead tr th.sortable .sort-indicator{position:absolute;right:var(--spacing-3);top:50%;transform:translateY(-50%);font-size:var(--typography-font-size-xs);color:var(--color-primary)}.lc-table thead tr th.sorted-asc,.lc-table thead tr th.sorted-desc{background-color:var(--color-surface-hover);color:var(--color-text-primary)}.lc-table tbody tr{border-bottom:1px solid var(--color-divider)}.lc-table tbody tr:focus-visible{outline:2px solid var(--color-primary-500);outline-offset:-2px}.lc-table tbody tr:last-child{border-bottom:none}.lc-table tbody tr td{padding:var(--lc-density-padding-sm, var(--spacing-3)) var(--lc-density-padding-md, var(--spacing-4))}.lc-table__empty{text-align:center;padding:var(--spacing-8) var(--spacing-4)!important;font-style:italic}.lc-table--striped tbody tr:nth-child(2n){background-color:var(--color-surface-2)}.lc-table--bordered{border:1px solid var(--color-border)}.lc-table--bordered thead tr th,.lc-table--bordered tbody tr td{border-right:1px solid var(--color-divider)}.lc-table--bordered thead tr th:last-child,.lc-table--bordered tbody tr td:last-child{border-right:none}.lc-table--bordered tbody tr{border-bottom:1px solid var(--color-border)}.lc-table--hoverable tbody tr,.lc-table--clickable tbody tr{transition:background-color .15s ease;cursor:pointer}.lc-table--hoverable tbody tr:hover,.lc-table--clickable tbody tr:hover{background-color:var(--color-surface-hover)}.lc-table--sm thead tr th,.lc-table--sm tbody tr td{padding:var(--lc-density-padding-xs, var(--spacing-2)) var(--lc-density-padding-sm, var(--spacing-3))}.lc-table--sm thead tr th{font-size:var(--typography-font-size-xs)}.lc-table--lg thead tr th,.lc-table--lg tbody tr td{padding:var(--lc-density-padding-md, var(--spacing-4)) var(--spacing-5)}.lc-table--lg thead tr th{font-size:var(--typography-font-size-base)}:where(.lc-table tbody tr td){font-size:var(--typography-font-size-sm);color:var(--color-text-primary)}:where(.lc-table--sm tbody tr td){font-size:var(--typography-font-size-xs)}:where(.lc-table--lg tbody tr td){font-size:var(--typography-font-size-base)}.lc-table thead tr th.lc-table__cell--end,.lc-table tbody tr td.lc-table__cell--end{text-align:end;font-variant-numeric:tabular-nums}.lc-table thead tr th.sortable.lc-table__cell--end{padding-inline-start:var(--spacing-8);padding-inline-end:var(--lc-density-padding-md, var(--spacing-4))}.lc-table thead tr th.sortable.lc-table__cell--end .sort-indicator{right:auto;inset-inline-end:calc(100% + var(--spacing-2))}.lc-table--sm thead tr th.sortable.lc-table__cell--end{padding-inline-end:var(--lc-density-padding-sm, var(--spacing-3))}.lc-table--lg thead tr th.sortable.lc-table__cell--end{padding-inline-end:var(--spacing-5)}.lc-table__sort-label{position:relative;display:inline-block}.lc-table__cell--end .lc-table__edit-input{text-align:end;font-variant-numeric:tabular-nums}.lc-table__caption{caption-side:top;padding:0 0 var(--spacing-3);text-align:start;font-family:var(--typography-font-family);font-size:var(--typography-font-size-base);font-weight:var(--typography-font-weight-semibold);line-height:var(--typography-line-height-normal);color:var(--color-text-primary)}.lc-table__caption--hidden{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}@media(forced-colors:active){.lc-table tbody tr:focus-visible{outline:2px solid Highlight}}.lc-table__filter-row th{padding:var(--spacing-2) var(--spacing-4)!important;background-color:var(--color-surface)!important;border-bottom:1px solid var(--color-divider)!important}.lc-table__filter-input{width:100%;display:block}.lc-table__filter-input .input-field{font-size:var(--typography-font-size-xs)}.lc-table__select-cell{width:40px;text-align:center!important;padding:var(--spacing-2)!important}.lc-table__checkbox{width:16px;height:16px;cursor:pointer;accent-color:var(--color-primary)}.lc-table__row--selected{background-color:var(--color-surface-selected)!important}.lc-table__actions-cell{white-space:nowrap}.lc-table thead tr th.lc-table__actions-cell--start,.lc-table tbody tr td.lc-table__actions-cell--start{text-align:left}.lc-table thead tr th.lc-table__actions-cell--center,.lc-table tbody tr td.lc-table__actions-cell--center{text-align:center}.lc-table thead tr th.lc-table__actions-cell--end,.lc-table tbody tr td.lc-table__actions-cell--end{text-align:right}.lc-table__actions{display:flex;align-items:center;gap:var(--spacing-2);justify-content:flex-start}.lc-table__actions-cell--center .lc-table__actions{justify-content:center}.lc-table__actions-cell--end .lc-table__actions{justify-content:flex-end}.lc-table__tree-cell{display:flex;align-items:center;min-width:0}.lc-table__tree-indent{flex:0 0 auto;align-self:stretch;position:relative}.lc-table__tree-indent:before{content:\"\";position:absolute;left:50%;top:0;bottom:0;width:1px;background-color:var(--color-border)}.lc-table__tree-chevron{flex:0 0 auto;display:inline-flex;align-items:center;justify-content:center}.lc-table__chevron-btn{display:inline-flex;align-items:center;justify-content:center;width:20px;height:20px;padding:0;border:none;background:transparent;color:var(--color-text-secondary);cursor:pointer;border-radius:var(--border-radius-sm);transition:transform .2s ease,background-color .15s ease,color .15s ease}.lc-table__chevron-btn:hover{background-color:var(--color-surface-hover);color:var(--color-text-primary)}.lc-table__chevron-btn:focus-visible{outline:2px solid var(--color-primary);outline-offset:1px}.lc-table__chevron-btn--expanded{transform:rotate(90deg)}.lc-table__tree-content{flex:1 1 auto;min-width:0}.lc-table__row--group .lc-table__tree-content{font-weight:var(--typography-font-weight-semibold)}.lc-table__edit-input{width:100%;padding:var(--spacing-1) var(--spacing-2);border:2px solid var(--color-primary);border-radius:var(--border-radius-sm);font-size:inherit;background-color:var(--color-surface-2);color:var(--color-text-primary);outline:none}.lc-table-pagination{--_lc-table-pagination-btn: var(--size-interactive-md-height);display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:var(--spacing-2) var(--spacing-4);padding:var(--spacing-3) var(--spacing-1);font-size:var(--typography-font-size-sm);color:var(--color-text-secondary)}.lc-table-pagination--sm{--_lc-table-pagination-btn: var(--size-interactive-sm-height)}.lc-table-pagination--lg{--_lc-table-pagination-btn: var(--size-interactive-lg-height)}.lc-table-pagination__info{white-space:nowrap}.lc-table-pagination__controls{display:flex;flex-wrap:wrap;align-items:center;justify-content:flex-end;gap:var(--spacing-2);margin-inline-start:auto}.lc-table-pagination__pager{display:flex;align-items:center;gap:var(--spacing-2)}.lc-table-pagination__size{--lc-select-clear-display: none;display:block;min-width:110px}.lc-table-pagination__btn{position:relative;appearance:none;border:1px solid var(--color-field-border);background-color:var(--color-surface-2);color:var(--color-text-primary);width:var(--_lc-table-pagination-btn);height:var(--_lc-table-pagination-btn);display:flex;align-items:center;justify-content:center;padding:0;border-radius:var(--border-radius-md);font-size:var(--typography-font-size-xl);line-height:1;cursor:pointer;transition:background-color .15s ease,border-color .15s ease}.lc-table-pagination__btn:before{content:\"\";position:absolute;inset:min(0px,(100% - var(--size-min-touch-height, 2.75rem)) / 2)}.lc-table-pagination__btn:hover:not(:disabled){background-color:var(--color-surface-hover);border-color:var(--color-text-secondary)}.lc-table-pagination__btn:focus-visible{outline:2px solid var(--color-primary-500);outline-offset:2px}.lc-table-pagination__btn:disabled{opacity:.4;cursor:not-allowed}.lc-table-pagination__page{white-space:nowrap;min-width:60px;text-align:center}@media(max-width:640px){.lc-table-wrapper--stack .lc-table thead{display:none}.lc-table-wrapper--stack .lc-table tbody tr{display:block;margin-bottom:var(--spacing-4);border:1px solid var(--color-border);border-radius:var(--border-radius-md)}.lc-table-wrapper--stack .lc-table tbody tr td{display:block;text-align:right;padding:var(--spacing-2) var(--spacing-4);border-bottom:1px solid var(--color-divider)}.lc-table-wrapper--stack .lc-table tbody tr td:last-child{border-bottom:none}.lc-table-wrapper--stack .lc-table tbody tr td:before{content:attr(data-label);float:left;font-weight:var(--typography-font-weight-semibold);color:var(--color-text-secondary)}}\n"]
|
|
1170
|
+
styles: [".lc-table-wrapper{width:100%}.lc-table-wrapper--responsive{overflow-x:auto;-webkit-overflow-scrolling:touch}@media(max-width:768px){.lc-table-wrapper--responsive::-webkit-scrollbar{height:8px}.lc-table-wrapper--responsive::-webkit-scrollbar-thumb{background-color:var(--color-border);border-radius:var(--border-radius-sm)}}.lc-table{width:100%;border-collapse:collapse;border-spacing:0;background-color:var(--color-surface);color:var(--color-text-primary);font-family:var(--typography-font-family)}.lc-table thead{background-color:var(--color-surface-2);border-bottom:2px solid var(--color-border-strong)}.lc-table thead tr th{padding:var(--lc-density-padding-sm, var(--spacing-3)) var(--lc-density-padding-md, var(--spacing-4));text-align:left;font-weight:var(--typography-font-weight-semibold);font-size:var(--typography-font-size-sm);text-transform:uppercase;letter-spacing:.04em;color:var(--color-text-secondary);white-space:nowrap;-webkit-user-select:none;user-select:none}.lc-table thead tr th.sortable{cursor:pointer;position:relative;padding-right:var(--spacing-8);transition:background-color .2s ease}.lc-table thead tr th.sortable:focus-visible{outline:2px solid var(--color-primary-500);outline-offset:-2px}.lc-table thead tr th.sortable:hover{background-color:var(--color-surface-hover);color:var(--color-text-primary)}.lc-table thead tr th.sortable .sort-indicator{position:absolute;right:var(--spacing-3);top:50%;transform:translateY(-50%);font-size:var(--typography-font-size-xs);color:var(--color-primary)}.lc-table thead tr th.sorted-asc,.lc-table thead tr th.sorted-desc{background-color:var(--color-surface-hover);color:var(--color-text-primary)}.lc-table tbody tr{border-bottom:1px solid var(--color-divider)}.lc-table tbody tr:focus-visible{outline:2px solid var(--color-primary-500);outline-offset:-2px}.lc-table tbody tr:last-child{border-bottom:none}.lc-table tbody tr td{padding:var(--lc-density-padding-sm, var(--spacing-3)) var(--lc-density-padding-md, var(--spacing-4))}.lc-table__empty{text-align:center;padding:var(--spacing-8) var(--spacing-4)!important;font-style:italic}.lc-table--striped tbody tr:nth-child(2n){background-color:var(--color-surface-2)}.lc-table--bordered{border:1px solid var(--color-border)}.lc-table--bordered thead tr th,.lc-table--bordered tbody tr td{border-right:1px solid var(--color-divider)}.lc-table--bordered thead tr th:last-child,.lc-table--bordered tbody tr td:last-child{border-right:none}.lc-table--bordered tbody tr{border-bottom:1px solid var(--color-border)}.lc-table--hoverable tbody tr,.lc-table--clickable tbody tr{transition:background-color .15s ease;cursor:pointer}.lc-table--hoverable tbody tr:hover,.lc-table--clickable tbody tr:hover{background-color:var(--color-surface-hover)}.lc-table--sm thead tr th,.lc-table--sm tbody tr td{padding:var(--lc-density-padding-xs, var(--spacing-2)) var(--lc-density-padding-sm, var(--spacing-3))}.lc-table--sm thead tr th{font-size:var(--typography-font-size-xs)}.lc-table--lg thead tr th,.lc-table--lg tbody tr td{padding:var(--lc-density-padding-md, var(--spacing-4)) var(--spacing-5)}.lc-table--lg thead tr th{font-size:var(--typography-font-size-base)}:where(.lc-table tbody tr td){font-size:var(--typography-font-size-sm);color:var(--color-text-primary)}:where(.lc-table--sm tbody tr td){font-size:var(--typography-font-size-xs)}:where(.lc-table--lg tbody tr td){font-size:var(--typography-font-size-base)}.lc-table thead tr th.lc-table__cell--end,.lc-table tbody tr td.lc-table__cell--end{text-align:end;font-variant-numeric:tabular-nums}.lc-table thead tr th.sortable.lc-table__cell--end{padding-inline-start:var(--spacing-8);padding-inline-end:var(--lc-density-padding-md, var(--spacing-4))}.lc-table thead tr th.sortable.lc-table__cell--end .sort-indicator{right:auto;inset-inline-end:calc(100% + var(--spacing-2))}.lc-table--sm thead tr th.sortable.lc-table__cell--end{padding-inline-end:var(--lc-density-padding-sm, var(--spacing-3))}.lc-table--lg thead tr th.sortable.lc-table__cell--end{padding-inline-end:var(--spacing-5)}.lc-table__sort-label{position:relative;display:inline-block}.lc-table__cell--end .lc-table__edit-input{text-align:end;font-variant-numeric:tabular-nums}.lc-table__caption{caption-side:top;padding:0 0 var(--spacing-3);text-align:start;font-family:var(--typography-font-family);font-size:var(--typography-font-size-base);font-weight:var(--typography-font-weight-semibold);line-height:var(--typography-line-height-normal);color:var(--color-text-primary)}.lc-table__caption--hidden{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}@media(forced-colors:active){.lc-table tbody tr:focus-visible{outline:2px solid Highlight}}.lc-table__filter-row th{padding:var(--spacing-2) var(--spacing-4)!important;background-color:var(--color-surface)!important;border-bottom:1px solid var(--color-divider)!important}.lc-table__filter-input{width:100%;display:block}.lc-table__filter-input .input-field{font-size:var(--typography-font-size-xs)}.lc-table__select-cell{width:40px;text-align:center!important;padding:var(--spacing-2)!important}.lc-table__checkbox{width:16px;height:16px;cursor:pointer;accent-color:var(--color-primary)}.lc-table__checkbox:focus-visible{outline:2px solid var(--color-primary-500);outline-offset:2px}.lc-table__row--selected{background-color:var(--color-surface-selected)!important}.lc-table__actions-cell{white-space:nowrap}.lc-table thead tr th.lc-table__actions-cell--start,.lc-table tbody tr td.lc-table__actions-cell--start{text-align:left}.lc-table thead tr th.lc-table__actions-cell--center,.lc-table tbody tr td.lc-table__actions-cell--center{text-align:center}.lc-table thead tr th.lc-table__actions-cell--end,.lc-table tbody tr td.lc-table__actions-cell--end{text-align:right}.lc-table__actions{display:flex;align-items:center;gap:var(--spacing-2);justify-content:flex-start}.lc-table__actions-cell--center .lc-table__actions{justify-content:center}.lc-table__actions-cell--end .lc-table__actions{justify-content:flex-end}.lc-table__tree-cell{display:flex;align-items:center;min-width:0}.lc-table__tree-indent{flex:0 0 auto;align-self:stretch;position:relative}.lc-table__tree-indent:before{content:\"\";position:absolute;left:50%;top:0;bottom:0;width:1px;background-color:var(--color-border)}.lc-table__tree-chevron{flex:0 0 auto;display:inline-flex;align-items:center;justify-content:center}.lc-table__chevron-btn{display:inline-flex;align-items:center;justify-content:center;width:20px;height:20px;padding:0;border:none;background:transparent;color:var(--color-text-secondary);cursor:pointer;border-radius:var(--border-radius-sm);transition:transform .2s ease,background-color .15s ease,color .15s ease}.lc-table__chevron-btn:hover{background-color:var(--color-surface-hover);color:var(--color-text-primary)}.lc-table__chevron-btn:focus-visible{outline:2px solid var(--color-primary);outline-offset:1px}.lc-table__chevron-btn--expanded{transform:rotate(90deg)}.lc-table__tree-content{flex:1 1 auto;min-width:0}.lc-table__row--group .lc-table__tree-content{font-weight:var(--typography-font-weight-semibold)}.lc-table__edit-input{width:100%;padding:var(--spacing-1) var(--spacing-2);border:2px solid var(--color-primary);border-radius:var(--border-radius-sm);font-size:inherit;background-color:var(--color-surface-2);color:var(--color-text-primary);outline:none}.lc-table-pagination{--_lc-table-pagination-btn: var(--size-interactive-md-height);display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:var(--spacing-2) var(--spacing-4);padding:var(--spacing-3) var(--spacing-1);font-size:var(--typography-font-size-sm);color:var(--color-text-secondary)}.lc-table-pagination--sm{--_lc-table-pagination-btn: var(--size-interactive-sm-height)}.lc-table-pagination--lg{--_lc-table-pagination-btn: var(--size-interactive-lg-height)}.lc-table-pagination__info{white-space:nowrap}.lc-table-pagination__controls{display:flex;flex-wrap:wrap;align-items:center;justify-content:flex-end;gap:var(--spacing-2);margin-inline-start:auto}.lc-table-pagination__pager{display:flex;align-items:center;gap:var(--spacing-2)}.lc-table-pagination__size{--lc-select-clear-display: none;display:block;min-width:110px}.lc-table-pagination__btn{position:relative;appearance:none;border:1px solid var(--color-field-border);background-color:var(--color-surface-2);color:var(--color-text-primary);width:var(--_lc-table-pagination-btn);height:var(--_lc-table-pagination-btn);display:flex;align-items:center;justify-content:center;padding:0;border-radius:var(--border-radius-md);font-size:var(--typography-font-size-xl);line-height:1;cursor:pointer;transition:background-color .15s ease,border-color .15s ease}.lc-table-pagination__btn:before{content:\"\";position:absolute;inset:min(0px,(100% - var(--size-min-touch-height, 2.75rem)) / 2)}.lc-table-pagination__btn:hover:not(:disabled){background-color:var(--color-surface-hover);border-color:var(--color-text-secondary)}.lc-table-pagination__btn:focus-visible{outline:2px solid var(--color-primary-500);outline-offset:2px}.lc-table-pagination__btn:disabled{opacity:.4;cursor:not-allowed}.lc-table-pagination__page{white-space:nowrap;min-width:60px;text-align:center}@media(max-width:640px){.lc-table-wrapper--stack .lc-table thead{display:none}.lc-table-wrapper--stack .lc-table tbody tr{display:block;margin-bottom:var(--spacing-4);border:1px solid var(--color-border);border-radius:var(--border-radius-md)}.lc-table-wrapper--stack .lc-table tbody tr td{display:block;text-align:right;padding:var(--spacing-2) var(--spacing-4);border-bottom:1px solid var(--color-divider)}.lc-table-wrapper--stack .lc-table tbody tr td:last-child{border-bottom:none}.lc-table-wrapper--stack .lc-table tbody tr td:before{content:attr(data-label);float:left;font-weight:var(--typography-font-weight-semibold);color:var(--color-text-secondary)}}@media(forced-colors:active){.lc-table__checkbox:focus-visible{outline-color:Highlight}}\n"]
|
|
1170
1171
|
}]
|
|
1171
1172
|
}],
|
|
1172
1173
|
ctorParameters: () => [],
|