@conciso/design-system-angular 0.0.0-bootstrap.0 → 2.1.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 CHANGED
@@ -11,28 +11,13 @@ nur deren CSS-Klassen zusammen und liefern **kein eigenes CSS**.
11
11
  > und importiert ausschließlich von hier
12
12
  > ([ADR-0002](../../../docs/adr/0002-topologie-und-quelle-der-wahrheit.md)).
13
13
 
14
- ## Installation von npmjs.org
14
+ ## Installation aus GitHub Packages
15
15
 
16
- Der empfohlene Weg: Beide Pakete (`@conciso/design-system-angular` **und**
17
- `@conciso/design-system`, [Lockstep](../../../CONTEXT.md#lockstep-versionierung))
18
- liegen auf der öffentlichen npm-Registry (seit
19
- [ADR-0011](../../../docs/adr/0011-veroeffentlichung-auf-npmjs.md)). Keine `.npmrc`,
20
- kein Token nötig:
21
-
22
- ```bash
23
- npm install @conciso/design-system-angular @conciso/design-system
24
- ```
25
-
26
- Gilt ab dem ersten echten Release nach dem Merge dieser Änderung; bis dahin liegt auf
27
- npmjs nur eine Bootstrap-Platzhalterversion (siehe ADR-0011).
28
-
29
- ## Installation aus GitHub Packages (Alternative)
30
-
31
- Beide Pakete liegen **zusätzlich** weiterhin privat, org-scoped in
32
- [GitHub Packages](https://npm.pkg.github.com) (siehe
33
- [ADR-0004](../../../docs/adr/0004-verteilung-und-versionierung.md)) — z. B. für
34
- Consumer innerhalb der GitHub-Organisation `conciso`, die ohnehin schon so
35
- eingerichtet sind. Ein einziger `.npmrc`-Mechanismus deckt beide ab, weil
16
+ Beide Pakete (`@conciso/design-system-angular` **und** `@conciso/design-system`,
17
+ [Lockstep](../../../CONTEXT.md#lockstep-versionierung)) liegen privat, org-scoped
18
+ in [GitHub Packages](https://npm.pkg.github.com) (siehe
19
+ [ADR-0004](../../../docs/adr/0004-verteilung-und-versionierung.md)) — nicht in der
20
+ öffentlichen npm-Registry. Ein einziger `.npmrc`-Mechanismus deckt beide ab, weil
36
21
  beide unter dem `@conciso`-Scope veröffentlicht werden.
37
22
 
38
23
  **1. `.npmrc`** im Konsumenten-Projekt (oder `~/.npmrc` für den eigenen Rechner)
@@ -178,6 +163,5 @@ Das Artefakt (Angular Package Format, via ng-packagr) landet unter
178
163
 
179
164
  MIT, siehe [LICENSE](../../../LICENSE) im Repository-Root (im gebauten Paket unter
180
165
  `dist/design-system-angular/LICENSE`). Ausnahmen (Brand-Assets, Schriften, Icons)
181
- siehe [NOTICE](../../../NOTICE). Das betrifft nur die Lizenz — an den beiden
182
- Bezugswegen (npmjs.org als Standard, GitHub Packages als Alternative, siehe oben)
183
- ändert sich dadurch nichts.
166
+ siehe [NOTICE](../../../NOTICE). Das betrifft nur die Lizenz — der Bezug über GitHub
167
+ Packages statt der öffentlichen npm-Registry bleibt unverändert (siehe oben).
@@ -4286,34 +4286,106 @@ class ScaleComponent extends CvaBase {
4286
4286
  outputClasses = computed(() => `field-slider-output slider-${this.area()}`, /* @ts-ignore */
4287
4287
  ...(ngDevMode ? [{ debugName: "outputClasses" }] : /* istanbul ignore next */ []));
4288
4288
  /**
4289
- * Alle Labels + Positions-Style. Mitte-Labels sind auf ihrer Thumb-Position
4290
- * zentriert; das ERSTE/LETZTE Label wird an der jeweiligen Kante verankert
4291
- * (linksbündig bei 11px bzw. rechtsbündig bei Breite−11px), damit lange
4292
- * Kategorie-Labels an den Enden nicht über den Rand hinaus abgeschnitten werden.
4293
- * (11px = halbe Thumb-Breite, siehe css/components.css.)
4289
+ * Spaltenbreiten für das Tick-Grid, mit `minmax()` statt fixer Breiten: Bei
4290
+ * ausreichend Platz treffen die Spaltenmitten exakt die Thumb-Positionen (wie
4291
+ * bisher); wird es zu schmal, um alle Labels einzeilig zu zeigen, gibt das Grid
4292
+ * Lesbarkeit den Vorrang vor exakter Ausrichtung (Entscheidung: Umbruch statt
4293
+ * Überlappung ODER Abschneiden).
4294
+ *
4295
+ * - Rand-Spalten: `minmax(halber Schritt + 11px, max-content)`. Der Mindestwert ist
4296
+ * wie zuvor die halbe „Schritt“-Distanz `(100% − 22px) / (n − 1)` zwischen zwei
4297
+ * benachbarten Thumb-Positionen plus 11px (halbe Thumb-Breite, siehe
4298
+ * css/components.css) — das kantenbündige Rand-Label beansprucht nur EINE
4299
+ * Richtung, die Gegenseite (vor der ersten/nach der letzten Thumb-Position) fließt
4300
+ * seiner Spalte zu. Bei breiten Containern übersteigt dieser Mindestwert die
4301
+ * natürliche (einzeilige) Breite des Labels — dann klemmt `minmax()` laut Spezifikation
4302
+ * auf den Mindestwert, die Spalte verhält sich also identisch zu vorher. Erst wenn
4303
+ * der Container schmaler wird als diese Mindestbreite, wächst die Spalte auf bis
4304
+ * zu `max-content`, das Label bleibt einzeilig, solange noch Platz da ist.
4305
+ * - Mitte-Spalten: `minmax(min-content, 1fr)` — nie schmäler als das breiteste
4306
+ * unteilbare Wort, sonst gleichberechtigt (1fr) um den verbleibenden Platz. Bei
4307
+ * schmalen Breiten kann die Spalte dadurch von ihrem rechnerischen Schritt
4308
+ * abweichen; die Spaltenmitte (und damit das zentrierte Label) liegt dann
4309
+ * geringfügig neben der Thumb-Position — akzeptierter Trade-off.
4310
+ *
4311
+ * Bei nur einem Label eine volle Spalte.
4312
+ *
4313
+ * @internal
4314
+ */
4315
+ tickColumns = computed(() => {
4316
+ const n = this.labels().length;
4317
+ if (n <= 1)
4318
+ return '1fr';
4319
+ const gaps = n - 1;
4320
+ const edge = `minmax(calc(11px + (100% - 22px) / ${gaps} / 2), max-content)`;
4321
+ if (n === 2)
4322
+ return `${edge} ${edge}`;
4323
+ const mid = `repeat(${n - 2}, minmax(min-content, 1fr))`;
4324
+ return `${edge} ${mid} ${edge}`;
4325
+ }, /* @ts-ignore */
4326
+ ...(ngDevMode ? [{ debugName: "tickColumns" }] : /* istanbul ignore next */ []));
4327
+ /**
4328
+ * Alle Labels + Ausrichtung innerhalb ihrer Grid-Spalte (`tickColumns()`). Mitte-
4329
+ * Labels sind in ihrer Spalte zentriert — bei ausreichend Platz liegt die
4330
+ * Spaltenmitte exakt auf der Thumb-Position; bei sehr schmalen Breiten, wenn
4331
+ * `minmax(min-content, 1fr)` eine Spalte über ihren rechnerischen Schritt hinaus
4332
+ * wachsen lässt, kann die Mitte geringfügig davon abweichen (siehe
4333
+ * `tickColumns()`). Das ERSTE/LETZTE Label wird an der jeweiligen Kante verankert
4334
+ * (linksbündig bzw. rechtsbündig, 11px Innenabstand = halbe Thumb-Breite), damit
4335
+ * lange Kategorie-Labels an den Enden nicht über den Rand hinaus abgeschnitten
4336
+ * werden.
4337
+ *
4338
+ * Zusätzlich 4px `padding-inline` an der jeweils INNEREN Seite (Mitte-Labels:
4339
+ * beidseitig — bei zentriertem Text bleibt die Mitte dadurch unverschoben):
4340
+ * Mindestabstand zwischen benachbarten Labels. Ohne das können bei mittleren
4341
+ * Breiten (Spalte klemmt schon auf `minmax()`-Mindestwert, aber Label füllt sie
4342
+ * fast aus) die Text-Ink-Boxes zweier Nachbarn exakt aneinanderstoßen (0px Lücke,
4343
+ * liest sich als ein zusammengeschriebenes Wort), obwohl sie sich nicht
4344
+ * überlappen. `box-sizing:border-box` (s. u.) sorgt dafür, dass `min-content` in
4345
+ * `tickColumns()` das Padding mit einrechnet, statt die Spalte zusätzlich zu
4346
+ * stauchen.
4347
+ *
4348
+ * `hyphens:auto` trennt einzelne Wörter, die trotz der `max-content`/
4349
+ * `min-content`-Untergrenze in `tickColumns()` noch breiter als ihre Spalte sind —
4350
+ * wirkt nur, wenn die einbettende Seite `lang="de"` setzt (Storybooks Vitest-Iframe
4351
+ * tut das nicht; bei Konsumenten ist es nicht garantiert, daher rein additiv).
4352
+ * Bewusst OHNE `overflow-wrap:break-word`: das bricht mitten im Wort ohne
4353
+ * Trennzeichen (z. B. „zufriede“/„n“) und ist schlechter lesbar als ein Wort, das
4354
+ * im Ausnahmefall über seine Spalte hinausragt — Lesbarkeit vor exakter
4355
+ * Breiteneinhaltung. Ohne `white-space:nowrap` umbrechen Labels normal (zeilenweise),
4356
+ * statt sich zu überlagern.
4294
4357
  *
4295
4358
  * @internal
4296
4359
  */
4297
4360
  tickItems = computed(() => {
4298
4361
  const labels = this.labels();
4299
4362
  const n = labels.length;
4300
- const base = { position: 'absolute', 'white-space': 'nowrap' };
4301
- // transform/left aus .field-slider-ticks>* (components.css) an den Kanten
4302
- // explizit neutralisieren — sonst spannt left+right das letzte Label über die
4303
- // volle Breite und translateX(-50%) schiebt es in die Mitte.
4363
+ // position/transform/white-space aus .field-slider-ticks>* (components.css)
4364
+ // explizit neutralisieren — sonst bleiben die Labels absolut positioniert und
4365
+ // ignorieren die Grid-Spalten, auf denen dieser Ansatz aufbaut.
4366
+ const base = {
4367
+ position: 'static',
4368
+ transform: 'none',
4369
+ 'white-space': 'normal',
4370
+ 'box-sizing': 'border-box',
4371
+ hyphens: 'auto',
4372
+ };
4304
4373
  return labels.map((label, i) => {
4305
- if (n <= 1 || i === 0)
4306
- return { label, style: { ...base, left: '11px', 'text-align': 'left', transform: 'none' } };
4374
+ if (n <= 1)
4375
+ return { label, style: { ...base, 'text-align': 'left', 'padding-left': '11px' } };
4376
+ if (i === 0)
4377
+ // Innere Seite (rechts, Richtung nächstes Label) zusätzlich 4px — Mindestlücke,
4378
+ // s. Kommentar oben.
4379
+ return {
4380
+ label,
4381
+ style: { ...base, 'text-align': 'left', 'padding-left': '11px', 'padding-right': '4px' },
4382
+ };
4307
4383
  if (i === n - 1)
4308
4384
  return {
4309
4385
  label,
4310
- style: { ...base, left: 'auto', right: '11px', 'text-align': 'right', transform: 'none' },
4386
+ style: { ...base, 'text-align': 'right', 'padding-left': '4px', 'padding-right': '11px' },
4311
4387
  };
4312
- const p = i / (n - 1);
4313
- return {
4314
- label,
4315
- style: { ...base, left: `calc(11px + ${p} * (100% - 22px))`, transform: 'translateX(-50%)' },
4316
- };
4388
+ return { label, style: { ...base, 'text-align': 'center', 'padding-inline': '4px' } };
4317
4389
  });
4318
4390
  }, /* @ts-ignore */
4319
4391
  ...(ngDevMode ? [{ debugName: "tickItems" }] : /* istanbul ignore next */ []));
@@ -4351,14 +4423,21 @@ class ScaleComponent extends CvaBase {
4351
4423
  (blur)="markTouched()"
4352
4424
  />
4353
4425
  @if (labels().length) {
4354
- <!-- Alle Skalen-Labels exakt auf ihre Position ausgerichtet (Thumb 22px, siehe
4355
- css/components.css), zentriert. KEINE Reduktion — jedes Label ist wählbar.
4356
- Self-contained positioniert (der --tick-p-Kernmechanismus liegt noch auf
4357
- dem main-PR; nach Merge kann das vereinfacht werden). -->
4426
+ <!-- Alle Skalen-Labels als CSS-Grid-Spalten (Breiten: tickColumns()), bei
4427
+ ausreichend Platz exakt auf ihre Thumb-Position ausgerichtet (Thumb 22px,
4428
+ siehe css/components.css); bei schmalen Breiten gibt das Grid lieber den
4429
+ Umbruch frei, statt Labels zu überlagern oder abzuschneiden (siehe dort).
4430
+ KEINE Reduktion — jedes Label ist wählbar, PFLICHT-Inhalt (kein Dropping
4431
+ wie bei cds-slider). Statt Absolut-Positionierung Normalfluss: mehrzeilige
4432
+ Labels (lange Kategorien bei schmaler Breite) wachsen den Container in der
4433
+ Höhe und schieben nachfolgenden Inhalt nach unten, statt ihn zu
4434
+ überlagern. Self-contained positioniert (der --tick-p-Kernmechanismus liegt
4435
+ noch auf dem main-PR; nach Merge kann das vereinfacht werden). -->
4358
4436
  <div
4359
4437
  class="field-slider-ticks"
4360
4438
  aria-hidden="true"
4361
- style="position:relative;display:block;padding:0;height:16px"
4439
+ style="position:relative;display:grid;padding:0;height:auto;align-items:start"
4440
+ [style.grid-template-columns]="tickColumns()"
4362
4441
  >
4363
4442
  @for (t of tickItems(); track $index) {
4364
4443
  <span [style]="t.style">{{ t.label }}</span>
@@ -4400,14 +4479,21 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImpor
4400
4479
  (blur)="markTouched()"
4401
4480
  />
4402
4481
  @if (labels().length) {
4403
- <!-- Alle Skalen-Labels exakt auf ihre Position ausgerichtet (Thumb 22px, siehe
4404
- css/components.css), zentriert. KEINE Reduktion — jedes Label ist wählbar.
4405
- Self-contained positioniert (der --tick-p-Kernmechanismus liegt noch auf
4406
- dem main-PR; nach Merge kann das vereinfacht werden). -->
4482
+ <!-- Alle Skalen-Labels als CSS-Grid-Spalten (Breiten: tickColumns()), bei
4483
+ ausreichend Platz exakt auf ihre Thumb-Position ausgerichtet (Thumb 22px,
4484
+ siehe css/components.css); bei schmalen Breiten gibt das Grid lieber den
4485
+ Umbruch frei, statt Labels zu überlagern oder abzuschneiden (siehe dort).
4486
+ KEINE Reduktion — jedes Label ist wählbar, PFLICHT-Inhalt (kein Dropping
4487
+ wie bei cds-slider). Statt Absolut-Positionierung Normalfluss: mehrzeilige
4488
+ Labels (lange Kategorien bei schmaler Breite) wachsen den Container in der
4489
+ Höhe und schieben nachfolgenden Inhalt nach unten, statt ihn zu
4490
+ überlagern. Self-contained positioniert (der --tick-p-Kernmechanismus liegt
4491
+ noch auf dem main-PR; nach Merge kann das vereinfacht werden). -->
4407
4492
  <div
4408
4493
  class="field-slider-ticks"
4409
4494
  aria-hidden="true"
4410
- style="position:relative;display:block;padding:0;height:16px"
4495
+ style="position:relative;display:grid;padding:0;height:auto;align-items:start"
4496
+ [style.grid-template-columns]="tickColumns()"
4411
4497
  >
4412
4498
  @for (t of tickItems(); track $index) {
4413
4499
  <span [style]="t.style">{{ t.label }}</span>
@@ -4450,11 +4536,13 @@ class SnackbarComponent {
4450
4536
  isError = computed(() => this.tone() === 'err', /* @ts-ignore */
4451
4537
  ...(ngDevMode ? [{ debugName: "isError" }] : /* istanbul ignore next */ []));
4452
4538
  /**
4453
- * Tonfarbe des Icons (wie im Doku-Markup).
4539
+ * Tonfarbe des Icons (wie im Doku-Markup). CSS-Variablen statt Hex (Befund 04) — als
4540
+ * [style.stroke] gesetzt, nicht als Präsentationsattribut, weil Präsentationsattribute var()
4541
+ * nicht auflösen.
4454
4542
  *
4455
4543
  * @internal
4456
4544
  */
4457
- iconStroke = computed(() => ({ def: '#80DEDE', ok: '#88f0c4', err: '#f9a8a8' })[this.tone()], /* @ts-ignore */
4545
+ iconStroke = computed(() => ({ def: 'var(--co-200)', ok: 'var(--c-success-strong-icon)', err: 'var(--c-error-strong-icon)' })[this.tone()], /* @ts-ignore */
4458
4546
  ...(ngDevMode ? [{ debugName: "iconStroke" }] : /* istanbul ignore next */ []));
4459
4547
  /**
4460
4548
  * Lucide-artiger Pfad je Ton (Glühbirne / Häkchen-Kreis / Ausrufezeichen-Kreis).
@@ -4479,7 +4567,7 @@ class SnackbarComponent {
4479
4567
  height="24"
4480
4568
  viewBox="0 0 24 24"
4481
4569
  fill="none"
4482
- [attr.stroke]="iconStroke()"
4570
+ [style.stroke]="iconStroke()"
4483
4571
  stroke-width="1.25"
4484
4572
  aria-hidden="true"
4485
4573
  focusable="false"
@@ -4510,7 +4598,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImpor
4510
4598
  height="24"
4511
4599
  viewBox="0 0 24 24"
4512
4600
  fill="none"
4513
- [attr.stroke]="iconStroke()"
4601
+ [style.stroke]="iconStroke()"
4514
4602
  stroke-width="1.25"
4515
4603
  aria-hidden="true"
4516
4604
  focusable="false"