@devjuliovilla/jv-ui 1.6.0 → 1.6.1
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
CHANGED
|
@@ -44,7 +44,8 @@ export class App {}
|
|
|
44
44
|
| Buttons | `JvButton`, `JvButtonGroup`, `JvIconButton` |
|
|
45
45
|
| Forms | `JvInput`, `JvTextarea`, `JvSelect`, `JvCheckbox`, `JvRadio`, `JvSwitch`, `JvFormContainer` |
|
|
46
46
|
| Data Grid | `JvGrid` — full-featured data table (see below) |
|
|
47
|
-
|
|
|
47
|
+
| Containeres | `JvCard`, `JvSection`, `JvDivider` |
|
|
48
|
+
| List | `JvList`, `JvListItem` — list with title, description, icons, badges, and interactive items |
|
|
48
49
|
| Feedback | `JvAlert`, `JvBadge`, `JvLoader`, `JvToast` |
|
|
49
50
|
| Dialogs | `JvDialog`, `JvConfirmDialog` |
|
|
50
51
|
| Layout | `JvDashboardShell`, `JvSidebar`, `JvTopbar`, `JvBreadcrumb`, `JvPage` |
|
|
@@ -196,6 +197,83 @@ export class ProductsComponent {
|
|
|
196
197
|
}
|
|
197
198
|
```
|
|
198
199
|
|
|
200
|
+
## List API
|
|
201
|
+
|
|
202
|
+
```typescript
|
|
203
|
+
import { JvListComponent, JvListItemComponent } from '@devjuliovilla/jv-ui';
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
**JvList inputs:**
|
|
207
|
+
|
|
208
|
+
| Input | Type | Default | Description |
|
|
209
|
+
|---|---|---|---|
|
|
210
|
+
| `role` | `'list' \| 'navigation'` | `'list'` | ARIA role for the list |
|
|
211
|
+
| `variant` | `'bordered' \| null` | `null` | Outer border + border-radius around the list (items always have bottom border) |
|
|
212
|
+
| `ariaLabel` | `string` | `''` | Accessible label |
|
|
213
|
+
|
|
214
|
+
**JvListItem inputs:**
|
|
215
|
+
|
|
216
|
+
| Input | Type | Default | Description |
|
|
217
|
+
|---|---|---|---|
|
|
218
|
+
| `title` | `string` (required) | — | Primary text |
|
|
219
|
+
| `description` | `string` | `''` | Secondary text below title |
|
|
220
|
+
| `leadingIcon` | `string \| null` | `null` | Lucide icon name on the left |
|
|
221
|
+
| `disabled` | `boolean` | `false` | Gray out and block interaction |
|
|
222
|
+
| `active` | `boolean` | `false` | Highlight with primary color and left border |
|
|
223
|
+
|
|
224
|
+
**JvListItem outputs:**
|
|
225
|
+
|
|
226
|
+
| Output | Type |
|
|
227
|
+
|---|---|
|
|
228
|
+
| `activated` | `void` |
|
|
229
|
+
|
|
230
|
+
**Content projection:** use the `meta` attribute selector for badges, icons, or any content on the right side:
|
|
231
|
+
|
|
232
|
+
```html
|
|
233
|
+
<jv-list-item title="Inbox" description="New messages">
|
|
234
|
+
<jv-badge tone="primary" meta>3</jv-badge>
|
|
235
|
+
<jv-icon name="chevron-right" meta />
|
|
236
|
+
</jv-list-item>
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
### Example
|
|
240
|
+
|
|
241
|
+
```typescript
|
|
242
|
+
import { Component } from '@angular/core';
|
|
243
|
+
import { JvListComponent, JvListItemComponent, JvBadgeComponent } from '@devjuliovilla/jv-ui';
|
|
244
|
+
|
|
245
|
+
@Component({
|
|
246
|
+
selector: 'app-nav-list',
|
|
247
|
+
standalone: true,
|
|
248
|
+
imports: [JvListComponent, JvListItemComponent, JvBadgeComponent],
|
|
249
|
+
template: `
|
|
250
|
+
<jv-list variant="bordered">
|
|
251
|
+
<jv-list-item
|
|
252
|
+
title="Dashboard"
|
|
253
|
+
description="Main overview"
|
|
254
|
+
leadingIcon="layout-dashboard"
|
|
255
|
+
[active]="true"
|
|
256
|
+
/>
|
|
257
|
+
<jv-list-item
|
|
258
|
+
title="Notifications"
|
|
259
|
+
description="3 pending"
|
|
260
|
+
(activated)="onOpen()"
|
|
261
|
+
>
|
|
262
|
+
<jv-badge tone="primary" meta>3</jv-badge>
|
|
263
|
+
</jv-list-item>
|
|
264
|
+
<jv-list-item
|
|
265
|
+
title="Reports"
|
|
266
|
+
description="Coming soon"
|
|
267
|
+
[disabled]="true"
|
|
268
|
+
/>
|
|
269
|
+
</jv-list>
|
|
270
|
+
`,
|
|
271
|
+
})
|
|
272
|
+
export class NavListComponent {
|
|
273
|
+
onOpen() { /* handle activation */ }
|
|
274
|
+
}
|
|
275
|
+
```
|
|
276
|
+
|
|
199
277
|
## Pagination API
|
|
200
278
|
|
|
201
279
|
```typescript
|
|
@@ -20292,29 +20292,29 @@ class JvListComponent {
|
|
|
20292
20292
|
return v ? `jv-list--${v}` : '';
|
|
20293
20293
|
}, ...(ngDevMode ? [{ debugName: "variantClass" }] : /* istanbul ignore next */ []));
|
|
20294
20294
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: JvListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
20295
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.17", type: JvListComponent, isStandalone: true, selector: "jv-list", inputs: { role: { classPropertyName: "role", publicName: "role", isSignal: true, isRequired: false, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
|
|
20296
|
-
<ul
|
|
20297
|
-
class="jv-list"
|
|
20298
|
-
[class]="variantClass()"
|
|
20299
|
-
[attr.role]="role() === 'navigation' ? 'list' : null"
|
|
20300
|
-
[attr.aria-label]="ariaLabel()"
|
|
20301
|
-
>
|
|
20302
|
-
<ng-content />
|
|
20303
|
-
</ul>
|
|
20304
|
-
`, isInline: true, styles: [".jv-list{display:block;list-style:none;margin:0;padding:0}.jv-list
|
|
20295
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.17", type: JvListComponent, isStandalone: true, selector: "jv-list", inputs: { role: { classPropertyName: "role", publicName: "role", isSignal: true, isRequired: false, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
|
|
20296
|
+
<ul
|
|
20297
|
+
class="jv-list"
|
|
20298
|
+
[class]="variantClass()"
|
|
20299
|
+
[attr.role]="role() === 'navigation' ? 'list' : null"
|
|
20300
|
+
[attr.aria-label]="ariaLabel()"
|
|
20301
|
+
>
|
|
20302
|
+
<ng-content />
|
|
20303
|
+
</ul>
|
|
20304
|
+
`, isInline: true, styles: [".jv-list{display:block;list-style:none;margin:0;padding:0}.jv-list>:not(:last-child){border-bottom:1px solid var(--jv-color-border)}.jv-list--bordered{border:1px solid var(--jv-color-border);border-radius:var(--jv-radius-md)}\n"] });
|
|
20305
20305
|
}
|
|
20306
20306
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: JvListComponent, decorators: [{
|
|
20307
20307
|
type: Component,
|
|
20308
|
-
args: [{ selector: 'jv-list', standalone: true, template: `
|
|
20309
|
-
<ul
|
|
20310
|
-
class="jv-list"
|
|
20311
|
-
[class]="variantClass()"
|
|
20312
|
-
[attr.role]="role() === 'navigation' ? 'list' : null"
|
|
20313
|
-
[attr.aria-label]="ariaLabel()"
|
|
20314
|
-
>
|
|
20315
|
-
<ng-content />
|
|
20316
|
-
</ul>
|
|
20317
|
-
`, styles: [".jv-list{display:block;list-style:none;margin:0;padding:0}.jv-list
|
|
20308
|
+
args: [{ selector: 'jv-list', standalone: true, template: `
|
|
20309
|
+
<ul
|
|
20310
|
+
class="jv-list"
|
|
20311
|
+
[class]="variantClass()"
|
|
20312
|
+
[attr.role]="role() === 'navigation' ? 'list' : null"
|
|
20313
|
+
[attr.aria-label]="ariaLabel()"
|
|
20314
|
+
>
|
|
20315
|
+
<ng-content />
|
|
20316
|
+
</ul>
|
|
20317
|
+
`, styles: [".jv-list{display:block;list-style:none;margin:0;padding:0}.jv-list>:not(:last-child){border-bottom:1px solid var(--jv-color-border)}.jv-list--bordered{border:1px solid var(--jv-color-border);border-radius:var(--jv-radius-md)}\n"] }]
|
|
20318
20318
|
}], propDecorators: { role: [{ type: i0.Input, args: [{ isSignal: true, alias: "role", required: false }] }], variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }] } });
|
|
20319
20319
|
|
|
20320
20320
|
class JvListItemComponent {
|
|
@@ -20330,58 +20330,58 @@ class JvListItemComponent {
|
|
|
20330
20330
|
}
|
|
20331
20331
|
}
|
|
20332
20332
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: JvListItemComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
20333
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: JvListItemComponent, isStandalone: true, selector: "jv-list-item", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: true, transformFunction: null }, description: { classPropertyName: "description", publicName: "description", isSignal: true, isRequired: false, transformFunction: null }, leadingIcon: { classPropertyName: "leadingIcon", publicName: "leadingIcon", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, active: { classPropertyName: "active", publicName: "active", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { activated: "activated" }, ngImport: i0, template: `
|
|
20334
|
-
<li
|
|
20335
|
-
class="jv-list-item"
|
|
20336
|
-
[class.jv-list-item--disabled]="disabled()"
|
|
20337
|
-
[class.jv-list-item--active]="active()"
|
|
20338
|
-
tabindex="0"
|
|
20339
|
-
role="listitem"
|
|
20340
|
-
(click)="onActivate()"
|
|
20341
|
-
(keydown.enter)="onActivate()"
|
|
20342
|
-
(keydown.space)="onActivate(); $event.preventDefault()"
|
|
20343
|
-
>
|
|
20344
|
-
@if (leadingIcon()) {
|
|
20345
|
-
<jv-icon [name]="leadingIcon()!" class="jv-list-item-leading" [size]="18" />
|
|
20346
|
-
}
|
|
20347
|
-
<div class="jv-list-item-text">
|
|
20348
|
-
<span class="jv-list-item-title">{{ title() }}</span>
|
|
20349
|
-
@if (description()) {
|
|
20350
|
-
<span class="jv-list-item-description">{{ description() }}</span>
|
|
20351
|
-
}
|
|
20352
|
-
</div>
|
|
20353
|
-
<div class="jv-list-item-meta">
|
|
20354
|
-
<ng-content select="[meta]" />
|
|
20355
|
-
</div>
|
|
20356
|
-
</li>
|
|
20333
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: JvListItemComponent, isStandalone: true, selector: "jv-list-item", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: true, transformFunction: null }, description: { classPropertyName: "description", publicName: "description", isSignal: true, isRequired: false, transformFunction: null }, leadingIcon: { classPropertyName: "leadingIcon", publicName: "leadingIcon", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, active: { classPropertyName: "active", publicName: "active", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { activated: "activated" }, ngImport: i0, template: `
|
|
20334
|
+
<li
|
|
20335
|
+
class="jv-list-item"
|
|
20336
|
+
[class.jv-list-item--disabled]="disabled()"
|
|
20337
|
+
[class.jv-list-item--active]="active()"
|
|
20338
|
+
tabindex="0"
|
|
20339
|
+
role="listitem"
|
|
20340
|
+
(click)="onActivate()"
|
|
20341
|
+
(keydown.enter)="onActivate()"
|
|
20342
|
+
(keydown.space)="onActivate(); $event.preventDefault()"
|
|
20343
|
+
>
|
|
20344
|
+
@if (leadingIcon()) {
|
|
20345
|
+
<jv-icon [name]="leadingIcon()!" class="jv-list-item-leading" [size]="18" />
|
|
20346
|
+
}
|
|
20347
|
+
<div class="jv-list-item-text">
|
|
20348
|
+
<span class="jv-list-item-title">{{ title() }}</span>
|
|
20349
|
+
@if (description()) {
|
|
20350
|
+
<span class="jv-list-item-description">{{ description() }}</span>
|
|
20351
|
+
}
|
|
20352
|
+
</div>
|
|
20353
|
+
<div class="jv-list-item-meta">
|
|
20354
|
+
<ng-content select="[meta]" />
|
|
20355
|
+
</div>
|
|
20356
|
+
</li>
|
|
20357
20357
|
`, isInline: true, styles: [":host{display:block}.jv-list-item{display:flex;align-items:center;gap:var(--jv-spacing-md);padding:var(--jv-spacing-md);background:var(--jv-color-surface);cursor:default;outline:none;transition:background-color .16s ease}.jv-list-item:hover{background:var(--jv-color-surface-muted)}.jv-list-item:focus-visible{outline:2px solid var(--jv-color-primary);outline-offset:-2px}.jv-list-item--disabled{opacity:.5;cursor:not-allowed;pointer-events:none}.jv-list-item--active{background:color-mix(in srgb,var(--jv-color-primary) 10%,var(--jv-color-surface));border-left:3px solid var(--jv-color-primary);padding-left:calc(var(--jv-spacing-md) - 3px)}.jv-list-item-text{flex:1;display:flex;flex-direction:column;gap:.125rem;min-width:0}.jv-list-item-title{font-weight:600;font-size:var(--jv-density-font-size);color:var(--jv-color-foreground);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.jv-list-item-description{font-size:.85rem;color:var(--jv-color-foreground-muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.jv-list-item-meta{display:flex;align-items:center;gap:var(--jv-spacing-sm);flex-shrink:0}.jv-list-item-leading{flex-shrink:0;color:var(--jv-color-foreground-muted)}\n"], dependencies: [{ kind: "component", type: JvIconComponent, selector: "jv-icon", inputs: ["name", "size", "strokeWidth", "decorative", "ariaLabel"] }] });
|
|
20358
20358
|
}
|
|
20359
20359
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: JvListItemComponent, decorators: [{
|
|
20360
20360
|
type: Component,
|
|
20361
|
-
args: [{ selector: 'jv-list-item', standalone: true, imports: [JvIconComponent], template: `
|
|
20362
|
-
<li
|
|
20363
|
-
class="jv-list-item"
|
|
20364
|
-
[class.jv-list-item--disabled]="disabled()"
|
|
20365
|
-
[class.jv-list-item--active]="active()"
|
|
20366
|
-
tabindex="0"
|
|
20367
|
-
role="listitem"
|
|
20368
|
-
(click)="onActivate()"
|
|
20369
|
-
(keydown.enter)="onActivate()"
|
|
20370
|
-
(keydown.space)="onActivate(); $event.preventDefault()"
|
|
20371
|
-
>
|
|
20372
|
-
@if (leadingIcon()) {
|
|
20373
|
-
<jv-icon [name]="leadingIcon()!" class="jv-list-item-leading" [size]="18" />
|
|
20374
|
-
}
|
|
20375
|
-
<div class="jv-list-item-text">
|
|
20376
|
-
<span class="jv-list-item-title">{{ title() }}</span>
|
|
20377
|
-
@if (description()) {
|
|
20378
|
-
<span class="jv-list-item-description">{{ description() }}</span>
|
|
20379
|
-
}
|
|
20380
|
-
</div>
|
|
20381
|
-
<div class="jv-list-item-meta">
|
|
20382
|
-
<ng-content select="[meta]" />
|
|
20383
|
-
</div>
|
|
20384
|
-
</li>
|
|
20361
|
+
args: [{ selector: 'jv-list-item', standalone: true, imports: [JvIconComponent], template: `
|
|
20362
|
+
<li
|
|
20363
|
+
class="jv-list-item"
|
|
20364
|
+
[class.jv-list-item--disabled]="disabled()"
|
|
20365
|
+
[class.jv-list-item--active]="active()"
|
|
20366
|
+
tabindex="0"
|
|
20367
|
+
role="listitem"
|
|
20368
|
+
(click)="onActivate()"
|
|
20369
|
+
(keydown.enter)="onActivate()"
|
|
20370
|
+
(keydown.space)="onActivate(); $event.preventDefault()"
|
|
20371
|
+
>
|
|
20372
|
+
@if (leadingIcon()) {
|
|
20373
|
+
<jv-icon [name]="leadingIcon()!" class="jv-list-item-leading" [size]="18" />
|
|
20374
|
+
}
|
|
20375
|
+
<div class="jv-list-item-text">
|
|
20376
|
+
<span class="jv-list-item-title">{{ title() }}</span>
|
|
20377
|
+
@if (description()) {
|
|
20378
|
+
<span class="jv-list-item-description">{{ description() }}</span>
|
|
20379
|
+
}
|
|
20380
|
+
</div>
|
|
20381
|
+
<div class="jv-list-item-meta">
|
|
20382
|
+
<ng-content select="[meta]" />
|
|
20383
|
+
</div>
|
|
20384
|
+
</li>
|
|
20385
20385
|
`, styles: [":host{display:block}.jv-list-item{display:flex;align-items:center;gap:var(--jv-spacing-md);padding:var(--jv-spacing-md);background:var(--jv-color-surface);cursor:default;outline:none;transition:background-color .16s ease}.jv-list-item:hover{background:var(--jv-color-surface-muted)}.jv-list-item:focus-visible{outline:2px solid var(--jv-color-primary);outline-offset:-2px}.jv-list-item--disabled{opacity:.5;cursor:not-allowed;pointer-events:none}.jv-list-item--active{background:color-mix(in srgb,var(--jv-color-primary) 10%,var(--jv-color-surface));border-left:3px solid var(--jv-color-primary);padding-left:calc(var(--jv-spacing-md) - 3px)}.jv-list-item-text{flex:1;display:flex;flex-direction:column;gap:.125rem;min-width:0}.jv-list-item-title{font-weight:600;font-size:var(--jv-density-font-size);color:var(--jv-color-foreground);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.jv-list-item-description{font-size:.85rem;color:var(--jv-color-foreground-muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.jv-list-item-meta{display:flex;align-items:center;gap:var(--jv-spacing-sm);flex-shrink:0}.jv-list-item-leading{flex-shrink:0;color:var(--jv-color-foreground-muted)}\n"] }]
|
|
20386
20386
|
}], propDecorators: { title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: true }] }], description: [{ type: i0.Input, args: [{ isSignal: true, alias: "description", required: false }] }], leadingIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "leadingIcon", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], active: [{ type: i0.Input, args: [{ isSignal: true, alias: "active", required: false }] }], activated: [{ type: i0.Output, args: ["activated"] }] } });
|
|
20387
20387
|
|