@besaitech/ng-design-system 0.0.47 → 0.0.49

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.
@@ -80,6 +80,8 @@ const SDS_ICONS = {
80
80
  'chevrons-up-down': '<path d="m7 15 5 5 5-5"/><path d="m7 9 5-5 5 5"/>',
81
81
  filter: '<polygon points="22 3 2 3 10 12.46 10 19 14 21 14 12.46 22 3"/>',
82
82
  table: '<path d="M12 3v18"/><rect width="18" height="18" x="3" y="3" rx="2"/><path d="M3 9h18"/><path d="M3 15h18"/>',
83
+ // Contactless ordering: every restaurant table gets its own QR code (Belvigo merchant nav).
84
+ 'qr-code': '<rect width="5" height="5" x="3" y="3" rx="1"/><rect width="5" height="5" x="16" y="3" rx="1"/><rect width="5" height="5" x="3" y="16" rx="1"/><path d="M21 16h-3a2 2 0 0 0-2 2v3"/><path d="M21 21v.01"/><path d="M12 7v3a2 2 0 0 1-2 2H7"/><path d="M3 12h.01"/><path d="M12 3h.01"/><path d="M12 16v.01"/><path d="M16 12h1"/><path d="M21 12v.01"/><path d="M12 21v-1"/>',
83
85
  eye: '<path d="M2 12s3-7 10-7 10 7 10 7-3 7-10 7-10-7-10-7Z"/><circle cx="12" cy="12" r="3"/>',
84
86
  // Pairs with `eye` for password reveal. Without it a show/hide toggle has no second state to draw,
85
87
  // and aria-pressed alone leaves sighted users with no visible change.
@@ -10260,26 +10262,42 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImpo
10260
10262
  }], propDecorators: { trigger: [{ type: i0.ViewChild, args: ['trigger', { isSignal: true }] }], name: [{ type: i0.Input, args: [{ isSignal: true, alias: "name", required: false }] }], email: [{ type: i0.Input, args: [{ isSignal: true, alias: "email", required: false }] }], initials: [{ type: i0.Input, args: [{ isSignal: true, alias: "initials", required: false }] }], src: [{ type: i0.Input, args: [{ isSignal: true, alias: "src", required: false }] }], status: [{ type: i0.Input, args: [{ isSignal: true, alias: "status", required: false }] }], appearance: [{ type: i0.Input, args: [{ isSignal: true, alias: "appearance", required: false }] }], align: [{ type: i0.Input, args: [{ isSignal: true, alias: "align", required: false }] }], showDetails: [{ type: i0.Input, args: [{ isSignal: true, alias: "showDetails", required: false }] }], avatarSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "avatarSize", required: false }] }], avatarBgClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "avatarBgClass", required: false }] }], menuLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "menuLabel", required: false }] }], openChange: [{ type: i0.Output, args: ["openChange"] }] } });
10261
10263
 
10262
10264
  /**
10263
- * A single row inside a menu surface (the {@link SdsUserMenu} dropdown, or any custom popover). Renders
10264
- * an anchor when [link] is set — with the Router — or a button otherwise, and emits {@link select} on
10265
- * activation. The parent menu closes itself when an item is activated, so an item never has to reach
10266
- * back into the menu.
10265
+ * A single row inside a menu surface (the {@link SdsUserMenu} dropdown, or any custom popover). Renders,
10266
+ * in order of precedence: a plain anchor when [href] is set (an EXTERNAL or cross-origin URL), a
10267
+ * Router anchor when [link] is set (an in-app route), or a button otherwise. It always emits
10268
+ * {@link select} on activation. The parent menu closes itself when an item is activated, so an item
10269
+ * never has to reach back into the menu.
10267
10270
  *
10268
10271
  * `tone="danger"` paints a destructive action (sign out, delete). Trailing content (a shortcut hint, a
10269
10272
  * count) projects into the default slot after the label.
10270
10273
  *
10271
10274
  * @example
10272
- * <sds-menu-item icon="user" label="Profil" link="/profile" />
10275
+ * <sds-menu-item icon="user" label="Profil" link="/profile" /> <!-- in-app route -->
10276
+ * <sds-menu-item icon="external-link" label="Site public" href="https://…" target="_blank" />
10273
10277
  * <sds-menu-item icon="log-out" label="Se déconnecter" tone="danger" (select)="signOut()" />
10274
10278
  */
10275
10279
  class SdsMenuItem {
10276
10280
  icon = input(null, ...(ngDevMode ? [{ debugName: "icon" }] : []));
10277
10281
  label = input.required(...(ngDevMode ? [{ debugName: "label" }] : []));
10278
- /** Router link target; when null (default) the item renders as a button. */
10282
+ /** Router link target for an in-app route; when null (default) the item is not a Router link. */
10279
10283
  link = input(null, ...(ngDevMode ? [{ debugName: "link" }] : []));
10284
+ /**
10285
+ * External / cross-origin URL. When set, the item renders a plain `<a [href]>` (NOT a Router link),
10286
+ * so it works for another app's origin. Takes precedence over {@link link}.
10287
+ */
10288
+ href = input(null, ...(ngDevMode ? [{ debugName: "href" }] : []));
10289
+ /** Anchor target for {@link href}, e.g. `_blank` to open the destination in a new tab. */
10290
+ target = input(null, ...(ngDevMode ? [{ debugName: "target" }] : []));
10291
+ /**
10292
+ * `rel` for {@link href}. Defaults to `noopener noreferrer` when {@link target} is `_blank` (the safe
10293
+ * default for a new-tab external link); pass a value to override, or `''` to clear it.
10294
+ */
10295
+ rel = input(null, ...(ngDevMode ? [{ debugName: "rel" }] : []));
10280
10296
  tone = input('default', ...(ngDevMode ? [{ debugName: "tone" }] : []));
10281
10297
  disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled", transform: booleanAttribute }] : [{ transform: booleanAttribute }]));
10282
10298
  select = output();
10299
+ /** `noopener noreferrer` is forced for a `_blank` external link unless the consumer set `rel` explicitly. */
10300
+ resolvedRel = computed(() => this.rel() !== null ? this.rel() : this.target() === '_blank' ? 'noopener noreferrer' : null, ...(ngDevMode ? [{ debugName: "resolvedRel" }] : []));
10283
10301
  rowClass = computed(() => {
10284
10302
  const base = 'flex w-full items-center gap-3 px-4 py-2.5 text-sm font-medium transition-colors ' +
10285
10303
  'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset ' +
@@ -10290,8 +10308,18 @@ class SdsMenuItem {
10290
10308
  return `${base} ${tone}`;
10291
10309
  }, ...(ngDevMode ? [{ debugName: "rowClass" }] : []));
10292
10310
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: SdsMenuItem, deps: [], target: i0.ɵɵFactoryTarget.Component });
10293
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.25", type: SdsMenuItem, isStandalone: true, selector: "sds-menu-item", inputs: { icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: true, transformFunction: null }, link: { classPropertyName: "link", publicName: "link", isSignal: true, isRequired: false, transformFunction: null }, tone: { classPropertyName: "tone", publicName: "tone", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { select: "select" }, host: { classAttribute: "block" }, ngImport: i0, template: `
10294
- @if (link() !== null) {
10311
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.25", type: SdsMenuItem, isStandalone: true, selector: "sds-menu-item", inputs: { icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: true, transformFunction: null }, link: { classPropertyName: "link", publicName: "link", isSignal: true, isRequired: false, transformFunction: null }, href: { classPropertyName: "href", publicName: "href", isSignal: true, isRequired: false, transformFunction: null }, target: { classPropertyName: "target", publicName: "target", isSignal: true, isRequired: false, transformFunction: null }, rel: { classPropertyName: "rel", publicName: "rel", isSignal: true, isRequired: false, transformFunction: null }, tone: { classPropertyName: "tone", publicName: "tone", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { select: "select" }, host: { classAttribute: "block" }, ngImport: i0, template: `
10312
+ @if (href() !== null) {
10313
+ <a
10314
+ [href]="href()"
10315
+ [attr.target]="target()"
10316
+ [attr.rel]="resolvedRel()"
10317
+ [class]="rowClass()"
10318
+ (click)="select.emit()"
10319
+ >
10320
+ <ng-container [ngTemplateOutlet]="content" />
10321
+ </a>
10322
+ } @else if (link() !== null) {
10295
10323
  <a [routerLink]="link()" [class]="rowClass()" (click)="select.emit()">
10296
10324
  <ng-container [ngTemplateOutlet]="content" />
10297
10325
  </a>
@@ -10318,7 +10346,17 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImpo
10318
10346
  imports: [NgTemplateOutlet, RouterLink, SdsIcon],
10319
10347
  host: { class: 'block' },
10320
10348
  template: `
10321
- @if (link() !== null) {
10349
+ @if (href() !== null) {
10350
+ <a
10351
+ [href]="href()"
10352
+ [attr.target]="target()"
10353
+ [attr.rel]="resolvedRel()"
10354
+ [class]="rowClass()"
10355
+ (click)="select.emit()"
10356
+ >
10357
+ <ng-container [ngTemplateOutlet]="content" />
10358
+ </a>
10359
+ } @else if (link() !== null) {
10322
10360
  <a [routerLink]="link()" [class]="rowClass()" (click)="select.emit()">
10323
10361
  <ng-container [ngTemplateOutlet]="content" />
10324
10362
  </a>
@@ -10337,7 +10375,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImpo
10337
10375
  </ng-template>
10338
10376
  `,
10339
10377
  }]
10340
- }], propDecorators: { icon: [{ type: i0.Input, args: [{ isSignal: true, alias: "icon", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: true }] }], link: [{ type: i0.Input, args: [{ isSignal: true, alias: "link", required: false }] }], tone: [{ type: i0.Input, args: [{ isSignal: true, alias: "tone", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], select: [{ type: i0.Output, args: ["select"] }] } });
10378
+ }], propDecorators: { icon: [{ type: i0.Input, args: [{ isSignal: true, alias: "icon", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: true }] }], link: [{ type: i0.Input, args: [{ isSignal: true, alias: "link", required: false }] }], href: [{ type: i0.Input, args: [{ isSignal: true, alias: "href", required: false }] }], target: [{ type: i0.Input, args: [{ isSignal: true, alias: "target", required: false }] }], rel: [{ type: i0.Input, args: [{ isSignal: true, alias: "rel", required: false }] }], tone: [{ type: i0.Input, args: [{ isSignal: true, alias: "tone", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], select: [{ type: i0.Output, args: ["select"] }] } });
10341
10379
 
10342
10380
  const norm = (s) => s.normalize('NFD').replace(/[̀-ͯ]/g, '').toLowerCase();
10343
10381
  /**