@cdevhub/ngx-tw 0.2.1 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +264 -49
- package/fesm2022/cdevhub-ngx-tw-accordion.mjs +11 -7
- package/fesm2022/cdevhub-ngx-tw-accordion.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-alert.mjs +43 -29
- package/fesm2022/cdevhub-ngx-tw-alert.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-aspect-ratio.mjs +103 -0
- package/fesm2022/cdevhub-ngx-tw-aspect-ratio.mjs.map +1 -0
- package/fesm2022/cdevhub-ngx-tw-avatar.mjs +56 -31
- package/fesm2022/cdevhub-ngx-tw-avatar.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-badge.mjs +61 -35
- package/fesm2022/cdevhub-ngx-tw-badge.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-breadcrumbs.mjs +154 -93
- package/fesm2022/cdevhub-ngx-tw-breadcrumbs.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-button.mjs +24 -15
- package/fesm2022/cdevhub-ngx-tw-button.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-calendar-luxon.mjs +3 -3
- package/fesm2022/cdevhub-ngx-tw-calendar-luxon.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-calendar.mjs +408 -215
- package/fesm2022/cdevhub-ngx-tw-calendar.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-card.mjs +33 -24
- package/fesm2022/cdevhub-ngx-tw-card.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-carousel.mjs +144 -79
- package/fesm2022/cdevhub-ngx-tw-carousel.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-checkbox.mjs +99 -47
- package/fesm2022/cdevhub-ngx-tw-checkbox.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-code-block.mjs +34 -20
- package/fesm2022/cdevhub-ngx-tw-code-block.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-collapsible.mjs +46 -29
- package/fesm2022/cdevhub-ngx-tw-collapsible.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-combobox.mjs +195 -110
- package/fesm2022/cdevhub-ngx-tw-combobox.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-command-palette.mjs +140 -73
- package/fesm2022/cdevhub-ngx-tw-command-palette.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-core.mjs +16 -11
- package/fesm2022/cdevhub-ngx-tw-core.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-date-picker.mjs +393 -149
- package/fesm2022/cdevhub-ngx-tw-date-picker.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-date-range-picker.mjs +305 -150
- package/fesm2022/cdevhub-ngx-tw-date-range-picker.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-dialog.mjs +56 -43
- package/fesm2022/cdevhub-ngx-tw-dialog.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-empty-state.mjs +51 -33
- package/fesm2022/cdevhub-ngx-tw-empty-state.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-file-upload.mjs +905 -0
- package/fesm2022/cdevhub-ngx-tw-file-upload.mjs.map +1 -0
- package/fesm2022/cdevhub-ngx-tw-flip-card.mjs +49 -26
- package/fesm2022/cdevhub-ngx-tw-flip-card.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-form-field.mjs +133 -74
- package/fesm2022/cdevhub-ngx-tw-form-field.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-icon-lucide.mjs +2 -2
- package/fesm2022/cdevhub-ngx-tw-icon-lucide.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-icon.mjs +28 -17
- package/fesm2022/cdevhub-ngx-tw-icon.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-input.mjs +37 -21
- package/fesm2022/cdevhub-ngx-tw-input.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-item.mjs +33 -24
- package/fesm2022/cdevhub-ngx-tw-item.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-menu.mjs +63 -48
- package/fesm2022/cdevhub-ngx-tw-menu.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-number-input.mjs +622 -0
- package/fesm2022/cdevhub-ngx-tw-number-input.mjs.map +1 -0
- package/fesm2022/cdevhub-ngx-tw-paginator.mjs +137 -71
- package/fesm2022/cdevhub-ngx-tw-paginator.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-popover.mjs +101 -46
- package/fesm2022/cdevhub-ngx-tw-popover.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-progress-bar.mjs +57 -30
- package/fesm2022/cdevhub-ngx-tw-progress-bar.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-radio.mjs +108 -57
- package/fesm2022/cdevhub-ngx-tw-radio.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-segmented-control.mjs +46 -26
- package/fesm2022/cdevhub-ngx-tw-segmented-control.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-select.mjs +217 -122
- package/fesm2022/cdevhub-ngx-tw-select.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-separator.mjs +21 -12
- package/fesm2022/cdevhub-ngx-tw-separator.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-sheet.mjs +58 -44
- package/fesm2022/cdevhub-ngx-tw-sheet.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-skeleton.mjs +25 -14
- package/fesm2022/cdevhub-ngx-tw-skeleton.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-slider.mjs +155 -79
- package/fesm2022/cdevhub-ngx-tw-slider.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-sort.mjs +44 -25
- package/fesm2022/cdevhub-ngx-tw-sort.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-spinner.mjs +29 -16
- package/fesm2022/cdevhub-ngx-tw-spinner.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-split.mjs +72 -42
- package/fesm2022/cdevhub-ngx-tw-split.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-stat.mjs +107 -64
- package/fesm2022/cdevhub-ngx-tw-stat.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-stepper.mjs +113 -47
- package/fesm2022/cdevhub-ngx-tw-stepper.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-switch.mjs +61 -32
- package/fesm2022/cdevhub-ngx-tw-switch.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-tab-nav.mjs +88 -42
- package/fesm2022/cdevhub-ngx-tw-tab-nav.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-table.mjs +266 -118
- package/fesm2022/cdevhub-ngx-tw-table.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-tabs.mjs +101 -51
- package/fesm2022/cdevhub-ngx-tw-tabs.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-tags-input.mjs +798 -0
- package/fesm2022/cdevhub-ngx-tw-tags-input.mjs.map +1 -0
- package/fesm2022/cdevhub-ngx-tw-textarea.mjs +11 -7
- package/fesm2022/cdevhub-ngx-tw-textarea.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-theme.mjs +22 -14
- package/fesm2022/cdevhub-ngx-tw-theme.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-time-picker.mjs +243 -95
- package/fesm2022/cdevhub-ngx-tw-time-picker.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-timeline.mjs +149 -82
- package/fesm2022/cdevhub-ngx-tw-timeline.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-toast.mjs +89 -55
- package/fesm2022/cdevhub-ngx-tw-toast.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-tooltip.mjs +50 -28
- package/fesm2022/cdevhub-ngx-tw-tooltip.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-transfer.mjs +1129 -0
- package/fesm2022/cdevhub-ngx-tw-transfer.mjs.map +1 -0
- package/fesm2022/cdevhub-ngx-tw-tree.mjs +554 -0
- package/fesm2022/cdevhub-ngx-tw-tree.mjs.map +1 -0
- package/fesm2022/cdevhub-ngx-tw.mjs +7 -0
- package/fesm2022/cdevhub-ngx-tw.mjs.map +1 -1
- package/package.json +45 -20
- package/theme/index.css +10 -2
- package/types/cdevhub-ngx-tw-aspect-ratio.d.ts +40 -0
- package/types/cdevhub-ngx-tw-calendar.d.ts +39 -8
- package/types/cdevhub-ngx-tw-command-palette.d.ts +7 -0
- package/types/cdevhub-ngx-tw-date-picker.d.ts +36 -10
- package/types/cdevhub-ngx-tw-file-upload.d.ts +250 -0
- package/types/cdevhub-ngx-tw-form-field.d.ts +22 -3
- package/types/cdevhub-ngx-tw-icon-lucide.d.ts +21 -3
- package/types/cdevhub-ngx-tw-number-input.d.ts +130 -0
- package/types/cdevhub-ngx-tw-popover.d.ts +8 -0
- package/types/cdevhub-ngx-tw-stepper.d.ts +30 -2
- package/types/cdevhub-ngx-tw-tab-nav.d.ts +8 -0
- package/types/cdevhub-ngx-tw-table.d.ts +30 -1
- package/types/cdevhub-ngx-tw-tabs.d.ts +8 -0
- package/types/cdevhub-ngx-tw-tags-input.d.ts +217 -0
- package/types/cdevhub-ngx-tw-time-picker.d.ts +31 -6
- package/types/cdevhub-ngx-tw-transfer.d.ts +330 -0
- package/types/cdevhub-ngx-tw-tree.d.ts +189 -0
- package/types/cdevhub-ngx-tw.d.ts +7 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cdevhub-ngx-tw-number-input.mjs","sources":["../../../projects/ngx-tw/number-input/number-input.ts","../../../projects/ngx-tw/number-input/number-stepper.ts","../../../projects/ngx-tw/number-input/cdevhub-ngx-tw-number-input.ts"],"sourcesContent":["import {\n afterNextRender,\n computed,\n Directive,\n ElementRef,\n forwardRef,\n inject,\n input,\n isDevMode,\n output,\n signal,\n} from '@angular/core';\nimport { type ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';\nimport { TW_INPUT_VALUE_ACCESSOR } from '@cdevhub/ngx-tw/input';\n\n/**\n * Turns a plain `<input twInput twNumberInput>` into a robust numeric field\n * without `type=\"number\"` — fixing the broken-on-mobile, browser-inconsistent\n * native control. It composes the sibling {@link InputDirective}: that directive\n * keeps owning the form-field chrome, error-state, and `aria-invalid` /\n * `aria-required`, while this directive owns the numeric value transport,\n * locale-aware parse/format, spinbutton ARIA, `inputmode`, and keyboard stepping.\n *\n * Pair it with the companion `<tw-number-stepper [for]=\"ref\">` for visible\n * up/down spinner buttons.\n *\n * Forms: implements `ControlValueAccessor`, so the value round-trips as a real\n * `number | null` (never a string) through template-driven, reactive, and\n * signal-based forms.\n */\n@Directive({\n selector: 'input[twNumberInput]',\n exportAs: 'twNumberInput',\n providers: [\n // Custom CVA — transports a real `number | null`, not a string. Registered\n // statically because this directive injects NO `NgControl` (matcher /\n // error-state stay on the sibling InputDirective), so the circular-DI trap\n // that forces runtime registration does not apply. Follows the\n // segmented-control / calendar precedent. A custom accessor takes precedence\n // over the built-in DefaultValueAccessor, so there is no \"more than one\n // value accessor\" error.\n {\n provide: NG_VALUE_ACCESSOR,\n useExisting: forwardRef(() => NumberInputDirective),\n multi: true,\n },\n // Lets the sibling InputDirective read the formatted *display text* (not the\n // numeric model) for its empty / float-label state. The factory exposes the\n // `displayText` signal so InputDirective's `isSignal(value)` effect stays\n // self-healing. Must NOT be `useExisting` — that would expose the numeric\n // `value` signal and report the field empty during intermediate typing.\n {\n provide: TW_INPUT_VALUE_ACCESSOR,\n useFactory: (dir: NumberInputDirective) => ({ value: dir.displayText }),\n deps: [forwardRef(() => NumberInputDirective)],\n },\n ],\n host: {\n 'role': 'spinbutton',\n '[attr.inputmode]': 'inputMode()',\n '[attr.aria-valuemin]': 'min() ?? null',\n '[attr.aria-valuemax]': 'max() ?? null',\n '[attr.aria-valuenow]': 'value() ?? null',\n '[attr.aria-valuetext]': 'displayText() || \"Empty\"',\n '(input)': 'onInput()',\n '(keydown)': 'onKeydown($event)',\n '(focus)': 'onFocus()',\n '(blur)': 'onBlur()',\n },\n})\nexport class NumberInputDirective implements ControlValueAccessor {\n private readonly el =\n inject<ElementRef<HTMLInputElement>>(ElementRef).nativeElement;\n\n // ── Inputs ──\n\n /** Smallest accepted value. Clamps the committed value (on blur, Enter, and stepping) and sets `aria-valuemin`. Does not clamp per keystroke. Defaults to `undefined` (no lower bound). */\n readonly min = input<number | undefined>(undefined);\n\n /** Largest accepted value. Clamps the committed value (on blur, Enter, and stepping) and sets `aria-valuemax`. Does not clamp per keystroke. Defaults to `undefined` (no upper bound). */\n readonly max = input<number | undefined>(undefined);\n\n /** Amount added or subtracted by ArrowUp/ArrowDown and the stepper buttons. Defaults to `1`. Values `<= 0` or non-finite fall back to `1`. */\n readonly step = input<number>(1);\n\n /** `Intl.NumberFormat` options driving the blurred display (grouping, decimals, currency). The formatter's resolved `maximumFractionDigits` also sets commit-time rounding precision and switches `inputmode` to `'numeric'` when it is `0`. Percent style is not supported in v1. Defaults to `undefined` (locale default number formatting, grouping on). */\n readonly format = input<Intl.NumberFormatOptions | undefined>(undefined);\n\n /** BCP-47 locale for `Intl.NumberFormat` formatting and for locale-aware parsing (decimal and group separators). Defaults to `undefined` (the runtime default locale). */\n readonly locale = input<string | undefined>(undefined);\n\n // ── Output ──\n\n /** Fires when the committed numeric value changes through user interaction (typing, stepping, clamping on blur/Enter). Does not fire on `writeValue` (programmatic form writes). Useful for non-form / template-ref usage alongside the `value` signal. */\n readonly valueChange = output<number | null>();\n\n // ── State ──\n\n private readonly _value = signal<number | null>(null);\n private readonly cvaDisabled = signal(false);\n private readonly readonlySig = signal(false);\n\n /** The current committed numeric value, or `null` when empty / unparseable. Read this from a template ref (`#n=\"twNumberInput\"`) for non-form usage. */\n readonly value = this._value.asReadonly();\n\n /** @internal Formatted display text surfaced through `TW_INPUT_VALUE_ACCESSOR` so the sibling InputDirective's empty / float-label state tracks the text in the box (not the numeric model). Updated on every field mutation. */\n readonly displayText = signal<string>('');\n\n /** True when the control is disabled. Reactively tracks the reactive-forms path (`setDisabledState` via `control.disable()`) and a static `disabled` attribute read at mount. A runtime-toggled declarative `[disabled]` binding without reactive forms is NOT reactively tracked (v2 limitation — same class as `readonly`). Read by the companion stepper so its buttons disable in lock-step. */\n readonly disabled = computed(() => this.cvaDisabled() || this.el.disabled);\n\n /** True when the host input carries the `readonly` attribute (static / declarative, seeded after render). A runtime toggle of the bare `readonly` attribute is not reactively tracked (v2). Read by the companion stepper so its buttons disable in lock-step. */\n readonly readonly = this.readonlySig.asReadonly();\n\n /** @internal Mobile-keyboard hint: `'numeric'` for integer-only formats, else `'decimal'`. */\n readonly inputMode = computed(() =>\n this.format()?.maximumFractionDigits === 0 ? 'numeric' : 'decimal',\n );\n\n /** @internal Locale group / decimal separators, memoized per `locale()`. */\n private readonly separators = computed<{ group: string; decimal: string }>(\n () => {\n try {\n const parts = new Intl.NumberFormat(this.locale()).formatToParts(\n 11000.1,\n );\n return {\n group: parts.find((p) => p.type === 'group')?.value ?? '',\n decimal: parts.find((p) => p.type === 'decimal')?.value ?? '.',\n };\n } catch {\n return { group: '', decimal: '.' };\n }\n },\n );\n\n // ── Plain (non-signal) bookkeeping ──\n\n private _focused = false;\n private _lastValue: number | null = null;\n private _lastDisplay = '';\n private onChange: (value: number | null) => void = () => {};\n private onTouched: () => void = () => {};\n\n constructor() {\n // Seed `readonly` after render. InputDirective mirrors its `readonly` input\n // onto the native attribute via an effect that runs AFTER construction\n // (input.ts:330-337), so a synchronous read here would be stale.\n afterNextRender(() => this.readonlySig.set(this.el.readOnly));\n\n // Dev-mode: warn once on a bogus step (mirrors time-picker).\n afterNextRender(() => {\n if (!isDevMode()) return;\n const s = this.step();\n if (s <= 0 || !Number.isFinite(s)) {\n console.warn(`[twNumberInput] step=${s} is invalid. Using 1 instead.`);\n }\n });\n }\n\n // ── ControlValueAccessor ──\n\n /** @internal */\n writeValue(value: number | null | undefined): void {\n if (value == null || Number.isNaN(value)) {\n this._value.set(null);\n this.displayText.set('');\n this._lastValue = null;\n this._lastDisplay = '';\n if (!this._focused) this.el.value = '';\n return;\n }\n // Normalize -0 → 0 (never store a negative zero); otherwise keep the value\n // un-rounded — a programmatic write is authoritative and must not silently\n // diverge from the parent FormControl.\n const n = Object.is(value, -0) ? 0 : value;\n const display = this.formatValue(n);\n this._value.set(n);\n this.displayText.set(display);\n // Update the revert anchor even while focused, so an unparseable blur after\n // a programmatic write snaps back to the form's value (not to '').\n this._lastValue = n;\n this._lastDisplay = display;\n // Caret guard: never rewrite el.value while focused (clobbers the caret);\n // defer the visible reformat to the next blur.\n if (!this._focused) this.el.value = display;\n }\n\n /** @internal */\n registerOnChange(fn: (value: number | null) => void): void {\n this.onChange = fn;\n }\n\n /** @internal */\n registerOnTouched(fn: () => void): void {\n this.onTouched = fn;\n }\n\n /** @internal */\n setDisabledState(isDisabled: boolean): void {\n this.cvaDisabled.set(isDisabled);\n }\n\n // ── Public methods ──\n\n /** Steps the value up: treats an empty field as `0`, adds `step`, clamps to `[min,max]`, rounds to the formatter's resolved precision, formats, and writes both the display and the model. Emits `valueChange`. No-op when the host input is disabled or readonly. Does not move focus. */\n increment(): void {\n this.stepBy(1);\n }\n\n /** Steps the value down: treats an empty field as `0`, subtracts `step`, clamps to `[min,max]`, rounds, formats, writes display and model. Emits `valueChange`. No-op when disabled or readonly. Does not move focus. */\n decrement(): void {\n this.stepBy(-1);\n }\n\n /** Moves focus to the underlying input element. */\n focus(options?: FocusOptions): void {\n this.el.focus(options);\n }\n\n // ── Host handlers ──\n\n /** @internal */\n onInput(): void {\n const raw = this.el.value;\n this.displayText.set(raw);\n const parsed = this.parseValue(raw);\n this._value.set(parsed);\n this.onChange(parsed);\n this.valueChange.emit(parsed);\n }\n\n /** @internal */\n onFocus(): void {\n this._focused = true;\n }\n\n /** @internal */\n onBlur(): void {\n this._focused = false;\n this.commitFromElement();\n this.onTouched();\n }\n\n /** @internal */\n onKeydown(event: KeyboardEvent): void {\n if (this.disabled() || this.el.readOnly) return;\n switch (event.key) {\n case 'ArrowUp':\n event.preventDefault();\n this.increment();\n break;\n case 'ArrowDown':\n event.preventDefault();\n this.decrement();\n break;\n case 'Home':\n if (this.min() !== undefined) {\n event.preventDefault();\n this.commitNumber(this.min() as number);\n }\n break;\n case 'End':\n if (this.max() !== undefined) {\n event.preventDefault();\n this.commitNumber(this.max() as number);\n }\n break;\n case 'Enter':\n // Do NOT preventDefault — preserve native form submission. Commit in place.\n this.commitFromElement();\n break;\n // All other keys (PageUp/Down, text entry, caret nav, Backspace) → native.\n }\n }\n\n // ── Internal commit / step logic ──\n\n private stepBy(direction: 1 | -1): void {\n if (this.disabled() || this.el.readOnly) return;\n // Treat an empty field as 0, apply ±step, then clamp — matches native\n // <input type=\"number\">.\n const current = this.parseValue(this.el.value) ?? 0;\n this.commitNumber(current + direction * this.resolvedStep());\n }\n\n private commitFromElement(): void {\n const raw = this.el.value;\n if (raw.trim() === '') {\n this.commitEmpty();\n return;\n }\n const parsed = this.parseValue(raw);\n if (parsed === null) {\n // Non-empty unparseable → snap back to the last committed value.\n this.revertToLastCommitted();\n return;\n }\n this.commitNumber(parsed);\n }\n\n private commitNumber(n: number): void {\n const rounded = this.roundToPrecision(this.clamp(n));\n const normalized = Object.is(rounded, -0) ? 0 : rounded;\n const display = this.formatValue(normalized);\n const changed = !Object.is(this._value(), normalized);\n this._value.set(normalized);\n this.displayText.set(display);\n this._lastValue = normalized;\n this._lastDisplay = display;\n this.el.value = display;\n if (changed) {\n this.onChange(normalized);\n this.valueChange.emit(normalized);\n }\n }\n\n private commitEmpty(): void {\n const changed = this._value() !== null;\n this._value.set(null);\n this.displayText.set('');\n this._lastValue = null;\n this._lastDisplay = '';\n this.el.value = '';\n if (changed) {\n this.onChange(null);\n this.valueChange.emit(null);\n }\n }\n\n private revertToLastCommitted(): void {\n const changed = this._value() !== this._lastValue;\n this._value.set(this._lastValue);\n this.displayText.set(this._lastDisplay);\n this.el.value = this._lastDisplay;\n if (changed) {\n this.onChange(this._lastValue);\n this.valueChange.emit(this._lastValue);\n }\n }\n\n // ── Inline numeric helpers ──\n\n private resolvedStep(): number {\n const s = this.step();\n return s > 0 && Number.isFinite(s) ? s : 1;\n }\n\n private clamp(n: number): number {\n const min = this.min();\n const max = this.max();\n let r = n;\n if (min !== undefined && r < min) r = min;\n if (max !== undefined && r > max) r = max;\n return r;\n }\n\n private roundToPrecision(n: number): number {\n if (!Number.isFinite(n)) return n;\n const digits = this.resolvedMaxFractionDigits();\n if (digits === undefined) return n;\n const factor = 10 ** digits;\n return Math.round(n * factor) / factor;\n }\n\n private resolvedMaxFractionDigits(): number | undefined {\n try {\n return new Intl.NumberFormat(\n this.locale(),\n this.format(),\n ).resolvedOptions().maximumFractionDigits;\n } catch {\n return undefined;\n }\n }\n\n private formatValue(n: number): string {\n const normalized = Object.is(n, -0) ? 0 : n;\n try {\n return new Intl.NumberFormat(this.locale(), this.format()).format(\n normalized,\n );\n } catch {\n return String(normalized);\n }\n }\n\n /**\n * Parse a raw string to `number | null` in a load-bearing order: the `e`/`E`\n * rejection MUST precede stripping (otherwise `'1e3'` would survive as `'13'`).\n */\n private parseValue(raw: string): number | null {\n const trimmed = raw.trim();\n if (trimmed === '') return null;\n // 2. Reject exponent notation before any stripping.\n if (/[eE]/.test(trimmed)) return null;\n const { group, decimal } = this.separators();\n // 3. Strip all Unicode whitespace (covers NBSP / narrow-NBSP group separators\n // and a user-typed ASCII space alike).\n let s = trimmed.replace(/\\s/gu, '');\n // 4. Strip group separators (redundant-but-harmless for space-grouped locales).\n if (group) s = s.split(group).join('');\n // 5. Normalize the locale decimal separator to '.'.\n if (decimal && decimal !== '.') s = s.split(decimal).join('.');\n // 6. Strip remaining non-numeric chars (currency symbols, '%', leading '+', …)\n // and collapse to a single leading '-'.\n s = s.replace(/[^\\d.-]/g, '').replace(/(?!^)-/g, '');\n // 7. Digit-presence + finiteness guard (prevents Number('') === 0 committing 0).\n if (!/\\d/.test(s)) return null;\n const n = Number(s);\n if (!Number.isFinite(n)) return null;\n // Normalize -0 → 0 so it never enters the model from any path.\n return Object.is(n, -0) ? 0 : n;\n }\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n computed,\n input,\n} from '@angular/core';\nimport { tv } from 'tailwind-variants';\nimport type { TwSize } from '@cdevhub/ngx-tw/core';\nimport type { NumberInputDirective } from './number-input';\n\nconst numberStepper = tv(\n {\n slots: {\n // The column stretches to the field's height (host is `flex self-stretch`)\n // and the two buttons split it via `flex-1`.\n group: 'flex flex-col self-stretch',\n // `flex-1` gives each button HALF the field height. Codified departure\n // from CLAUDE.md \"Square interactive targets\" (size-6/7/8): stacking two\n // square buttons made the column 2× a button tall — far taller than the\n // text line — which is exactly what bloated the field's height. So the\n // buttons carry a fixed WIDTH only; the chevron glyph's min-content\n // (size-3 = 12px) is the natural floor that keeps the column compact.\n //\n // WCAG 2.5.8 (target-size, 24px — which slider.ts / badge.ts codify):\n // two stacked buttons cannot each be ≥24px tall inside a ~38–42px field\n // without re-bloating it, so each spinner ends up < 24px tall. The\n // equivalent-control exception covers most cases — the value is reachable\n // by typing into the ≥24px spinbutton input and, with a keyboard, via ↑/↓.\n // Known gap: a negative-allowed field on touch — iOS `inputmode`\n // numeric/decimal exposes no minus key and there are no hardware arrows,\n // so the sub-24px decrement button becomes the only path to a negative\n // value; a consumer needing negatives on touch must provide an alternative.\n // Matches the sub-24px stacked-spinner convention of native/Mantine/Chakra.\n button:\n 'flex-1 inline-flex items-center justify-center text-fg-muted hover:text-fg hover:bg-surface-muted rounded-md transition-colors duration-normal motion-reduce:transition-none focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary-500 disabled:opacity-40 disabled:pointer-events-none',\n icon: '',\n },\n variants: {\n // Button WIDTH (the height comes from `flex-1`); glyph sub-scale for the\n // chevrons (per CLAUDE.md \"Icon Sizing\").\n size: {\n xs: { button: 'w-6', icon: 'size-3' },\n sm: { button: 'w-7', icon: 'size-3' },\n md: { button: 'w-7', icon: 'size-3' },\n lg: { button: 'w-8', icon: 'size-4' },\n xl: { button: 'w-8', icon: 'size-4' },\n },\n },\n defaultVariants: { size: 'md' },\n },\n { twMerge: true },\n);\n\n/**\n * The visible up/down spinner column for a {@link NumberInputDirective}. A\n * directive cannot emit sibling DOM, so the spinner buttons live in this tiny\n * companion. Bind it to the directive via a template ref and drop it into a\n * `<tw-form-field>`'s `[twSuffix]` slot (or a standalone flex row):\n *\n * ```html\n * <input twInput twNumberInput #qty=\"twNumberInput\" [formControl]=\"ctrl\" />\n * <tw-number-stepper twSuffix [for]=\"qty\" />\n * ```\n *\n * The buttons are kept out of the tab order (`tabindex=\"-1\"`) — the spinbutton\n * input owns value + keyboard semantics — and refocus the input after stepping.\n */\n@Component({\n selector: 'tw-number-stepper',\n exportAs: 'twNumberStepper',\n changeDetection: ChangeDetectionStrategy.OnPush,\n // `flex` makes the inner group fill the host; `self-stretch` makes the host\n // fill the field height — overriding `items-center` in a `<tw-form-field>`\n // `[twSuffix]` slot, and matching `items-stretch` in a standalone flex row.\n host: {\n 'class': 'flex self-stretch',\n },\n template: `\n <div [class]=\"groupClasses()\">\n <button\n type=\"button\"\n tabindex=\"-1\"\n aria-label=\"Increase\"\n [class]=\"buttonClasses()\"\n [disabled]=\"isDisabled()\"\n (mousedown)=\"$event.preventDefault()\"\n (click)=\"onStep(1)\"\n >\n <ng-content select=\"[slot=up]\">\n <svg\n viewBox=\"0 0 20 20\"\n fill=\"currentColor\"\n aria-hidden=\"true\"\n [class]=\"iconClasses()\"\n >\n <path\n fill-rule=\"evenodd\"\n d=\"M14.77 12.79a.75.75 0 0 1-1.06-.02L10 8.94l-3.71 3.83a.75.75 0 1 1-1.08-1.04l4.25-4.39a.75.75 0 0 1 1.08 0l4.25 4.39a.75.75 0 0 1-.02 1.06Z\"\n clip-rule=\"evenodd\"\n />\n </svg>\n </ng-content>\n </button>\n <button\n type=\"button\"\n tabindex=\"-1\"\n aria-label=\"Decrease\"\n [class]=\"buttonClasses()\"\n [disabled]=\"isDisabled()\"\n (mousedown)=\"$event.preventDefault()\"\n (click)=\"onStep(-1)\"\n >\n <ng-content select=\"[slot=down]\">\n <svg\n viewBox=\"0 0 20 20\"\n fill=\"currentColor\"\n aria-hidden=\"true\"\n [class]=\"iconClasses()\"\n >\n <path\n fill-rule=\"evenodd\"\n d=\"M5.23 7.21a.75.75 0 0 1 1.06.02L10 11.06l3.71-3.83a.75.75 0 1 1 1.08 1.04l-4.25 4.39a.75.75 0 0 1-1.08 0L5.21 8.27a.75.75 0 0 1 .02-1.06Z\"\n clip-rule=\"evenodd\"\n />\n </svg>\n </ng-content>\n </button>\n </div>\n `,\n})\nexport class NumberStepperComponent {\n /** The number-input directive instance this stepper controls. Bind to a template ref, e.g. `[for]=\"qty\"` with `#qty=\"twNumberInput\"`. When omitted, the buttons render but do nothing (no-op) and disable. */\n readonly for = input<NumberInputDirective | undefined>(undefined);\n\n /** Button + glyph density. Match the field's `size` for visual alignment. Defaults to `'md'`. */\n readonly size = input<TwSize>('md');\n\n private readonly variant = computed(() => numberStepper({ size: this.size() }));\n\n /** @internal */\n readonly groupClasses = computed(() => this.variant().group());\n\n /** @internal */\n readonly buttonClasses = computed(() => this.variant().button());\n\n /** @internal */\n readonly iconClasses = computed(() => this.variant().icon());\n\n /** @internal Disabled when there is no target, or the target input is disabled / readonly. */\n readonly isDisabled = computed(() => {\n const d = this.for();\n return !d || d.disabled() || d.readonly();\n });\n\n /** @internal Step the bound directive, then refocus the input (the refocus lives here, not in `increment`/`decrement`). */\n onStep(direction: 1 | -1): void {\n const dir = this.for();\n if (!dir) return;\n if (direction === 1) {\n dir.increment();\n } else {\n dir.decrement();\n }\n dir.focus();\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
|
@@ -203,17 +203,18 @@ const paginatorVariants = tv({
|
|
|
203
203
|
*/
|
|
204
204
|
class PaginatorLabelDirective {
|
|
205
205
|
/** The label slot this template overrides. */
|
|
206
|
-
slot = input.required(
|
|
206
|
+
slot = input.required(/* @ts-ignore */
|
|
207
|
+
...(ngDevMode ? [{ debugName: "slot" }] : /* istanbul ignore next */ []));
|
|
207
208
|
/** @internal */
|
|
208
209
|
templateRef = inject((TemplateRef));
|
|
209
210
|
/** @internal */
|
|
210
211
|
static ngTemplateContextGuard(_dir, _ctx) {
|
|
211
212
|
return true;
|
|
212
213
|
}
|
|
213
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
214
|
-
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "
|
|
214
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: PaginatorLabelDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
215
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.0.7", type: PaginatorLabelDirective, isStandalone: true, selector: "ng-template[twPaginatorLabel]", inputs: { slot: { classPropertyName: "slot", publicName: "slot", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0 });
|
|
215
216
|
}
|
|
216
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
217
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: PaginatorLabelDirective, decorators: [{
|
|
217
218
|
type: Directive,
|
|
218
219
|
args: [{ selector: 'ng-template[twPaginatorLabel]' }]
|
|
219
220
|
}], propDecorators: { slot: [{ type: i0.Input, args: [{ isSignal: true, alias: "slot", required: true }] }] } });
|
|
@@ -228,10 +229,10 @@ class PaginatorEmptyDirective {
|
|
|
228
229
|
static ngTemplateContextGuard(_dir, _ctx) {
|
|
229
230
|
return true;
|
|
230
231
|
}
|
|
231
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
232
|
-
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "
|
|
232
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: PaginatorEmptyDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
233
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.0.7", type: PaginatorEmptyDirective, isStandalone: true, selector: "ng-template[twPaginatorEmpty]", ngImport: i0 });
|
|
233
234
|
}
|
|
234
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
235
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: PaginatorEmptyDirective, decorators: [{
|
|
235
236
|
type: Directive,
|
|
236
237
|
args: [{ selector: 'ng-template[twPaginatorEmpty]' }]
|
|
237
238
|
}] });
|
|
@@ -246,10 +247,10 @@ class PaginatorPageSizeSelectorDirective {
|
|
|
246
247
|
static ngTemplateContextGuard(_dir, _ctx) {
|
|
247
248
|
return true;
|
|
248
249
|
}
|
|
249
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
250
|
-
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "
|
|
250
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: PaginatorPageSizeSelectorDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
251
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.0.7", type: PaginatorPageSizeSelectorDirective, isStandalone: true, selector: "ng-template[twPaginatorPageSizeSelector]", ngImport: i0 });
|
|
251
252
|
}
|
|
252
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
253
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: PaginatorPageSizeSelectorDirective, decorators: [{
|
|
253
254
|
type: Directive,
|
|
254
255
|
args: [{ selector: 'ng-template[twPaginatorPageSizeSelector]' }]
|
|
255
256
|
}] });
|
|
@@ -266,7 +267,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
|
|
|
266
267
|
class PaginatorFocusableDirective {
|
|
267
268
|
elementRef = inject((ElementRef));
|
|
268
269
|
/** When true, the element is skipped by `FocusKeyManager` roving focus. */
|
|
269
|
-
isDisabled = input(false,
|
|
270
|
+
isDisabled = input(false, /* @ts-ignore */
|
|
271
|
+
...(ngDevMode ? [{ debugName: "isDisabled" }] : /* istanbul ignore next */ []));
|
|
270
272
|
focus() {
|
|
271
273
|
this.elementRef.nativeElement.focus();
|
|
272
274
|
}
|
|
@@ -278,10 +280,10 @@ class PaginatorFocusableDirective {
|
|
|
278
280
|
get disabled() {
|
|
279
281
|
return this.isDisabled();
|
|
280
282
|
}
|
|
281
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
282
|
-
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "
|
|
283
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: PaginatorFocusableDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
284
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.0.7", type: PaginatorFocusableDirective, isStandalone: true, selector: "[data-tw-paginator-focusable]", inputs: { isDisabled: { classPropertyName: "isDisabled", publicName: "isDisabled", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0 });
|
|
283
285
|
}
|
|
284
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
286
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: PaginatorFocusableDirective, decorators: [{
|
|
285
287
|
type: Directive,
|
|
286
288
|
args: [{
|
|
287
289
|
// eslint-disable-next-line @angular-eslint/directive-selector
|
|
@@ -293,49 +295,68 @@ let nextPaginatorId = 0;
|
|
|
293
295
|
class PaginatorComponent {
|
|
294
296
|
// ── Inputs ──
|
|
295
297
|
/** Total number of items across all pages. Defaults to `0`. */
|
|
296
|
-
totalItems = input(0,
|
|
298
|
+
totalItems = input(0, /* @ts-ignore */
|
|
299
|
+
...(ngDevMode ? [{ debugName: "totalItems" }] : /* istanbul ignore next */ []));
|
|
297
300
|
/** Items per page. Two-way bindable via `[(pageSize)]`. Defaults to `10`. */
|
|
298
|
-
pageSize = model(10,
|
|
301
|
+
pageSize = model(10, /* @ts-ignore */
|
|
302
|
+
...(ngDevMode ? [{ debugName: "pageSize" }] : /* istanbul ignore next */ []));
|
|
299
303
|
/** 1-based current page. Two-way bindable via `[(page)]`. Clamped internally. Defaults to `1`. */
|
|
300
|
-
page = model(1,
|
|
304
|
+
page = model(1, /* @ts-ignore */
|
|
305
|
+
...(ngDevMode ? [{ debugName: "page" }] : /* istanbul ignore next */ []));
|
|
301
306
|
/** Rendering type. Defaults to `'numbered'`. */
|
|
302
|
-
type = input('numbered',
|
|
307
|
+
type = input('numbered', /* @ts-ignore */
|
|
308
|
+
...(ngDevMode ? [{ debugName: "type" }] : /* istanbul ignore next */ []));
|
|
303
309
|
/** Layout density. Defaults to `'compact'`. */
|
|
304
|
-
layout = input('compact',
|
|
310
|
+
layout = input('compact', /* @ts-ignore */
|
|
311
|
+
...(ngDevMode ? [{ debugName: "layout" }] : /* istanbul ignore next */ []));
|
|
305
312
|
/** Controls padding, font size, and icon size. Defaults to `'md'`. */
|
|
306
|
-
size = input('md',
|
|
313
|
+
size = input('md', /* @ts-ignore */
|
|
314
|
+
...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
|
|
307
315
|
/** Semantic color used for the active page indicator. Defaults to `'primary'`. */
|
|
308
|
-
color = input('primary',
|
|
316
|
+
color = input('primary', /* @ts-ignore */
|
|
317
|
+
...(ngDevMode ? [{ debugName: "color" }] : /* istanbul ignore next */ []));
|
|
309
318
|
/** How many sibling pages to show on each side of the current page. Defaults to `1`. */
|
|
310
|
-
siblingCount = input(1,
|
|
319
|
+
siblingCount = input(1, /* @ts-ignore */
|
|
320
|
+
...(ngDevMode ? [{ debugName: "siblingCount" }] : /* istanbul ignore next */ []));
|
|
311
321
|
/** How many pages to always show at the start and end boundaries. Defaults to `1`. */
|
|
312
|
-
boundaryCount = input(1,
|
|
322
|
+
boundaryCount = input(1, /* @ts-ignore */
|
|
323
|
+
...(ngDevMode ? [{ debugName: "boundaryCount" }] : /* istanbul ignore next */ []));
|
|
313
324
|
/** When true, renders jump-to-first and jump-to-last buttons. Defaults to `true`. */
|
|
314
325
|
// TRUE-default: first/last jumps are the standard pagination affordance for
|
|
315
326
|
// any list large enough to need a paginator; opt-out is for compact paginators.
|
|
316
|
-
showFirstLastButtons = input(true,
|
|
327
|
+
showFirstLastButtons = input(true, /* @ts-ignore */
|
|
328
|
+
...(ngDevMode ? [{ debugName: "showFirstLastButtons" }] : /* istanbul ignore next */ []));
|
|
317
329
|
/** When true, renders the page-size selector region. Defaults to `false`. */
|
|
318
|
-
showPageSizeSelector = input(false,
|
|
330
|
+
showPageSizeSelector = input(false, /* @ts-ignore */
|
|
331
|
+
...(ngDevMode ? [{ debugName: "showPageSizeSelector" }] : /* istanbul ignore next */ []));
|
|
319
332
|
/** Options for the default page-size selector. Ignored when `*twPaginatorPageSizeSelector` is projected. Defaults to `[10, 25, 50, 100]`. */
|
|
320
|
-
pageSizeOptions = input([10, 25, 50, 100],
|
|
333
|
+
pageSizeOptions = input([10, 25, 50, 100], /* @ts-ignore */
|
|
334
|
+
...(ngDevMode ? [{ debugName: "pageSizeOptions" }] : /* istanbul ignore next */ []));
|
|
321
335
|
/** When true, renders the page-info text region. Defaults to `true`. */
|
|
322
336
|
// TRUE-default: showing "X–Y of Z" is the expected pagination context; opt-out
|
|
323
337
|
// is for ultra-compact paginators that fit in tight UI.
|
|
324
|
-
showPageInfo = input(true,
|
|
338
|
+
showPageInfo = input(true, /* @ts-ignore */
|
|
339
|
+
...(ngDevMode ? [{ debugName: "showPageInfo" }] : /* istanbul ignore next */ []));
|
|
325
340
|
/** When true, renders nothing when `totalItems === 0`. Defaults to `true`. */
|
|
326
341
|
// TRUE-default: hiding the paginator on empty data is expected UX; opt-out is
|
|
327
342
|
// for layouts that need to reserve the paginator's vertical space.
|
|
328
|
-
hideOnEmpty = input(true,
|
|
343
|
+
hideOnEmpty = input(true, /* @ts-ignore */
|
|
344
|
+
...(ngDevMode ? [{ debugName: "hideOnEmpty" }] : /* istanbul ignore next */ []));
|
|
329
345
|
/** When true, renders nothing when `totalPages <= 1`. Defaults to `false`. */
|
|
330
|
-
hideOnSinglePage = input(false,
|
|
346
|
+
hideOnSinglePage = input(false, /* @ts-ignore */
|
|
347
|
+
...(ngDevMode ? [{ debugName: "hideOnSinglePage" }] : /* istanbul ignore next */ []));
|
|
331
348
|
/** Responsive collapse mode. Defaults to `'auto'`. */
|
|
332
|
-
responsive = input('auto',
|
|
349
|
+
responsive = input('auto', /* @ts-ignore */
|
|
350
|
+
...(ngDevMode ? [{ debugName: "responsive" }] : /* istanbul ignore next */ []));
|
|
333
351
|
/** When true, every button is disabled. Defaults to `false`. */
|
|
334
|
-
disabled = input(false,
|
|
352
|
+
disabled = input(false, /* @ts-ignore */
|
|
353
|
+
...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
|
|
335
354
|
/** Partial string labels object for i18n. Unset keys fall back to English defaults. Defaults to `{}`. */
|
|
336
|
-
labels = input({},
|
|
355
|
+
labels = input({}, /* @ts-ignore */
|
|
356
|
+
...(ngDevMode ? [{ debugName: "labels" }] : /* istanbul ignore next */ []));
|
|
337
357
|
/** When provided, buttons render as anchor links using the returned `href`. Defaults to `undefined` (renders as buttons). */
|
|
338
|
-
linkFactory = input(undefined,
|
|
358
|
+
linkFactory = input(undefined, /* @ts-ignore */
|
|
359
|
+
...(ngDevMode ? [{ debugName: "linkFactory" }] : /* istanbul ignore next */ []));
|
|
339
360
|
/** Overrides `labels.ariaLabel` for the root `<nav>` element. */
|
|
340
361
|
customAriaLabel = input(undefined, { ...(ngDevMode ? { debugName: "customAriaLabel" } : /* istanbul ignore next */ {}), alias: 'aria-label' });
|
|
341
362
|
// ── Outputs ──
|
|
@@ -343,63 +364,81 @@ class PaginatorComponent {
|
|
|
343
364
|
paginated = output();
|
|
344
365
|
// ── Projected templates ──
|
|
345
366
|
/** @internal */
|
|
346
|
-
labelDirectives = contentChildren(PaginatorLabelDirective,
|
|
367
|
+
labelDirectives = contentChildren(PaginatorLabelDirective, /* @ts-ignore */
|
|
368
|
+
...(ngDevMode ? [{ debugName: "labelDirectives" }] : /* istanbul ignore next */ []));
|
|
347
369
|
/** @internal */
|
|
348
|
-
emptyDirective = contentChild(PaginatorEmptyDirective,
|
|
370
|
+
emptyDirective = contentChild(PaginatorEmptyDirective, /* @ts-ignore */
|
|
371
|
+
...(ngDevMode ? [{ debugName: "emptyDirective" }] : /* istanbul ignore next */ []));
|
|
349
372
|
/** @internal */
|
|
350
|
-
pageSizeSelectorDirective = contentChild(PaginatorPageSizeSelectorDirective,
|
|
373
|
+
pageSizeSelectorDirective = contentChild(PaginatorPageSizeSelectorDirective, /* @ts-ignore */
|
|
374
|
+
...(ngDevMode ? [{ debugName: "pageSizeSelectorDirective" }] : /* istanbul ignore next */ []));
|
|
351
375
|
// ── Injected services ──
|
|
352
376
|
_liveAnnouncer = inject(LiveAnnouncer);
|
|
353
377
|
_elementRef = inject((ElementRef));
|
|
354
378
|
// ── View children ──
|
|
355
379
|
/** @internal All nav-group focusables (first/prev/page/next/last) for `FocusKeyManager`. */
|
|
356
|
-
focusableItems = viewChildren(PaginatorFocusableDirective,
|
|
380
|
+
focusableItems = viewChildren(PaginatorFocusableDirective, /* @ts-ignore */
|
|
381
|
+
...(ngDevMode ? [{ debugName: "focusableItems" }] : /* istanbul ignore next */ []));
|
|
357
382
|
// ── IDs ──
|
|
358
383
|
_componentId = `tw-paginator-${nextPaginatorId++}`;
|
|
359
384
|
/** @internal */
|
|
360
385
|
pageSizeSelectId = `${this._componentId}-size`;
|
|
361
386
|
// ── Derived state ──
|
|
362
387
|
/** @internal Effective page size, coerced to at least 1. */
|
|
363
|
-
effectivePageSize = computed(() => Math.max(1, this.pageSize()),
|
|
388
|
+
effectivePageSize = computed(() => Math.max(1, this.pageSize()), /* @ts-ignore */
|
|
389
|
+
...(ngDevMode ? [{ debugName: "effectivePageSize" }] : /* istanbul ignore next */ []));
|
|
364
390
|
/** @internal Total number of pages; always ≥ 1 to keep clamping math well-defined. */
|
|
365
391
|
totalPages = computed(() => {
|
|
366
392
|
const total = this.totalItems();
|
|
367
393
|
if (total <= 0)
|
|
368
394
|
return 1;
|
|
369
395
|
return Math.max(1, Math.ceil(total / this.effectivePageSize()));
|
|
370
|
-
},
|
|
396
|
+
}, /* @ts-ignore */
|
|
397
|
+
...(ngDevMode ? [{ debugName: "totalPages" }] : /* istanbul ignore next */ []));
|
|
371
398
|
/** @internal Current page clamped into `[1, totalPages]`. */
|
|
372
|
-
clampedPage = computed(() => Math.min(Math.max(1, this.page()), this.totalPages()),
|
|
399
|
+
clampedPage = computed(() => Math.min(Math.max(1, this.page()), this.totalPages()), /* @ts-ignore */
|
|
400
|
+
...(ngDevMode ? [{ debugName: "clampedPage" }] : /* istanbul ignore next */ []));
|
|
373
401
|
/** @internal 1-based start item index on the current page. `0` when empty. */
|
|
374
402
|
startItem = computed(() => {
|
|
375
403
|
if (this.totalItems() <= 0)
|
|
376
404
|
return 0;
|
|
377
405
|
return (this.clampedPage() - 1) * this.effectivePageSize() + 1;
|
|
378
|
-
},
|
|
406
|
+
}, /* @ts-ignore */
|
|
407
|
+
...(ngDevMode ? [{ debugName: "startItem" }] : /* istanbul ignore next */ []));
|
|
379
408
|
/** @internal 1-based end item index on the current page. `0` when empty. */
|
|
380
409
|
endItem = computed(() => {
|
|
381
410
|
if (this.totalItems() <= 0)
|
|
382
411
|
return 0;
|
|
383
412
|
return Math.min(this.clampedPage() * this.effectivePageSize(), this.totalItems());
|
|
384
|
-
},
|
|
413
|
+
}, /* @ts-ignore */
|
|
414
|
+
...(ngDevMode ? [{ debugName: "endItem" }] : /* istanbul ignore next */ []));
|
|
385
415
|
/** @internal Visible page range for the numbered type. */
|
|
386
|
-
range = computed(() => buildPaginationRange(this.clampedPage(), this.totalPages(), this.siblingCount(), this.boundaryCount()),
|
|
416
|
+
range = computed(() => buildPaginationRange(this.clampedPage(), this.totalPages(), this.siblingCount(), this.boundaryCount()), /* @ts-ignore */
|
|
417
|
+
...(ngDevMode ? [{ debugName: "range" }] : /* istanbul ignore next */ []));
|
|
387
418
|
/** @internal Merged labels. */
|
|
388
419
|
resolvedLabels = computed(() => ({
|
|
389
420
|
...DEFAULT_LABELS,
|
|
390
421
|
...this.labels(),
|
|
391
|
-
}),
|
|
422
|
+
}), /* @ts-ignore */
|
|
423
|
+
...(ngDevMode ? [{ debugName: "resolvedLabels" }] : /* istanbul ignore next */ []));
|
|
392
424
|
/** @internal Resolved aria-label for the root. */
|
|
393
|
-
resolvedAriaLabel = computed(() => this.customAriaLabel() ?? this.resolvedLabels().ariaLabel,
|
|
425
|
+
resolvedAriaLabel = computed(() => this.customAriaLabel() ?? this.resolvedLabels().ariaLabel, /* @ts-ignore */
|
|
426
|
+
...(ngDevMode ? [{ debugName: "resolvedAriaLabel" }] : /* istanbul ignore next */ []));
|
|
394
427
|
/** @internal `container-name` for the CSS container query (set only when responsive="auto"). */
|
|
395
|
-
containerName = computed(() => this.responsive() === 'auto' ? 'paginator' : null,
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
428
|
+
containerName = computed(() => this.responsive() === 'auto' ? 'paginator' : null, /* @ts-ignore */
|
|
429
|
+
...(ngDevMode ? [{ debugName: "containerName" }] : /* istanbul ignore next */ []));
|
|
430
|
+
isEmpty = computed(() => this.totalItems() <= 0, /* @ts-ignore */
|
|
431
|
+
...(ngDevMode ? [{ debugName: "isEmpty" }] : /* istanbul ignore next */ []));
|
|
432
|
+
isAtFirstPage = computed(() => this.clampedPage() <= 1, /* @ts-ignore */
|
|
433
|
+
...(ngDevMode ? [{ debugName: "isAtFirstPage" }] : /* istanbul ignore next */ []));
|
|
434
|
+
isAtLastPage = computed(() => this.clampedPage() >= this.totalPages(), /* @ts-ignore */
|
|
435
|
+
...(ngDevMode ? [{ debugName: "isAtLastPage" }] : /* istanbul ignore next */ []));
|
|
399
436
|
/** @internal Target page for the Previous button (clamped to `[1, totalPages]`). */
|
|
400
|
-
previousTarget = computed(() => Math.max(1, this.clampedPage() - 1),
|
|
437
|
+
previousTarget = computed(() => Math.max(1, this.clampedPage() - 1), /* @ts-ignore */
|
|
438
|
+
...(ngDevMode ? [{ debugName: "previousTarget" }] : /* istanbul ignore next */ []));
|
|
401
439
|
/** @internal Target page for the Next button (clamped to `[1, totalPages]`). */
|
|
402
|
-
nextTarget = computed(() => Math.min(this.totalPages(), this.clampedPage() + 1),
|
|
440
|
+
nextTarget = computed(() => Math.min(this.totalPages(), this.clampedPage() + 1), /* @ts-ignore */
|
|
441
|
+
...(ngDevMode ? [{ debugName: "nextTarget" }] : /* istanbul ignore next */ []));
|
|
403
442
|
/** @internal Whether the component should render at all. */
|
|
404
443
|
shouldRender = computed(() => {
|
|
405
444
|
if (this.isEmpty() && this.hideOnEmpty())
|
|
@@ -407,7 +446,8 @@ class PaginatorComponent {
|
|
|
407
446
|
if (this.hideOnSinglePage() && this.totalPages() <= 1 && !this.isEmpty())
|
|
408
447
|
return false;
|
|
409
448
|
return true;
|
|
410
|
-
},
|
|
449
|
+
}, /* @ts-ignore */
|
|
450
|
+
...(ngDevMode ? [{ debugName: "shouldRender" }] : /* istanbul ignore next */ []));
|
|
411
451
|
// ── Variant class computation ──
|
|
412
452
|
_variantResult = computed(() => paginatorVariants({
|
|
413
453
|
size: this.size(),
|
|
@@ -415,19 +455,32 @@ class PaginatorComponent {
|
|
|
415
455
|
type: this.type(),
|
|
416
456
|
responsive: this.responsive(),
|
|
417
457
|
disabled: this.disabled(),
|
|
418
|
-
}),
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
458
|
+
}), /* @ts-ignore */
|
|
459
|
+
...(ngDevMode ? [{ debugName: "_variantResult" }] : /* istanbul ignore next */ []));
|
|
460
|
+
rootClasses = computed(() => this._variantResult().root(), /* @ts-ignore */
|
|
461
|
+
...(ngDevMode ? [{ debugName: "rootClasses" }] : /* istanbul ignore next */ []));
|
|
462
|
+
innerClasses = computed(() => this._variantResult().inner(), /* @ts-ignore */
|
|
463
|
+
...(ngDevMode ? [{ debugName: "innerClasses" }] : /* istanbul ignore next */ []));
|
|
464
|
+
pageSizeGroupClasses = computed(() => this._variantResult().pageSizeGroup(), /* @ts-ignore */
|
|
465
|
+
...(ngDevMode ? [{ debugName: "pageSizeGroupClasses" }] : /* istanbul ignore next */ []));
|
|
466
|
+
pageSizeLabelClasses = computed(() => this._variantResult().pageSizeLabel(), /* @ts-ignore */
|
|
467
|
+
...(ngDevMode ? [{ debugName: "pageSizeLabelClasses" }] : /* istanbul ignore next */ []));
|
|
468
|
+
pageSizeSelectClasses = computed(() => this._variantResult().pageSizeSelect(), /* @ts-ignore */
|
|
469
|
+
...(ngDevMode ? [{ debugName: "pageSizeSelectClasses" }] : /* istanbul ignore next */ []));
|
|
470
|
+
pageInfoClasses = computed(() => this._variantResult().pageInfo(), /* @ts-ignore */
|
|
471
|
+
...(ngDevMode ? [{ debugName: "pageInfoClasses" }] : /* istanbul ignore next */ []));
|
|
472
|
+
navGroupClasses = computed(() => this._variantResult().navGroup(), /* @ts-ignore */
|
|
473
|
+
...(ngDevMode ? [{ debugName: "navGroupClasses" }] : /* istanbul ignore next */ []));
|
|
474
|
+
pageListClasses = computed(() => this._variantResult().pageList(), /* @ts-ignore */
|
|
475
|
+
...(ngDevMode ? [{ debugName: "pageListClasses" }] : /* istanbul ignore next */ []));
|
|
476
|
+
navButtonClasses = computed(() => this._variantResult().navButton(), /* @ts-ignore */
|
|
477
|
+
...(ngDevMode ? [{ debugName: "navButtonClasses" }] : /* istanbul ignore next */ []));
|
|
478
|
+
ellipsisClasses = computed(() => this._variantResult().ellipsis(), /* @ts-ignore */
|
|
479
|
+
...(ngDevMode ? [{ debugName: "ellipsisClasses" }] : /* istanbul ignore next */ []));
|
|
480
|
+
emptyStateClasses = computed(() => this._variantResult().emptyState(), /* @ts-ignore */
|
|
481
|
+
...(ngDevMode ? [{ debugName: "emptyStateClasses" }] : /* istanbul ignore next */ []));
|
|
482
|
+
iconClasses = computed(() => this._variantResult().icon(), /* @ts-ignore */
|
|
483
|
+
...(ngDevMode ? [{ debugName: "iconClasses" }] : /* istanbul ignore next */ []));
|
|
431
484
|
/** @internal Applies active-color classes to the current page button. */
|
|
432
485
|
pageButtonClasses(active) {
|
|
433
486
|
const base = this._variantResult().pageButton();
|
|
@@ -453,7 +506,8 @@ class PaginatorComponent {
|
|
|
453
506
|
pageSize: this.effectivePageSize(),
|
|
454
507
|
disabled: this.disabled(),
|
|
455
508
|
},
|
|
456
|
-
}),
|
|
509
|
+
}), /* @ts-ignore */
|
|
510
|
+
...(ngDevMode ? [{ debugName: "labelContext" }] : /* istanbul ignore next */ []));
|
|
457
511
|
/** @internal */
|
|
458
512
|
pageSizeContext = computed(() => ({
|
|
459
513
|
$implicit: {
|
|
@@ -461,7 +515,8 @@ class PaginatorComponent {
|
|
|
461
515
|
options: this.pageSizeOptions(),
|
|
462
516
|
setPageSize: (n) => this._setPageSize(n),
|
|
463
517
|
},
|
|
464
|
-
}),
|
|
518
|
+
}), /* @ts-ignore */
|
|
519
|
+
...(ngDevMode ? [{ debugName: "pageSizeContext" }] : /* istanbul ignore next */ []));
|
|
465
520
|
// ── Rendered strings ──
|
|
466
521
|
/** @internal Default page-info string (type-aware). */
|
|
467
522
|
formattedPageInfo = computed(() => {
|
|
@@ -476,7 +531,8 @@ class PaginatorComponent {
|
|
|
476
531
|
});
|
|
477
532
|
}
|
|
478
533
|
return `${labels.pageInfo} ${this.clampedPage()}${labels.pageInfoSeparator}${this.totalPages()}`;
|
|
479
|
-
},
|
|
534
|
+
}, /* @ts-ignore */
|
|
535
|
+
...(ngDevMode ? [{ debugName: "formattedPageInfo" }] : /* istanbul ignore next */ []));
|
|
480
536
|
/** @internal ARIA label for a numbered page button. */
|
|
481
537
|
formatPageButtonLabel(page) {
|
|
482
538
|
return formatLabel(this.resolvedLabels().pageButtonAriaLabel, { page });
|
|
@@ -511,6 +567,16 @@ class PaginatorComponent {
|
|
|
511
567
|
});
|
|
512
568
|
// Emit pageChange whenever page or pageSize changes (after initial render).
|
|
513
569
|
// When an out-of-range page is detected, clamp and emit with source 'programmatic'.
|
|
570
|
+
//
|
|
571
|
+
// DOCUMENTED no-write-in-effect exception (see CLAUDE.md). This effect reads
|
|
572
|
+
// `page()` *and* writes `page.set(clamped)` — an intrinsic cycle, because the
|
|
573
|
+
// clamp must fire both when `totalPages` shrinks AND when the consumer assigns
|
|
574
|
+
// an out-of-range page (so `page` must stay a tracked dependency). The cycle is
|
|
575
|
+
// bounded by the `clamped !== newPage` guard: the write re-triggers the effect
|
|
576
|
+
// exactly once, the re-run sees an in-range value, and it settles. It never
|
|
577
|
+
// loops/freezes. The `untracked()` wrapper does NOT break this cycle (page is
|
|
578
|
+
// tracked above); its job is to keep the signal reads inside `_emitChange` /
|
|
579
|
+
// `_announce` from registering as effect dependencies.
|
|
514
580
|
effect(() => {
|
|
515
581
|
const newPage = this.page();
|
|
516
582
|
const newSize = this.pageSize();
|
|
@@ -674,10 +740,10 @@ class PaginatorComponent {
|
|
|
674
740
|
console.warn('[tw-paginator] showPageSizeSelector is true but pageSizeOptions is empty — selector will not render.');
|
|
675
741
|
}
|
|
676
742
|
}
|
|
677
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
678
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: PaginatorComponent, isStandalone: true, selector: "tw-paginator", inputs: { totalItems: { classPropertyName: "totalItems", publicName: "totalItems", isSignal: true, isRequired: false, transformFunction: null }, pageSize: { classPropertyName: "pageSize", publicName: "pageSize", isSignal: true, isRequired: false, transformFunction: null }, page: { classPropertyName: "page", publicName: "page", isSignal: true, isRequired: false, transformFunction: null }, type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: false, transformFunction: null }, layout: { classPropertyName: "layout", publicName: "layout", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null }, siblingCount: { classPropertyName: "siblingCount", publicName: "siblingCount", isSignal: true, isRequired: false, transformFunction: null }, boundaryCount: { classPropertyName: "boundaryCount", publicName: "boundaryCount", isSignal: true, isRequired: false, transformFunction: null }, showFirstLastButtons: { classPropertyName: "showFirstLastButtons", publicName: "showFirstLastButtons", isSignal: true, isRequired: false, transformFunction: null }, showPageSizeSelector: { classPropertyName: "showPageSizeSelector", publicName: "showPageSizeSelector", isSignal: true, isRequired: false, transformFunction: null }, pageSizeOptions: { classPropertyName: "pageSizeOptions", publicName: "pageSizeOptions", isSignal: true, isRequired: false, transformFunction: null }, showPageInfo: { classPropertyName: "showPageInfo", publicName: "showPageInfo", isSignal: true, isRequired: false, transformFunction: null }, hideOnEmpty: { classPropertyName: "hideOnEmpty", publicName: "hideOnEmpty", isSignal: true, isRequired: false, transformFunction: null }, hideOnSinglePage: { classPropertyName: "hideOnSinglePage", publicName: "hideOnSinglePage", isSignal: true, isRequired: false, transformFunction: null }, responsive: { classPropertyName: "responsive", publicName: "responsive", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, labels: { classPropertyName: "labels", publicName: "labels", isSignal: true, isRequired: false, transformFunction: null }, linkFactory: { classPropertyName: "linkFactory", publicName: "linkFactory", isSignal: true, isRequired: false, transformFunction: null }, customAriaLabel: { classPropertyName: "customAriaLabel", publicName: "aria-label", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { pageSize: "pageSizeChange", page: "pageChange", paginated: "paginated" }, host: { properties: { "attr.role": "shouldRender() ? \"navigation\" : null", "class": "rootClasses()", "attr.aria-label": "shouldRender() ? resolvedAriaLabel() : null", "style.container-name": "containerName()" } }, queries: [{ propertyName: "labelDirectives", predicate: PaginatorLabelDirective, isSignal: true }, { propertyName: "emptyDirective", first: true, predicate: PaginatorEmptyDirective, descendants: true, isSignal: true }, { propertyName: "pageSizeSelectorDirective", first: true, predicate: PaginatorPageSizeSelectorDirective, descendants: true, isSignal: true }], viewQueries: [{ propertyName: "focusableItems", predicate: PaginatorFocusableDirective, descendants: true, isSignal: true }], exportAs: ["twPaginator"], ngImport: i0, template: "@if (shouldRender()) {\n <div [class]=\"innerClasses()\">\n @if (isEmpty()) {\n <!-- Empty state -->\n @if (emptyDirective(); as emptyDir) {\n <ng-container\n [ngTemplateOutlet]=\"emptyDir.templateRef\"\n [ngTemplateOutletContext]=\"labelContext()\"\n />\n } @else {\n <span [class]=\"emptyStateClasses()\">{{ resolvedLabels().empty }}</span>\n }\n } @else {\n <!-- Page-size selector region -->\n @if (showPageSizeSelector() && pageSizeOptions().length > 0) {\n <div [class]=\"pageSizeGroupClasses()\">\n <label\n [attr.for]=\"pageSizeSelectId\"\n [class]=\"pageSizeLabelClasses()\"\n >\n @if (labelTemplateFor('pageSizeLabel'); as tmpl) {\n <ng-container\n [ngTemplateOutlet]=\"tmpl\"\n [ngTemplateOutletContext]=\"labelContext()\"\n />\n } @else {\n {{ resolvedLabels().pageSizeLabel }}\n }\n </label>\n\n @if (pageSizeSelectorDirective(); as dir) {\n <ng-container\n [ngTemplateOutlet]=\"dir.templateRef\"\n [ngTemplateOutletContext]=\"pageSizeContext()\"\n />\n } @else {\n <select\n [id]=\"pageSizeSelectId\"\n [class]=\"pageSizeSelectClasses()\"\n [disabled]=\"disabled()\"\n [value]=\"effectivePageSize()\"\n (change)=\"onPageSizeSelectChange($event)\"\n >\n @for (opt of pageSizeOptions(); track opt) {\n <option [value]=\"opt\">{{ opt }}</option>\n }\n </select>\n }\n </div>\n }\n\n <!-- Page info region -->\n @if (showPageInfo()) {\n <div [class]=\"pageInfoClasses()\">\n @if (labelTemplateFor('pageInfo'); as tmpl) {\n <ng-container\n [ngTemplateOutlet]=\"tmpl\"\n [ngTemplateOutletContext]=\"labelContext()\"\n />\n } @else {\n {{ formattedPageInfo() }}\n }\n </div>\n }\n\n <!-- Nav buttons region. Roving focus is owned by FocusKeyManager on the\n child buttons; this wrapper only relays keydown to the manager, so\n it does not need its own tabindex. -->\n <!-- eslint-disable-next-line @angular-eslint/template/interactive-supports-focus -->\n <div\n [class]=\"navGroupClasses()\"\n (keydown)=\"onKeydown($event)\"\n >\n <!-- First -->\n @if (showFirstLastButtons()) {\n @let firstDisabled = disabled() || isAtFirstPage();\n @if (linkFactory()) {\n <a\n data-tw-paginator-focusable\n [isDisabled]=\"firstDisabled\"\n data-tw-paginator-nav=\"first\"\n [class]=\"navButtonClasses()\"\n [attr.href]=\"firstDisabled ? null : hrefFor(1)\"\n [attr.aria-disabled]=\"firstDisabled ? 'true' : null\"\n [attr.tabindex]=\"firstDisabled ? -1 : 0\"\n [attr.aria-label]=\"resolvedLabels().first\"\n (click)=\"onLinkClick($event, 1, firstDisabled, 'click')\"\n >\n @if (labelTemplateFor('first'); as tmpl) {\n <ng-container\n [ngTemplateOutlet]=\"tmpl\"\n [ngTemplateOutletContext]=\"labelContext()\"\n />\n } @else {\n <svg\n [class]=\"iconClasses()\"\n viewBox=\"0 0 20 20\"\n fill=\"currentColor\"\n aria-hidden=\"true\"\n >\n <path\n fill-rule=\"evenodd\"\n d=\"M10.78 4.22a.75.75 0 0 1 0 1.06L6.06 10l4.72 4.72a.75.75 0 0 1-1.06 1.06l-5.25-5.25a.75.75 0 0 1 0-1.06l5.25-5.25a.75.75 0 0 1 1.06 0Zm6 0a.75.75 0 0 1 0 1.06L12.06 10l4.72 4.72a.75.75 0 1 1-1.06 1.06l-5.25-5.25a.75.75 0 0 1 0-1.06l5.25-5.25a.75.75 0 0 1 1.06 0Z\"\n clip-rule=\"evenodd\"\n />\n </svg>\n }\n </a>\n } @else {\n <button\n type=\"button\"\n data-tw-paginator-focusable\n [isDisabled]=\"firstDisabled\"\n data-tw-paginator-nav=\"first\"\n [class]=\"navButtonClasses()\"\n [disabled]=\"firstDisabled\"\n [attr.aria-label]=\"resolvedLabels().first\"\n (click)=\"goTo(1, 'click')\"\n >\n @if (labelTemplateFor('first'); as tmpl) {\n <ng-container\n [ngTemplateOutlet]=\"tmpl\"\n [ngTemplateOutletContext]=\"labelContext()\"\n />\n } @else {\n <svg\n [class]=\"iconClasses()\"\n viewBox=\"0 0 20 20\"\n fill=\"currentColor\"\n aria-hidden=\"true\"\n >\n <path\n fill-rule=\"evenodd\"\n d=\"M10.78 4.22a.75.75 0 0 1 0 1.06L6.06 10l4.72 4.72a.75.75 0 0 1-1.06 1.06l-5.25-5.25a.75.75 0 0 1 0-1.06l5.25-5.25a.75.75 0 0 1 1.06 0Zm6 0a.75.75 0 0 1 0 1.06L12.06 10l4.72 4.72a.75.75 0 1 1-1.06 1.06l-5.25-5.25a.75.75 0 0 1 0-1.06l5.25-5.25a.75.75 0 0 1 1.06 0Z\"\n clip-rule=\"evenodd\"\n />\n </svg>\n }\n </button>\n }\n }\n\n <!-- Previous -->\n @let prevDisabled = disabled() || isAtFirstPage();\n @let prevTarget = previousTarget();\n @if (linkFactory()) {\n <a\n data-tw-paginator-focusable\n [isDisabled]=\"prevDisabled\"\n data-tw-paginator-nav=\"prev\"\n [class]=\"navButtonClasses()\"\n [attr.href]=\"prevDisabled ? null : hrefFor(prevTarget)\"\n [attr.aria-disabled]=\"prevDisabled ? 'true' : null\"\n [attr.tabindex]=\"prevDisabled ? -1 : 0\"\n [attr.aria-label]=\"resolvedLabels().previous\"\n (click)=\"onLinkClick($event, prevTarget, prevDisabled, 'click')\"\n >\n @if (labelTemplateFor('previous'); as tmpl) {\n <ng-container\n [ngTemplateOutlet]=\"tmpl\"\n [ngTemplateOutletContext]=\"labelContext()\"\n />\n } @else {\n <svg\n [class]=\"iconClasses()\"\n viewBox=\"0 0 20 20\"\n fill=\"currentColor\"\n aria-hidden=\"true\"\n >\n <path\n fill-rule=\"evenodd\"\n d=\"M12.78 5.22a.75.75 0 0 1 0 1.06L9.06 10l3.72 3.72a.75.75 0 1 1-1.06 1.06l-4.25-4.25a.75.75 0 0 1 0-1.06l4.25-4.25a.75.75 0 0 1 1.06 0Z\"\n clip-rule=\"evenodd\"\n />\n </svg>\n }\n </a>\n } @else {\n <button\n type=\"button\"\n data-tw-paginator-focusable\n [isDisabled]=\"prevDisabled\"\n data-tw-paginator-nav=\"prev\"\n [class]=\"navButtonClasses()\"\n [disabled]=\"prevDisabled\"\n [attr.aria-label]=\"resolvedLabels().previous\"\n (click)=\"goTo(prevTarget, 'click')\"\n >\n @if (labelTemplateFor('previous'); as tmpl) {\n <ng-container\n [ngTemplateOutlet]=\"tmpl\"\n [ngTemplateOutletContext]=\"labelContext()\"\n />\n } @else {\n <svg\n [class]=\"iconClasses()\"\n viewBox=\"0 0 20 20\"\n fill=\"currentColor\"\n aria-hidden=\"true\"\n >\n <path\n fill-rule=\"evenodd\"\n d=\"M12.78 5.22a.75.75 0 0 1 0 1.06L9.06 10l3.72 3.72a.75.75 0 1 1-1.06 1.06l-4.25-4.25a.75.75 0 0 1 0-1.06l4.25-4.25a.75.75 0 0 1 1.06 0Z\"\n clip-rule=\"evenodd\"\n />\n </svg>\n }\n </button>\n }\n\n <!-- Numbered page list -->\n @if (type() === 'numbered') {\n <div [class]=\"pageListClasses()\">\n @for (item of range(); track $index) {\n @if (item === 'ellipsis-left' || item === 'ellipsis-right') {\n <span\n [class]=\"ellipsisClasses()\"\n [attr.aria-label]=\"resolvedLabels().ellipsis\"\n >\n <span aria-hidden=\"true\">…</span>\n </span>\n } @else {\n @let pageNumber = item;\n @let isActive = pageNumber === clampedPage();\n @let pageDisabled = disabled();\n @if (linkFactory()) {\n <a\n data-tw-paginator-focusable\n [isDisabled]=\"pageDisabled\"\n data-tw-paginator-nav=\"page\"\n [class]=\"pageButtonClasses(isActive)\"\n [attr.href]=\"pageDisabled ? null : hrefFor(pageNumber)\"\n [attr.aria-disabled]=\"pageDisabled ? 'true' : null\"\n [attr.tabindex]=\"pageDisabled ? -1 : 0\"\n [attr.aria-current]=\"isActive ? 'page' : null\"\n [attr.aria-label]=\"\n isActive\n ? formatCurrentPageLabel(pageNumber)\n : formatPageButtonLabel(pageNumber)\n \"\n (click)=\"onLinkClick($event, pageNumber, pageDisabled, 'click')\"\n >{{ pageNumber }}</a>\n } @else {\n <button\n type=\"button\"\n data-tw-paginator-focusable\n [isDisabled]=\"pageDisabled\"\n data-tw-paginator-nav=\"page\"\n [class]=\"pageButtonClasses(isActive)\"\n [disabled]=\"pageDisabled\"\n [attr.aria-current]=\"isActive ? 'page' : null\"\n [attr.aria-label]=\"\n isActive\n ? formatCurrentPageLabel(pageNumber)\n : formatPageButtonLabel(pageNumber)\n \"\n (click)=\"goTo(pageNumber, 'click')\"\n >{{ pageNumber }}</button>\n }\n }\n }\n </div>\n }\n\n <!-- Next -->\n @let nextDisabled = disabled() || isAtLastPage();\n @let nextTargetPage = nextTarget();\n @if (linkFactory()) {\n <a\n data-tw-paginator-focusable\n [isDisabled]=\"nextDisabled\"\n data-tw-paginator-nav=\"next\"\n [class]=\"navButtonClasses()\"\n [attr.href]=\"nextDisabled ? null : hrefFor(nextTargetPage)\"\n [attr.aria-disabled]=\"nextDisabled ? 'true' : null\"\n [attr.tabindex]=\"nextDisabled ? -1 : 0\"\n [attr.aria-label]=\"resolvedLabels().next\"\n (click)=\"onLinkClick($event, nextTargetPage, nextDisabled, 'click')\"\n >\n @if (labelTemplateFor('next'); as tmpl) {\n <ng-container\n [ngTemplateOutlet]=\"tmpl\"\n [ngTemplateOutletContext]=\"labelContext()\"\n />\n } @else {\n <svg\n [class]=\"iconClasses()\"\n viewBox=\"0 0 20 20\"\n fill=\"currentColor\"\n aria-hidden=\"true\"\n >\n <path\n fill-rule=\"evenodd\"\n d=\"M7.22 14.78a.75.75 0 0 1 0-1.06L10.94 10 7.22 6.28a.75.75 0 0 1 1.06-1.06l4.25 4.25a.75.75 0 0 1 0 1.06l-4.25 4.25a.75.75 0 0 1-1.06 0Z\"\n clip-rule=\"evenodd\"\n />\n </svg>\n }\n </a>\n } @else {\n <button\n type=\"button\"\n data-tw-paginator-focusable\n [isDisabled]=\"nextDisabled\"\n data-tw-paginator-nav=\"next\"\n [class]=\"navButtonClasses()\"\n [disabled]=\"nextDisabled\"\n [attr.aria-label]=\"resolvedLabels().next\"\n (click)=\"goTo(nextTargetPage, 'click')\"\n >\n @if (labelTemplateFor('next'); as tmpl) {\n <ng-container\n [ngTemplateOutlet]=\"tmpl\"\n [ngTemplateOutletContext]=\"labelContext()\"\n />\n } @else {\n <svg\n [class]=\"iconClasses()\"\n viewBox=\"0 0 20 20\"\n fill=\"currentColor\"\n aria-hidden=\"true\"\n >\n <path\n fill-rule=\"evenodd\"\n d=\"M7.22 14.78a.75.75 0 0 1 0-1.06L10.94 10 7.22 6.28a.75.75 0 0 1 1.06-1.06l4.25 4.25a.75.75 0 0 1 0 1.06l-4.25 4.25a.75.75 0 0 1-1.06 0Z\"\n clip-rule=\"evenodd\"\n />\n </svg>\n }\n </button>\n }\n\n <!-- Last -->\n @if (showFirstLastButtons()) {\n @let lastDisabled = disabled() || isAtLastPage();\n @if (linkFactory()) {\n <a\n data-tw-paginator-focusable\n [isDisabled]=\"lastDisabled\"\n data-tw-paginator-nav=\"last\"\n [class]=\"navButtonClasses()\"\n [attr.href]=\"lastDisabled ? null : hrefFor(totalPages())\"\n [attr.aria-disabled]=\"lastDisabled ? 'true' : null\"\n [attr.tabindex]=\"lastDisabled ? -1 : 0\"\n [attr.aria-label]=\"resolvedLabels().last\"\n (click)=\"onLinkClick($event, totalPages(), lastDisabled, 'click')\"\n >\n @if (labelTemplateFor('last'); as tmpl) {\n <ng-container\n [ngTemplateOutlet]=\"tmpl\"\n [ngTemplateOutletContext]=\"labelContext()\"\n />\n } @else {\n <svg\n [class]=\"iconClasses()\"\n viewBox=\"0 0 20 20\"\n fill=\"currentColor\"\n aria-hidden=\"true\"\n >\n <path\n fill-rule=\"evenodd\"\n d=\"M3.22 4.22a.75.75 0 0 1 1.06 0l5.25 5.25a.75.75 0 0 1 0 1.06l-5.25 5.25a.75.75 0 0 1-1.06-1.06L7.94 10 3.22 5.28a.75.75 0 0 1 0-1.06Zm6 0a.75.75 0 0 1 1.06 0l5.25 5.25a.75.75 0 0 1 0 1.06l-5.25 5.25a.75.75 0 1 1-1.06-1.06L13.94 10 9.22 5.28a.75.75 0 0 1 0-1.06Z\"\n clip-rule=\"evenodd\"\n />\n </svg>\n }\n </a>\n } @else {\n <button\n type=\"button\"\n data-tw-paginator-focusable\n [isDisabled]=\"lastDisabled\"\n data-tw-paginator-nav=\"last\"\n [class]=\"navButtonClasses()\"\n [disabled]=\"lastDisabled\"\n [attr.aria-label]=\"resolvedLabels().last\"\n (click)=\"goTo(totalPages(), 'click')\"\n >\n @if (labelTemplateFor('last'); as tmpl) {\n <ng-container\n [ngTemplateOutlet]=\"tmpl\"\n [ngTemplateOutletContext]=\"labelContext()\"\n />\n } @else {\n <svg\n [class]=\"iconClasses()\"\n viewBox=\"0 0 20 20\"\n fill=\"currentColor\"\n aria-hidden=\"true\"\n >\n <path\n fill-rule=\"evenodd\"\n d=\"M3.22 4.22a.75.75 0 0 1 1.06 0l5.25 5.25a.75.75 0 0 1 0 1.06l-5.25 5.25a.75.75 0 0 1-1.06-1.06L7.94 10 3.22 5.28a.75.75 0 0 1 0-1.06Zm6 0a.75.75 0 0 1 1.06 0l5.25 5.25a.75.75 0 0 1 0 1.06l-5.25 5.25a.75.75 0 1 1-1.06-1.06L13.94 10 9.22 5.28a.75.75 0 0 1 0-1.06Z\"\n clip-rule=\"evenodd\"\n />\n </svg>\n }\n </button>\n }\n }\n </div>\n }\n </div>\n}\n", dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: PaginatorFocusableDirective, selector: "[data-tw-paginator-focusable]", inputs: ["isDisabled"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
743
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: PaginatorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
744
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.7", type: PaginatorComponent, isStandalone: true, selector: "tw-paginator", inputs: { totalItems: { classPropertyName: "totalItems", publicName: "totalItems", isSignal: true, isRequired: false, transformFunction: null }, pageSize: { classPropertyName: "pageSize", publicName: "pageSize", isSignal: true, isRequired: false, transformFunction: null }, page: { classPropertyName: "page", publicName: "page", isSignal: true, isRequired: false, transformFunction: null }, type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: false, transformFunction: null }, layout: { classPropertyName: "layout", publicName: "layout", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null }, siblingCount: { classPropertyName: "siblingCount", publicName: "siblingCount", isSignal: true, isRequired: false, transformFunction: null }, boundaryCount: { classPropertyName: "boundaryCount", publicName: "boundaryCount", isSignal: true, isRequired: false, transformFunction: null }, showFirstLastButtons: { classPropertyName: "showFirstLastButtons", publicName: "showFirstLastButtons", isSignal: true, isRequired: false, transformFunction: null }, showPageSizeSelector: { classPropertyName: "showPageSizeSelector", publicName: "showPageSizeSelector", isSignal: true, isRequired: false, transformFunction: null }, pageSizeOptions: { classPropertyName: "pageSizeOptions", publicName: "pageSizeOptions", isSignal: true, isRequired: false, transformFunction: null }, showPageInfo: { classPropertyName: "showPageInfo", publicName: "showPageInfo", isSignal: true, isRequired: false, transformFunction: null }, hideOnEmpty: { classPropertyName: "hideOnEmpty", publicName: "hideOnEmpty", isSignal: true, isRequired: false, transformFunction: null }, hideOnSinglePage: { classPropertyName: "hideOnSinglePage", publicName: "hideOnSinglePage", isSignal: true, isRequired: false, transformFunction: null }, responsive: { classPropertyName: "responsive", publicName: "responsive", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, labels: { classPropertyName: "labels", publicName: "labels", isSignal: true, isRequired: false, transformFunction: null }, linkFactory: { classPropertyName: "linkFactory", publicName: "linkFactory", isSignal: true, isRequired: false, transformFunction: null }, customAriaLabel: { classPropertyName: "customAriaLabel", publicName: "aria-label", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { pageSize: "pageSizeChange", page: "pageChange", paginated: "paginated" }, host: { properties: { "attr.role": "shouldRender() ? \"navigation\" : null", "class": "rootClasses()", "attr.aria-label": "shouldRender() ? resolvedAriaLabel() : null", "style.container-name": "containerName()" } }, queries: [{ propertyName: "labelDirectives", predicate: PaginatorLabelDirective, isSignal: true }, { propertyName: "emptyDirective", first: true, predicate: PaginatorEmptyDirective, descendants: true, isSignal: true }, { propertyName: "pageSizeSelectorDirective", first: true, predicate: PaginatorPageSizeSelectorDirective, descendants: true, isSignal: true }], viewQueries: [{ propertyName: "focusableItems", predicate: PaginatorFocusableDirective, descendants: true, isSignal: true }], exportAs: ["twPaginator"], ngImport: i0, template: "@if (shouldRender()) {\n <div [class]=\"innerClasses()\">\n @if (isEmpty()) {\n <!-- Empty state -->\n @if (emptyDirective(); as emptyDir) {\n <ng-container\n [ngTemplateOutlet]=\"emptyDir.templateRef\"\n [ngTemplateOutletContext]=\"labelContext()\"\n />\n } @else {\n <span [class]=\"emptyStateClasses()\">{{ resolvedLabels().empty }}</span>\n }\n } @else {\n <!-- Page-size selector region -->\n @if (showPageSizeSelector() && pageSizeOptions().length > 0) {\n <div [class]=\"pageSizeGroupClasses()\">\n <label\n [attr.for]=\"pageSizeSelectId\"\n [class]=\"pageSizeLabelClasses()\"\n >\n @if (labelTemplateFor('pageSizeLabel'); as tmpl) {\n <ng-container\n [ngTemplateOutlet]=\"tmpl\"\n [ngTemplateOutletContext]=\"labelContext()\"\n />\n } @else {\n {{ resolvedLabels().pageSizeLabel }}\n }\n </label>\n\n @if (pageSizeSelectorDirective(); as dir) {\n <ng-container\n [ngTemplateOutlet]=\"dir.templateRef\"\n [ngTemplateOutletContext]=\"pageSizeContext()\"\n />\n } @else {\n <select\n [id]=\"pageSizeSelectId\"\n [class]=\"pageSizeSelectClasses()\"\n [disabled]=\"disabled()\"\n [value]=\"effectivePageSize()\"\n (change)=\"onPageSizeSelectChange($event)\"\n >\n @for (opt of pageSizeOptions(); track opt) {\n <option [value]=\"opt\">{{ opt }}</option>\n }\n </select>\n }\n </div>\n }\n\n <!-- Page info region -->\n @if (showPageInfo()) {\n <div [class]=\"pageInfoClasses()\">\n @if (labelTemplateFor('pageInfo'); as tmpl) {\n <ng-container\n [ngTemplateOutlet]=\"tmpl\"\n [ngTemplateOutletContext]=\"labelContext()\"\n />\n } @else {\n {{ formattedPageInfo() }}\n }\n </div>\n }\n\n <!-- Nav buttons region. Roving focus is owned by FocusKeyManager on the\n child buttons; this wrapper only relays keydown to the manager, so\n it does not need its own tabindex. -->\n <!-- eslint-disable-next-line @angular-eslint/template/interactive-supports-focus -->\n <div\n [class]=\"navGroupClasses()\"\n (keydown)=\"onKeydown($event)\"\n >\n <!-- First -->\n @if (showFirstLastButtons()) {\n @let firstDisabled = disabled() || isAtFirstPage();\n @if (linkFactory()) {\n <a\n data-tw-paginator-focusable\n [isDisabled]=\"firstDisabled\"\n data-tw-paginator-nav=\"first\"\n [class]=\"navButtonClasses()\"\n [attr.href]=\"firstDisabled ? null : hrefFor(1)\"\n [attr.aria-disabled]=\"firstDisabled ? 'true' : null\"\n [attr.tabindex]=\"firstDisabled ? -1 : 0\"\n [attr.aria-label]=\"resolvedLabels().first\"\n (click)=\"onLinkClick($event, 1, firstDisabled, 'click')\"\n >\n @if (labelTemplateFor('first'); as tmpl) {\n <ng-container\n [ngTemplateOutlet]=\"tmpl\"\n [ngTemplateOutletContext]=\"labelContext()\"\n />\n } @else {\n <svg\n [class]=\"iconClasses()\"\n viewBox=\"0 0 20 20\"\n fill=\"currentColor\"\n aria-hidden=\"true\"\n >\n <path\n fill-rule=\"evenodd\"\n d=\"M10.78 4.22a.75.75 0 0 1 0 1.06L6.06 10l4.72 4.72a.75.75 0 0 1-1.06 1.06l-5.25-5.25a.75.75 0 0 1 0-1.06l5.25-5.25a.75.75 0 0 1 1.06 0Zm6 0a.75.75 0 0 1 0 1.06L12.06 10l4.72 4.72a.75.75 0 1 1-1.06 1.06l-5.25-5.25a.75.75 0 0 1 0-1.06l5.25-5.25a.75.75 0 0 1 1.06 0Z\"\n clip-rule=\"evenodd\"\n />\n </svg>\n }\n </a>\n } @else {\n <button\n type=\"button\"\n data-tw-paginator-focusable\n [isDisabled]=\"firstDisabled\"\n data-tw-paginator-nav=\"first\"\n [class]=\"navButtonClasses()\"\n [disabled]=\"firstDisabled\"\n [attr.aria-label]=\"resolvedLabels().first\"\n (click)=\"goTo(1, 'click')\"\n >\n @if (labelTemplateFor('first'); as tmpl) {\n <ng-container\n [ngTemplateOutlet]=\"tmpl\"\n [ngTemplateOutletContext]=\"labelContext()\"\n />\n } @else {\n <svg\n [class]=\"iconClasses()\"\n viewBox=\"0 0 20 20\"\n fill=\"currentColor\"\n aria-hidden=\"true\"\n >\n <path\n fill-rule=\"evenodd\"\n d=\"M10.78 4.22a.75.75 0 0 1 0 1.06L6.06 10l4.72 4.72a.75.75 0 0 1-1.06 1.06l-5.25-5.25a.75.75 0 0 1 0-1.06l5.25-5.25a.75.75 0 0 1 1.06 0Zm6 0a.75.75 0 0 1 0 1.06L12.06 10l4.72 4.72a.75.75 0 1 1-1.06 1.06l-5.25-5.25a.75.75 0 0 1 0-1.06l5.25-5.25a.75.75 0 0 1 1.06 0Z\"\n clip-rule=\"evenodd\"\n />\n </svg>\n }\n </button>\n }\n }\n\n <!-- Previous -->\n @let prevDisabled = disabled() || isAtFirstPage();\n @let prevTarget = previousTarget();\n @if (linkFactory()) {\n <a\n data-tw-paginator-focusable\n [isDisabled]=\"prevDisabled\"\n data-tw-paginator-nav=\"prev\"\n [class]=\"navButtonClasses()\"\n [attr.href]=\"prevDisabled ? null : hrefFor(prevTarget)\"\n [attr.aria-disabled]=\"prevDisabled ? 'true' : null\"\n [attr.tabindex]=\"prevDisabled ? -1 : 0\"\n [attr.aria-label]=\"resolvedLabels().previous\"\n (click)=\"onLinkClick($event, prevTarget, prevDisabled, 'click')\"\n >\n @if (labelTemplateFor('previous'); as tmpl) {\n <ng-container\n [ngTemplateOutlet]=\"tmpl\"\n [ngTemplateOutletContext]=\"labelContext()\"\n />\n } @else {\n <svg\n [class]=\"iconClasses()\"\n viewBox=\"0 0 20 20\"\n fill=\"currentColor\"\n aria-hidden=\"true\"\n >\n <path\n fill-rule=\"evenodd\"\n d=\"M12.78 5.22a.75.75 0 0 1 0 1.06L9.06 10l3.72 3.72a.75.75 0 1 1-1.06 1.06l-4.25-4.25a.75.75 0 0 1 0-1.06l4.25-4.25a.75.75 0 0 1 1.06 0Z\"\n clip-rule=\"evenodd\"\n />\n </svg>\n }\n </a>\n } @else {\n <button\n type=\"button\"\n data-tw-paginator-focusable\n [isDisabled]=\"prevDisabled\"\n data-tw-paginator-nav=\"prev\"\n [class]=\"navButtonClasses()\"\n [disabled]=\"prevDisabled\"\n [attr.aria-label]=\"resolvedLabels().previous\"\n (click)=\"goTo(prevTarget, 'click')\"\n >\n @if (labelTemplateFor('previous'); as tmpl) {\n <ng-container\n [ngTemplateOutlet]=\"tmpl\"\n [ngTemplateOutletContext]=\"labelContext()\"\n />\n } @else {\n <svg\n [class]=\"iconClasses()\"\n viewBox=\"0 0 20 20\"\n fill=\"currentColor\"\n aria-hidden=\"true\"\n >\n <path\n fill-rule=\"evenodd\"\n d=\"M12.78 5.22a.75.75 0 0 1 0 1.06L9.06 10l3.72 3.72a.75.75 0 1 1-1.06 1.06l-4.25-4.25a.75.75 0 0 1 0-1.06l4.25-4.25a.75.75 0 0 1 1.06 0Z\"\n clip-rule=\"evenodd\"\n />\n </svg>\n }\n </button>\n }\n\n <!-- Numbered page list -->\n @if (type() === 'numbered') {\n <div [class]=\"pageListClasses()\">\n @for (item of range(); track $index) {\n @if (item === 'ellipsis-left' || item === 'ellipsis-right') {\n <span\n [class]=\"ellipsisClasses()\"\n [attr.aria-label]=\"resolvedLabels().ellipsis\"\n >\n <span aria-hidden=\"true\">…</span>\n </span>\n } @else {\n @let pageNumber = item;\n @let isActive = pageNumber === clampedPage();\n @let pageDisabled = disabled();\n @if (linkFactory()) {\n <a\n data-tw-paginator-focusable\n [isDisabled]=\"pageDisabled\"\n data-tw-paginator-nav=\"page\"\n [class]=\"pageButtonClasses(isActive)\"\n [attr.href]=\"pageDisabled ? null : hrefFor(pageNumber)\"\n [attr.aria-disabled]=\"pageDisabled ? 'true' : null\"\n [attr.tabindex]=\"pageDisabled ? -1 : 0\"\n [attr.aria-current]=\"isActive ? 'page' : null\"\n [attr.aria-label]=\"\n isActive\n ? formatCurrentPageLabel(pageNumber)\n : formatPageButtonLabel(pageNumber)\n \"\n (click)=\"onLinkClick($event, pageNumber, pageDisabled, 'click')\"\n >{{ pageNumber }}</a>\n } @else {\n <button\n type=\"button\"\n data-tw-paginator-focusable\n [isDisabled]=\"pageDisabled\"\n data-tw-paginator-nav=\"page\"\n [class]=\"pageButtonClasses(isActive)\"\n [disabled]=\"pageDisabled\"\n [attr.aria-current]=\"isActive ? 'page' : null\"\n [attr.aria-label]=\"\n isActive\n ? formatCurrentPageLabel(pageNumber)\n : formatPageButtonLabel(pageNumber)\n \"\n (click)=\"goTo(pageNumber, 'click')\"\n >{{ pageNumber }}</button>\n }\n }\n }\n </div>\n }\n\n <!-- Next -->\n @let nextDisabled = disabled() || isAtLastPage();\n @let nextTargetPage = nextTarget();\n @if (linkFactory()) {\n <a\n data-tw-paginator-focusable\n [isDisabled]=\"nextDisabled\"\n data-tw-paginator-nav=\"next\"\n [class]=\"navButtonClasses()\"\n [attr.href]=\"nextDisabled ? null : hrefFor(nextTargetPage)\"\n [attr.aria-disabled]=\"nextDisabled ? 'true' : null\"\n [attr.tabindex]=\"nextDisabled ? -1 : 0\"\n [attr.aria-label]=\"resolvedLabels().next\"\n (click)=\"onLinkClick($event, nextTargetPage, nextDisabled, 'click')\"\n >\n @if (labelTemplateFor('next'); as tmpl) {\n <ng-container\n [ngTemplateOutlet]=\"tmpl\"\n [ngTemplateOutletContext]=\"labelContext()\"\n />\n } @else {\n <svg\n [class]=\"iconClasses()\"\n viewBox=\"0 0 20 20\"\n fill=\"currentColor\"\n aria-hidden=\"true\"\n >\n <path\n fill-rule=\"evenodd\"\n d=\"M7.22 14.78a.75.75 0 0 1 0-1.06L10.94 10 7.22 6.28a.75.75 0 0 1 1.06-1.06l4.25 4.25a.75.75 0 0 1 0 1.06l-4.25 4.25a.75.75 0 0 1-1.06 0Z\"\n clip-rule=\"evenodd\"\n />\n </svg>\n }\n </a>\n } @else {\n <button\n type=\"button\"\n data-tw-paginator-focusable\n [isDisabled]=\"nextDisabled\"\n data-tw-paginator-nav=\"next\"\n [class]=\"navButtonClasses()\"\n [disabled]=\"nextDisabled\"\n [attr.aria-label]=\"resolvedLabels().next\"\n (click)=\"goTo(nextTargetPage, 'click')\"\n >\n @if (labelTemplateFor('next'); as tmpl) {\n <ng-container\n [ngTemplateOutlet]=\"tmpl\"\n [ngTemplateOutletContext]=\"labelContext()\"\n />\n } @else {\n <svg\n [class]=\"iconClasses()\"\n viewBox=\"0 0 20 20\"\n fill=\"currentColor\"\n aria-hidden=\"true\"\n >\n <path\n fill-rule=\"evenodd\"\n d=\"M7.22 14.78a.75.75 0 0 1 0-1.06L10.94 10 7.22 6.28a.75.75 0 0 1 1.06-1.06l4.25 4.25a.75.75 0 0 1 0 1.06l-4.25 4.25a.75.75 0 0 1-1.06 0Z\"\n clip-rule=\"evenodd\"\n />\n </svg>\n }\n </button>\n }\n\n <!-- Last -->\n @if (showFirstLastButtons()) {\n @let lastDisabled = disabled() || isAtLastPage();\n @if (linkFactory()) {\n <a\n data-tw-paginator-focusable\n [isDisabled]=\"lastDisabled\"\n data-tw-paginator-nav=\"last\"\n [class]=\"navButtonClasses()\"\n [attr.href]=\"lastDisabled ? null : hrefFor(totalPages())\"\n [attr.aria-disabled]=\"lastDisabled ? 'true' : null\"\n [attr.tabindex]=\"lastDisabled ? -1 : 0\"\n [attr.aria-label]=\"resolvedLabels().last\"\n (click)=\"onLinkClick($event, totalPages(), lastDisabled, 'click')\"\n >\n @if (labelTemplateFor('last'); as tmpl) {\n <ng-container\n [ngTemplateOutlet]=\"tmpl\"\n [ngTemplateOutletContext]=\"labelContext()\"\n />\n } @else {\n <svg\n [class]=\"iconClasses()\"\n viewBox=\"0 0 20 20\"\n fill=\"currentColor\"\n aria-hidden=\"true\"\n >\n <path\n fill-rule=\"evenodd\"\n d=\"M3.22 4.22a.75.75 0 0 1 1.06 0l5.25 5.25a.75.75 0 0 1 0 1.06l-5.25 5.25a.75.75 0 0 1-1.06-1.06L7.94 10 3.22 5.28a.75.75 0 0 1 0-1.06Zm6 0a.75.75 0 0 1 1.06 0l5.25 5.25a.75.75 0 0 1 0 1.06l-5.25 5.25a.75.75 0 1 1-1.06-1.06L13.94 10 9.22 5.28a.75.75 0 0 1 0-1.06Z\"\n clip-rule=\"evenodd\"\n />\n </svg>\n }\n </a>\n } @else {\n <button\n type=\"button\"\n data-tw-paginator-focusable\n [isDisabled]=\"lastDisabled\"\n data-tw-paginator-nav=\"last\"\n [class]=\"navButtonClasses()\"\n [disabled]=\"lastDisabled\"\n [attr.aria-label]=\"resolvedLabels().last\"\n (click)=\"goTo(totalPages(), 'click')\"\n >\n @if (labelTemplateFor('last'); as tmpl) {\n <ng-container\n [ngTemplateOutlet]=\"tmpl\"\n [ngTemplateOutletContext]=\"labelContext()\"\n />\n } @else {\n <svg\n [class]=\"iconClasses()\"\n viewBox=\"0 0 20 20\"\n fill=\"currentColor\"\n aria-hidden=\"true\"\n >\n <path\n fill-rule=\"evenodd\"\n d=\"M3.22 4.22a.75.75 0 0 1 1.06 0l5.25 5.25a.75.75 0 0 1 0 1.06l-5.25 5.25a.75.75 0 0 1-1.06-1.06L7.94 10 3.22 5.28a.75.75 0 0 1 0-1.06Zm6 0a.75.75 0 0 1 1.06 0l5.25 5.25a.75.75 0 0 1 0 1.06l-5.25 5.25a.75.75 0 1 1-1.06-1.06L13.94 10 9.22 5.28a.75.75 0 0 1 0-1.06Z\"\n clip-rule=\"evenodd\"\n />\n </svg>\n }\n </button>\n }\n }\n </div>\n }\n </div>\n}\n", dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: PaginatorFocusableDirective, selector: "[data-tw-paginator-focusable]", inputs: ["isDisabled"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
679
745
|
}
|
|
680
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
746
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: PaginatorComponent, decorators: [{
|
|
681
747
|
type: Component,
|
|
682
748
|
args: [{ selector: 'tw-paginator', exportAs: 'twPaginator', changeDetection: ChangeDetectionStrategy.OnPush, imports: [NgTemplateOutlet, PaginatorFocusableDirective], host: {
|
|
683
749
|
'[attr.role]': 'shouldRender() ? "navigation" : null',
|