@cdevhub/ngx-tw 0.2.0 → 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 +35 -22
- 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 +416 -216
- 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 +152 -81
- 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 +42 -29
- 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 +205 -110
- package/fesm2022/cdevhub-ngx-tw-combobox.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-command-palette.mjs +141 -74
- 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 +395 -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 +142 -72
- 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 +227 -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 +47 -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 +102 -52
- 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 +16 -8
- 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 +100 -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 -17
- package/theme/_dark.css +16 -12
- package/theme/_semantic.css +3 -2
- 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-code-block.d.ts +8 -7
- 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-select.d.ts +1 -1
- 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-toast.d.ts +1 -1
- 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
|
@@ -8,7 +8,7 @@ import { Platform } from '@angular/cdk/platform';
|
|
|
8
8
|
import { merge } from 'rxjs';
|
|
9
9
|
import { tv } from 'tailwind-variants';
|
|
10
10
|
import { TW_ERROR_STATE_MATCHER } from '@cdevhub/ngx-tw/core';
|
|
11
|
-
import { FormFieldControl,
|
|
11
|
+
import { FormFieldControl, TW_FORM_FIELD, TW_FORM_FIELD_CONTROL } from '@cdevhub/ngx-tw/form-field';
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
14
|
* Extension point for directives that wrap an `<input twInput>` and need to
|
|
@@ -105,7 +105,7 @@ class InputDirective extends FormFieldControl {
|
|
|
105
105
|
autofillMonitor = inject(AutofillMonitor);
|
|
106
106
|
platform = inject(Platform);
|
|
107
107
|
destroyRef = inject(DestroyRef);
|
|
108
|
-
formField = inject(
|
|
108
|
+
formField = inject(TW_FORM_FIELD, { optional: true });
|
|
109
109
|
ngControl = inject(NgControl, {
|
|
110
110
|
optional: true,
|
|
111
111
|
self: true,
|
|
@@ -127,9 +127,11 @@ class InputDirective extends FormFieldControl {
|
|
|
127
127
|
/** Id on the underlying element. Auto-generated as `tw-input-N` when not provided. Used by the form-field's `<label for>` attribute. */
|
|
128
128
|
idInput = input(undefined, { ...(ngDevMode ? { debugName: "idInput" } : /* istanbul ignore next */ {}), alias: 'id' });
|
|
129
129
|
/** Native HTML input `type`. Defaults to `'text'`. Dev-mode throws on unsupported values (`checkbox`, `radio`, `submit`, etc.) — use the dedicated component instead. Ignored on `<textarea>`. */
|
|
130
|
-
type = input('text',
|
|
130
|
+
type = input('text', /* @ts-ignore */
|
|
131
|
+
...(ngDevMode ? [{ debugName: "type" }] : /* istanbul ignore next */ []));
|
|
131
132
|
/** Density of a standalone field. Maps to the inline-padding scale (`px-2 py-1` xs … `px-6 py-3` xl) and font scale (`text-xs` xs, `text-sm` sm/md, `text-base` lg/xl). Ignored inside a `<tw-form-field>` — the wrapper's `size` carries density. Defaults to `'md'`. */
|
|
132
|
-
size = input('md',
|
|
133
|
+
size = input('md', /* @ts-ignore */
|
|
134
|
+
...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
|
|
133
135
|
/** Disables the control. Also reflects `ngControl.disabled` when the element is bound to a reactive form. Defaults to `false`. */
|
|
134
136
|
disabledInput = input(false, { ...(ngDevMode ? { debugName: "disabledInput" } : /* istanbul ignore next */ {}), alias: 'disabled',
|
|
135
137
|
transform: booleanAttribute });
|
|
@@ -140,22 +142,30 @@ class InputDirective extends FormFieldControl {
|
|
|
140
142
|
readonlyInput = input(false, { ...(ngDevMode ? { debugName: "readonlyInput" } : /* istanbul ignore next */ {}), alias: 'readonly',
|
|
141
143
|
transform: booleanAttribute });
|
|
142
144
|
/** Per-instance override of the {@link ErrorStateMatcher}. When omitted, the directive uses the `TW_ERROR_STATE_MATCHER` token's value. */
|
|
143
|
-
errorStateMatcher = input(undefined,
|
|
145
|
+
errorStateMatcher = input(undefined, /* @ts-ignore */
|
|
146
|
+
...(ngDevMode ? [{ debugName: "errorStateMatcher" }] : /* istanbul ignore next */ []));
|
|
144
147
|
/** Consumer-supplied `aria-describedby` ids. The form-field preserves these when merging hint and error ids. Alias: `aria-describedby`. */
|
|
145
148
|
userAriaDescribedBy = input(undefined, { ...(ngDevMode ? { debugName: "userAriaDescribedBy" } : /* istanbul ignore next */ {}), alias: 'aria-describedby' });
|
|
146
149
|
/** Consumer-supplied `aria-labelledby` ids. The form-field preserves these when merging in the projected label id. Alias: `aria-labelledby`. */
|
|
147
150
|
userAriaLabelledby = input(undefined, { ...(ngDevMode ? { debugName: "userAriaLabelledby" } : /* istanbul ignore next */ {}), alias: 'aria-labelledby' });
|
|
148
151
|
// ── Internal state signals ──
|
|
149
|
-
_value = signal(this._readInitialValue(),
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
152
|
+
_value = signal(this._readInitialValue(), /* @ts-ignore */
|
|
153
|
+
...(ngDevMode ? [{ debugName: "_value" }] : /* istanbul ignore next */ []));
|
|
154
|
+
_focused = signal(false, /* @ts-ignore */
|
|
155
|
+
...(ngDevMode ? [{ debugName: "_focused" }] : /* istanbul ignore next */ []));
|
|
156
|
+
_autofilled = signal(false, /* @ts-ignore */
|
|
157
|
+
...(ngDevMode ? [{ debugName: "_autofilled" }] : /* istanbul ignore next */ []));
|
|
158
|
+
_ngControlRev = signal(0, /* @ts-ignore */
|
|
159
|
+
...(ngDevMode ? [{ debugName: "_ngControlRev" }] : /* istanbul ignore next */ []));
|
|
160
|
+
_formSubmitRev = signal(0, /* @ts-ignore */
|
|
161
|
+
...(ngDevMode ? [{ debugName: "_formSubmitRev" }] : /* istanbul ignore next */ []));
|
|
154
162
|
// ── FormFieldControl signals ──
|
|
155
163
|
/** @internal */
|
|
156
|
-
id = computed(() => this.idInput() ?? this.uid,
|
|
164
|
+
id = computed(() => this.idInput() ?? this.uid, /* @ts-ignore */
|
|
165
|
+
...(ngDevMode ? [{ debugName: "id" }] : /* istanbul ignore next */ []));
|
|
157
166
|
/** @internal */
|
|
158
|
-
value = computed(() => this._value() || null,
|
|
167
|
+
value = computed(() => this._value() || null, /* @ts-ignore */
|
|
168
|
+
...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
|
|
159
169
|
/** @internal */
|
|
160
170
|
focused = this._focused.asReadonly();
|
|
161
171
|
/** @internal */
|
|
@@ -164,19 +174,22 @@ class InputDirective extends FormFieldControl {
|
|
|
164
174
|
return false;
|
|
165
175
|
}
|
|
166
176
|
return !this._value() && !this._autofilled();
|
|
167
|
-
},
|
|
177
|
+
}, /* @ts-ignore */
|
|
178
|
+
...(ngDevMode ? [{ debugName: "empty" }] : /* istanbul ignore next */ []));
|
|
168
179
|
/** @internal */
|
|
169
180
|
disabled = computed(() => {
|
|
170
181
|
this._ngControlRev();
|
|
171
182
|
return this.disabledInput() || !!this.ngControl?.disabled;
|
|
172
|
-
},
|
|
183
|
+
}, /* @ts-ignore */
|
|
184
|
+
...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
|
|
173
185
|
/** @internal */
|
|
174
186
|
required = computed(() => {
|
|
175
187
|
this._ngControlRev();
|
|
176
188
|
if (this.requiredInput())
|
|
177
189
|
return true;
|
|
178
190
|
return !!this.ngControl?.control?.hasValidator(Validators.required);
|
|
179
|
-
},
|
|
191
|
+
}, /* @ts-ignore */
|
|
192
|
+
...(ngDevMode ? [{ debugName: "required" }] : /* istanbul ignore next */ []));
|
|
180
193
|
/** @internal */
|
|
181
194
|
errorState = computed(() => {
|
|
182
195
|
this._ngControlRev();
|
|
@@ -186,19 +199,22 @@ class InputDirective extends FormFieldControl {
|
|
|
186
199
|
const form = this.parentFormGroup ??
|
|
187
200
|
this.parentForm;
|
|
188
201
|
return matcher.isErrorState(this.ngControl?.control ?? null, form);
|
|
189
|
-
},
|
|
202
|
+
}, /* @ts-ignore */
|
|
203
|
+
...(ngDevMode ? [{ debugName: "errorState" }] : /* istanbul ignore next */ []));
|
|
190
204
|
/** @internal Active validation errors map from the bound `NgControl` (or `null` when the control reports none / is unbound). Recomputes on every `_ngControlRev` tick so `[twError match="…"]` reacts to validator transitions, including rules that fire/clear without flipping `VALID`/`INVALID`. */
|
|
191
205
|
errors = computed(() => {
|
|
192
206
|
this._ngControlRev();
|
|
193
207
|
return this.ngControl?.control?.errors ?? null;
|
|
194
|
-
},
|
|
208
|
+
}, /* @ts-ignore */
|
|
209
|
+
...(ngDevMode ? [{ debugName: "errors" }] : /* istanbul ignore next */ []));
|
|
195
210
|
/** @internal */
|
|
196
211
|
classes = computed(() => inputVariants({
|
|
197
212
|
inFormField: !!this.formField,
|
|
198
213
|
size: this.size(),
|
|
199
214
|
errorState: this.errorState(),
|
|
200
215
|
disabled: this.disabled(),
|
|
201
|
-
}),
|
|
216
|
+
}), /* @ts-ignore */
|
|
217
|
+
...(ngDevMode ? [{ debugName: "classes" }] : /* istanbul ignore next */ []));
|
|
202
218
|
constructor() {
|
|
203
219
|
super();
|
|
204
220
|
this.focusMonitor
|
|
@@ -322,12 +338,12 @@ class InputDirective extends FormFieldControl {
|
|
|
322
338
|
_stringify(v) {
|
|
323
339
|
return v === null || v === undefined ? '' : String(v);
|
|
324
340
|
}
|
|
325
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
326
|
-
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "
|
|
341
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: InputDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
342
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.0.7", type: InputDirective, isStandalone: true, selector: "input[twInput], textarea[twInput]", inputs: { idInput: { classPropertyName: "idInput", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, disabledInput: { classPropertyName: "disabledInput", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, requiredInput: { classPropertyName: "requiredInput", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, readonlyInput: { classPropertyName: "readonlyInput", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, errorStateMatcher: { classPropertyName: "errorStateMatcher", publicName: "errorStateMatcher", isSignal: true, isRequired: false, transformFunction: null }, userAriaDescribedBy: { classPropertyName: "userAriaDescribedBy", publicName: "aria-describedby", isSignal: true, isRequired: false, transformFunction: null }, userAriaLabelledby: { classPropertyName: "userAriaLabelledby", publicName: "aria-labelledby", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "input": "_onInput()" }, properties: { "class": "classes()", "attr.id": "id()", "attr.type": "_isTextarea ? null : type()", "disabled": "disabled()", "attr.aria-invalid": "errorState() || null", "attr.aria-required": "required() || null" } }, providers: [
|
|
327
343
|
{ provide: TW_FORM_FIELD_CONTROL, useExisting: InputDirective },
|
|
328
344
|
], exportAs: ["twInput"], usesInheritance: true, ngImport: i0 });
|
|
329
345
|
}
|
|
330
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
346
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: InputDirective, decorators: [{
|
|
331
347
|
type: Directive,
|
|
332
348
|
args: [{
|
|
333
349
|
selector: 'input[twInput], textarea[twInput]',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cdevhub-ngx-tw-input.mjs","sources":["../../../projects/ngx-tw/input/input.ts","../../../projects/ngx-tw/input/cdevhub-ngx-tw-input.ts"],"sourcesContent":["import {\n booleanAttribute,\n computed,\n DestroyRef,\n Directive,\n effect,\n ElementRef,\n inject,\n InjectionToken,\n input,\n isDevMode,\n isSignal,\n type OnInit,\n signal,\n type Signal,\n untracked,\n type WritableSignal,\n} from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport {\n FormGroupDirective,\n NgControl,\n NgForm,\n Validators,\n} from '@angular/forms';\nimport { FocusMonitor } from '@angular/cdk/a11y';\nimport { AutofillMonitor } from '@angular/cdk/text-field';\nimport { Platform } from '@angular/cdk/platform';\nimport { merge } from 'rxjs';\nimport { tv } from 'tailwind-variants';\nimport {\n type ErrorStateMatcher,\n TW_ERROR_STATE_MATCHER,\n type TwFormSubmitted,\n type TwSize,\n} from '@cdevhub/ngx-tw/core';\nimport {\n FormFieldComponent,\n FormFieldControl,\n TW_FORM_FIELD_CONTROL,\n} from '@cdevhub/ngx-tw/form-field';\n\n/**\n * Extension point for directives that wrap an `<input twInput>` and need to\n * own how its value is read and written. The directive's `value` property can\n * be a plain object slot (`{ value: T }`) or a `WritableSignal<T>`. Mirrors\n * Angular Material's `MAT_INPUT_VALUE_ACCESSOR`.\n */\nexport const TW_INPUT_VALUE_ACCESSOR = new InjectionToken<{\n value: unknown | WritableSignal<unknown>;\n}>('TW_INPUT_VALUE_ACCESSOR');\n\nconst INVALID_INPUT_TYPES = new Set([\n 'button',\n 'checkbox',\n 'file',\n 'hidden',\n 'image',\n 'radio',\n 'range',\n 'reset',\n 'submit',\n]);\n\nconst NEVER_EMPTY_TYPES = new Set([\n 'date',\n 'datetime-local',\n 'month',\n 'time',\n 'week',\n 'color',\n]);\n\nconst inputVariants = tv(\n {\n base: 'block w-full bg-transparent text-fg placeholder:text-fg-subtle outline-none',\n variants: {\n inFormField: {\n true: 'border-0 p-0 shadow-none focus:outline-none focus-visible:outline-none',\n false:\n 'rounded-md border border-border transition-[color,border-color,box-shadow] duration-normal motion-reduce:transition-none hover:border-border-strong focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary-500',\n },\n size: {\n xs: '',\n sm: '',\n md: '',\n lg: '',\n xl: '',\n },\n errorState: {\n true: '',\n false: '',\n },\n disabled: {\n true: 'opacity-50 cursor-not-allowed',\n false: '',\n },\n },\n compoundVariants: [\n // Standalone density × size — inline padding + font scale.\n { inFormField: false, size: 'xs', class: 'px-2 py-1 text-xs' },\n { inFormField: false, size: 'sm', class: 'px-3 py-1.5 text-sm' },\n { inFormField: false, size: 'md', class: 'px-4 py-2 text-sm' },\n { inFormField: false, size: 'lg', class: 'px-5 py-2.5 text-base' },\n { inFormField: false, size: 'xl', class: 'px-6 py-3 text-base' },\n // Standalone error state — colored border and focus ring.\n {\n inFormField: false,\n errorState: true,\n class: 'border-error-500 focus-visible:outline-error-500',\n },\n ],\n defaultVariants: {\n inFormField: false,\n size: 'md',\n errorState: false,\n disabled: false,\n },\n },\n { twMerge: true },\n);\n\nlet nextInputId = 0;\n\n/**\n * Adapts a native `<input>` or `<textarea>` into an ngx-tw form-field-compatible\n * control. Works standalone (applies its own border and focus styling) or\n * inside a `<tw-form-field>` (strips its chrome and provides signals the\n * form-field uses to float the label and wire `aria-describedby`).\n *\n * Extension points:\n * - Implement a completely custom control → extend {@link FormFieldControl}\n * and provide under `TW_FORM_FIELD_CONTROL`.\n * - Swap value storage for an existing `<input twInput>` (masked input,\n * date parser, etc.) → provide {@link TW_INPUT_VALUE_ACCESSOR}.\n * - Change when errors show → override {@link TW_ERROR_STATE_MATCHER} at any\n * injector level, or pass `errorStateMatcher` per instance.\n *\n * Forms integration is inherited: Angular's native value accessors attach to\n * the underlying element, so the directive works with template-driven,\n * reactive, and signal-based forms without additional glue.\n */\n@Directive({\n selector: 'input[twInput], textarea[twInput]',\n exportAs: 'twInput',\n providers: [\n { provide: TW_FORM_FIELD_CONTROL, useExisting: InputDirective },\n ],\n host: {\n '[class]': 'classes()',\n '[attr.id]': 'id()',\n '[attr.type]': '_isTextarea ? null : type()',\n '[disabled]': 'disabled()',\n '[attr.aria-invalid]': 'errorState() || null',\n '[attr.aria-required]': 'required() || null',\n '(input)': '_onInput()',\n },\n})\nexport class InputDirective\n extends FormFieldControl<string>\n implements OnInit\n{\n private readonly elementRef = inject<\n ElementRef<HTMLInputElement | HTMLTextAreaElement>\n >(ElementRef);\n private readonly focusMonitor = inject(FocusMonitor);\n private readonly autofillMonitor = inject(AutofillMonitor);\n private readonly platform = inject(Platform);\n private readonly destroyRef = inject(DestroyRef);\n private readonly formField = inject(FormFieldComponent, { optional: true });\n private readonly ngControl = inject(NgControl, {\n optional: true,\n self: true,\n });\n private readonly parentForm = inject(NgForm, { optional: true });\n private readonly parentFormGroup = inject(FormGroupDirective, {\n optional: true,\n });\n private readonly defaultMatcher = inject(TW_ERROR_STATE_MATCHER);\n private readonly valueAccessor = inject(TW_INPUT_VALUE_ACCESSOR, {\n optional: true,\n self: true,\n });\n\n /** @internal */\n readonly _isTextarea =\n this.elementRef.nativeElement.tagName.toLowerCase() === 'textarea';\n\n /** Contract value — `'input'` for `<input>` and `'textarea'` for `<textarea>`. Form-field appends it as `tw-form-field-type-*` for styling hooks. */\n readonly controlType: string = this._isTextarea ? 'textarea' : 'input';\n\n private readonly uid = `tw-input-${nextInputId++}`;\n\n /** Id on the underlying element. Auto-generated as `tw-input-N` when not provided. Used by the form-field's `<label for>` attribute. */\n readonly idInput = input<string | undefined>(undefined, { alias: 'id' });\n\n /** Native HTML input `type`. Defaults to `'text'`. Dev-mode throws on unsupported values (`checkbox`, `radio`, `submit`, etc.) — use the dedicated component instead. Ignored on `<textarea>`. */\n readonly type = input<string>('text');\n\n /** Density of a standalone field. Maps to the inline-padding scale (`px-2 py-1` xs … `px-6 py-3` xl) and font scale (`text-xs` xs, `text-sm` sm/md, `text-base` lg/xl). Ignored inside a `<tw-form-field>` — the wrapper's `size` carries density. Defaults to `'md'`. */\n readonly size = input<TwSize>('md');\n\n /** Disables the control. Also reflects `ngControl.disabled` when the element is bound to a reactive form. Defaults to `false`. */\n readonly disabledInput = input<boolean, unknown>(false, {\n alias: 'disabled',\n transform: booleanAttribute,\n });\n\n /** Marks the control as required. Also inferred from `Validators.required` on a bound `NgControl`. Defaults to `false`. */\n readonly requiredInput = input<boolean, unknown>(false, {\n alias: 'required',\n transform: booleanAttribute,\n });\n\n /** Makes the control read-only (native `readonly` attribute). Defaults to `false`. */\n readonly readonlyInput = input<boolean, unknown>(false, {\n alias: 'readonly',\n transform: booleanAttribute,\n });\n\n /** Per-instance override of the {@link ErrorStateMatcher}. When omitted, the directive uses the `TW_ERROR_STATE_MATCHER` token's value. */\n readonly errorStateMatcher = input<ErrorStateMatcher | undefined>(undefined);\n\n /** Consumer-supplied `aria-describedby` ids. The form-field preserves these when merging hint and error ids. Alias: `aria-describedby`. */\n override readonly userAriaDescribedBy = input<string | undefined>(undefined, {\n alias: 'aria-describedby',\n });\n\n /** Consumer-supplied `aria-labelledby` ids. The form-field preserves these when merging in the projected label id. Alias: `aria-labelledby`. */\n override readonly userAriaLabelledby = input<string | undefined>(undefined, {\n alias: 'aria-labelledby',\n });\n\n // ── Internal state signals ──\n\n private readonly _value = signal<string>(this._readInitialValue());\n private readonly _focused = signal(false);\n private readonly _autofilled = signal(false);\n private readonly _ngControlRev = signal(0);\n private readonly _formSubmitRev = signal(0);\n\n // ── FormFieldControl signals ──\n\n /** @internal */\n readonly id = computed(() => this.idInput() ?? this.uid);\n\n /** @internal */\n readonly value = computed<string | null>(() => this._value() || null);\n\n /** @internal */\n readonly focused = this._focused.asReadonly();\n\n /** @internal */\n readonly empty = computed(() => {\n if (!this._isTextarea && NEVER_EMPTY_TYPES.has(this.type())) {\n return false;\n }\n return !this._value() && !this._autofilled();\n });\n\n /** @internal */\n readonly disabled = computed(() => {\n this._ngControlRev();\n return this.disabledInput() || !!this.ngControl?.disabled;\n });\n\n /** @internal */\n readonly required = computed(() => {\n this._ngControlRev();\n if (this.requiredInput()) return true;\n return !!this.ngControl?.control?.hasValidator(Validators.required);\n });\n\n /** @internal */\n readonly errorState = computed(() => {\n this._ngControlRev();\n this._formSubmitRev();\n this._focused();\n const matcher = this.errorStateMatcher() ?? this.defaultMatcher;\n const form: TwFormSubmitted | null =\n (this.parentFormGroup as TwFormSubmitted | null) ??\n (this.parentForm as TwFormSubmitted | null);\n return matcher.isErrorState(this.ngControl?.control ?? null, form);\n });\n\n /** @internal Active validation errors map from the bound `NgControl` (or `null` when the control reports none / is unbound). Recomputes on every `_ngControlRev` tick so `[twError match=\"…\"]` reacts to validator transitions, including rules that fire/clear without flipping `VALID`/`INVALID`. */\n override readonly errors = computed<Record<string, unknown> | null>(() => {\n this._ngControlRev();\n return (this.ngControl?.control?.errors as Record<string, unknown> | null) ?? null;\n });\n\n /** @internal */\n readonly classes = computed(() =>\n inputVariants({\n inFormField: !!this.formField,\n size: this.size(),\n errorState: this.errorState(),\n disabled: this.disabled(),\n }),\n );\n\n constructor() {\n super();\n\n this.focusMonitor\n .monitor(this.elementRef)\n .pipe(takeUntilDestroyed())\n .subscribe((origin) => {\n const wasFocused = this._focused();\n this._focused.set(!!origin);\n if (wasFocused && !origin) {\n // Blur often flips `touched` on the bound `NgControl`; bump the\n // revision signal so `errorState` recomputes.\n this._ngControlRev.update((n) => n + 1);\n }\n });\n this.destroyRef.onDestroy(() =>\n this.focusMonitor.stopMonitoring(this.elementRef),\n );\n\n // Keep `_value` in sync when the accessor's value is itself a signal.\n if (this.valueAccessor && isSignal(this.valueAccessor.value)) {\n effect(() => {\n const v = (this.valueAccessor!.value as Signal<unknown>)();\n untracked(() => this._value.set(this._stringify(v)));\n });\n }\n\n // Sync the `readonly` input to the native attribute.\n effect(() => {\n const el = this.elementRef.nativeElement;\n if (this.readonlyInput()) {\n el.setAttribute('readonly', 'true');\n } else {\n el.removeAttribute('readonly');\n }\n });\n\n // Validate the input type in dev mode.\n effect(() => {\n const t = this.type();\n if (\n isDevMode() &&\n !this._isTextarea &&\n INVALID_INPUT_TYPES.has(t)\n ) {\n throw new Error(\n `tw-input: unsupported input type \"${t}\". Use a dedicated ngx-tw component for that control.`,\n );\n }\n });\n }\n\n ngOnInit(): void {\n if (this.platform.isBrowser) {\n this.autofillMonitor\n .monitor(this.elementRef.nativeElement)\n .pipe(takeUntilDestroyed(this.destroyRef))\n .subscribe((event) => this._autofilled.set(event.isAutofilled));\n this.destroyRef.onDestroy(() =>\n this.autofillMonitor.stopMonitoring(this.elementRef.nativeElement),\n );\n }\n\n // NgControl's `control` is set by the parent `FormControl*` directive's\n // own `ngOnChanges`, which runs before children's `ngOnInit`. Subscribe\n // here so `statusChanges`/`valueChanges` are actually available.\n const ctrl = this.ngControl?.control;\n if (ctrl) {\n const streams = [ctrl.statusChanges, ctrl.valueChanges].filter(\n (s): s is NonNullable<typeof s> => !!s,\n );\n if (streams.length) {\n merge(...streams)\n .pipe(takeUntilDestroyed(this.destroyRef))\n .subscribe(() => this._ngControlRev.update((n) => n + 1));\n }\n }\n\n const submit = this.parentFormGroup?.ngSubmit ?? this.parentForm?.ngSubmit;\n if (submit) {\n submit\n .pipe(takeUntilDestroyed(this.destroyRef))\n .subscribe(() => this._formSubmitRev.update((n) => n + 1));\n }\n }\n\n /** Moves focus to the underlying element. */\n focus(options?: FocusOptions): void {\n this.elementRef.nativeElement.focus(options);\n }\n\n /** @internal Called when `<tw-form-field>` has computed the merged describedby ids. */\n setDescribedByIds(ids: string[]): void {\n const el = this.elementRef.nativeElement;\n if (ids.length) {\n el.setAttribute('aria-describedby', ids.join(' '));\n } else {\n el.removeAttribute('aria-describedby');\n }\n }\n\n /** @internal Called when `<tw-form-field>` has computed the merged labelledby ids. The native `<label for>` association covers most cases; this attribute is mainly useful when a consumer also supplies `aria-labelledby` for an external label. */\n override setLabelledByIds(ids: string[]): void {\n const el = this.elementRef.nativeElement;\n // Skip applying the projected label id by itself — native `<label for=>` already wires it\n // and a redundant `aria-labelledby` can cause double-announcements in some screen readers.\n // Only apply when the consumer supplied additional ids via `aria-labelledby`.\n const userIds = this.userAriaLabelledby();\n if (userIds || (ids.length > 1)) {\n el.setAttribute('aria-labelledby', ids.join(' '));\n } else {\n el.removeAttribute('aria-labelledby');\n }\n }\n\n /** @internal Called when the form-field container is clicked. */\n onContainerClick(_event: MouseEvent): void {\n if (!this._focused()) {\n this.focus();\n }\n }\n\n /** @internal */\n _onInput(): void {\n this._value.set(this._currentValue());\n }\n\n private _currentValue(): string {\n if (this.valueAccessor) {\n const v = this.valueAccessor.value;\n if (isSignal(v)) return this._stringify((v as Signal<unknown>)());\n return this._stringify(v);\n }\n return this.elementRef.nativeElement.value;\n }\n\n private _readInitialValue(): string {\n const el = this.elementRef.nativeElement;\n return el.value ?? '';\n }\n\n private _stringify(v: unknown): string {\n return v === null || v === undefined ? '' : String(v);\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"cdevhub-ngx-tw-input.mjs","sources":["../../../projects/ngx-tw/input/input.ts","../../../projects/ngx-tw/input/cdevhub-ngx-tw-input.ts"],"sourcesContent":["import {\n booleanAttribute,\n computed,\n DestroyRef,\n Directive,\n effect,\n ElementRef,\n inject,\n InjectionToken,\n input,\n isDevMode,\n isSignal,\n type OnInit,\n signal,\n type Signal,\n untracked,\n type WritableSignal,\n} from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport {\n FormGroupDirective,\n NgControl,\n NgForm,\n Validators,\n} from '@angular/forms';\nimport { FocusMonitor } from '@angular/cdk/a11y';\nimport { AutofillMonitor } from '@angular/cdk/text-field';\nimport { Platform } from '@angular/cdk/platform';\nimport { merge } from 'rxjs';\nimport { tv } from 'tailwind-variants';\nimport {\n type ErrorStateMatcher,\n TW_ERROR_STATE_MATCHER,\n type TwFormSubmitted,\n type TwSize,\n} from '@cdevhub/ngx-tw/core';\nimport {\n FormFieldControl,\n TW_FORM_FIELD,\n TW_FORM_FIELD_CONTROL,\n} from '@cdevhub/ngx-tw/form-field';\n\n/**\n * Extension point for directives that wrap an `<input twInput>` and need to\n * own how its value is read and written. The directive's `value` property can\n * be a plain object slot (`{ value: T }`) or a `WritableSignal<T>`. Mirrors\n * Angular Material's `MAT_INPUT_VALUE_ACCESSOR`.\n */\nexport const TW_INPUT_VALUE_ACCESSOR = new InjectionToken<{\n value: unknown | WritableSignal<unknown>;\n}>('TW_INPUT_VALUE_ACCESSOR');\n\nconst INVALID_INPUT_TYPES = new Set([\n 'button',\n 'checkbox',\n 'file',\n 'hidden',\n 'image',\n 'radio',\n 'range',\n 'reset',\n 'submit',\n]);\n\nconst NEVER_EMPTY_TYPES = new Set([\n 'date',\n 'datetime-local',\n 'month',\n 'time',\n 'week',\n 'color',\n]);\n\nconst inputVariants = tv(\n {\n base: 'block w-full bg-transparent text-fg placeholder:text-fg-subtle outline-none',\n variants: {\n inFormField: {\n true: 'border-0 p-0 shadow-none focus:outline-none focus-visible:outline-none',\n false:\n 'rounded-md border border-border transition-[color,border-color,box-shadow] duration-normal motion-reduce:transition-none hover:border-border-strong focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary-500',\n },\n size: {\n xs: '',\n sm: '',\n md: '',\n lg: '',\n xl: '',\n },\n errorState: {\n true: '',\n false: '',\n },\n disabled: {\n true: 'opacity-50 cursor-not-allowed',\n false: '',\n },\n },\n compoundVariants: [\n // Standalone density × size — inline padding + font scale.\n { inFormField: false, size: 'xs', class: 'px-2 py-1 text-xs' },\n { inFormField: false, size: 'sm', class: 'px-3 py-1.5 text-sm' },\n { inFormField: false, size: 'md', class: 'px-4 py-2 text-sm' },\n { inFormField: false, size: 'lg', class: 'px-5 py-2.5 text-base' },\n { inFormField: false, size: 'xl', class: 'px-6 py-3 text-base' },\n // Standalone error state — colored border and focus ring.\n {\n inFormField: false,\n errorState: true,\n class: 'border-error-500 focus-visible:outline-error-500',\n },\n ],\n defaultVariants: {\n inFormField: false,\n size: 'md',\n errorState: false,\n disabled: false,\n },\n },\n { twMerge: true },\n);\n\nlet nextInputId = 0;\n\n/**\n * Adapts a native `<input>` or `<textarea>` into an ngx-tw form-field-compatible\n * control. Works standalone (applies its own border and focus styling) or\n * inside a `<tw-form-field>` (strips its chrome and provides signals the\n * form-field uses to float the label and wire `aria-describedby`).\n *\n * Extension points:\n * - Implement a completely custom control → extend {@link FormFieldControl}\n * and provide under `TW_FORM_FIELD_CONTROL`.\n * - Swap value storage for an existing `<input twInput>` (masked input,\n * date parser, etc.) → provide {@link TW_INPUT_VALUE_ACCESSOR}.\n * - Change when errors show → override {@link TW_ERROR_STATE_MATCHER} at any\n * injector level, or pass `errorStateMatcher` per instance.\n *\n * Forms integration is inherited: Angular's native value accessors attach to\n * the underlying element, so the directive works with template-driven,\n * reactive, and signal-based forms without additional glue.\n */\n@Directive({\n selector: 'input[twInput], textarea[twInput]',\n exportAs: 'twInput',\n providers: [\n { provide: TW_FORM_FIELD_CONTROL, useExisting: InputDirective },\n ],\n host: {\n '[class]': 'classes()',\n '[attr.id]': 'id()',\n '[attr.type]': '_isTextarea ? null : type()',\n '[disabled]': 'disabled()',\n '[attr.aria-invalid]': 'errorState() || null',\n '[attr.aria-required]': 'required() || null',\n '(input)': '_onInput()',\n },\n})\nexport class InputDirective\n extends FormFieldControl<string>\n implements OnInit\n{\n private readonly elementRef = inject<\n ElementRef<HTMLInputElement | HTMLTextAreaElement>\n >(ElementRef);\n private readonly focusMonitor = inject(FocusMonitor);\n private readonly autofillMonitor = inject(AutofillMonitor);\n private readonly platform = inject(Platform);\n private readonly destroyRef = inject(DestroyRef);\n private readonly formField = inject(TW_FORM_FIELD, { optional: true });\n private readonly ngControl = inject(NgControl, {\n optional: true,\n self: true,\n });\n private readonly parentForm = inject(NgForm, { optional: true });\n private readonly parentFormGroup = inject(FormGroupDirective, {\n optional: true,\n });\n private readonly defaultMatcher = inject(TW_ERROR_STATE_MATCHER);\n private readonly valueAccessor = inject(TW_INPUT_VALUE_ACCESSOR, {\n optional: true,\n self: true,\n });\n\n /** @internal */\n readonly _isTextarea =\n this.elementRef.nativeElement.tagName.toLowerCase() === 'textarea';\n\n /** Contract value — `'input'` for `<input>` and `'textarea'` for `<textarea>`. Form-field appends it as `tw-form-field-type-*` for styling hooks. */\n readonly controlType: string = this._isTextarea ? 'textarea' : 'input';\n\n private readonly uid = `tw-input-${nextInputId++}`;\n\n /** Id on the underlying element. Auto-generated as `tw-input-N` when not provided. Used by the form-field's `<label for>` attribute. */\n readonly idInput = input<string | undefined>(undefined, { alias: 'id' });\n\n /** Native HTML input `type`. Defaults to `'text'`. Dev-mode throws on unsupported values (`checkbox`, `radio`, `submit`, etc.) — use the dedicated component instead. Ignored on `<textarea>`. */\n readonly type = input<string>('text');\n\n /** Density of a standalone field. Maps to the inline-padding scale (`px-2 py-1` xs … `px-6 py-3` xl) and font scale (`text-xs` xs, `text-sm` sm/md, `text-base` lg/xl). Ignored inside a `<tw-form-field>` — the wrapper's `size` carries density. Defaults to `'md'`. */\n readonly size = input<TwSize>('md');\n\n /** Disables the control. Also reflects `ngControl.disabled` when the element is bound to a reactive form. Defaults to `false`. */\n readonly disabledInput = input<boolean, unknown>(false, {\n alias: 'disabled',\n transform: booleanAttribute,\n });\n\n /** Marks the control as required. Also inferred from `Validators.required` on a bound `NgControl`. Defaults to `false`. */\n readonly requiredInput = input<boolean, unknown>(false, {\n alias: 'required',\n transform: booleanAttribute,\n });\n\n /** Makes the control read-only (native `readonly` attribute). Defaults to `false`. */\n readonly readonlyInput = input<boolean, unknown>(false, {\n alias: 'readonly',\n transform: booleanAttribute,\n });\n\n /** Per-instance override of the {@link ErrorStateMatcher}. When omitted, the directive uses the `TW_ERROR_STATE_MATCHER` token's value. */\n readonly errorStateMatcher = input<ErrorStateMatcher | undefined>(undefined);\n\n /** Consumer-supplied `aria-describedby` ids. The form-field preserves these when merging hint and error ids. Alias: `aria-describedby`. */\n override readonly userAriaDescribedBy = input<string | undefined>(undefined, {\n alias: 'aria-describedby',\n });\n\n /** Consumer-supplied `aria-labelledby` ids. The form-field preserves these when merging in the projected label id. Alias: `aria-labelledby`. */\n override readonly userAriaLabelledby = input<string | undefined>(undefined, {\n alias: 'aria-labelledby',\n });\n\n // ── Internal state signals ──\n\n private readonly _value = signal<string>(this._readInitialValue());\n private readonly _focused = signal(false);\n private readonly _autofilled = signal(false);\n private readonly _ngControlRev = signal(0);\n private readonly _formSubmitRev = signal(0);\n\n // ── FormFieldControl signals ──\n\n /** @internal */\n readonly id = computed(() => this.idInput() ?? this.uid);\n\n /** @internal */\n readonly value = computed<string | null>(() => this._value() || null);\n\n /** @internal */\n readonly focused = this._focused.asReadonly();\n\n /** @internal */\n readonly empty = computed(() => {\n if (!this._isTextarea && NEVER_EMPTY_TYPES.has(this.type())) {\n return false;\n }\n return !this._value() && !this._autofilled();\n });\n\n /** @internal */\n readonly disabled = computed(() => {\n this._ngControlRev();\n return this.disabledInput() || !!this.ngControl?.disabled;\n });\n\n /** @internal */\n readonly required = computed(() => {\n this._ngControlRev();\n if (this.requiredInput()) return true;\n return !!this.ngControl?.control?.hasValidator(Validators.required);\n });\n\n /** @internal */\n readonly errorState = computed(() => {\n this._ngControlRev();\n this._formSubmitRev();\n this._focused();\n const matcher = this.errorStateMatcher() ?? this.defaultMatcher;\n const form: TwFormSubmitted | null =\n (this.parentFormGroup as TwFormSubmitted | null) ??\n (this.parentForm as TwFormSubmitted | null);\n return matcher.isErrorState(this.ngControl?.control ?? null, form);\n });\n\n /** @internal Active validation errors map from the bound `NgControl` (or `null` when the control reports none / is unbound). Recomputes on every `_ngControlRev` tick so `[twError match=\"…\"]` reacts to validator transitions, including rules that fire/clear without flipping `VALID`/`INVALID`. */\n override readonly errors = computed<Record<string, unknown> | null>(() => {\n this._ngControlRev();\n return (this.ngControl?.control?.errors as Record<string, unknown> | null) ?? null;\n });\n\n /** @internal */\n readonly classes = computed(() =>\n inputVariants({\n inFormField: !!this.formField,\n size: this.size(),\n errorState: this.errorState(),\n disabled: this.disabled(),\n }),\n );\n\n constructor() {\n super();\n\n this.focusMonitor\n .monitor(this.elementRef)\n .pipe(takeUntilDestroyed())\n .subscribe((origin) => {\n const wasFocused = this._focused();\n this._focused.set(!!origin);\n if (wasFocused && !origin) {\n // Blur often flips `touched` on the bound `NgControl`; bump the\n // revision signal so `errorState` recomputes.\n this._ngControlRev.update((n) => n + 1);\n }\n });\n this.destroyRef.onDestroy(() =>\n this.focusMonitor.stopMonitoring(this.elementRef),\n );\n\n // Keep `_value` in sync when the accessor's value is itself a signal.\n if (this.valueAccessor && isSignal(this.valueAccessor.value)) {\n effect(() => {\n const v = (this.valueAccessor!.value as Signal<unknown>)();\n untracked(() => this._value.set(this._stringify(v)));\n });\n }\n\n // Sync the `readonly` input to the native attribute.\n effect(() => {\n const el = this.elementRef.nativeElement;\n if (this.readonlyInput()) {\n el.setAttribute('readonly', 'true');\n } else {\n el.removeAttribute('readonly');\n }\n });\n\n // Validate the input type in dev mode.\n effect(() => {\n const t = this.type();\n if (\n isDevMode() &&\n !this._isTextarea &&\n INVALID_INPUT_TYPES.has(t)\n ) {\n throw new Error(\n `tw-input: unsupported input type \"${t}\". Use a dedicated ngx-tw component for that control.`,\n );\n }\n });\n }\n\n ngOnInit(): void {\n if (this.platform.isBrowser) {\n this.autofillMonitor\n .monitor(this.elementRef.nativeElement)\n .pipe(takeUntilDestroyed(this.destroyRef))\n .subscribe((event) => this._autofilled.set(event.isAutofilled));\n this.destroyRef.onDestroy(() =>\n this.autofillMonitor.stopMonitoring(this.elementRef.nativeElement),\n );\n }\n\n // NgControl's `control` is set by the parent `FormControl*` directive's\n // own `ngOnChanges`, which runs before children's `ngOnInit`. Subscribe\n // here so `statusChanges`/`valueChanges` are actually available.\n const ctrl = this.ngControl?.control;\n if (ctrl) {\n const streams = [ctrl.statusChanges, ctrl.valueChanges].filter(\n (s): s is NonNullable<typeof s> => !!s,\n );\n if (streams.length) {\n merge(...streams)\n .pipe(takeUntilDestroyed(this.destroyRef))\n .subscribe(() => this._ngControlRev.update((n) => n + 1));\n }\n }\n\n const submit = this.parentFormGroup?.ngSubmit ?? this.parentForm?.ngSubmit;\n if (submit) {\n submit\n .pipe(takeUntilDestroyed(this.destroyRef))\n .subscribe(() => this._formSubmitRev.update((n) => n + 1));\n }\n }\n\n /** Moves focus to the underlying element. */\n focus(options?: FocusOptions): void {\n this.elementRef.nativeElement.focus(options);\n }\n\n /** @internal Called when `<tw-form-field>` has computed the merged describedby ids. */\n setDescribedByIds(ids: string[]): void {\n const el = this.elementRef.nativeElement;\n if (ids.length) {\n el.setAttribute('aria-describedby', ids.join(' '));\n } else {\n el.removeAttribute('aria-describedby');\n }\n }\n\n /** @internal Called when `<tw-form-field>` has computed the merged labelledby ids. The native `<label for>` association covers most cases; this attribute is mainly useful when a consumer also supplies `aria-labelledby` for an external label. */\n override setLabelledByIds(ids: string[]): void {\n const el = this.elementRef.nativeElement;\n // Skip applying the projected label id by itself — native `<label for=>` already wires it\n // and a redundant `aria-labelledby` can cause double-announcements in some screen readers.\n // Only apply when the consumer supplied additional ids via `aria-labelledby`.\n const userIds = this.userAriaLabelledby();\n if (userIds || (ids.length > 1)) {\n el.setAttribute('aria-labelledby', ids.join(' '));\n } else {\n el.removeAttribute('aria-labelledby');\n }\n }\n\n /** @internal Called when the form-field container is clicked. */\n onContainerClick(_event: MouseEvent): void {\n if (!this._focused()) {\n this.focus();\n }\n }\n\n /** @internal */\n _onInput(): void {\n this._value.set(this._currentValue());\n }\n\n private _currentValue(): string {\n if (this.valueAccessor) {\n const v = this.valueAccessor.value;\n if (isSignal(v)) return this._stringify((v as Signal<unknown>)());\n return this._stringify(v);\n }\n return this.elementRef.nativeElement.value;\n }\n\n private _readInitialValue(): string {\n const el = this.elementRef.nativeElement;\n return el.value ?? '';\n }\n\n private _stringify(v: unknown): string {\n return v === null || v === undefined ? '' : String(v);\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
|
@@ -86,9 +86,11 @@ const itemVariants = tv({
|
|
|
86
86
|
}, { twMerge: true });
|
|
87
87
|
class ItemComponent {
|
|
88
88
|
/** Density and typography scale. `'sm'` is compact with truncated single-line title and description (table rows). `'md'` is the default list-item size. `'lg'` is the section-header scale with a larger title. Defaults to `'md'`. */
|
|
89
|
-
size = input('md',
|
|
89
|
+
size = input('md', /* @ts-ignore */
|
|
90
|
+
...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
|
|
90
91
|
/** Vertical alignment of the leading and trailing slots relative to the content stack. `'start'` aligns them with the title baseline (recommended when a description is present). `'center'` vertically centers them on the whole block (recommended for single-line items). Defaults to `'start'`. */
|
|
91
|
-
align = input('start',
|
|
92
|
+
align = input('start', /* @ts-ignore */
|
|
93
|
+
...(ngDevMode ? [{ debugName: "align" }] : /* istanbul ignore next */ []));
|
|
92
94
|
/**
|
|
93
95
|
* When `true`, the item is keyboard-activatable: adds `role="button"`, `tabindex="0"`, a hover background, pointer cursor, and a visible focus ring. Click and Enter/Space emit `selected`. Defaults to `false`.
|
|
94
96
|
*
|
|
@@ -112,13 +114,20 @@ class ItemComponent {
|
|
|
112
114
|
interactive: this.interactive(),
|
|
113
115
|
disabled: this.disabled(),
|
|
114
116
|
current: this.current(),
|
|
115
|
-
}),
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
117
|
+
}), /* @ts-ignore */
|
|
118
|
+
...(ngDevMode ? [{ debugName: "variantResult" }] : /* istanbul ignore next */ []));
|
|
119
|
+
rootClasses = computed(() => this.variantResult().root(), /* @ts-ignore */
|
|
120
|
+
...(ngDevMode ? [{ debugName: "rootClasses" }] : /* istanbul ignore next */ []));
|
|
121
|
+
leadingClasses = computed(() => this.variantResult().leading(), /* @ts-ignore */
|
|
122
|
+
...(ngDevMode ? [{ debugName: "leadingClasses" }] : /* istanbul ignore next */ []));
|
|
123
|
+
contentClasses = computed(() => this.variantResult().content(), /* @ts-ignore */
|
|
124
|
+
...(ngDevMode ? [{ debugName: "contentClasses" }] : /* istanbul ignore next */ []));
|
|
125
|
+
titleClasses = computed(() => this.variantResult().title(), /* @ts-ignore */
|
|
126
|
+
...(ngDevMode ? [{ debugName: "titleClasses" }] : /* istanbul ignore next */ []));
|
|
127
|
+
descriptionClasses = computed(() => this.variantResult().description(), /* @ts-ignore */
|
|
128
|
+
...(ngDevMode ? [{ debugName: "descriptionClasses" }] : /* istanbul ignore next */ []));
|
|
129
|
+
trailingClasses = computed(() => this.variantResult().trailing(), /* @ts-ignore */
|
|
130
|
+
...(ngDevMode ? [{ debugName: "trailingClasses" }] : /* istanbul ignore next */ []));
|
|
122
131
|
ngOnInit() {
|
|
123
132
|
this.focusMonitor.monitor(this.elementRef);
|
|
124
133
|
this.destroyRef.onDestroy(() => {
|
|
@@ -138,8 +147,8 @@ class ItemComponent {
|
|
|
138
147
|
this.selected.emit(event);
|
|
139
148
|
}
|
|
140
149
|
}
|
|
141
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
142
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "
|
|
150
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: ItemComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
151
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.0.7", type: ItemComponent, isStandalone: true, selector: "tw-item", inputs: { size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, align: { classPropertyName: "align", publicName: "align", isSignal: true, isRequired: false, transformFunction: null }, interactive: { classPropertyName: "interactive", publicName: "interactive", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, current: { classPropertyName: "current", publicName: "current", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selected: "selected" }, host: { listeners: { "click": "onActivate($event)", "keydown": "onKeydown($event)" }, properties: { "class": "rootClasses()", "attr.role": "interactive() ? \"button\" : null", "attr.tabindex": "interactive() && !disabled() ? 0 : null", "attr.aria-disabled": "disabled() ? \"true\" : null", "attr.aria-current": "current() ? \"true\" : null" } }, ngImport: i0, template: `
|
|
143
152
|
<ng-content select="[twItemLeading]" />
|
|
144
153
|
<div [class]="contentClasses()">
|
|
145
154
|
<ng-content select="[twItemTitle]" />
|
|
@@ -148,7 +157,7 @@ class ItemComponent {
|
|
|
148
157
|
<ng-content select="[twItemTrailing]" />
|
|
149
158
|
`, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
150
159
|
}
|
|
151
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
160
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: ItemComponent, decorators: [{
|
|
152
161
|
type: Component,
|
|
153
162
|
args: [{
|
|
154
163
|
selector: 'tw-item',
|
|
@@ -175,10 +184,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
|
|
|
175
184
|
class ItemLeadingDirective {
|
|
176
185
|
item = inject(ItemComponent);
|
|
177
186
|
classes = this.item.leadingClasses;
|
|
178
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
179
|
-
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "
|
|
187
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: ItemLeadingDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
188
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.0.7", type: ItemLeadingDirective, isStandalone: true, selector: "[twItemLeading]", host: { properties: { "class": "classes()" } }, ngImport: i0 });
|
|
180
189
|
}
|
|
181
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
190
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: ItemLeadingDirective, decorators: [{
|
|
182
191
|
type: Directive,
|
|
183
192
|
args: [{
|
|
184
193
|
selector: '[twItemLeading]',
|
|
@@ -190,10 +199,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
|
|
|
190
199
|
class ItemTitleDirective {
|
|
191
200
|
item = inject(ItemComponent);
|
|
192
201
|
classes = this.item.titleClasses;
|
|
193
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
194
|
-
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "
|
|
202
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: ItemTitleDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
203
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.0.7", type: ItemTitleDirective, isStandalone: true, selector: "[twItemTitle]", host: { properties: { "class": "classes()" } }, ngImport: i0 });
|
|
195
204
|
}
|
|
196
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
205
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: ItemTitleDirective, decorators: [{
|
|
197
206
|
type: Directive,
|
|
198
207
|
args: [{
|
|
199
208
|
selector: '[twItemTitle]',
|
|
@@ -205,10 +214,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
|
|
|
205
214
|
class ItemDescriptionDirective {
|
|
206
215
|
item = inject(ItemComponent);
|
|
207
216
|
classes = this.item.descriptionClasses;
|
|
208
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
209
|
-
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "
|
|
217
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: ItemDescriptionDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
218
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.0.7", type: ItemDescriptionDirective, isStandalone: true, selector: "[twItemDescription]", host: { properties: { "class": "classes()" } }, ngImport: i0 });
|
|
210
219
|
}
|
|
211
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
220
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: ItemDescriptionDirective, decorators: [{
|
|
212
221
|
type: Directive,
|
|
213
222
|
args: [{
|
|
214
223
|
selector: '[twItemDescription]',
|
|
@@ -220,10 +229,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
|
|
|
220
229
|
class ItemTrailingDirective {
|
|
221
230
|
item = inject(ItemComponent);
|
|
222
231
|
classes = this.item.trailingClasses;
|
|
223
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
224
|
-
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: ItemTrailingDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
233
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.0.7", type: ItemTrailingDirective, isStandalone: true, selector: "[twItemTrailing]", host: { properties: { "class": "classes()" } }, ngImport: i0 });
|
|
225
234
|
}
|
|
226
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
235
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: ItemTrailingDirective, decorators: [{
|
|
227
236
|
type: Directive,
|
|
228
237
|
args: [{
|
|
229
238
|
selector: '[twItemTrailing]',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cdevhub-ngx-tw-item.mjs","sources":["../../../projects/ngx-tw/item/item.ts","../../../projects/ngx-tw/item/cdevhub-ngx-tw-item.ts"],"sourcesContent":["import {\n booleanAttribute,\n ChangeDetectionStrategy,\n Component,\n computed,\n DestroyRef,\n Directive,\n ElementRef,\n inject,\n input,\n output,\n type OnInit,\n} from '@angular/core';\nimport { FocusMonitor } from '@angular/cdk/a11y';\nimport { tv } from 'tailwind-variants';\nimport type { TwSize } from '@cdevhub/ngx-tw/core';\n\n/** Density / typography scale for `tw-item`. A narrower subset of `TwSize` — the three sizes that match real use cases (table row, list item, section header). */\nexport type ItemSize = Extract<TwSize, 'sm' | 'md' | 'lg'>;\n\n/** Vertical alignment of the leading and trailing slots relative to the title/description stack. */\nexport type ItemAlign = 'start' | 'center';\n\nconst itemVariants = tv(\n {\n slots: {\n root: 'flex w-full text-fg',\n // Leading is a layout slot only: `shrink-0` + optional `mt-*` nudge for baseline\n // alignment. No `flex` / `items-*` here — those would conflict with the consumer's\n // own tile styling (e.g. `flex items-center justify-center` on an icon tile).\n leading: 'shrink-0',\n content: 'flex min-w-0 flex-col',\n title: 'text-fg font-medium',\n description: 'text-fg-muted',\n trailing: 'flex shrink-0',\n },\n variants: {\n size: {\n sm: {\n root: 'gap-2 py-1.5',\n content: 'gap-0',\n title: 'text-sm truncate',\n description: 'text-xs truncate',\n trailing: 'gap-1.5',\n },\n md: {\n root: 'gap-3 py-2',\n leading: 'mt-0.5',\n content: 'gap-1',\n title: 'text-sm',\n description: 'text-sm',\n trailing: 'gap-2',\n },\n lg: {\n root: 'gap-3 py-3',\n leading: 'mt-0.5',\n content: 'gap-1',\n title: 'text-base font-semibold',\n description: 'text-sm',\n trailing: 'gap-2',\n },\n },\n align: {\n start: {\n root: 'items-start',\n trailing: 'items-start',\n },\n center: {\n root: 'items-center',\n leading: 'mt-0',\n trailing: 'items-center',\n },\n },\n interactive: {\n true: {\n root: '-mx-2 cursor-pointer rounded-md px-2 transition-colors duration-normal hover:bg-surface-muted focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary-500 motion-reduce:transition-none',\n },\n false: {},\n },\n disabled: {\n true: {\n root: 'pointer-events-none opacity-50',\n },\n false: {},\n },\n current: {\n true: {\n root: 'bg-primary-soft ring-2 ring-inset ring-primary-border',\n },\n false: {},\n },\n },\n compoundVariants: [\n { size: 'sm', align: 'center', class: { leading: 'mt-0', root: 'items-center' } },\n { size: 'md', align: 'center', class: { leading: 'mt-0', root: 'items-center' } },\n { size: 'lg', align: 'center', class: { leading: 'mt-0', root: 'items-center' } },\n ],\n defaultVariants: {\n size: 'md',\n align: 'start',\n interactive: false,\n disabled: false,\n current: false,\n },\n },\n { twMerge: true },\n);\n\n@Component({\n selector: 'tw-item',\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n '[class]': 'rootClasses()',\n '[attr.role]': 'interactive() ? \"button\" : null',\n '[attr.tabindex]': 'interactive() && !disabled() ? 0 : null',\n '[attr.aria-disabled]': 'disabled() ? \"true\" : null',\n '[attr.aria-current]': 'current() ? \"true\" : null',\n '(click)': 'onActivate($event)',\n '(keydown)': 'onKeydown($event)',\n },\n template: `\n <ng-content select=\"[twItemLeading]\" />\n <div [class]=\"contentClasses()\">\n <ng-content select=\"[twItemTitle]\" />\n <ng-content select=\"[twItemDescription]\" />\n </div>\n <ng-content select=\"[twItemTrailing]\" />\n `,\n})\nexport class ItemComponent implements OnInit {\n /** Density and typography scale. `'sm'` is compact with truncated single-line title and description (table rows). `'md'` is the default list-item size. `'lg'` is the section-header scale with a larger title. Defaults to `'md'`. */\n readonly size = input<ItemSize>('md');\n\n /** Vertical alignment of the leading and trailing slots relative to the content stack. `'start'` aligns them with the title baseline (recommended when a description is present). `'center'` vertically centers them on the whole block (recommended for single-line items). Defaults to `'start'`. */\n readonly align = input<ItemAlign>('start');\n\n /**\n * When `true`, the item is keyboard-activatable: adds `role=\"button\"`, `tabindex=\"0\"`, a hover background, pointer cursor, and a visible focus ring. Click and Enter/Space emit `selected`. Defaults to `false`.\n *\n * Do not project additional focusable elements (buttons, links, inputs) into `[twItemLeading]` or `[twItemTrailing]` when this is `true` — they create nested interactive controls that fail AXE. For action-row patterns, keep `interactive` as `false` and let the projected control carry the semantics instead.\n *\n * For `role=\"menuitem\"`, `role=\"option\"`, or other listbox/menu semantics, do not use `tw-item` — the menu, select, and command-palette components own those roles and the keyboard contracts that come with them.\n */\n readonly interactive = input(false, { transform: booleanAttribute });\n\n /** Disables an interactive item. Applies `opacity-50`, `pointer-events-none`, and sets `aria-disabled`. Only meaningful when `interactive` is `true`. Defaults to `false`. */\n readonly disabled = input(false, { transform: booleanAttribute });\n\n /** When `true`, marks the item as the visually highlighted \"current\" row (e.g. selected list entry, active settings tab). Applies a low-prominence primary tint, an inset ring, and `aria-current=\"true\"`. Stacks cleanly with `interactive` (the focus ring sits on top of the current ring). Defaults to `false`. */\n readonly current = input(false, { transform: booleanAttribute });\n\n /** Fires when an interactive item is activated via click, Enter, or Space. Payload is the originating DOM event. Does not emit when `interactive` is `false` or `disabled` is `true`. */\n readonly selected = output<Event>();\n\n private readonly elementRef = inject<ElementRef<HTMLElement>>(ElementRef);\n private readonly focusMonitor = inject(FocusMonitor);\n private readonly destroyRef = inject(DestroyRef);\n\n private readonly variantResult = computed(() =>\n itemVariants({\n size: this.size(),\n align: this.align(),\n interactive: this.interactive(),\n disabled: this.disabled(),\n current: this.current(),\n }),\n );\n\n readonly rootClasses = computed(() => this.variantResult().root());\n readonly leadingClasses = computed(() => this.variantResult().leading());\n readonly contentClasses = computed(() => this.variantResult().content());\n readonly titleClasses = computed(() => this.variantResult().title());\n readonly descriptionClasses = computed(() => this.variantResult().description());\n readonly trailingClasses = computed(() => this.variantResult().trailing());\n\n ngOnInit(): void {\n this.focusMonitor.monitor(this.elementRef);\n this.destroyRef.onDestroy(() => {\n this.focusMonitor.stopMonitoring(this.elementRef);\n });\n }\n\n onActivate(event: Event): void {\n if (!this.interactive() || this.disabled()) return;\n this.selected.emit(event);\n }\n\n onKeydown(event: KeyboardEvent): void {\n if (!this.interactive() || this.disabled()) return;\n if (event.key === 'Enter' || event.key === ' ') {\n event.preventDefault();\n this.selected.emit(event);\n }\n }\n}\n\n@Directive({\n selector: '[twItemLeading]',\n host: {\n '[class]': 'classes()',\n },\n})\nexport class ItemLeadingDirective {\n private readonly item = inject(ItemComponent);\n readonly classes = this.item.leadingClasses;\n}\n\n@Directive({\n selector: '[twItemTitle]',\n host: {\n '[class]': 'classes()',\n },\n})\nexport class ItemTitleDirective {\n private readonly item = inject(ItemComponent);\n readonly classes = this.item.titleClasses;\n}\n\n@Directive({\n selector: '[twItemDescription]',\n host: {\n '[class]': 'classes()',\n },\n})\nexport class ItemDescriptionDirective {\n private readonly item = inject(ItemComponent);\n readonly classes = this.item.descriptionClasses;\n}\n\n@Directive({\n selector: '[twItemTrailing]',\n host: {\n '[class]': 'classes()',\n },\n})\nexport class ItemTrailingDirective {\n private readonly item = inject(ItemComponent);\n readonly classes = this.item.trailingClasses;\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;;;AAuBA,MAAM,YAAY,GAAG,EAAE,CACrB;AACE,IAAA,KAAK,EAAE;AACL,QAAA,IAAI,EAAE,qBAAqB;;;;AAI3B,QAAA,OAAO,EAAE,UAAU;AACnB,QAAA,OAAO,EAAE,uBAAuB;AAChC,QAAA,KAAK,EAAE,qBAAqB;AAC5B,QAAA,WAAW,EAAE,eAAe;AAC5B,QAAA,QAAQ,EAAE,eAAe;AAC1B,KAAA;AACD,IAAA,QAAQ,EAAE;AACR,QAAA,IAAI,EAAE;AACJ,YAAA,EAAE,EAAE;AACF,gBAAA,IAAI,EAAE,cAAc;AACpB,gBAAA,OAAO,EAAE,OAAO;AAChB,gBAAA,KAAK,EAAE,kBAAkB;AACzB,gBAAA,WAAW,EAAE,kBAAkB;AAC/B,gBAAA,QAAQ,EAAE,SAAS;AACpB,aAAA;AACD,YAAA,EAAE,EAAE;AACF,gBAAA,IAAI,EAAE,YAAY;AAClB,gBAAA,OAAO,EAAE,QAAQ;AACjB,gBAAA,OAAO,EAAE,OAAO;AAChB,gBAAA,KAAK,EAAE,SAAS;AAChB,gBAAA,WAAW,EAAE,SAAS;AACtB,gBAAA,QAAQ,EAAE,OAAO;AAClB,aAAA;AACD,YAAA,EAAE,EAAE;AACF,gBAAA,IAAI,EAAE,YAAY;AAClB,gBAAA,OAAO,EAAE,QAAQ;AACjB,gBAAA,OAAO,EAAE,OAAO;AAChB,gBAAA,KAAK,EAAE,yBAAyB;AAChC,gBAAA,WAAW,EAAE,SAAS;AACtB,gBAAA,QAAQ,EAAE,OAAO;AAClB,aAAA;AACF,SAAA;AACD,QAAA,KAAK,EAAE;AACL,YAAA,KAAK,EAAE;AACL,gBAAA,IAAI,EAAE,aAAa;AACnB,gBAAA,QAAQ,EAAE,aAAa;AACxB,aAAA;AACD,YAAA,MAAM,EAAE;AACN,gBAAA,IAAI,EAAE,cAAc;AACpB,gBAAA,OAAO,EAAE,MAAM;AACf,gBAAA,QAAQ,EAAE,cAAc;AACzB,aAAA;AACF,SAAA;AACD,QAAA,WAAW,EAAE;AACX,YAAA,IAAI,EAAE;AACJ,gBAAA,IAAI,EAAE,sNAAsN;AAC7N,aAAA;AACD,YAAA,KAAK,EAAE,EAAE;AACV,SAAA;AACD,QAAA,QAAQ,EAAE;AACR,YAAA,IAAI,EAAE;AACJ,gBAAA,IAAI,EAAE,gCAAgC;AACvC,aAAA;AACD,YAAA,KAAK,EAAE,EAAE;AACV,SAAA;AACD,QAAA,OAAO,EAAE;AACP,YAAA,IAAI,EAAE;AACJ,gBAAA,IAAI,EAAE,uDAAuD;AAC9D,aAAA;AACD,YAAA,KAAK,EAAE,EAAE;AACV,SAAA;AACF,KAAA;AACD,IAAA,gBAAgB,EAAE;AAChB,QAAA,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,cAAc,EAAE,EAAE;AACjF,QAAA,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,cAAc,EAAE,EAAE;AACjF,QAAA,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,cAAc,EAAE,EAAE;AAClF,KAAA;AACD,IAAA,eAAe,EAAE;AACf,QAAA,IAAI,EAAE,IAAI;AACV,QAAA,KAAK,EAAE,OAAO;AACd,QAAA,WAAW,EAAE,KAAK;AAClB,QAAA,QAAQ,EAAE,KAAK;AACf,QAAA,OAAO,EAAE,KAAK;AACf,KAAA;AACF,CAAA,EACD,EAAE,OAAO,EAAE,IAAI,EAAE,CAClB;MAuBY,aAAa,CAAA;;AAEf,IAAA,IAAI,GAAG,KAAK,CAAW,IAAI,2EAAC;;AAG5B,IAAA,KAAK,GAAG,KAAK,CAAY,OAAO,4EAAC;AAE1C;;;;;;AAMG;IACM,WAAW,GAAG,KAAK,CAAC,KAAK,mFAAI,SAAS,EAAE,gBAAgB,EAAA,CAAG;;IAG3D,QAAQ,GAAG,KAAK,CAAC,KAAK,gFAAI,SAAS,EAAE,gBAAgB,EAAA,CAAG;;IAGxD,OAAO,GAAG,KAAK,CAAC,KAAK,+EAAI,SAAS,EAAE,gBAAgB,EAAA,CAAG;;IAGvD,QAAQ,GAAG,MAAM,EAAS;AAElB,IAAA,UAAU,GAAG,MAAM,CAA0B,UAAU,CAAC;AACxD,IAAA,YAAY,GAAG,MAAM,CAAC,YAAY,CAAC;AACnC,IAAA,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC;AAE/B,IAAA,aAAa,GAAG,QAAQ,CAAC,MACxC,YAAY,CAAC;AACX,QAAA,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE;AACjB,QAAA,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE;AACnB,QAAA,WAAW,EAAE,IAAI,CAAC,WAAW,EAAE;AAC/B,QAAA,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE;AACzB,QAAA,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE;AACxB,KAAA,CAAC,oFACH;AAEQ,IAAA,WAAW,GAAG,QAAQ,CAAC,MAAM,IAAI,CAAC,aAAa,EAAE,CAAC,IAAI,EAAE,kFAAC;AACzD,IAAA,cAAc,GAAG,QAAQ,CAAC,MAAM,IAAI,CAAC,aAAa,EAAE,CAAC,OAAO,EAAE,qFAAC;AAC/D,IAAA,cAAc,GAAG,QAAQ,CAAC,MAAM,IAAI,CAAC,aAAa,EAAE,CAAC,OAAO,EAAE,qFAAC;AAC/D,IAAA,YAAY,GAAG,QAAQ,CAAC,MAAM,IAAI,CAAC,aAAa,EAAE,CAAC,KAAK,EAAE,mFAAC;AAC3D,IAAA,kBAAkB,GAAG,QAAQ,CAAC,MAAM,IAAI,CAAC,aAAa,EAAE,CAAC,WAAW,EAAE,yFAAC;AACvE,IAAA,eAAe,GAAG,QAAQ,CAAC,MAAM,IAAI,CAAC,aAAa,EAAE,CAAC,QAAQ,EAAE,sFAAC;IAE1E,QAAQ,GAAA;QACN,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC;AAC1C,QAAA,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,MAAK;YAC7B,IAAI,CAAC,YAAY,CAAC,cAAc,CAAC,IAAI,CAAC,UAAU,CAAC;AACnD,QAAA,CAAC,CAAC;IACJ;AAEA,IAAA,UAAU,CAAC,KAAY,EAAA;QACrB,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,IAAI,IAAI,CAAC,QAAQ,EAAE;YAAE;AAC5C,QAAA,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC;IAC3B;AAEA,IAAA,SAAS,CAAC,KAAoB,EAAA;QAC5B,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,IAAI,IAAI,CAAC,QAAQ,EAAE;YAAE;AAC5C,QAAA,IAAI,KAAK,CAAC,GAAG,KAAK,OAAO,IAAI,KAAK,CAAC,GAAG,KAAK,GAAG,EAAE;YAC9C,KAAK,CAAC,cAAc,EAAE;AACtB,YAAA,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC;QAC3B;IACF;wGAhEW,aAAa,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAb,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,IAAA,EAAA,aAAa,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,SAAA,EAAA,MAAA,EAAA,EAAA,IAAA,EAAA,EAAA,iBAAA,EAAA,MAAA,EAAA,UAAA,EAAA,MAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,KAAA,EAAA,EAAA,iBAAA,EAAA,OAAA,EAAA,UAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,WAAA,EAAA,EAAA,iBAAA,EAAA,aAAA,EAAA,UAAA,EAAA,aAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,QAAA,EAAA,EAAA,iBAAA,EAAA,UAAA,EAAA,UAAA,EAAA,UAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,OAAA,EAAA,EAAA,iBAAA,EAAA,SAAA,EAAA,UAAA,EAAA,SAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,OAAA,EAAA,EAAA,QAAA,EAAA,UAAA,EAAA,EAAA,IAAA,EAAA,EAAA,SAAA,EAAA,EAAA,OAAA,EAAA,oBAAA,EAAA,SAAA,EAAA,mBAAA,EAAA,EAAA,UAAA,EAAA,EAAA,OAAA,EAAA,eAAA,EAAA,WAAA,EAAA,mCAAA,EAAA,eAAA,EAAA,yCAAA,EAAA,oBAAA,EAAA,8BAAA,EAAA,mBAAA,EAAA,6BAAA,EAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EATd;;;;;;;AAOT,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA;;4FAEU,aAAa,EAAA,UAAA,EAAA,CAAA;kBArBzB,SAAS;AAAC,YAAA,IAAA,EAAA,CAAA;AACT,oBAAA,QAAQ,EAAE,SAAS;oBACnB,eAAe,EAAE,uBAAuB,CAAC,MAAM;AAC/C,oBAAA,IAAI,EAAE;AACJ,wBAAA,SAAS,EAAE,eAAe;AAC1B,wBAAA,aAAa,EAAE,iCAAiC;AAChD,wBAAA,iBAAiB,EAAE,yCAAyC;AAC5D,wBAAA,sBAAsB,EAAE,4BAA4B;AACpD,wBAAA,qBAAqB,EAAE,2BAA2B;AAClD,wBAAA,SAAS,EAAE,oBAAoB;AAC/B,wBAAA,WAAW,EAAE,mBAAmB;AACjC,qBAAA;AACD,oBAAA,QAAQ,EAAE;;;;;;;AAOT,EAAA,CAAA;AACF,iBAAA;;MA0EY,oBAAoB,CAAA;AACd,IAAA,IAAI,GAAG,MAAM,CAAC,aAAa,CAAC;AACpC,IAAA,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,cAAc;wGAFhC,oBAAoB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;4FAApB,oBAAoB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,UAAA,EAAA,EAAA,OAAA,EAAA,WAAA,EAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,CAAA;;4FAApB,oBAAoB,EAAA,UAAA,EAAA,CAAA;kBANhC,SAAS;AAAC,YAAA,IAAA,EAAA,CAAA;AACT,oBAAA,QAAQ,EAAE,iBAAiB;AAC3B,oBAAA,IAAI,EAAE;AACJ,wBAAA,SAAS,EAAE,WAAW;AACvB,qBAAA;AACF,iBAAA;;MAYY,kBAAkB,CAAA;AACZ,IAAA,IAAI,GAAG,MAAM,CAAC,aAAa,CAAC;AACpC,IAAA,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,YAAY;wGAF9B,kBAAkB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;4FAAlB,kBAAkB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,eAAA,EAAA,IAAA,EAAA,EAAA,UAAA,EAAA,EAAA,OAAA,EAAA,WAAA,EAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,CAAA;;4FAAlB,kBAAkB,EAAA,UAAA,EAAA,CAAA;kBAN9B,SAAS;AAAC,YAAA,IAAA,EAAA,CAAA;AACT,oBAAA,QAAQ,EAAE,eAAe;AACzB,oBAAA,IAAI,EAAE;AACJ,wBAAA,SAAS,EAAE,WAAW;AACvB,qBAAA;AACF,iBAAA;;MAYY,wBAAwB,CAAA;AAClB,IAAA,IAAI,GAAG,MAAM,CAAC,aAAa,CAAC;AACpC,IAAA,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,kBAAkB;wGAFpC,wBAAwB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;4FAAxB,wBAAwB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,qBAAA,EAAA,IAAA,EAAA,EAAA,UAAA,EAAA,EAAA,OAAA,EAAA,WAAA,EAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,CAAA;;4FAAxB,wBAAwB,EAAA,UAAA,EAAA,CAAA;kBANpC,SAAS;AAAC,YAAA,IAAA,EAAA,CAAA;AACT,oBAAA,QAAQ,EAAE,qBAAqB;AAC/B,oBAAA,IAAI,EAAE;AACJ,wBAAA,SAAS,EAAE,WAAW;AACvB,qBAAA;AACF,iBAAA;;MAYY,qBAAqB,CAAA;AACf,IAAA,IAAI,GAAG,MAAM,CAAC,aAAa,CAAC;AACpC,IAAA,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,eAAe;wGAFjC,qBAAqB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;4FAArB,qBAAqB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,kBAAA,EAAA,IAAA,EAAA,EAAA,UAAA,EAAA,EAAA,OAAA,EAAA,WAAA,EAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,CAAA;;4FAArB,qBAAqB,EAAA,UAAA,EAAA,CAAA;kBANjC,SAAS;AAAC,YAAA,IAAA,EAAA,CAAA;AACT,oBAAA,QAAQ,EAAE,kBAAkB;AAC5B,oBAAA,IAAI,EAAE;AACJ,wBAAA,SAAS,EAAE,WAAW;AACvB,qBAAA;AACF,iBAAA;;;AC1OD;;AAEG;;;;"}
|
|
1
|
+
{"version":3,"file":"cdevhub-ngx-tw-item.mjs","sources":["../../../projects/ngx-tw/item/item.ts","../../../projects/ngx-tw/item/cdevhub-ngx-tw-item.ts"],"sourcesContent":["import {\n booleanAttribute,\n ChangeDetectionStrategy,\n Component,\n computed,\n DestroyRef,\n Directive,\n ElementRef,\n inject,\n input,\n output,\n type OnInit,\n} from '@angular/core';\nimport { FocusMonitor } from '@angular/cdk/a11y';\nimport { tv } from 'tailwind-variants';\nimport type { TwSize } from '@cdevhub/ngx-tw/core';\n\n/** Density / typography scale for `tw-item`. A narrower subset of `TwSize` — the three sizes that match real use cases (table row, list item, section header). */\nexport type ItemSize = Extract<TwSize, 'sm' | 'md' | 'lg'>;\n\n/** Vertical alignment of the leading and trailing slots relative to the title/description stack. */\nexport type ItemAlign = 'start' | 'center';\n\nconst itemVariants = tv(\n {\n slots: {\n root: 'flex w-full text-fg',\n // Leading is a layout slot only: `shrink-0` + optional `mt-*` nudge for baseline\n // alignment. No `flex` / `items-*` here — those would conflict with the consumer's\n // own tile styling (e.g. `flex items-center justify-center` on an icon tile).\n leading: 'shrink-0',\n content: 'flex min-w-0 flex-col',\n title: 'text-fg font-medium',\n description: 'text-fg-muted',\n trailing: 'flex shrink-0',\n },\n variants: {\n size: {\n sm: {\n root: 'gap-2 py-1.5',\n content: 'gap-0',\n title: 'text-sm truncate',\n description: 'text-xs truncate',\n trailing: 'gap-1.5',\n },\n md: {\n root: 'gap-3 py-2',\n leading: 'mt-0.5',\n content: 'gap-1',\n title: 'text-sm',\n description: 'text-sm',\n trailing: 'gap-2',\n },\n lg: {\n root: 'gap-3 py-3',\n leading: 'mt-0.5',\n content: 'gap-1',\n title: 'text-base font-semibold',\n description: 'text-sm',\n trailing: 'gap-2',\n },\n },\n align: {\n start: {\n root: 'items-start',\n trailing: 'items-start',\n },\n center: {\n root: 'items-center',\n leading: 'mt-0',\n trailing: 'items-center',\n },\n },\n interactive: {\n true: {\n root: '-mx-2 cursor-pointer rounded-md px-2 transition-colors duration-normal hover:bg-surface-muted focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary-500 motion-reduce:transition-none',\n },\n false: {},\n },\n disabled: {\n true: {\n root: 'pointer-events-none opacity-50',\n },\n false: {},\n },\n current: {\n true: {\n root: 'bg-primary-soft ring-2 ring-inset ring-primary-border',\n },\n false: {},\n },\n },\n compoundVariants: [\n { size: 'sm', align: 'center', class: { leading: 'mt-0', root: 'items-center' } },\n { size: 'md', align: 'center', class: { leading: 'mt-0', root: 'items-center' } },\n { size: 'lg', align: 'center', class: { leading: 'mt-0', root: 'items-center' } },\n ],\n defaultVariants: {\n size: 'md',\n align: 'start',\n interactive: false,\n disabled: false,\n current: false,\n },\n },\n { twMerge: true },\n);\n\n@Component({\n selector: 'tw-item',\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n '[class]': 'rootClasses()',\n '[attr.role]': 'interactive() ? \"button\" : null',\n '[attr.tabindex]': 'interactive() && !disabled() ? 0 : null',\n '[attr.aria-disabled]': 'disabled() ? \"true\" : null',\n '[attr.aria-current]': 'current() ? \"true\" : null',\n '(click)': 'onActivate($event)',\n '(keydown)': 'onKeydown($event)',\n },\n template: `\n <ng-content select=\"[twItemLeading]\" />\n <div [class]=\"contentClasses()\">\n <ng-content select=\"[twItemTitle]\" />\n <ng-content select=\"[twItemDescription]\" />\n </div>\n <ng-content select=\"[twItemTrailing]\" />\n `,\n})\nexport class ItemComponent implements OnInit {\n /** Density and typography scale. `'sm'` is compact with truncated single-line title and description (table rows). `'md'` is the default list-item size. `'lg'` is the section-header scale with a larger title. Defaults to `'md'`. */\n readonly size = input<ItemSize>('md');\n\n /** Vertical alignment of the leading and trailing slots relative to the content stack. `'start'` aligns them with the title baseline (recommended when a description is present). `'center'` vertically centers them on the whole block (recommended for single-line items). Defaults to `'start'`. */\n readonly align = input<ItemAlign>('start');\n\n /**\n * When `true`, the item is keyboard-activatable: adds `role=\"button\"`, `tabindex=\"0\"`, a hover background, pointer cursor, and a visible focus ring. Click and Enter/Space emit `selected`. Defaults to `false`.\n *\n * Do not project additional focusable elements (buttons, links, inputs) into `[twItemLeading]` or `[twItemTrailing]` when this is `true` — they create nested interactive controls that fail AXE. For action-row patterns, keep `interactive` as `false` and let the projected control carry the semantics instead.\n *\n * For `role=\"menuitem\"`, `role=\"option\"`, or other listbox/menu semantics, do not use `tw-item` — the menu, select, and command-palette components own those roles and the keyboard contracts that come with them.\n */\n readonly interactive = input(false, { transform: booleanAttribute });\n\n /** Disables an interactive item. Applies `opacity-50`, `pointer-events-none`, and sets `aria-disabled`. Only meaningful when `interactive` is `true`. Defaults to `false`. */\n readonly disabled = input(false, { transform: booleanAttribute });\n\n /** When `true`, marks the item as the visually highlighted \"current\" row (e.g. selected list entry, active settings tab). Applies a low-prominence primary tint, an inset ring, and `aria-current=\"true\"`. Stacks cleanly with `interactive` (the focus ring sits on top of the current ring). Defaults to `false`. */\n readonly current = input(false, { transform: booleanAttribute });\n\n /** Fires when an interactive item is activated via click, Enter, or Space. Payload is the originating DOM event. Does not emit when `interactive` is `false` or `disabled` is `true`. */\n readonly selected = output<Event>();\n\n private readonly elementRef = inject<ElementRef<HTMLElement>>(ElementRef);\n private readonly focusMonitor = inject(FocusMonitor);\n private readonly destroyRef = inject(DestroyRef);\n\n private readonly variantResult = computed(() =>\n itemVariants({\n size: this.size(),\n align: this.align(),\n interactive: this.interactive(),\n disabled: this.disabled(),\n current: this.current(),\n }),\n );\n\n readonly rootClasses = computed(() => this.variantResult().root());\n readonly leadingClasses = computed(() => this.variantResult().leading());\n readonly contentClasses = computed(() => this.variantResult().content());\n readonly titleClasses = computed(() => this.variantResult().title());\n readonly descriptionClasses = computed(() => this.variantResult().description());\n readonly trailingClasses = computed(() => this.variantResult().trailing());\n\n ngOnInit(): void {\n this.focusMonitor.monitor(this.elementRef);\n this.destroyRef.onDestroy(() => {\n this.focusMonitor.stopMonitoring(this.elementRef);\n });\n }\n\n onActivate(event: Event): void {\n if (!this.interactive() || this.disabled()) return;\n this.selected.emit(event);\n }\n\n onKeydown(event: KeyboardEvent): void {\n if (!this.interactive() || this.disabled()) return;\n if (event.key === 'Enter' || event.key === ' ') {\n event.preventDefault();\n this.selected.emit(event);\n }\n }\n}\n\n@Directive({\n selector: '[twItemLeading]',\n host: {\n '[class]': 'classes()',\n },\n})\nexport class ItemLeadingDirective {\n private readonly item = inject(ItemComponent);\n readonly classes = this.item.leadingClasses;\n}\n\n@Directive({\n selector: '[twItemTitle]',\n host: {\n '[class]': 'classes()',\n },\n})\nexport class ItemTitleDirective {\n private readonly item = inject(ItemComponent);\n readonly classes = this.item.titleClasses;\n}\n\n@Directive({\n selector: '[twItemDescription]',\n host: {\n '[class]': 'classes()',\n },\n})\nexport class ItemDescriptionDirective {\n private readonly item = inject(ItemComponent);\n readonly classes = this.item.descriptionClasses;\n}\n\n@Directive({\n selector: '[twItemTrailing]',\n host: {\n '[class]': 'classes()',\n },\n})\nexport class ItemTrailingDirective {\n private readonly item = inject(ItemComponent);\n readonly classes = this.item.trailingClasses;\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|