@cdevhub/ngx-tw 0.2.1 → 0.4.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/index.json +1 -0
- 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
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cdevhub/ngx-tw",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "Angular component library for Tailwind CSS v4 — accessible, signal-based, built on Angular CDK.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"angular",
|
|
@@ -24,26 +24,8 @@
|
|
|
24
24
|
"bugs": {
|
|
25
25
|
"url": "https://github.com/avs2001/ngx-tw/issues"
|
|
26
26
|
},
|
|
27
|
-
"peerDependencies": {
|
|
28
|
-
"@angular/common": "^21.2.0",
|
|
29
|
-
"@angular/core": "^21.2.0",
|
|
30
|
-
"@angular/cdk": "^21.0.0",
|
|
31
|
-
"tailwindcss": "^4.0.0",
|
|
32
|
-
"tailwind-variants": "^0.3.0"
|
|
33
|
-
},
|
|
34
|
-
"dependencies": {
|
|
35
|
-
"tslib": "^2.3.0"
|
|
36
|
-
},
|
|
37
|
-
"engines": {
|
|
38
|
-
"node": ">=20.19.0 || >=22.12.0"
|
|
39
|
-
},
|
|
40
|
-
"sideEffects": false,
|
|
41
|
-
"publishConfig": {
|
|
42
|
-
"access": "public"
|
|
43
|
-
},
|
|
44
|
-
"module": "fesm2022/cdevhub-ngx-tw.mjs",
|
|
45
|
-
"typings": "types/cdevhub-ngx-tw.d.ts",
|
|
46
27
|
"exports": {
|
|
28
|
+
"./theme/*.css": "./theme/*.css",
|
|
47
29
|
"./package.json": {
|
|
48
30
|
"default": "./package.json"
|
|
49
31
|
},
|
|
@@ -59,6 +41,10 @@
|
|
|
59
41
|
"types": "./types/cdevhub-ngx-tw-alert.d.ts",
|
|
60
42
|
"default": "./fesm2022/cdevhub-ngx-tw-alert.mjs"
|
|
61
43
|
},
|
|
44
|
+
"./aspect-ratio": {
|
|
45
|
+
"types": "./types/cdevhub-ngx-tw-aspect-ratio.d.ts",
|
|
46
|
+
"default": "./fesm2022/cdevhub-ngx-tw-aspect-ratio.mjs"
|
|
47
|
+
},
|
|
62
48
|
"./avatar": {
|
|
63
49
|
"types": "./types/cdevhub-ngx-tw-avatar.d.ts",
|
|
64
50
|
"default": "./fesm2022/cdevhub-ngx-tw-avatar.mjs"
|
|
@@ -135,6 +121,10 @@
|
|
|
135
121
|
"types": "./types/cdevhub-ngx-tw-empty-state.d.ts",
|
|
136
122
|
"default": "./fesm2022/cdevhub-ngx-tw-empty-state.mjs"
|
|
137
123
|
},
|
|
124
|
+
"./file-upload": {
|
|
125
|
+
"types": "./types/cdevhub-ngx-tw-file-upload.d.ts",
|
|
126
|
+
"default": "./fesm2022/cdevhub-ngx-tw-file-upload.mjs"
|
|
127
|
+
},
|
|
138
128
|
"./flip-card": {
|
|
139
129
|
"types": "./types/cdevhub-ngx-tw-flip-card.d.ts",
|
|
140
130
|
"default": "./fesm2022/cdevhub-ngx-tw-flip-card.mjs"
|
|
@@ -163,6 +153,10 @@
|
|
|
163
153
|
"types": "./types/cdevhub-ngx-tw-menu.d.ts",
|
|
164
154
|
"default": "./fesm2022/cdevhub-ngx-tw-menu.mjs"
|
|
165
155
|
},
|
|
156
|
+
"./number-input": {
|
|
157
|
+
"types": "./types/cdevhub-ngx-tw-number-input.d.ts",
|
|
158
|
+
"default": "./fesm2022/cdevhub-ngx-tw-number-input.mjs"
|
|
159
|
+
},
|
|
166
160
|
"./paginator": {
|
|
167
161
|
"types": "./types/cdevhub-ngx-tw-paginator.d.ts",
|
|
168
162
|
"default": "./fesm2022/cdevhub-ngx-tw-paginator.mjs"
|
|
@@ -239,6 +233,10 @@
|
|
|
239
233
|
"types": "./types/cdevhub-ngx-tw-tabs.d.ts",
|
|
240
234
|
"default": "./fesm2022/cdevhub-ngx-tw-tabs.mjs"
|
|
241
235
|
},
|
|
236
|
+
"./tags-input": {
|
|
237
|
+
"types": "./types/cdevhub-ngx-tw-tags-input.d.ts",
|
|
238
|
+
"default": "./fesm2022/cdevhub-ngx-tw-tags-input.mjs"
|
|
239
|
+
},
|
|
242
240
|
"./textarea": {
|
|
243
241
|
"types": "./types/cdevhub-ngx-tw-textarea.d.ts",
|
|
244
242
|
"default": "./fesm2022/cdevhub-ngx-tw-textarea.mjs"
|
|
@@ -262,7 +260,34 @@
|
|
|
262
260
|
"./tooltip": {
|
|
263
261
|
"types": "./types/cdevhub-ngx-tw-tooltip.d.ts",
|
|
264
262
|
"default": "./fesm2022/cdevhub-ngx-tw-tooltip.mjs"
|
|
263
|
+
},
|
|
264
|
+
"./transfer": {
|
|
265
|
+
"types": "./types/cdevhub-ngx-tw-transfer.d.ts",
|
|
266
|
+
"default": "./fesm2022/cdevhub-ngx-tw-transfer.mjs"
|
|
267
|
+
},
|
|
268
|
+
"./tree": {
|
|
269
|
+
"types": "./types/cdevhub-ngx-tw-tree.d.ts",
|
|
270
|
+
"default": "./fesm2022/cdevhub-ngx-tw-tree.mjs"
|
|
265
271
|
}
|
|
266
272
|
},
|
|
273
|
+
"peerDependencies": {
|
|
274
|
+
"@angular/common": "^22.0.0",
|
|
275
|
+
"@angular/core": "^22.0.0",
|
|
276
|
+
"@angular/cdk": "^22.0.0",
|
|
277
|
+
"tailwindcss": "^4.0.0",
|
|
278
|
+
"tailwind-variants": "^0.3.0"
|
|
279
|
+
},
|
|
280
|
+
"dependencies": {
|
|
281
|
+
"tslib": "^2.3.0"
|
|
282
|
+
},
|
|
283
|
+
"engines": {
|
|
284
|
+
"node": "^22.22.3 || ^24.15.0 || >=26.0.0"
|
|
285
|
+
},
|
|
286
|
+
"sideEffects": false,
|
|
287
|
+
"publishConfig": {
|
|
288
|
+
"access": "public"
|
|
289
|
+
},
|
|
290
|
+
"module": "fesm2022/cdevhub-ngx-tw.mjs",
|
|
291
|
+
"typings": "types/cdevhub-ngx-tw.d.ts",
|
|
267
292
|
"type": "module"
|
|
268
293
|
}
|
package/theme/index.css
CHANGED
|
@@ -25,8 +25,16 @@
|
|
|
25
25
|
}
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
-
/*
|
|
29
|
-
|
|
28
|
+
/* ===== Library class scanning =====
|
|
29
|
+
Paths here resolve relative to THIS file's location in the *published*
|
|
30
|
+
package (`node_modules/@cdevhub/ngx-tw/theme/`), because that is the only
|
|
31
|
+
copy a consumer ever imports. The published tarball ships compiled bundles
|
|
32
|
+
(`fesm2022/*.mjs`) and no `.ts` source, and Tailwind v4 never auto-scans
|
|
33
|
+
`node_modules` — so without this line a consumer's build emits the semantic
|
|
34
|
+
tokens and base layer but *zero* component utilities, silently. Tailwind
|
|
35
|
+
does not error on a glob that matches nothing, so a wrong path here fails
|
|
36
|
+
invisibly — `npm run verify:package` is what guards it. */
|
|
37
|
+
@source "../fesm2022/**/*.mjs";
|
|
30
38
|
|
|
31
39
|
/* ===== Slot-token utility safelist =====
|
|
32
40
|
Components consume role slot utilities (`bg-info-soft`, `text-info-fg`, …)
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import * as _angular_core from '@angular/core';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Sets the native CSS `aspect-ratio` property on its host element, standardizing
|
|
5
|
+
* the `aspect-[16/9]` pattern consumers otherwise hand-roll across cards,
|
|
6
|
+
* thumbnails, video, and image grids.
|
|
7
|
+
*
|
|
8
|
+
* The directive sets **only** `aspect-ratio` — it does not set `width`,
|
|
9
|
+
* `display`, or any other layout property (matching Tailwind's `aspect-*`
|
|
10
|
+
* utility). Block-level hosts already fill their container width; for replaced
|
|
11
|
+
* elements (`<img>`, `<video>`) pair it with `w-full` / `object-cover` so the
|
|
12
|
+
* box has a definite cross-axis size.
|
|
13
|
+
*
|
|
14
|
+
* Purely presentational: it adds no `role` or `aria-*` and leaves the host
|
|
15
|
+
* media's own accessibility (`alt`, `aria-*`, `title`) untouched.
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* ```html
|
|
19
|
+
* <div twAspectRatio class="w-full bg-surface-muted"></div>
|
|
20
|
+
* <img twAspectRatio="16/9" class="w-full object-cover rounded-lg" [src]="thumb" alt="Preview" />
|
|
21
|
+
* <div [twAspectRatio]="4 / 3" class="w-full"></div>
|
|
22
|
+
* <video twAspectRatio="21:9" class="w-full" [src]="clip"></video>
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
declare class AspectRatioDirective {
|
|
26
|
+
/**
|
|
27
|
+
* Sets the host's aspect ratio. Accepts a unitless number (e.g. `1.7777`) or a
|
|
28
|
+
* ratio string using `/` or `:` (e.g. `'16/9'` or `'16:9'`). The value is
|
|
29
|
+
* normalized to CSS `'<w> / <h>'` form (a bare number `n` becomes `'n / 1'`).
|
|
30
|
+
* Invalid or non-positive values fall back to the default. Defaults to a
|
|
31
|
+
* square (`1 / 1`).
|
|
32
|
+
*/
|
|
33
|
+
readonly twAspectRatio: _angular_core.InputSignal<string | number>;
|
|
34
|
+
/** The coerced, CSS-valid `aspect-ratio` value applied to the host. */
|
|
35
|
+
readonly ratio: _angular_core.Signal<string>;
|
|
36
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<AspectRatioDirective, never>;
|
|
37
|
+
static ɵdir: _angular_core.ɵɵDirectiveDeclaration<AspectRatioDirective, "[twAspectRatio]", ["twAspectRatio"], { "twAspectRatio": { "alias": "twAspectRatio"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export { AspectRatioDirective };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { Provider, InjectionToken, Type, OnInit,
|
|
2
|
+
import { Provider, InjectionToken, Type, OnInit, InputSignal, WritableSignal, TemplateRef, OutputEmitterRef, Signal, ModelSignal, EnvironmentProviders } from '@angular/core';
|
|
3
3
|
import { ControlValueAccessor, Validator, AbstractControl, ValidationErrors, ValidatorFn } from '@angular/forms';
|
|
4
4
|
import { RangeBehaviorConfig } from '@cdevhub/ngx-tw/core';
|
|
5
5
|
import { FormValueControl, ValidationError, WithOptionalFieldTree, DisabledReason } from '@angular/forms/signals';
|
|
@@ -523,12 +523,14 @@ declare class CalendarComponent<M extends CalendarMode = 'single', D = Date, TOu
|
|
|
523
523
|
*/
|
|
524
524
|
private readonly localStrategies;
|
|
525
525
|
/** Selection mode (§5). Changing this at runtime clears the value and emits `modeChange`. */
|
|
526
|
-
readonly
|
|
526
|
+
readonly modeInput: InputSignal<CalendarMode>;
|
|
527
|
+
readonly mode: WritableSignal<CalendarMode>;
|
|
527
528
|
/**
|
|
528
529
|
* Consumer-bound value. Shape narrows by `M`: `D | null` for single,
|
|
529
530
|
* `D[]` for multiple, `{ start; end }` for range.
|
|
530
531
|
*/
|
|
531
|
-
readonly
|
|
532
|
+
readonly valueInput: InputSignal<CalendarValue<M, D>>;
|
|
533
|
+
readonly value: WritableSignal<CalendarValue<M, D>>;
|
|
532
534
|
/** Anchor date for the displayed view. Defaults to today on mount. */
|
|
533
535
|
readonly startAt: InputSignal<D | null>;
|
|
534
536
|
/** Minimum selectable date. */
|
|
@@ -826,14 +828,43 @@ declare class CalendarComponent<M extends CalendarMode = 'single', D = Date, TOu
|
|
|
826
828
|
clearSelection(): void;
|
|
827
829
|
/** Resets to initial state — value + view + active date per `resetBehavior`. Phase 3 extends this with form-reset integration. */
|
|
828
830
|
reset(): void;
|
|
829
|
-
/**
|
|
831
|
+
/**
|
|
832
|
+
* Re-runs validation against the current constraints and cell filters.
|
|
833
|
+
*
|
|
834
|
+
* Call this after mutating a constraint imperatively (rather than through an
|
|
835
|
+
* input binding), so the bound control's errors reflect the new rules.
|
|
836
|
+
*/
|
|
830
837
|
revalidate(): void;
|
|
831
|
-
/**
|
|
838
|
+
/**
|
|
839
|
+
* Opens the overlay.
|
|
840
|
+
*
|
|
841
|
+
* @deprecated Not implemented. `tw-calendar` is inline-only today; the overlay
|
|
842
|
+
* is part of the phased v1 cutover. Use `tw-date-picker` or
|
|
843
|
+
* `tw-date-range-picker` for an overlay-mounted calendar. Throws in dev mode.
|
|
844
|
+
*/
|
|
832
845
|
open(): void;
|
|
833
|
-
/**
|
|
846
|
+
/**
|
|
847
|
+
* Closes the overlay.
|
|
848
|
+
*
|
|
849
|
+
* @deprecated Not implemented — see {@link open}. Throws in dev mode.
|
|
850
|
+
*/
|
|
834
851
|
close(): void;
|
|
835
|
-
/**
|
|
852
|
+
/**
|
|
853
|
+
* Toggles the overlay.
|
|
854
|
+
*
|
|
855
|
+
* @deprecated Not implemented — see {@link open}. Throws in dev mode.
|
|
856
|
+
*/
|
|
836
857
|
toggle(): void;
|
|
858
|
+
/**
|
|
859
|
+
* Fails loudly in development for the unimplemented overlay API.
|
|
860
|
+
*
|
|
861
|
+
* These three shipped as silent no-ops with JSDoc that described them as
|
|
862
|
+
* working ("Closes the overlay."), which Compodoc rendered straight into the
|
|
863
|
+
* published API table. A consumer calling `calendar.open()` got no overlay, no
|
|
864
|
+
* error, and no clue. Dev-mode throw turns that into an immediate, explainable
|
|
865
|
+
* failure while leaving production builds untouched.
|
|
866
|
+
*/
|
|
867
|
+
private warnOverlayUnsupported;
|
|
837
868
|
/** Imperatively focuses the currently active cell. */
|
|
838
869
|
focusActiveCell(): void;
|
|
839
870
|
/** @internal */
|
|
@@ -917,7 +948,7 @@ declare class CalendarComponent<M extends CalendarMode = 'single', D = Date, TOu
|
|
|
917
948
|
/** Locale-aware long-form date format used in announcements (e.g. "Wednesday, April 15, 2026"). */
|
|
918
949
|
private formatDate;
|
|
919
950
|
static ɵfac: i0.ɵɵFactoryDeclaration<CalendarComponent<any, any, any>, never>;
|
|
920
|
-
static ɵcmp: i0.ɵɵComponentDeclaration<CalendarComponent<any, any, any>, "tw-calendar", never, { "
|
|
951
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<CalendarComponent<any, any, any>, "tw-calendar", never, { "modeInput": { "alias": "mode"; "required": false; "isSignal": true; }; "valueInput": { "alias": "value"; "required": false; "isSignal": true; }; "startAt": { "alias": "startAt"; "required": false; "isSignal": true; }; "minDate": { "alias": "minDate"; "required": false; "isSignal": true; }; "maxDate": { "alias": "maxDate"; "required": false; "isSignal": true; }; "dateFilter": { "alias": "dateFilter"; "required": false; "isSignal": true; }; "disabledDates": { "alias": "disabledDates"; "required": false; "isSignal": true; }; "disabledDaysOfWeek": { "alias": "disabledDaysOfWeek"; "required": false; "isSignal": true; }; "constraints": { "alias": "constraints"; "required": false; "isSignal": true; }; "minRangeLength": { "alias": "minRangeLength"; "required": false; "isSignal": true; }; "maxRangeLength": { "alias": "maxRangeLength"; "required": false; "isSignal": true; }; "maxSelections": { "alias": "maxSelections"; "required": false; "isSignal": true; }; "maxSelectionBehavior": { "alias": "maxSelectionBehavior"; "required": false; "isSignal": true; }; "errorAriaDescribedBy": { "alias": "errorAriaDescribedBy"; "required": false; "isSignal": true; }; "rangeClickBehavior": { "alias": "rangeClickBehavior"; "required": false; "isSignal": true; }; "rangeBehavior": { "alias": "rangeBehavior"; "required": false; "isSignal": true; }; "dateClass": { "alias": "dateClass"; "required": false; "isSignal": true; }; "bordered": { "alias": "bordered"; "required": false; "isSignal": true; }; "startView": { "alias": "startView"; "required": false; "isSignal": true; }; "firstDayOfWeek": { "alias": "firstDayOfWeek"; "required": false; "isSignal": true; }; "monthColumns": { "alias": "monthColumns"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "readonly": { "alias": "readonly"; "required": false; "isSignal": true; }; "resetBehavior": { "alias": "resetBehavior"; "required": false; "isSignal": true; }; "cellTemplate": { "alias": "cellTemplate"; "required": false; "isSignal": true; }; "locale": { "alias": "locale"; "required": false; "isSignal": true; }; "intl": { "alias": "intl"; "required": false; "isSignal": true; }; }, { "valueChange": "valueChange"; "selectionStart": "selectionStart"; "rangePreview": "rangePreview"; "selectionComplete": "selectionComplete"; "selectionRestart": "selectionRestart"; "selectionCleared": "selectionCleared"; "selectionLimitReached": "selectionLimitReached"; "presetChange": "presetChange"; "viewChange": "viewChange"; "activeDateChange": "activeDateChange"; "monthChange": "monthChange"; "yearChange": "yearChange"; "cellClick": "cellClick"; "cellHover": "cellHover"; "modeChange": "modeChange"; }, never, ["[twCalendarPresets]"], true, never>;
|
|
921
952
|
}
|
|
922
953
|
|
|
923
954
|
/**
|
|
@@ -205,6 +205,13 @@ declare class CommandPaletteComponent {
|
|
|
205
205
|
private setupFocusTrap;
|
|
206
206
|
private destroyFocusTrap;
|
|
207
207
|
private disposeOverlay;
|
|
208
|
+
/**
|
|
209
|
+
* Aborts an in-flight close, leaving the palette open.
|
|
210
|
+
*
|
|
211
|
+
* The overlay is still attached (only the detach is deferred), so this
|
|
212
|
+
* restores the focus trap that `closePalette` tore down up front.
|
|
213
|
+
*/
|
|
214
|
+
private cancelPendingClose;
|
|
208
215
|
private clearCloseTimer;
|
|
209
216
|
private clearAnnounceTimer;
|
|
210
217
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<CommandPaletteComponent, never>;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as _angular_core from '@angular/core';
|
|
2
2
|
import { OnInit, TemplateRef, Signal } from '@angular/core';
|
|
3
|
-
import { ControlValueAccessor } from '@angular/forms';
|
|
3
|
+
import { ControlValueAccessor, Validator, AbstractControl, ValidationErrors } from '@angular/forms';
|
|
4
4
|
import { TwSize, TwColor, TimePickerFormat, ErrorStateMatcher } from '@cdevhub/ngx-tw/core';
|
|
5
5
|
export { TimePickerFormat } from '@cdevhub/ngx-tw/core';
|
|
6
6
|
import { FormFieldControl } from '@cdevhub/ngx-tw/form-field';
|
|
@@ -72,14 +72,14 @@ interface DatePickerTimeConfig<D = Date> {
|
|
|
72
72
|
* All date operations go through the injected `DateAdapter<D>`; call
|
|
73
73
|
* `provideNativeDateAdapter()` in your app providers to bootstrap the default.
|
|
74
74
|
*/
|
|
75
|
-
declare class DatePickerComponent<D = Date> extends FormFieldControl<D> implements ControlValueAccessor, OnInit {
|
|
75
|
+
declare class DatePickerComponent<D = Date> extends FormFieldControl<D> implements ControlValueAccessor, Validator, OnInit {
|
|
76
76
|
/** Id on the date-picker's input element. Auto-generated when not provided. Used by the form-field's `<label for>` attribute. */
|
|
77
77
|
readonly idInput: _angular_core.InputSignal<string | undefined>;
|
|
78
|
-
/** Minimum selectable date. Typed input earlier than this
|
|
78
|
+
/** Minimum selectable date. Typed input earlier than this commits the value and marks the bound control invalid with `calendarMinDate`; the calendar disables the cell. Defaults to `null`. */
|
|
79
79
|
readonly minDate: _angular_core.InputSignal<D | null>;
|
|
80
|
-
/** Maximum selectable date. Typed input later than this
|
|
80
|
+
/** Maximum selectable date. Typed input later than this commits the value and marks the bound control invalid with `calendarMaxDate`; the calendar disables the cell. Defaults to `null`. */
|
|
81
81
|
readonly maxDate: _angular_core.InputSignal<D | null>;
|
|
82
|
-
/** Per-date predicate — return `false` to disable. Applied in
|
|
82
|
+
/** Per-date predicate — return `false` to disable. Applied in the calendar, the text-parse path, and the `calendarDisabledDate` validation error. */
|
|
83
83
|
readonly dateFilter: _angular_core.InputSignal<DateFilterFn<D> | null>;
|
|
84
84
|
/** Which calendar view opens first — `'day'`, `'month'`, or `'year'`. Defaults to `'day'`. */
|
|
85
85
|
readonly startView: _angular_core.InputSignal<CalendarViewState>;
|
|
@@ -173,7 +173,7 @@ declare class DatePickerComponent<D = Date> extends FormFieldControl<D> implemen
|
|
|
173
173
|
private readonly injector;
|
|
174
174
|
private readonly destroyRef;
|
|
175
175
|
private readonly formField;
|
|
176
|
-
private
|
|
176
|
+
private ngControl;
|
|
177
177
|
private readonly parentForm;
|
|
178
178
|
private readonly parentFormGroup;
|
|
179
179
|
private readonly defaultMatcher;
|
|
@@ -190,10 +190,31 @@ declare class DatePickerComponent<D = Date> extends FormFieldControl<D> implemen
|
|
|
190
190
|
readonly internalValue: _angular_core.WritableSignal<D | null>;
|
|
191
191
|
/** @internal */
|
|
192
192
|
readonly rawInputText: _angular_core.WritableSignal<string>;
|
|
193
|
-
/**
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
193
|
+
/**
|
|
194
|
+
* @internal The text the user typed that could not be parsed into a date,
|
|
195
|
+
* or `null` when the current entry parsed cleanly.
|
|
196
|
+
*
|
|
197
|
+
* This is the single source of truth for "the typed text is bad". It drives
|
|
198
|
+
* both the visual error state (via `parseError` below) and the form error
|
|
199
|
+
* (via `validate()`, which feeds it to `calendarValidator` as
|
|
200
|
+
* `lastInvalidFormValue`). Keeping one field instead of a boolean flag plus a
|
|
201
|
+
* separate string is what stops the two from disagreeing.
|
|
202
|
+
*/
|
|
203
|
+
private readonly unparseableText;
|
|
204
|
+
/** @internal Whether the current input text failed to parse. */
|
|
205
|
+
readonly parseError: Signal<boolean>;
|
|
206
|
+
/**
|
|
207
|
+
* @internal Whether the committed value violates `minDate` / `maxDate` /
|
|
208
|
+
* `dateFilter`.
|
|
209
|
+
*
|
|
210
|
+
* Derived, not a flag. An out-of-range entry is committed to the form (so the
|
|
211
|
+
* control holds what the user typed and is *invalid*, rather than silently
|
|
212
|
+
* keeping an older value), which means the value-sync effect below runs and
|
|
213
|
+
* would immediately clear any manually-set flag. Deriving it also keeps the
|
|
214
|
+
* error correct when the consumer moves a constraint after the fact, which a
|
|
215
|
+
* flag set once at commit time cannot do.
|
|
216
|
+
*/
|
|
217
|
+
readonly rangeError: Signal<boolean>;
|
|
197
218
|
/** @internal */
|
|
198
219
|
readonly focusedSignal: _angular_core.WritableSignal<boolean>;
|
|
199
220
|
private readonly cvaDisabled;
|
|
@@ -305,6 +326,11 @@ declare class DatePickerComponent<D = Date> extends FormFieldControl<D> implemen
|
|
|
305
326
|
registerOnChange(fn: (value: D | null) => void): void;
|
|
306
327
|
registerOnTouched(fn: () => void): void;
|
|
307
328
|
setDisabledState(isDisabled: boolean): void;
|
|
329
|
+
private validatorOnChange;
|
|
330
|
+
/** @internal */
|
|
331
|
+
validate(control: AbstractControl): ValidationErrors | null;
|
|
332
|
+
/** @internal */
|
|
333
|
+
registerOnValidatorChange(fn: () => void): void;
|
|
308
334
|
/** @internal */
|
|
309
335
|
setDescribedByIds(ids: string[]): void;
|
|
310
336
|
/** @internal */
|
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
import * as _angular_core from '@angular/core';
|
|
2
|
+
import { OnInit, Signal, TemplateRef } from '@angular/core';
|
|
3
|
+
import { ControlValueAccessor } from '@angular/forms';
|
|
4
|
+
import { TwSize, ErrorStateMatcher } from '@cdevhub/ngx-tw/core';
|
|
5
|
+
import { FormFieldControl } from '@cdevhub/ngx-tw/form-field';
|
|
6
|
+
|
|
7
|
+
/** Lifecycle status of a single selected file. */
|
|
8
|
+
type FileUploadStatus = 'pending' | 'uploading' | 'success' | 'error';
|
|
9
|
+
/** Visual variant of the drop zone container. */
|
|
10
|
+
type FileUploadVariant = 'outline' | 'soft';
|
|
11
|
+
/** Reason a file was rejected during validation. */
|
|
12
|
+
type FileUploadRejectionReason = 'accept' | 'size' | 'count';
|
|
13
|
+
/** A single tracked entry in the file-upload's internal state. */
|
|
14
|
+
interface FileUploadItem {
|
|
15
|
+
/** Stable opaque id for this entry. Generated by the component on add. Use as the key when calling `setItemProgress` / `setItemStatus`. */
|
|
16
|
+
readonly id: string;
|
|
17
|
+
/** The underlying `File` object as provided by the browser (or by `writeValue`). */
|
|
18
|
+
readonly file: File;
|
|
19
|
+
/** Current upload progress, integer 0–100. `0` when no progress has been reported. */
|
|
20
|
+
readonly progress: number;
|
|
21
|
+
/** Current lifecycle status. Defaults to `'pending'`. */
|
|
22
|
+
readonly status: FileUploadStatus;
|
|
23
|
+
/** Optional error message attached when `status === 'error'`. Displayed in the file row and announced via `LiveAnnouncer`. */
|
|
24
|
+
readonly error?: string;
|
|
25
|
+
}
|
|
26
|
+
/** Payload emitted on `fileRejected`. */
|
|
27
|
+
interface FileUploadRejection {
|
|
28
|
+
/** The browser-supplied `File` that was rejected. */
|
|
29
|
+
readonly file: File;
|
|
30
|
+
/** Why the file was rejected. */
|
|
31
|
+
readonly reason: FileUploadRejectionReason;
|
|
32
|
+
/** Human-readable message suitable for assistive-tech announcement and inline display. */
|
|
33
|
+
readonly message: string;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Structural directive that captures a template used to render each item row.
|
|
37
|
+
* Apply with `*twFileUploadItem="let item"` to override the default row layout.
|
|
38
|
+
*
|
|
39
|
+
* The template context exposes the current `FileUploadItem` as both `$implicit`
|
|
40
|
+
* and `item`, so both `let-item` and `let-item="item"` work.
|
|
41
|
+
*/
|
|
42
|
+
declare class FileUploadItemDirective {
|
|
43
|
+
/** @internal Reference to the captured template — read by the host component. */
|
|
44
|
+
readonly templateRef: TemplateRef<{
|
|
45
|
+
$implicit: FileUploadItem;
|
|
46
|
+
item: FileUploadItem;
|
|
47
|
+
}>;
|
|
48
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<FileUploadItemDirective, never>;
|
|
49
|
+
static ɵdir: _angular_core.ɵɵDirectiveDeclaration<FileUploadItemDirective, "ng-template[twFileUploadItem]", never, {}, {}, never, never, true, never>;
|
|
50
|
+
}
|
|
51
|
+
declare class FileUploadComponent extends FormFieldControl<File[]> implements ControlValueAccessor, OnInit {
|
|
52
|
+
/** When true, the user can select more than one file. Mirrors to the hidden `<input multiple>` attribute. Defaults to `false`. */
|
|
53
|
+
readonly multiple: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
54
|
+
/** Comma-separated list of accepted file types using the native `<input accept>` syntax (e.g., `'image/*,.pdf'`). Forwarded to the hidden input and used to reject dropped files that do not match. Defaults to `undefined` (accept any). */
|
|
55
|
+
readonly accept: _angular_core.InputSignal<string | undefined>;
|
|
56
|
+
/** Maximum size per file, in bytes. Files exceeding this are rejected with reason `'size'` and never reach `value`. Defaults to `undefined` (no limit). */
|
|
57
|
+
readonly maxSize: _angular_core.InputSignal<number | undefined>;
|
|
58
|
+
/** Maximum total file count. Drops that would push the count over this limit are rejected with reason `'count'`. Ignored when `multiple` is `false` (the limit is always 1). Defaults to `undefined` (no limit). */
|
|
59
|
+
readonly maxFiles: _angular_core.InputSignal<number | undefined>;
|
|
60
|
+
/** Visual style of the drop zone. `'outline'` renders a dashed-bordered transparent region; `'soft'` renders a filled muted background. Defaults to `'outline'`. */
|
|
61
|
+
readonly variant: _angular_core.InputSignal<FileUploadVariant>;
|
|
62
|
+
/** Controls overall density: drop-zone padding, icon scale, headline typography. Defaults to `'md'`. */
|
|
63
|
+
readonly size: _angular_core.InputSignal<TwSize>;
|
|
64
|
+
/** When true, blocks file selection (button, click, drop, keyboard) and applies muted styling. Reactive forms also propagate `disabled` via `setDisabledState`. Defaults to `false`. */
|
|
65
|
+
readonly disabledInput: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
66
|
+
/** Marks the control as required. Mirrors to `aria-required`. Also inferred from `Validators.required` on a bound `NgControl`. Defaults to `false`. */
|
|
67
|
+
readonly requiredInput: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
68
|
+
/** Headline text rendered inside the drop zone (e.g., `'Drag files here'`). Projected `[twFileUploadHeadline]` content takes precedence over this input. */
|
|
69
|
+
readonly label: _angular_core.InputSignal<string | undefined>;
|
|
70
|
+
/** Secondary text rendered under the label (e.g., `'PDF up to 10MB'`). Projected `[twFileUploadDescription]` content takes precedence. */
|
|
71
|
+
readonly description: _angular_core.InputSignal<string | undefined>;
|
|
72
|
+
/** Label rendered inside the trigger button. Defaults to `'Choose files'`. Use `'Choose file'` when `multiple` is `false` (consumer responsibility). */
|
|
73
|
+
readonly triggerLabel: _angular_core.InputSignal<string>;
|
|
74
|
+
/** Accessible name applied to the host when no visible label is projected. Mirrored to `aria-label`. */
|
|
75
|
+
readonly ariaLabel: _angular_core.InputSignal<string | undefined>;
|
|
76
|
+
/** ID of an external element that labels the control. Mirrored to `aria-labelledby`. */
|
|
77
|
+
readonly ariaLabelledby: _angular_core.InputSignal<string | undefined>;
|
|
78
|
+
/** ID of an external element that describes the control. Form-field merges its hint/error ids alongside. */
|
|
79
|
+
readonly ariaDescribedby: _angular_core.InputSignal<string | undefined>;
|
|
80
|
+
/** Optional `name` attribute on the hidden `<input type="file">` for native form submissions. */
|
|
81
|
+
readonly name: _angular_core.InputSignal<string | undefined>;
|
|
82
|
+
/** Id on the host element. Auto-generated as `tw-file-upload-N` when not provided. Used by the form-field's `<label for>` attribute. */
|
|
83
|
+
readonly idInput: _angular_core.InputSignal<string | undefined>;
|
|
84
|
+
/** Per-instance override of the {@link ErrorStateMatcher}. When omitted, the component uses the `TW_ERROR_STATE_MATCHER` token's value. */
|
|
85
|
+
readonly errorStateMatcher: _angular_core.InputSignal<ErrorStateMatcher | undefined>;
|
|
86
|
+
/** Fires once per add operation with the items that were accepted and appended. Does not fire for rejected files (see `fileRejected`). Does not fire on `writeValue`. */
|
|
87
|
+
readonly filesAdded: _angular_core.OutputEmitterRef<FileUploadItem[]>;
|
|
88
|
+
/** Fires when a file is removed via the remove button or programmatic `remove()`. Does not fire on `writeValue`. */
|
|
89
|
+
readonly fileRemoved: _angular_core.OutputEmitterRef<FileUploadItem>;
|
|
90
|
+
/** Fires for each file that failed validation during add. Payload includes a human-readable message suitable for assistive-tech announcement. */
|
|
91
|
+
readonly fileRejected: _angular_core.OutputEmitterRef<FileUploadRejection>;
|
|
92
|
+
/** Fires when all files are cleared at once via programmatic `clear()`. Does not fire on `writeValue`, even when the new value is empty. */
|
|
93
|
+
readonly cleared: _angular_core.OutputEmitterRef<void>;
|
|
94
|
+
private readonly elementRef;
|
|
95
|
+
private readonly focusMonitor;
|
|
96
|
+
private readonly liveAnnouncer;
|
|
97
|
+
private readonly destroyRef;
|
|
98
|
+
private readonly ngControl;
|
|
99
|
+
private readonly parentForm;
|
|
100
|
+
private readonly parentFormGroup;
|
|
101
|
+
private readonly defaultMatcher;
|
|
102
|
+
private readonly itemsSignal;
|
|
103
|
+
private readonly cvaDisabled;
|
|
104
|
+
private readonly isDraggingSignal;
|
|
105
|
+
private readonly dragHasInvalidFilesSignal;
|
|
106
|
+
private readonly _focused;
|
|
107
|
+
private readonly _ngControlRev;
|
|
108
|
+
private readonly _formSubmitRev;
|
|
109
|
+
private readonly describedByIdsSignal;
|
|
110
|
+
private readonly labelledByIdsSignal;
|
|
111
|
+
private dragCounter;
|
|
112
|
+
private onChange;
|
|
113
|
+
private onTouched;
|
|
114
|
+
/** @internal Captured custom-item template (from `*twFileUploadItem`). When absent, the default row template renders. */
|
|
115
|
+
readonly itemSlot: Signal<FileUploadItemDirective | undefined>;
|
|
116
|
+
/** @internal Dropzone wrapper — used to scope the form-field container-click guard. */
|
|
117
|
+
private readonly dropzoneRef;
|
|
118
|
+
/** @internal The visible trigger button — the keyboard-operable control that receives focus on container click and after the last item is removed. */
|
|
119
|
+
private readonly triggerRef;
|
|
120
|
+
/** @internal Hidden native input — used as the OS picker trigger. */
|
|
121
|
+
private readonly hiddenInputRef;
|
|
122
|
+
private readonly uid;
|
|
123
|
+
/** @internal Auto-generated host id used when `[id]` is not supplied. */
|
|
124
|
+
readonly hostId: string;
|
|
125
|
+
/** @internal */
|
|
126
|
+
readonly headlineId: string;
|
|
127
|
+
/** @internal */
|
|
128
|
+
readonly descriptionId: string;
|
|
129
|
+
/** @internal */
|
|
130
|
+
readonly hiddenInputId: string;
|
|
131
|
+
/** Current items with their progress and status. Snapshot of internal state. */
|
|
132
|
+
readonly items: Signal<readonly FileUploadItem[]>;
|
|
133
|
+
/** True while a valid file drag is over the drop zone. */
|
|
134
|
+
readonly isDragging: Signal<boolean>;
|
|
135
|
+
/** Convenience alias for `items().length`. Useful for counter hints. */
|
|
136
|
+
readonly valueLength: Signal<number>;
|
|
137
|
+
/** @internal */
|
|
138
|
+
readonly id: Signal<string>;
|
|
139
|
+
/** @internal */
|
|
140
|
+
readonly value: Signal<File[] | null>;
|
|
141
|
+
/** @internal */
|
|
142
|
+
readonly focused: Signal<boolean>;
|
|
143
|
+
/** @internal */
|
|
144
|
+
readonly empty: Signal<boolean>;
|
|
145
|
+
/** @internal */
|
|
146
|
+
readonly disabled: Signal<boolean>;
|
|
147
|
+
/** @internal */
|
|
148
|
+
readonly required: Signal<boolean>;
|
|
149
|
+
/** @internal */
|
|
150
|
+
readonly errorState: Signal<boolean>;
|
|
151
|
+
/** @internal Validation errors map from the bound `NgControl`. */
|
|
152
|
+
readonly errors: Signal<Record<string, unknown> | null>;
|
|
153
|
+
/** @internal */
|
|
154
|
+
readonly controlType = "file-upload";
|
|
155
|
+
/** @internal */
|
|
156
|
+
readonly userAriaDescribedBy: Signal<string | undefined>;
|
|
157
|
+
/** @internal */
|
|
158
|
+
readonly userAriaLabelledby: Signal<string | undefined>;
|
|
159
|
+
/** @internal */
|
|
160
|
+
readonly effectiveAriaLabelledby: Signal<string | undefined>;
|
|
161
|
+
/** @internal */
|
|
162
|
+
readonly effectiveAriaDescribedby: Signal<string | undefined>;
|
|
163
|
+
private readonly stateVariant;
|
|
164
|
+
private readonly variantResult;
|
|
165
|
+
/** @internal */
|
|
166
|
+
readonly rootClasses: Signal<string>;
|
|
167
|
+
/** @internal */
|
|
168
|
+
readonly dropzoneClasses: Signal<string>;
|
|
169
|
+
/** @internal */
|
|
170
|
+
readonly dropzoneInnerClasses: Signal<string>;
|
|
171
|
+
/** @internal */
|
|
172
|
+
readonly illustrationClasses: Signal<string>;
|
|
173
|
+
/** @internal */
|
|
174
|
+
readonly headlineClasses: Signal<string>;
|
|
175
|
+
/** @internal */
|
|
176
|
+
readonly descriptionClasses: Signal<string>;
|
|
177
|
+
/** @internal */
|
|
178
|
+
readonly listClasses: Signal<string>;
|
|
179
|
+
/** @internal */
|
|
180
|
+
readonly itemClasses: Signal<string>;
|
|
181
|
+
/** @internal */
|
|
182
|
+
readonly itemIconClasses: Signal<string>;
|
|
183
|
+
/** @internal */
|
|
184
|
+
readonly itemBodyClasses: Signal<string>;
|
|
185
|
+
/** @internal */
|
|
186
|
+
readonly itemNameClasses: Signal<string>;
|
|
187
|
+
/** @internal */
|
|
188
|
+
readonly itemMetaClasses: Signal<string>;
|
|
189
|
+
/** @internal */
|
|
190
|
+
readonly itemProgressClasses: Signal<string>;
|
|
191
|
+
/** @internal */
|
|
192
|
+
readonly itemActionsClasses: Signal<string>;
|
|
193
|
+
/** @internal Mapping component size → icon size for the illustration. */
|
|
194
|
+
readonly iconSize: Signal<TwSize>;
|
|
195
|
+
constructor();
|
|
196
|
+
/** Programmatically opens the OS file picker. No-op when disabled. */
|
|
197
|
+
open(): void;
|
|
198
|
+
/** Removes the item with the given id. Emits `fileRemoved`. No-op when the id is unknown or the component is disabled. */
|
|
199
|
+
remove(id: string): void;
|
|
200
|
+
/** Removes all items. Emits `cleared` and calls `onChange([])`. No-op when already empty or disabled. */
|
|
201
|
+
clear(): void;
|
|
202
|
+
/** Updates the per-item progress (0–100, clamped). Does not change status. No-op when the id is unknown. */
|
|
203
|
+
setItemProgress(id: string, percent: number): void;
|
|
204
|
+
/** Updates the per-item status and (optionally) the error message. Announces status transitions via `LiveAnnouncer`. No-op when the id is unknown. */
|
|
205
|
+
setItemStatus(id: string, status: FileUploadStatus, error?: string): void;
|
|
206
|
+
/** @internal */
|
|
207
|
+
onDragEnter(event: DragEvent): void;
|
|
208
|
+
/** @internal */
|
|
209
|
+
onDragOver(event: DragEvent): void;
|
|
210
|
+
/** @internal */
|
|
211
|
+
onDragLeave(event: DragEvent): void;
|
|
212
|
+
/** @internal */
|
|
213
|
+
onDrop(event: DragEvent): void;
|
|
214
|
+
/** @internal */
|
|
215
|
+
onTriggerClick(event: MouseEvent): void;
|
|
216
|
+
/** @internal Called by the hidden `<input type="file">` `change` event. */
|
|
217
|
+
onNativeChange(event: Event): void;
|
|
218
|
+
private addFiles;
|
|
219
|
+
private wrapFile;
|
|
220
|
+
private reject;
|
|
221
|
+
private rejectionMessage;
|
|
222
|
+
private isFileDrag;
|
|
223
|
+
private computeDragInvalid;
|
|
224
|
+
writeValue(value: File[] | File | null | undefined): void;
|
|
225
|
+
registerOnChange(fn: (value: File[]) => void): void;
|
|
226
|
+
registerOnTouched(fn: () => void): void;
|
|
227
|
+
setDisabledState(isDisabled: boolean): void;
|
|
228
|
+
private emitChange;
|
|
229
|
+
/** @internal */
|
|
230
|
+
setDescribedByIds(ids: string[]): void;
|
|
231
|
+
/** @internal */
|
|
232
|
+
setLabelledByIds(ids: string[]): void;
|
|
233
|
+
/** @internal */
|
|
234
|
+
onContainerClick(event: MouseEvent): void;
|
|
235
|
+
/** @internal */
|
|
236
|
+
iconNameFor(item: FileUploadItem): string;
|
|
237
|
+
/** @internal */
|
|
238
|
+
shouldShowProgress(item: FileUploadItem): boolean;
|
|
239
|
+
/** @internal */
|
|
240
|
+
progressColorFor(item: FileUploadItem): 'primary' | 'success' | 'error';
|
|
241
|
+
/** @internal */
|
|
242
|
+
metaTextFor(item: FileUploadItem): string;
|
|
243
|
+
ngOnInit(): void;
|
|
244
|
+
private hasAccessibleNameHint;
|
|
245
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<FileUploadComponent, never>;
|
|
246
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<FileUploadComponent, "tw-file-upload", ["twFileUpload"], { "multiple": { "alias": "multiple"; "required": false; "isSignal": true; }; "accept": { "alias": "accept"; "required": false; "isSignal": true; }; "maxSize": { "alias": "maxSize"; "required": false; "isSignal": true; }; "maxFiles": { "alias": "maxFiles"; "required": false; "isSignal": true; }; "variant": { "alias": "variant"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "disabledInput": { "alias": "disabled"; "required": false; "isSignal": true; }; "requiredInput": { "alias": "required"; "required": false; "isSignal": true; }; "label": { "alias": "label"; "required": false; "isSignal": true; }; "description": { "alias": "description"; "required": false; "isSignal": true; }; "triggerLabel": { "alias": "triggerLabel"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "aria-label"; "required": false; "isSignal": true; }; "ariaLabelledby": { "alias": "aria-labelledby"; "required": false; "isSignal": true; }; "ariaDescribedby": { "alias": "aria-describedby"; "required": false; "isSignal": true; }; "name": { "alias": "name"; "required": false; "isSignal": true; }; "idInput": { "alias": "id"; "required": false; "isSignal": true; }; "errorStateMatcher": { "alias": "errorStateMatcher"; "required": false; "isSignal": true; }; }, { "filesAdded": "filesAdded"; "fileRemoved": "fileRemoved"; "fileRejected": "fileRejected"; "cleared": "cleared"; }, ["itemSlot"], ["[twFileUploadIcon]", "[twFileUploadHeadline]", "[twFileUploadDescription]"], true, never>;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
export { FileUploadComponent, FileUploadItemDirective };
|
|
250
|
+
export type { FileUploadItem, FileUploadRejection, FileUploadRejectionReason, FileUploadStatus, FileUploadVariant };
|