@skra/ui 0.2.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.
Files changed (160) hide show
  1. package/LICENSE +201 -0
  2. package/NOTICE +7 -0
  3. package/README.md +39 -0
  4. package/consumer-guide/README.md +84 -0
  5. package/consumer-guide/accessible-names.md +80 -0
  6. package/consumer-guide/forms-and-binding.md +149 -0
  7. package/consumer-guide/layout.md +86 -0
  8. package/consumer-guide/overlays.md +100 -0
  9. package/consumer-guide/setup-and-gotchas.md +103 -0
  10. package/consumer-guide/theming-and-encapsulation.md +115 -0
  11. package/consumer-guide/wrapping-patterns.md +90 -0
  12. package/fesm2022/skra-ui-accordion.mjs +333 -0
  13. package/fesm2022/skra-ui-accordion.mjs.map +1 -0
  14. package/fesm2022/skra-ui-alert.mjs +110 -0
  15. package/fesm2022/skra-ui-alert.mjs.map +1 -0
  16. package/fesm2022/skra-ui-avatar.mjs +83 -0
  17. package/fesm2022/skra-ui-avatar.mjs.map +1 -0
  18. package/fesm2022/skra-ui-badge.mjs +91 -0
  19. package/fesm2022/skra-ui-badge.mjs.map +1 -0
  20. package/fesm2022/skra-ui-button.mjs +67 -0
  21. package/fesm2022/skra-ui-button.mjs.map +1 -0
  22. package/fesm2022/skra-ui-checkbox.mjs +98 -0
  23. package/fesm2022/skra-ui-checkbox.mjs.map +1 -0
  24. package/fesm2022/skra-ui-chip.mjs +82 -0
  25. package/fesm2022/skra-ui-chip.mjs.map +1 -0
  26. package/fesm2022/skra-ui-combobox.mjs +335 -0
  27. package/fesm2022/skra-ui-combobox.mjs.map +1 -0
  28. package/fesm2022/skra-ui-core.mjs +529 -0
  29. package/fesm2022/skra-ui-core.mjs.map +1 -0
  30. package/fesm2022/skra-ui-counter.mjs +53 -0
  31. package/fesm2022/skra-ui-counter.mjs.map +1 -0
  32. package/fesm2022/skra-ui-datepicker.mjs +867 -0
  33. package/fesm2022/skra-ui-datepicker.mjs.map +1 -0
  34. package/fesm2022/skra-ui-dialog.mjs +133 -0
  35. package/fesm2022/skra-ui-dialog.mjs.map +1 -0
  36. package/fesm2022/skra-ui-field.mjs +293 -0
  37. package/fesm2022/skra-ui-field.mjs.map +1 -0
  38. package/fesm2022/skra-ui-icon.mjs +54 -0
  39. package/fesm2022/skra-ui-icon.mjs.map +1 -0
  40. package/fesm2022/skra-ui-input.mjs +42 -0
  41. package/fesm2022/skra-ui-input.mjs.map +1 -0
  42. package/fesm2022/skra-ui-kbd.mjs +44 -0
  43. package/fesm2022/skra-ui-kbd.mjs.map +1 -0
  44. package/fesm2022/skra-ui-layout.mjs +119 -0
  45. package/fesm2022/skra-ui-layout.mjs.map +1 -0
  46. package/fesm2022/skra-ui-link.mjs +29 -0
  47. package/fesm2022/skra-ui-link.mjs.map +1 -0
  48. package/fesm2022/skra-ui-loading-indicator.mjs +24 -0
  49. package/fesm2022/skra-ui-loading-indicator.mjs.map +1 -0
  50. package/fesm2022/skra-ui-menu.mjs +334 -0
  51. package/fesm2022/skra-ui-menu.mjs.map +1 -0
  52. package/fesm2022/skra-ui-multi-select.mjs +179 -0
  53. package/fesm2022/skra-ui-multi-select.mjs.map +1 -0
  54. package/fesm2022/skra-ui-native-select.mjs +123 -0
  55. package/fesm2022/skra-ui-native-select.mjs.map +1 -0
  56. package/fesm2022/skra-ui-popover.mjs +158 -0
  57. package/fesm2022/skra-ui-popover.mjs.map +1 -0
  58. package/fesm2022/skra-ui-progress.mjs +57 -0
  59. package/fesm2022/skra-ui-progress.mjs.map +1 -0
  60. package/fesm2022/skra-ui-radio.mjs +92 -0
  61. package/fesm2022/skra-ui-radio.mjs.map +1 -0
  62. package/fesm2022/skra-ui-rating-display.mjs +81 -0
  63. package/fesm2022/skra-ui-rating-display.mjs.map +1 -0
  64. package/fesm2022/skra-ui-select.mjs +151 -0
  65. package/fesm2022/skra-ui-select.mjs.map +1 -0
  66. package/fesm2022/skra-ui-skeleton.mjs +65 -0
  67. package/fesm2022/skra-ui-skeleton.mjs.map +1 -0
  68. package/fesm2022/skra-ui-star-rating.mjs +110 -0
  69. package/fesm2022/skra-ui-star-rating.mjs.map +1 -0
  70. package/fesm2022/skra-ui-status-dot.mjs +61 -0
  71. package/fesm2022/skra-ui-status-dot.mjs.map +1 -0
  72. package/fesm2022/skra-ui-switch.mjs +94 -0
  73. package/fesm2022/skra-ui-switch.mjs.map +1 -0
  74. package/fesm2022/skra-ui-tabs.mjs +356 -0
  75. package/fesm2022/skra-ui-tabs.mjs.map +1 -0
  76. package/fesm2022/skra-ui-textarea.mjs +81 -0
  77. package/fesm2022/skra-ui-textarea.mjs.map +1 -0
  78. package/fesm2022/skra-ui-toast.mjs +208 -0
  79. package/fesm2022/skra-ui-toast.mjs.map +1 -0
  80. package/fesm2022/skra-ui-tooltip.mjs +252 -0
  81. package/fesm2022/skra-ui-tooltip.mjs.map +1 -0
  82. package/fesm2022/skra-ui-typography.mjs +35 -0
  83. package/fesm2022/skra-ui-typography.mjs.map +1 -0
  84. package/fesm2022/skra-ui.mjs +4 -0
  85. package/fesm2022/skra-ui.mjs.map +1 -0
  86. package/package.json +175 -0
  87. package/types/skra-ui-accordion.d.ts +196 -0
  88. package/types/skra-ui-accordion.d.ts.map +1 -0
  89. package/types/skra-ui-alert.d.ts +81 -0
  90. package/types/skra-ui-alert.d.ts.map +1 -0
  91. package/types/skra-ui-avatar.d.ts +71 -0
  92. package/types/skra-ui-avatar.d.ts.map +1 -0
  93. package/types/skra-ui-badge.d.ts +73 -0
  94. package/types/skra-ui-badge.d.ts.map +1 -0
  95. package/types/skra-ui-button.d.ts +45 -0
  96. package/types/skra-ui-button.d.ts.map +1 -0
  97. package/types/skra-ui-checkbox.d.ts +52 -0
  98. package/types/skra-ui-checkbox.d.ts.map +1 -0
  99. package/types/skra-ui-chip.d.ts +60 -0
  100. package/types/skra-ui-chip.d.ts.map +1 -0
  101. package/types/skra-ui-combobox.d.ts +95 -0
  102. package/types/skra-ui-combobox.d.ts.map +1 -0
  103. package/types/skra-ui-core.d.ts +314 -0
  104. package/types/skra-ui-core.d.ts.map +1 -0
  105. package/types/skra-ui-counter.d.ts +33 -0
  106. package/types/skra-ui-counter.d.ts.map +1 -0
  107. package/types/skra-ui-datepicker.d.ts +164 -0
  108. package/types/skra-ui-datepicker.d.ts.map +1 -0
  109. package/types/skra-ui-dialog.d.ts +59 -0
  110. package/types/skra-ui-dialog.d.ts.map +1 -0
  111. package/types/skra-ui-field.d.ts +181 -0
  112. package/types/skra-ui-field.d.ts.map +1 -0
  113. package/types/skra-ui-icon.d.ts +38 -0
  114. package/types/skra-ui-icon.d.ts.map +1 -0
  115. package/types/skra-ui-input.d.ts +22 -0
  116. package/types/skra-ui-input.d.ts.map +1 -0
  117. package/types/skra-ui-kbd.d.ts +33 -0
  118. package/types/skra-ui-kbd.d.ts.map +1 -0
  119. package/types/skra-ui-layout.d.ts +86 -0
  120. package/types/skra-ui-layout.d.ts.map +1 -0
  121. package/types/skra-ui-link.d.ts +20 -0
  122. package/types/skra-ui-link.d.ts.map +1 -0
  123. package/types/skra-ui-loading-indicator.d.ts +9 -0
  124. package/types/skra-ui-loading-indicator.d.ts.map +1 -0
  125. package/types/skra-ui-menu.d.ts +116 -0
  126. package/types/skra-ui-menu.d.ts.map +1 -0
  127. package/types/skra-ui-multi-select.d.ts +47 -0
  128. package/types/skra-ui-multi-select.d.ts.map +1 -0
  129. package/types/skra-ui-native-select.d.ts +74 -0
  130. package/types/skra-ui-native-select.d.ts.map +1 -0
  131. package/types/skra-ui-popover.d.ts +57 -0
  132. package/types/skra-ui-popover.d.ts.map +1 -0
  133. package/types/skra-ui-progress.d.ts +41 -0
  134. package/types/skra-ui-progress.d.ts.map +1 -0
  135. package/types/skra-ui-radio.d.ts +54 -0
  136. package/types/skra-ui-radio.d.ts.map +1 -0
  137. package/types/skra-ui-rating-display.d.ts +56 -0
  138. package/types/skra-ui-rating-display.d.ts.map +1 -0
  139. package/types/skra-ui-select.d.ts +43 -0
  140. package/types/skra-ui-select.d.ts.map +1 -0
  141. package/types/skra-ui-skeleton.d.ts +42 -0
  142. package/types/skra-ui-skeleton.d.ts.map +1 -0
  143. package/types/skra-ui-star-rating.d.ts +71 -0
  144. package/types/skra-ui-star-rating.d.ts.map +1 -0
  145. package/types/skra-ui-status-dot.d.ts +62 -0
  146. package/types/skra-ui-status-dot.d.ts.map +1 -0
  147. package/types/skra-ui-switch.d.ts +54 -0
  148. package/types/skra-ui-switch.d.ts.map +1 -0
  149. package/types/skra-ui-tabs.d.ts +191 -0
  150. package/types/skra-ui-tabs.d.ts.map +1 -0
  151. package/types/skra-ui-textarea.d.ts +55 -0
  152. package/types/skra-ui-textarea.d.ts.map +1 -0
  153. package/types/skra-ui-toast.d.ts +140 -0
  154. package/types/skra-ui-toast.d.ts.map +1 -0
  155. package/types/skra-ui-tooltip.d.ts +90 -0
  156. package/types/skra-ui-tooltip.d.ts.map +1 -0
  157. package/types/skra-ui-typography.d.ts +17 -0
  158. package/types/skra-ui-typography.d.ts.map +1 -0
  159. package/types/skra-ui.d.ts +3 -0
  160. package/types/skra-ui.d.ts.map +1 -0
@@ -0,0 +1,252 @@
1
+ import * as i0 from '@angular/core';
2
+ import { input, ViewEncapsulation, ChangeDetectionStrategy, Component, inject, ElementRef, ViewContainerRef, Renderer2, effect, DestroyRef, Directive } from '@angular/core';
3
+ import { _attachPositioner } from '@skra/ui/core';
4
+
5
+ let nextId = 0;
6
+ /**
7
+ * SkraTooltipPanel — the floating tooltip surface (ADR 0044 native top layer via the Popover API).
8
+ *
9
+ * INTERNAL: never placed by consumers in a template. `SkraTooltip` creates it programmatically with
10
+ * `ViewContainerRef.createComponent` (Angular-idiomatic, in-tree → inherits the design-context cascade
11
+ * + the O-8 Shadow-DOM bridge per ADR 0044 §3 rule 3) and drives `showPopover()`/`hidePopover()` on the
12
+ * host element.
13
+ *
14
+ * `popover="manual"` (NOT `auto`): a hover/focus tooltip's show/hide is Forge-owned, not click-toggle
15
+ * light-dismiss. `role="tooltip"` is the AT semantics; the trigger references this panel's `id` via
16
+ * `aria-describedby` (wired by the directive). The 13-axis Universal Surface (ADR 025) + motion live in
17
+ * `tooltip.scss`; geometry (`left`/`top` + `data-skra-placement`) is written by `SkraPositioner`.
18
+ *
19
+ * Full contract: adr/specs/component-tooltip-spec.md.
20
+ */
21
+ class SkraTooltipPanel {
22
+ /** Tooltip text; set by the directive and kept in sync. */
23
+ text = input('', ...(ngDevMode ? [{ debugName: "text" }] : /* istanbul ignore next */ []));
24
+ /** Stable unique id — target of the trigger's `aria-describedby`. */
25
+ panelId = `skra-tooltip-${nextId++}`;
26
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.7", ngImport: i0, type: SkraTooltipPanel, deps: [], target: i0.ɵɵFactoryTarget.Component });
27
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.7", type: SkraTooltipPanel, isStandalone: true, selector: "skra-tooltip-panel", inputs: { text: { classPropertyName: "text", publicName: "text", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "role": "tooltip", "popover": "manual" }, properties: { "id": "panelId" } }, ngImport: i0, template: '{{ text() }}', isInline: true, styles: ["@charset \"UTF-8\";:host{position:fixed;margin:0;inset:auto;box-sizing:border-box;background:var(--skra-comp-tooltip-background);color:var(--skra-comp-tooltip-foreground);border-color:var(--skra-comp-tooltip-border-color);border-width:var(--skra-comp-tooltip-border-width);border-style:var(--skra-comp-tooltip-border-style);border-radius:var(--skra-comp-tooltip-radius);padding-block:var(--skra-comp-tooltip-padding-block);padding-inline:var(--skra-comp-tooltip-padding-inline);box-shadow:var(--skra-comp-tooltip-shadow);inline-size:max-content;max-inline-size:var(--skra-comp-tooltip-max-inline-size);font-family:var(--skra-sys-typography-role-body-small-font-family);font-size:var(--skra-sys-typography-role-body-small-font-size);font-weight:var(--skra-sys-typography-role-body-small-font-weight);line-height:var(--skra-sys-typography-role-body-small-line-height);letter-spacing:var(--skra-sys-typography-role-body-small-letter-spacing);opacity:0;transition:opacity var(--skra-comp-tooltip-motion-duration) var(--skra-comp-tooltip-motion-easing),display var(--skra-comp-tooltip-motion-duration) allow-discrete,overlay var(--skra-comp-tooltip-motion-duration) allow-discrete}:host(:popover-open){display:block;opacity:1}@starting-style{:host(:popover-open){opacity:0}}@media(prefers-reduced-motion:reduce){:host{transition-duration:0ms}}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
28
+ }
29
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.7", ngImport: i0, type: SkraTooltipPanel, decorators: [{
30
+ type: Component,
31
+ args: [{ selector: 'skra-tooltip-panel', standalone: true, template: '{{ text() }}', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.Emulated, host: {
32
+ role: 'tooltip',
33
+ popover: 'manual',
34
+ '[id]': 'panelId',
35
+ }, styles: ["@charset \"UTF-8\";:host{position:fixed;margin:0;inset:auto;box-sizing:border-box;background:var(--skra-comp-tooltip-background);color:var(--skra-comp-tooltip-foreground);border-color:var(--skra-comp-tooltip-border-color);border-width:var(--skra-comp-tooltip-border-width);border-style:var(--skra-comp-tooltip-border-style);border-radius:var(--skra-comp-tooltip-radius);padding-block:var(--skra-comp-tooltip-padding-block);padding-inline:var(--skra-comp-tooltip-padding-inline);box-shadow:var(--skra-comp-tooltip-shadow);inline-size:max-content;max-inline-size:var(--skra-comp-tooltip-max-inline-size);font-family:var(--skra-sys-typography-role-body-small-font-family);font-size:var(--skra-sys-typography-role-body-small-font-size);font-weight:var(--skra-sys-typography-role-body-small-font-weight);line-height:var(--skra-sys-typography-role-body-small-line-height);letter-spacing:var(--skra-sys-typography-role-body-small-letter-spacing);opacity:0;transition:opacity var(--skra-comp-tooltip-motion-duration) var(--skra-comp-tooltip-motion-easing),display var(--skra-comp-tooltip-motion-duration) allow-discrete,overlay var(--skra-comp-tooltip-motion-duration) allow-discrete}:host(:popover-open){display:block;opacity:1}@starting-style{:host(:popover-open){opacity:0}}@media(prefers-reduced-motion:reduce){:host{transition-duration:0ms}}\n"] }]
36
+ }], propDecorators: { text: [{ type: i0.Input, args: [{ isSignal: true, alias: "text", required: false }] }] } });
37
+
38
+ /** A focusable trigger is required (WCAG 2.1.1); used only for the dev-mode nudge. */
39
+ const FOCUSABLE_SELECTOR = 'a[href],area[href],button,input,select,textarea,[tabindex],summary,' +
40
+ '[contenteditable]:not([contenteditable="false"])';
41
+ /**
42
+ * SkraTooltip — a supplementary, non-interactive text description on a focusable trigger, shown on
43
+ * hover AND keyboard focus (ADR 0044 native top layer via the Popover API). Applied to the consumer's
44
+ * own trigger: `<button skraButton [skraTooltip]="'Settings'">`.
45
+ *
46
+ * The bulk of this directive is the WCAG 1.4.13 (Content on Hover or Focus) state machine — the
47
+ * platform's `popover="manual"` gives top-layer rendering but no dismiss/Escape, so Forge wires it:
48
+ * - Dismissible: Escape hides WITHOUT moving focus.
49
+ * - Hoverable: a hide grace-delay lets the pointer travel trigger→panel; hovering the panel keeps it.
50
+ * - Persistent: no auto-timeout.
51
+ * - Keyboard: focus shows immediately (no delay).
52
+ *
53
+ * Accessible-name contract (ADR 033, describedby-only): the tooltip is a DESCRIPTION, never the name —
54
+ * it MERGES its panel id into the trigger's `aria-describedby` (preserving any existing value) and
55
+ * removes only its own token on destroy. The trigger owns its own accessible name (an icon-only button
56
+ * still needs its own `aria-label`). No `ariaLabel` input, no `aria-labelledby` wiring.
57
+ *
58
+ * The panel is created EAGERLY (hidden) so `aria-describedby` resolves and a screen reader announces
59
+ * the description on first focus. Positioning is delegated to `SkraPositioner` (single JS path,
60
+ * geometry-only inline; ADR 0044 §3 rules 4–5). Full contract: adr/specs/component-tooltip-spec.md.
61
+ */
62
+ class SkraTooltip {
63
+ /** The tooltip text (bound as `[skraTooltip]="..."`). */
64
+ skraTooltip = input.required(...(ngDevMode ? [{ debugName: "skraTooltip" }] : /* istanbul ignore next */ []));
65
+ /** Placement intent; `flip`/`shift` adjust at runtime. */
66
+ placement = input('top', ...(ngDevMode ? [{ debugName: "placement" }] : /* istanbul ignore next */ []));
67
+ host = inject(ElementRef);
68
+ vcr = inject(ViewContainerRef);
69
+ renderer = inject(Renderer2);
70
+ panelRef;
71
+ panelEl;
72
+ panelId;
73
+ positioner;
74
+ showTimer;
75
+ hideTimer;
76
+ docEscapeUnlisten;
77
+ open = false;
78
+ hovered = false;
79
+ focused = false;
80
+ panelHovered = false;
81
+ constructor() {
82
+ // Eager, in-tree panel (ADR 0044 §3 rule 3): inherits the design-context cascade + O-8 bridge.
83
+ this.panelRef = this.vcr.createComponent(SkraTooltipPanel);
84
+ this.panelEl = this.panelRef.location.nativeElement;
85
+ this.panelId = this.panelRef.instance.panelId;
86
+ // Describedby-only (ADR 033) — merge, never overwrite.
87
+ this.wireDescribedBy();
88
+ // Keep the panel text in sync with the input (effect runs after inputs are set).
89
+ effect(() => this.panelRef.setInput('text', this.skraTooltip()));
90
+ // Hoverable (WCAG 1.4.13): hovering the panel itself keeps the tooltip open.
91
+ this.renderer.listen(this.panelEl, 'pointerenter', () => {
92
+ this.panelHovered = true;
93
+ clearTimeout(this.hideTimer);
94
+ });
95
+ this.renderer.listen(this.panelEl, 'pointerleave', () => {
96
+ this.panelHovered = false;
97
+ this.scheduleHide();
98
+ });
99
+ if (typeof ngDevMode === 'undefined' || ngDevMode) {
100
+ this.warnIfTriggerNotFocusable();
101
+ }
102
+ inject(DestroyRef).onDestroy(() => this.teardown());
103
+ }
104
+ // ── Trigger events ──────────────────────────────────────────────────────────
105
+ onPointerEnter() {
106
+ this.hovered = true;
107
+ this.scheduleShow();
108
+ }
109
+ onPointerLeave() {
110
+ this.hovered = false;
111
+ this.scheduleHide();
112
+ }
113
+ onFocusIn() {
114
+ this.focused = true;
115
+ // Keyboard users get it immediately (WCAG 2.1.1) — no show-delay.
116
+ clearTimeout(this.showTimer);
117
+ clearTimeout(this.hideTimer);
118
+ this.show();
119
+ }
120
+ onFocusOut() {
121
+ this.focused = false;
122
+ this.scheduleHide();
123
+ }
124
+ // ── Show / hide state machine ─────────────────────────────────────────────────
125
+ scheduleShow() {
126
+ clearTimeout(this.hideTimer);
127
+ if (this.open)
128
+ return;
129
+ clearTimeout(this.showTimer);
130
+ this.showTimer = setTimeout(() => this.show(), this.cssTimeMs('--skra-comp-tooltip-show-delay'));
131
+ }
132
+ scheduleHide() {
133
+ clearTimeout(this.showTimer);
134
+ clearTimeout(this.hideTimer);
135
+ this.hideTimer = setTimeout(() => {
136
+ // Only hide once nothing keeps it engaged (hoverable + focus coordination).
137
+ if (!this.hovered && !this.focused && !this.panelHovered)
138
+ this.hide();
139
+ }, this.cssTimeMs('--skra-comp-tooltip-hide-delay'));
140
+ }
141
+ show() {
142
+ clearTimeout(this.showTimer);
143
+ if (this.open)
144
+ return;
145
+ this.open = true;
146
+ this.panelEl.showPopover?.();
147
+ this.positioner?.destroy();
148
+ this.positioner = _attachPositioner(this.host.nativeElement, this.panelEl, () => ({
149
+ placement: this.placement(),
150
+ offset: this.cssLenPx('--skra-comp-tooltip-offset'),
151
+ viewportPadding: this.cssLenPx('--skra-comp-tooltip-viewport-padding'),
152
+ }));
153
+ // Dismissible (WCAG 1.4.13): Escape hides without moving focus. Transient document listener
154
+ // (active only while open) so Escape works even for a hover-triggered tooltip whose trigger is
155
+ // not focused — `popover="manual"` does not provide platform Escape.
156
+ this.docEscapeUnlisten = this.renderer.listen('document', 'keydown', (event) => {
157
+ if (event.key === 'Escape')
158
+ this.hide();
159
+ });
160
+ }
161
+ hide() {
162
+ clearTimeout(this.showTimer);
163
+ clearTimeout(this.hideTimer);
164
+ if (!this.open)
165
+ return;
166
+ this.open = false;
167
+ this.panelEl.hidePopover?.();
168
+ this.positioner?.destroy();
169
+ this.positioner = undefined;
170
+ this.docEscapeUnlisten?.();
171
+ this.docEscapeUnlisten = undefined;
172
+ }
173
+ // ── aria-describedby merge (ADR 033 / ADR 013-style wiring) ───────────────────
174
+ wireDescribedBy() {
175
+ const tokens = this.describedByTokens();
176
+ if (!tokens.includes(this.panelId))
177
+ tokens.push(this.panelId);
178
+ this.renderer.setAttribute(this.host.nativeElement, 'aria-describedby', tokens.join(' '));
179
+ }
180
+ unwireDescribedBy() {
181
+ const remaining = this.describedByTokens().filter((t) => t !== this.panelId);
182
+ if (remaining.length) {
183
+ this.renderer.setAttribute(this.host.nativeElement, 'aria-describedby', remaining.join(' '));
184
+ }
185
+ else {
186
+ this.renderer.removeAttribute(this.host.nativeElement, 'aria-describedby');
187
+ }
188
+ }
189
+ describedByTokens() {
190
+ return (this.host.nativeElement.getAttribute('aria-describedby') ?? '')
191
+ .split(/\s+/)
192
+ .filter(Boolean);
193
+ }
194
+ // ── token resolution helpers (read computed comp tokens at runtime) ───────────
195
+ cssTimeMs(prop) {
196
+ const raw = getComputedStyle(this.panelEl).getPropertyValue(prop).trim();
197
+ if (raw.endsWith('ms'))
198
+ return parseFloat(raw);
199
+ if (raw.endsWith('s'))
200
+ return parseFloat(raw) * 1000;
201
+ return parseFloat(raw) || 0;
202
+ }
203
+ cssLenPx(prop) {
204
+ const raw = getComputedStyle(this.panelEl).getPropertyValue(prop).trim();
205
+ if (raw.endsWith('px'))
206
+ return parseFloat(raw);
207
+ if (raw.endsWith('rem')) {
208
+ const rootFontSize = parseFloat(getComputedStyle(document.documentElement).fontSize) || 16;
209
+ return parseFloat(raw) * rootFontSize;
210
+ }
211
+ return parseFloat(raw) || 0;
212
+ }
213
+ warnIfTriggerNotFocusable() {
214
+ const el = this.host.nativeElement;
215
+ if (!el.matches(FOCUSABLE_SELECTOR)) {
216
+ console.warn('[skraTooltip] host is not focusable — the tooltip is unreachable by keyboard ' +
217
+ '(WCAG 2.1.1) and never shows on focus. Apply it to a button/link/form control, ' +
218
+ 'or add tabindex to the trigger.');
219
+ }
220
+ }
221
+ teardown() {
222
+ clearTimeout(this.showTimer);
223
+ clearTimeout(this.hideTimer);
224
+ this.docEscapeUnlisten?.();
225
+ this.positioner?.destroy();
226
+ this.unwireDescribedBy();
227
+ this.panelRef.destroy();
228
+ }
229
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.7", ngImport: i0, type: SkraTooltip, deps: [], target: i0.ɵɵFactoryTarget.Directive });
230
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.7", type: SkraTooltip, isStandalone: true, selector: "[skraTooltip]", inputs: { skraTooltip: { classPropertyName: "skraTooltip", publicName: "skraTooltip", isSignal: true, isRequired: true, transformFunction: null }, placement: { classPropertyName: "placement", publicName: "placement", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "pointerenter": "onPointerEnter()", "pointerleave": "onPointerLeave()", "focusin": "onFocusIn()", "focusout": "onFocusOut()" } }, exportAs: ["skraTooltip"], ngImport: i0 });
231
+ }
232
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.7", ngImport: i0, type: SkraTooltip, decorators: [{
233
+ type: Directive,
234
+ args: [{
235
+ selector: '[skraTooltip]',
236
+ standalone: true,
237
+ exportAs: 'skraTooltip',
238
+ host: {
239
+ '(pointerenter)': 'onPointerEnter()',
240
+ '(pointerleave)': 'onPointerLeave()',
241
+ '(focusin)': 'onFocusIn()',
242
+ '(focusout)': 'onFocusOut()',
243
+ },
244
+ }]
245
+ }], ctorParameters: () => [], propDecorators: { skraTooltip: [{ type: i0.Input, args: [{ isSignal: true, alias: "skraTooltip", required: true }] }], placement: [{ type: i0.Input, args: [{ isSignal: true, alias: "placement", required: false }] }] } });
246
+
247
+ /**
248
+ * Generated bundle index. Do not edit.
249
+ */
250
+
251
+ export { SkraTooltip, SkraTooltipPanel };
252
+ //# sourceMappingURL=skra-ui-tooltip.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skra-ui-tooltip.mjs","sources":["../../../../libs/ui/tooltip/src/lib/tooltip/tooltip-panel.ts","../../../../libs/ui/tooltip/src/lib/tooltip/tooltip.ts","../../../../libs/ui/tooltip/src/skra-ui-tooltip.ts"],"sourcesContent":["import {\n ChangeDetectionStrategy,\n Component,\n ViewEncapsulation,\n input,\n} from '@angular/core';\n\nlet nextId = 0;\n\n/**\n * SkraTooltipPanel — the floating tooltip surface (ADR 0044 native top layer via the Popover API).\n *\n * INTERNAL: never placed by consumers in a template. `SkraTooltip` creates it programmatically with\n * `ViewContainerRef.createComponent` (Angular-idiomatic, in-tree → inherits the design-context cascade\n * + the O-8 Shadow-DOM bridge per ADR 0044 §3 rule 3) and drives `showPopover()`/`hidePopover()` on the\n * host element.\n *\n * `popover=\"manual\"` (NOT `auto`): a hover/focus tooltip's show/hide is Forge-owned, not click-toggle\n * light-dismiss. `role=\"tooltip\"` is the AT semantics; the trigger references this panel's `id` via\n * `aria-describedby` (wired by the directive). The 13-axis Universal Surface (ADR 025) + motion live in\n * `tooltip.scss`; geometry (`left`/`top` + `data-skra-placement`) is written by `SkraPositioner`.\n *\n * Full contract: adr/specs/component-tooltip-spec.md.\n */\n@Component({\n selector: 'skra-tooltip-panel',\n standalone: true,\n template: '{{ text() }}',\n styleUrl: './tooltip.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.Emulated,\n host: {\n role: 'tooltip',\n popover: 'manual',\n '[id]': 'panelId',\n },\n})\nexport class SkraTooltipPanel {\n /** Tooltip text; set by the directive and kept in sync. */\n readonly text = input<string>('');\n\n /** Stable unique id — target of the trigger's `aria-describedby`. */\n readonly panelId = `skra-tooltip-${nextId++}`;\n}\n","import {\n ComponentRef,\n DestroyRef,\n Directive,\n ElementRef,\n Renderer2,\n ViewContainerRef,\n effect,\n inject,\n input,\n} from '@angular/core';\n\nimport {\n _attachPositioner,\n type SkraPlacement,\n type _PositionerHandle,\n} from '@skra/ui/core';\nimport { SkraTooltipPanel } from './tooltip-panel';\n\ndeclare const ngDevMode: boolean | undefined;\n\n/** A focusable trigger is required (WCAG 2.1.1); used only for the dev-mode nudge. */\nconst FOCUSABLE_SELECTOR =\n 'a[href],area[href],button,input,select,textarea,[tabindex],summary,' +\n '[contenteditable]:not([contenteditable=\"false\"])';\n\n/**\n * SkraTooltip — a supplementary, non-interactive text description on a focusable trigger, shown on\n * hover AND keyboard focus (ADR 0044 native top layer via the Popover API). Applied to the consumer's\n * own trigger: `<button skraButton [skraTooltip]=\"'Settings'\">`.\n *\n * The bulk of this directive is the WCAG 1.4.13 (Content on Hover or Focus) state machine — the\n * platform's `popover=\"manual\"` gives top-layer rendering but no dismiss/Escape, so Forge wires it:\n * - Dismissible: Escape hides WITHOUT moving focus.\n * - Hoverable: a hide grace-delay lets the pointer travel trigger→panel; hovering the panel keeps it.\n * - Persistent: no auto-timeout.\n * - Keyboard: focus shows immediately (no delay).\n *\n * Accessible-name contract (ADR 033, describedby-only): the tooltip is a DESCRIPTION, never the name —\n * it MERGES its panel id into the trigger's `aria-describedby` (preserving any existing value) and\n * removes only its own token on destroy. The trigger owns its own accessible name (an icon-only button\n * still needs its own `aria-label`). No `ariaLabel` input, no `aria-labelledby` wiring.\n *\n * The panel is created EAGERLY (hidden) so `aria-describedby` resolves and a screen reader announces\n * the description on first focus. Positioning is delegated to `SkraPositioner` (single JS path,\n * geometry-only inline; ADR 0044 §3 rules 4–5). Full contract: adr/specs/component-tooltip-spec.md.\n */\n@Directive({\n selector: '[skraTooltip]',\n standalone: true,\n exportAs: 'skraTooltip',\n host: {\n '(pointerenter)': 'onPointerEnter()',\n '(pointerleave)': 'onPointerLeave()',\n '(focusin)': 'onFocusIn()',\n '(focusout)': 'onFocusOut()',\n },\n})\nexport class SkraTooltip {\n /** The tooltip text (bound as `[skraTooltip]=\"...\"`). */\n readonly skraTooltip = input.required<string>();\n /** Placement intent; `flip`/`shift` adjust at runtime. */\n readonly placement = input<SkraPlacement>('top');\n\n private readonly host = inject<ElementRef<HTMLElement>>(ElementRef);\n private readonly vcr = inject(ViewContainerRef);\n private readonly renderer = inject(Renderer2);\n\n private readonly panelRef: ComponentRef<SkraTooltipPanel>;\n private readonly panelEl: HTMLElement;\n private readonly panelId: string;\n\n private positioner?: _PositionerHandle;\n private showTimer?: ReturnType<typeof setTimeout>;\n private hideTimer?: ReturnType<typeof setTimeout>;\n private docEscapeUnlisten?: () => void;\n\n private open = false;\n private hovered = false;\n private focused = false;\n private panelHovered = false;\n\n constructor() {\n // Eager, in-tree panel (ADR 0044 §3 rule 3): inherits the design-context cascade + O-8 bridge.\n this.panelRef = this.vcr.createComponent(SkraTooltipPanel);\n this.panelEl = this.panelRef.location.nativeElement as HTMLElement;\n this.panelId = this.panelRef.instance.panelId;\n\n // Describedby-only (ADR 033) — merge, never overwrite.\n this.wireDescribedBy();\n\n // Keep the panel text in sync with the input (effect runs after inputs are set).\n effect(() => this.panelRef.setInput('text', this.skraTooltip()));\n\n // Hoverable (WCAG 1.4.13): hovering the panel itself keeps the tooltip open.\n this.renderer.listen(this.panelEl, 'pointerenter', () => {\n this.panelHovered = true;\n clearTimeout(this.hideTimer);\n });\n this.renderer.listen(this.panelEl, 'pointerleave', () => {\n this.panelHovered = false;\n this.scheduleHide();\n });\n\n if (typeof ngDevMode === 'undefined' || ngDevMode) {\n this.warnIfTriggerNotFocusable();\n }\n\n inject(DestroyRef).onDestroy(() => this.teardown());\n }\n\n // ── Trigger events ──────────────────────────────────────────────────────────\n protected onPointerEnter(): void {\n this.hovered = true;\n this.scheduleShow();\n }\n\n protected onPointerLeave(): void {\n this.hovered = false;\n this.scheduleHide();\n }\n\n protected onFocusIn(): void {\n this.focused = true;\n // Keyboard users get it immediately (WCAG 2.1.1) — no show-delay.\n clearTimeout(this.showTimer);\n clearTimeout(this.hideTimer);\n this.show();\n }\n\n protected onFocusOut(): void {\n this.focused = false;\n this.scheduleHide();\n }\n\n // ── Show / hide state machine ─────────────────────────────────────────────────\n private scheduleShow(): void {\n clearTimeout(this.hideTimer);\n if (this.open) return;\n clearTimeout(this.showTimer);\n this.showTimer = setTimeout(\n () => this.show(),\n this.cssTimeMs('--skra-comp-tooltip-show-delay'),\n );\n }\n\n private scheduleHide(): void {\n clearTimeout(this.showTimer);\n clearTimeout(this.hideTimer);\n this.hideTimer = setTimeout(() => {\n // Only hide once nothing keeps it engaged (hoverable + focus coordination).\n if (!this.hovered && !this.focused && !this.panelHovered) this.hide();\n }, this.cssTimeMs('--skra-comp-tooltip-hide-delay'));\n }\n\n private show(): void {\n clearTimeout(this.showTimer);\n if (this.open) return;\n this.open = true;\n\n this.panelEl.showPopover?.();\n\n this.positioner?.destroy();\n this.positioner = _attachPositioner(\n this.host.nativeElement,\n this.panelEl,\n () => ({\n placement: this.placement(),\n offset: this.cssLenPx('--skra-comp-tooltip-offset'),\n viewportPadding: this.cssLenPx('--skra-comp-tooltip-viewport-padding'),\n }),\n );\n\n // Dismissible (WCAG 1.4.13): Escape hides without moving focus. Transient document listener\n // (active only while open) so Escape works even for a hover-triggered tooltip whose trigger is\n // not focused — `popover=\"manual\"` does not provide platform Escape.\n this.docEscapeUnlisten = this.renderer.listen(\n 'document',\n 'keydown',\n (event: KeyboardEvent) => {\n if (event.key === 'Escape') this.hide();\n },\n );\n }\n\n private hide(): void {\n clearTimeout(this.showTimer);\n clearTimeout(this.hideTimer);\n if (!this.open) return;\n this.open = false;\n\n this.panelEl.hidePopover?.();\n this.positioner?.destroy();\n this.positioner = undefined;\n this.docEscapeUnlisten?.();\n this.docEscapeUnlisten = undefined;\n }\n\n // ── aria-describedby merge (ADR 033 / ADR 013-style wiring) ───────────────────\n private wireDescribedBy(): void {\n const tokens = this.describedByTokens();\n if (!tokens.includes(this.panelId)) tokens.push(this.panelId);\n this.renderer.setAttribute(\n this.host.nativeElement,\n 'aria-describedby',\n tokens.join(' '),\n );\n }\n\n private unwireDescribedBy(): void {\n const remaining = this.describedByTokens().filter(\n (t) => t !== this.panelId,\n );\n if (remaining.length) {\n this.renderer.setAttribute(\n this.host.nativeElement,\n 'aria-describedby',\n remaining.join(' '),\n );\n } else {\n this.renderer.removeAttribute(\n this.host.nativeElement,\n 'aria-describedby',\n );\n }\n }\n\n private describedByTokens(): string[] {\n return (this.host.nativeElement.getAttribute('aria-describedby') ?? '')\n .split(/\\s+/)\n .filter(Boolean);\n }\n\n // ── token resolution helpers (read computed comp tokens at runtime) ───────────\n private cssTimeMs(prop: string): number {\n const raw = getComputedStyle(this.panelEl).getPropertyValue(prop).trim();\n if (raw.endsWith('ms')) return parseFloat(raw);\n if (raw.endsWith('s')) return parseFloat(raw) * 1000;\n return parseFloat(raw) || 0;\n }\n\n private cssLenPx(prop: string): number {\n const raw = getComputedStyle(this.panelEl).getPropertyValue(prop).trim();\n if (raw.endsWith('px')) return parseFloat(raw);\n if (raw.endsWith('rem')) {\n const rootFontSize =\n parseFloat(getComputedStyle(document.documentElement).fontSize) || 16;\n return parseFloat(raw) * rootFontSize;\n }\n return parseFloat(raw) || 0;\n }\n\n private warnIfTriggerNotFocusable(): void {\n const el = this.host.nativeElement;\n if (!el.matches(FOCUSABLE_SELECTOR)) {\n console.warn(\n '[skraTooltip] host is not focusable — the tooltip is unreachable by keyboard ' +\n '(WCAG 2.1.1) and never shows on focus. Apply it to a button/link/form control, ' +\n 'or add tabindex to the trigger.',\n );\n }\n }\n\n private teardown(): void {\n clearTimeout(this.showTimer);\n clearTimeout(this.hideTimer);\n this.docEscapeUnlisten?.();\n this.positioner?.destroy();\n this.unwireDescribedBy();\n this.panelRef.destroy();\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,35 @@
1
+ import * as i0 from '@angular/core';
2
+ import { input, ViewEncapsulation, ChangeDetectionStrategy, Component } from '@angular/core';
3
+
4
+ class SkraTypography {
5
+ role = input('body-medium', { ...(ngDevMode ? { debugName: "role" } : /* istanbul ignore next */ {}), alias: 'skraTypography' });
6
+ severity = input(null, ...(ngDevMode ? [{ debugName: "severity" }] : /* istanbul ignore next */ []));
7
+ truncate = input(null, ...(ngDevMode ? [{ debugName: "truncate" }] : /* istanbul ignore next */ []));
8
+ lineClamp = input(2, ...(ngDevMode ? [{ debugName: "lineClamp" }] : /* istanbul ignore next */ []));
9
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.7", ngImport: i0, type: SkraTypography, deps: [], target: i0.ɵɵFactoryTarget.Component });
10
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.7", type: SkraTypography, isStandalone: true, selector: "[skraTypography]", inputs: { role: { classPropertyName: "role", publicName: "skraTypography", isSignal: true, isRequired: false, transformFunction: null }, severity: { classPropertyName: "severity", publicName: "severity", isSignal: true, isRequired: false, transformFunction: null }, truncate: { classPropertyName: "truncate", publicName: "truncate", isSignal: true, isRequired: false, transformFunction: null }, lineClamp: { classPropertyName: "lineClamp", publicName: "lineClamp", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "attr.data-skra-typo-role": "role()", "attr.data-skra-severity": "severity()", "attr.data-skra-truncate": "truncate()", "attr.data-skra-line-clamp": "truncate() === \"multi\" ? lineClamp() : null" } }, ngImport: i0, template: '<ng-content />', isInline: true, styles: ["@charset \"UTF-8\";:host{display:block;margin:0;font-family:var(--skra-comp-typography-font-family);font-size:var(--skra-comp-typography-font-size);font-weight:var(--skra-comp-typography-font-weight);line-height:var(--skra-comp-typography-line-height);letter-spacing:var(--skra-comp-typography-letter-spacing);color:var(--skra-comp-typography-foreground)}:host([data-skra-typo-role=display-large]){--skra-comp-typography-font-family: var( --skra-comp-typography-display-large-font-family );--skra-comp-typography-font-size: var( --skra-comp-typography-display-large-font-size );--skra-comp-typography-font-weight: var( --skra-comp-typography-display-large-font-weight );--skra-comp-typography-line-height: var( --skra-comp-typography-display-large-line-height );--skra-comp-typography-letter-spacing: var( --skra-comp-typography-display-large-letter-spacing );--skra-comp-typography-foreground: var( --skra-comp-typography-display-large-foreground )}:host([data-skra-typo-role=display-medium]){--skra-comp-typography-font-family: var( --skra-comp-typography-display-medium-font-family );--skra-comp-typography-font-size: var( --skra-comp-typography-display-medium-font-size );--skra-comp-typography-font-weight: var( --skra-comp-typography-display-medium-font-weight );--skra-comp-typography-line-height: var( --skra-comp-typography-display-medium-line-height );--skra-comp-typography-letter-spacing: var( --skra-comp-typography-display-medium-letter-spacing );--skra-comp-typography-foreground: var( --skra-comp-typography-display-medium-foreground )}:host([data-skra-typo-role=display-small]){--skra-comp-typography-font-family: var( --skra-comp-typography-display-small-font-family );--skra-comp-typography-font-size: var( --skra-comp-typography-display-small-font-size );--skra-comp-typography-font-weight: var( --skra-comp-typography-display-small-font-weight );--skra-comp-typography-line-height: var( --skra-comp-typography-display-small-line-height );--skra-comp-typography-letter-spacing: var( --skra-comp-typography-display-small-letter-spacing );--skra-comp-typography-foreground: var( --skra-comp-typography-display-small-foreground )}:host([data-skra-typo-role=headline-large]){--skra-comp-typography-font-family: var( --skra-comp-typography-headline-large-font-family );--skra-comp-typography-font-size: var( --skra-comp-typography-headline-large-font-size );--skra-comp-typography-font-weight: var( --skra-comp-typography-headline-large-font-weight );--skra-comp-typography-line-height: var( --skra-comp-typography-headline-large-line-height );--skra-comp-typography-letter-spacing: var( --skra-comp-typography-headline-large-letter-spacing );--skra-comp-typography-foreground: var( --skra-comp-typography-headline-large-foreground )}:host([data-skra-typo-role=headline-medium]){--skra-comp-typography-font-family: var( --skra-comp-typography-headline-medium-font-family );--skra-comp-typography-font-size: var( --skra-comp-typography-headline-medium-font-size );--skra-comp-typography-font-weight: var( --skra-comp-typography-headline-medium-font-weight );--skra-comp-typography-line-height: var( --skra-comp-typography-headline-medium-line-height );--skra-comp-typography-letter-spacing: var( --skra-comp-typography-headline-medium-letter-spacing );--skra-comp-typography-foreground: var( --skra-comp-typography-headline-medium-foreground )}:host([data-skra-typo-role=headline-small]){--skra-comp-typography-font-family: var( --skra-comp-typography-headline-small-font-family );--skra-comp-typography-font-size: var( --skra-comp-typography-headline-small-font-size );--skra-comp-typography-font-weight: var( --skra-comp-typography-headline-small-font-weight );--skra-comp-typography-line-height: var( --skra-comp-typography-headline-small-line-height );--skra-comp-typography-letter-spacing: var( --skra-comp-typography-headline-small-letter-spacing );--skra-comp-typography-foreground: var( --skra-comp-typography-headline-small-foreground )}:host([data-skra-typo-role=title-large]){--skra-comp-typography-font-family: var( --skra-comp-typography-title-large-font-family );--skra-comp-typography-font-size: var( --skra-comp-typography-title-large-font-size );--skra-comp-typography-font-weight: var( --skra-comp-typography-title-large-font-weight );--skra-comp-typography-line-height: var( --skra-comp-typography-title-large-line-height );--skra-comp-typography-letter-spacing: var( --skra-comp-typography-title-large-letter-spacing );--skra-comp-typography-foreground: var( --skra-comp-typography-title-large-foreground )}:host([data-skra-typo-role=title-medium]){--skra-comp-typography-font-family: var( --skra-comp-typography-title-medium-font-family );--skra-comp-typography-font-size: var( --skra-comp-typography-title-medium-font-size );--skra-comp-typography-font-weight: var( --skra-comp-typography-title-medium-font-weight );--skra-comp-typography-line-height: var( --skra-comp-typography-title-medium-line-height );--skra-comp-typography-letter-spacing: var( --skra-comp-typography-title-medium-letter-spacing );--skra-comp-typography-foreground: var( --skra-comp-typography-title-medium-foreground )}:host([data-skra-typo-role=title-small]){--skra-comp-typography-font-family: var( --skra-comp-typography-title-small-font-family );--skra-comp-typography-font-size: var( --skra-comp-typography-title-small-font-size );--skra-comp-typography-font-weight: var( --skra-comp-typography-title-small-font-weight );--skra-comp-typography-line-height: var( --skra-comp-typography-title-small-line-height );--skra-comp-typography-letter-spacing: var( --skra-comp-typography-title-small-letter-spacing );--skra-comp-typography-foreground: var( --skra-comp-typography-title-small-foreground )}:host([data-skra-typo-role=body-large]){--skra-comp-typography-font-family: var( --skra-comp-typography-body-large-font-family );--skra-comp-typography-font-size: var( --skra-comp-typography-body-large-font-size );--skra-comp-typography-font-weight: var( --skra-comp-typography-body-large-font-weight );--skra-comp-typography-line-height: var( --skra-comp-typography-body-large-line-height );--skra-comp-typography-letter-spacing: var( --skra-comp-typography-body-large-letter-spacing );--skra-comp-typography-foreground: var( --skra-comp-typography-body-large-foreground )}:host([data-skra-typo-role=body-medium]){--skra-comp-typography-font-family: var( --skra-comp-typography-body-medium-font-family );--skra-comp-typography-font-size: var( --skra-comp-typography-body-medium-font-size );--skra-comp-typography-font-weight: var( --skra-comp-typography-body-medium-font-weight );--skra-comp-typography-line-height: var( --skra-comp-typography-body-medium-line-height );--skra-comp-typography-letter-spacing: var( --skra-comp-typography-body-medium-letter-spacing );--skra-comp-typography-foreground: var( --skra-comp-typography-body-medium-foreground )}:host([data-skra-typo-role=body-small]){--skra-comp-typography-font-family: var( --skra-comp-typography-body-small-font-family );--skra-comp-typography-font-size: var( --skra-comp-typography-body-small-font-size );--skra-comp-typography-font-weight: var( --skra-comp-typography-body-small-font-weight );--skra-comp-typography-line-height: var( --skra-comp-typography-body-small-line-height );--skra-comp-typography-letter-spacing: var( --skra-comp-typography-body-small-letter-spacing );--skra-comp-typography-foreground: var( --skra-comp-typography-body-small-foreground )}:host([data-skra-typo-role=label-large]){--skra-comp-typography-font-family: var( --skra-comp-typography-label-large-font-family );--skra-comp-typography-font-size: var( --skra-comp-typography-label-large-font-size );--skra-comp-typography-font-weight: var( --skra-comp-typography-label-large-font-weight );--skra-comp-typography-line-height: var( --skra-comp-typography-label-large-line-height );--skra-comp-typography-letter-spacing: var( --skra-comp-typography-label-large-letter-spacing );--skra-comp-typography-foreground: var( --skra-comp-typography-label-large-foreground )}:host([data-skra-typo-role=label-medium]){--skra-comp-typography-font-family: var( --skra-comp-typography-label-medium-font-family );--skra-comp-typography-font-size: var( --skra-comp-typography-label-medium-font-size );--skra-comp-typography-font-weight: var( --skra-comp-typography-label-medium-font-weight );--skra-comp-typography-line-height: var( --skra-comp-typography-label-medium-line-height );--skra-comp-typography-letter-spacing: var( --skra-comp-typography-label-medium-letter-spacing );--skra-comp-typography-foreground: var( --skra-comp-typography-label-medium-foreground )}:host([data-skra-typo-role=label-small]){--skra-comp-typography-font-family: var( --skra-comp-typography-label-small-font-family );--skra-comp-typography-font-size: var( --skra-comp-typography-label-small-font-size );--skra-comp-typography-font-weight: var( --skra-comp-typography-label-small-font-weight );--skra-comp-typography-line-height: var( --skra-comp-typography-label-small-line-height );--skra-comp-typography-letter-spacing: var( --skra-comp-typography-label-small-letter-spacing );--skra-comp-typography-foreground: var( --skra-comp-typography-label-small-foreground )}:host([data-skra-severity=error]){--skra-comp-typography-foreground: var( --skra-comp-typography-foreground-error )}:host([data-skra-severity=warning]){--skra-comp-typography-foreground: var( --skra-comp-typography-foreground-warning )}:host([data-skra-severity=success]){--skra-comp-typography-foreground: var( --skra-comp-typography-foreground-success )}:host([data-skra-truncate=single]){display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}:host([data-skra-truncate=multi]){display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;overflow:hidden}:host([data-skra-truncate=multi][data-skra-line-clamp=\"3\"]){-webkit-line-clamp:3}:host([data-skra-truncate=multi][data-skra-line-clamp=\"4\"]){-webkit-line-clamp:4}:host([data-skra-truncate=multi][data-skra-line-clamp=\"5\"]){-webkit-line-clamp:5}:host([data-skra-truncate=multi][data-skra-line-clamp=\"6\"]){-webkit-line-clamp:6}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
11
+ }
12
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.7", ngImport: i0, type: SkraTypography, decorators: [{
13
+ type: Component,
14
+ args: [{ selector: '[skraTypography]', standalone: true, imports: [], template: '<ng-content />', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.Emulated, host: {
15
+ // ADR 021 — CSP-safe state reflection. The zero-margin reset (ADR 022)
16
+ // lives in typography.scss `:host` — host-metadata bare keys would render
17
+ // as junk attributes, not styles.
18
+ '[attr.data-skra-typo-role]': 'role()',
19
+ '[attr.data-skra-severity]': 'severity()',
20
+ '[attr.data-skra-truncate]': 'truncate()',
21
+ // Line-clamp count — reflected as an enumerated data-attribute, consumed by
22
+ // static `-webkit-line-clamp` rules in typography.scss (buckets 2–6). NOT a
23
+ // `[style.--var]` binding (ADR 021 iron boundary) — same enumerated-bucket
24
+ // approach Grid/Stack use to keep CSP-safe. Values outside 2–6 fall back to
25
+ // the base 2-line rule.
26
+ '[attr.data-skra-line-clamp]': 'truncate() === "multi" ? lineClamp() : null',
27
+ }, styles: ["@charset \"UTF-8\";:host{display:block;margin:0;font-family:var(--skra-comp-typography-font-family);font-size:var(--skra-comp-typography-font-size);font-weight:var(--skra-comp-typography-font-weight);line-height:var(--skra-comp-typography-line-height);letter-spacing:var(--skra-comp-typography-letter-spacing);color:var(--skra-comp-typography-foreground)}:host([data-skra-typo-role=display-large]){--skra-comp-typography-font-family: var( --skra-comp-typography-display-large-font-family );--skra-comp-typography-font-size: var( --skra-comp-typography-display-large-font-size );--skra-comp-typography-font-weight: var( --skra-comp-typography-display-large-font-weight );--skra-comp-typography-line-height: var( --skra-comp-typography-display-large-line-height );--skra-comp-typography-letter-spacing: var( --skra-comp-typography-display-large-letter-spacing );--skra-comp-typography-foreground: var( --skra-comp-typography-display-large-foreground )}:host([data-skra-typo-role=display-medium]){--skra-comp-typography-font-family: var( --skra-comp-typography-display-medium-font-family );--skra-comp-typography-font-size: var( --skra-comp-typography-display-medium-font-size );--skra-comp-typography-font-weight: var( --skra-comp-typography-display-medium-font-weight );--skra-comp-typography-line-height: var( --skra-comp-typography-display-medium-line-height );--skra-comp-typography-letter-spacing: var( --skra-comp-typography-display-medium-letter-spacing );--skra-comp-typography-foreground: var( --skra-comp-typography-display-medium-foreground )}:host([data-skra-typo-role=display-small]){--skra-comp-typography-font-family: var( --skra-comp-typography-display-small-font-family );--skra-comp-typography-font-size: var( --skra-comp-typography-display-small-font-size );--skra-comp-typography-font-weight: var( --skra-comp-typography-display-small-font-weight );--skra-comp-typography-line-height: var( --skra-comp-typography-display-small-line-height );--skra-comp-typography-letter-spacing: var( --skra-comp-typography-display-small-letter-spacing );--skra-comp-typography-foreground: var( --skra-comp-typography-display-small-foreground )}:host([data-skra-typo-role=headline-large]){--skra-comp-typography-font-family: var( --skra-comp-typography-headline-large-font-family );--skra-comp-typography-font-size: var( --skra-comp-typography-headline-large-font-size );--skra-comp-typography-font-weight: var( --skra-comp-typography-headline-large-font-weight );--skra-comp-typography-line-height: var( --skra-comp-typography-headline-large-line-height );--skra-comp-typography-letter-spacing: var( --skra-comp-typography-headline-large-letter-spacing );--skra-comp-typography-foreground: var( --skra-comp-typography-headline-large-foreground )}:host([data-skra-typo-role=headline-medium]){--skra-comp-typography-font-family: var( --skra-comp-typography-headline-medium-font-family );--skra-comp-typography-font-size: var( --skra-comp-typography-headline-medium-font-size );--skra-comp-typography-font-weight: var( --skra-comp-typography-headline-medium-font-weight );--skra-comp-typography-line-height: var( --skra-comp-typography-headline-medium-line-height );--skra-comp-typography-letter-spacing: var( --skra-comp-typography-headline-medium-letter-spacing );--skra-comp-typography-foreground: var( --skra-comp-typography-headline-medium-foreground )}:host([data-skra-typo-role=headline-small]){--skra-comp-typography-font-family: var( --skra-comp-typography-headline-small-font-family );--skra-comp-typography-font-size: var( --skra-comp-typography-headline-small-font-size );--skra-comp-typography-font-weight: var( --skra-comp-typography-headline-small-font-weight );--skra-comp-typography-line-height: var( --skra-comp-typography-headline-small-line-height );--skra-comp-typography-letter-spacing: var( --skra-comp-typography-headline-small-letter-spacing );--skra-comp-typography-foreground: var( --skra-comp-typography-headline-small-foreground )}:host([data-skra-typo-role=title-large]){--skra-comp-typography-font-family: var( --skra-comp-typography-title-large-font-family );--skra-comp-typography-font-size: var( --skra-comp-typography-title-large-font-size );--skra-comp-typography-font-weight: var( --skra-comp-typography-title-large-font-weight );--skra-comp-typography-line-height: var( --skra-comp-typography-title-large-line-height );--skra-comp-typography-letter-spacing: var( --skra-comp-typography-title-large-letter-spacing );--skra-comp-typography-foreground: var( --skra-comp-typography-title-large-foreground )}:host([data-skra-typo-role=title-medium]){--skra-comp-typography-font-family: var( --skra-comp-typography-title-medium-font-family );--skra-comp-typography-font-size: var( --skra-comp-typography-title-medium-font-size );--skra-comp-typography-font-weight: var( --skra-comp-typography-title-medium-font-weight );--skra-comp-typography-line-height: var( --skra-comp-typography-title-medium-line-height );--skra-comp-typography-letter-spacing: var( --skra-comp-typography-title-medium-letter-spacing );--skra-comp-typography-foreground: var( --skra-comp-typography-title-medium-foreground )}:host([data-skra-typo-role=title-small]){--skra-comp-typography-font-family: var( --skra-comp-typography-title-small-font-family );--skra-comp-typography-font-size: var( --skra-comp-typography-title-small-font-size );--skra-comp-typography-font-weight: var( --skra-comp-typography-title-small-font-weight );--skra-comp-typography-line-height: var( --skra-comp-typography-title-small-line-height );--skra-comp-typography-letter-spacing: var( --skra-comp-typography-title-small-letter-spacing );--skra-comp-typography-foreground: var( --skra-comp-typography-title-small-foreground )}:host([data-skra-typo-role=body-large]){--skra-comp-typography-font-family: var( --skra-comp-typography-body-large-font-family );--skra-comp-typography-font-size: var( --skra-comp-typography-body-large-font-size );--skra-comp-typography-font-weight: var( --skra-comp-typography-body-large-font-weight );--skra-comp-typography-line-height: var( --skra-comp-typography-body-large-line-height );--skra-comp-typography-letter-spacing: var( --skra-comp-typography-body-large-letter-spacing );--skra-comp-typography-foreground: var( --skra-comp-typography-body-large-foreground )}:host([data-skra-typo-role=body-medium]){--skra-comp-typography-font-family: var( --skra-comp-typography-body-medium-font-family );--skra-comp-typography-font-size: var( --skra-comp-typography-body-medium-font-size );--skra-comp-typography-font-weight: var( --skra-comp-typography-body-medium-font-weight );--skra-comp-typography-line-height: var( --skra-comp-typography-body-medium-line-height );--skra-comp-typography-letter-spacing: var( --skra-comp-typography-body-medium-letter-spacing );--skra-comp-typography-foreground: var( --skra-comp-typography-body-medium-foreground )}:host([data-skra-typo-role=body-small]){--skra-comp-typography-font-family: var( --skra-comp-typography-body-small-font-family );--skra-comp-typography-font-size: var( --skra-comp-typography-body-small-font-size );--skra-comp-typography-font-weight: var( --skra-comp-typography-body-small-font-weight );--skra-comp-typography-line-height: var( --skra-comp-typography-body-small-line-height );--skra-comp-typography-letter-spacing: var( --skra-comp-typography-body-small-letter-spacing );--skra-comp-typography-foreground: var( --skra-comp-typography-body-small-foreground )}:host([data-skra-typo-role=label-large]){--skra-comp-typography-font-family: var( --skra-comp-typography-label-large-font-family );--skra-comp-typography-font-size: var( --skra-comp-typography-label-large-font-size );--skra-comp-typography-font-weight: var( --skra-comp-typography-label-large-font-weight );--skra-comp-typography-line-height: var( --skra-comp-typography-label-large-line-height );--skra-comp-typography-letter-spacing: var( --skra-comp-typography-label-large-letter-spacing );--skra-comp-typography-foreground: var( --skra-comp-typography-label-large-foreground )}:host([data-skra-typo-role=label-medium]){--skra-comp-typography-font-family: var( --skra-comp-typography-label-medium-font-family );--skra-comp-typography-font-size: var( --skra-comp-typography-label-medium-font-size );--skra-comp-typography-font-weight: var( --skra-comp-typography-label-medium-font-weight );--skra-comp-typography-line-height: var( --skra-comp-typography-label-medium-line-height );--skra-comp-typography-letter-spacing: var( --skra-comp-typography-label-medium-letter-spacing );--skra-comp-typography-foreground: var( --skra-comp-typography-label-medium-foreground )}:host([data-skra-typo-role=label-small]){--skra-comp-typography-font-family: var( --skra-comp-typography-label-small-font-family );--skra-comp-typography-font-size: var( --skra-comp-typography-label-small-font-size );--skra-comp-typography-font-weight: var( --skra-comp-typography-label-small-font-weight );--skra-comp-typography-line-height: var( --skra-comp-typography-label-small-line-height );--skra-comp-typography-letter-spacing: var( --skra-comp-typography-label-small-letter-spacing );--skra-comp-typography-foreground: var( --skra-comp-typography-label-small-foreground )}:host([data-skra-severity=error]){--skra-comp-typography-foreground: var( --skra-comp-typography-foreground-error )}:host([data-skra-severity=warning]){--skra-comp-typography-foreground: var( --skra-comp-typography-foreground-warning )}:host([data-skra-severity=success]){--skra-comp-typography-foreground: var( --skra-comp-typography-foreground-success )}:host([data-skra-truncate=single]){display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}:host([data-skra-truncate=multi]){display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;overflow:hidden}:host([data-skra-truncate=multi][data-skra-line-clamp=\"3\"]){-webkit-line-clamp:3}:host([data-skra-truncate=multi][data-skra-line-clamp=\"4\"]){-webkit-line-clamp:4}:host([data-skra-truncate=multi][data-skra-line-clamp=\"5\"]){-webkit-line-clamp:5}:host([data-skra-truncate=multi][data-skra-line-clamp=\"6\"]){-webkit-line-clamp:6}\n"] }]
28
+ }], propDecorators: { role: [{ type: i0.Input, args: [{ isSignal: true, alias: "skraTypography", required: false }] }], severity: [{ type: i0.Input, args: [{ isSignal: true, alias: "severity", required: false }] }], truncate: [{ type: i0.Input, args: [{ isSignal: true, alias: "truncate", required: false }] }], lineClamp: [{ type: i0.Input, args: [{ isSignal: true, alias: "lineClamp", required: false }] }] } });
29
+
30
+ /**
31
+ * Generated bundle index. Do not edit.
32
+ */
33
+
34
+ export { SkraTypography };
35
+ //# sourceMappingURL=skra-ui-typography.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skra-ui-typography.mjs","sources":["../../../../libs/ui/typography/src/lib/typography/typography.ts","../../../../libs/ui/typography/src/skra-ui-typography.ts"],"sourcesContent":["import {\n ChangeDetectionStrategy,\n Component,\n ViewEncapsulation,\n input,\n} from '@angular/core';\n\nexport type TypographyRole =\n | 'display-large'\n | 'display-medium'\n | 'display-small'\n | 'headline-large'\n | 'headline-medium'\n | 'headline-small'\n | 'title-large'\n | 'title-medium'\n | 'title-small'\n | 'body-large'\n | 'body-medium'\n | 'body-small'\n | 'label-large'\n | 'label-medium'\n | 'label-small';\n\nexport type TypographySeverity = 'error' | 'warning' | 'success';\nexport type TypographyTruncate = 'single' | 'multi';\n\n@Component({\n selector: '[skraTypography]',\n standalone: true,\n imports: [],\n template: '<ng-content />',\n styleUrl: './typography.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.Emulated,\n host: {\n // ADR 021 — CSP-safe state reflection. The zero-margin reset (ADR 022)\n // lives in typography.scss `:host` — host-metadata bare keys would render\n // as junk attributes, not styles.\n '[attr.data-skra-typo-role]': 'role()',\n '[attr.data-skra-severity]': 'severity()',\n '[attr.data-skra-truncate]': 'truncate()',\n // Line-clamp count — reflected as an enumerated data-attribute, consumed by\n // static `-webkit-line-clamp` rules in typography.scss (buckets 2–6). NOT a\n // `[style.--var]` binding (ADR 021 iron boundary) — same enumerated-bucket\n // approach Grid/Stack use to keep CSP-safe. Values outside 2–6 fall back to\n // the base 2-line rule.\n '[attr.data-skra-line-clamp]':\n 'truncate() === \"multi\" ? lineClamp() : null',\n },\n})\nexport class SkraTypography {\n readonly role = input<TypographyRole>('body-medium', {\n alias: 'skraTypography',\n });\n readonly severity = input<TypographySeverity | null>(null);\n readonly truncate = input<TypographyTruncate | null>(null);\n readonly lineClamp = input<number>(2);\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;MAmDa,cAAc,CAAA;IAChB,IAAI,GAAG,KAAK,CAAiB,aAAa,4EACjD,KAAK,EAAE,gBAAgB,EAAA,CACvB;AACO,IAAA,QAAQ,GAAG,KAAK,CAA4B,IAAI,+EAAC;AACjD,IAAA,QAAQ,GAAG,KAAK,CAA4B,IAAI,+EAAC;AACjD,IAAA,SAAS,GAAG,KAAK,CAAS,CAAC,gFAAC;uGAN1B,cAAc,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAd,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,cAAc,6zBApBf,gBAAgB,EAAA,QAAA,EAAA,IAAA,EAAA,MAAA,EAAA,CAAA,23TAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA;;2FAoBf,cAAc,EAAA,UAAA,EAAA,CAAA;kBAxB1B,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,kBAAkB,EAAA,UAAA,EAChB,IAAI,EAAA,OAAA,EACP,EAAE,YACD,gBAAgB,EAAA,eAAA,EAET,uBAAuB,CAAC,MAAM,EAAA,aAAA,EAChC,iBAAiB,CAAC,QAAQ,EAAA,IAAA,EACnC;;;;AAIJ,wBAAA,4BAA4B,EAAE,QAAQ;AACtC,wBAAA,2BAA2B,EAAE,YAAY;AACzC,wBAAA,2BAA2B,EAAE,YAAY;;;;;;AAMzC,wBAAA,6BAA6B,EAC3B,6CAA6C;AAChD,qBAAA,EAAA,MAAA,EAAA,CAAA,23TAAA,CAAA,EAAA;;;ACjDH;;AAEG;;;;"}
@@ -0,0 +1,4 @@
1
+ /**
2
+ * Generated bundle index. Do not edit.
3
+ */
4
+ //# sourceMappingURL=skra-ui.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skra-ui.mjs","sources":["../../../../libs/ui/src/skra-ui.ts"],"sourcesContent":["/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"AAAA;;AAEG"}
package/package.json ADDED
@@ -0,0 +1,175 @@
1
+ {
2
+ "name": "@skra/ui",
3
+ "version": "0.2.0",
4
+ "license": "Apache-2.0",
5
+ "publishConfig": {
6
+ "access": "public"
7
+ },
8
+ "sideEffects": false,
9
+ "peerDependencies": {
10
+ "@angular/core": "~21.2.0",
11
+ "@angular/common": "~21.2.0",
12
+ "@angular/cdk": "~21.2.0",
13
+ "@skra/tokens": "^0.2.0"
14
+ },
15
+ "dependencies": {
16
+ "@floating-ui/dom": "^1.7.6",
17
+ "tslib": "^2.3.0"
18
+ },
19
+ "module": "fesm2022/skra-ui.mjs",
20
+ "typings": "types/skra-ui.d.ts",
21
+ "exports": {
22
+ "./package.json": {
23
+ "default": "./package.json"
24
+ },
25
+ ".": {
26
+ "types": "./types/skra-ui.d.ts",
27
+ "default": "./fesm2022/skra-ui.mjs"
28
+ },
29
+ "./accordion": {
30
+ "types": "./types/skra-ui-accordion.d.ts",
31
+ "default": "./fesm2022/skra-ui-accordion.mjs"
32
+ },
33
+ "./alert": {
34
+ "types": "./types/skra-ui-alert.d.ts",
35
+ "default": "./fesm2022/skra-ui-alert.mjs"
36
+ },
37
+ "./avatar": {
38
+ "types": "./types/skra-ui-avatar.d.ts",
39
+ "default": "./fesm2022/skra-ui-avatar.mjs"
40
+ },
41
+ "./badge": {
42
+ "types": "./types/skra-ui-badge.d.ts",
43
+ "default": "./fesm2022/skra-ui-badge.mjs"
44
+ },
45
+ "./button": {
46
+ "types": "./types/skra-ui-button.d.ts",
47
+ "default": "./fesm2022/skra-ui-button.mjs"
48
+ },
49
+ "./checkbox": {
50
+ "types": "./types/skra-ui-checkbox.d.ts",
51
+ "default": "./fesm2022/skra-ui-checkbox.mjs"
52
+ },
53
+ "./chip": {
54
+ "types": "./types/skra-ui-chip.d.ts",
55
+ "default": "./fesm2022/skra-ui-chip.mjs"
56
+ },
57
+ "./combobox": {
58
+ "types": "./types/skra-ui-combobox.d.ts",
59
+ "default": "./fesm2022/skra-ui-combobox.mjs"
60
+ },
61
+ "./core": {
62
+ "types": "./types/skra-ui-core.d.ts",
63
+ "default": "./fesm2022/skra-ui-core.mjs"
64
+ },
65
+ "./counter": {
66
+ "types": "./types/skra-ui-counter.d.ts",
67
+ "default": "./fesm2022/skra-ui-counter.mjs"
68
+ },
69
+ "./datepicker": {
70
+ "types": "./types/skra-ui-datepicker.d.ts",
71
+ "default": "./fesm2022/skra-ui-datepicker.mjs"
72
+ },
73
+ "./dialog": {
74
+ "types": "./types/skra-ui-dialog.d.ts",
75
+ "default": "./fesm2022/skra-ui-dialog.mjs"
76
+ },
77
+ "./field": {
78
+ "types": "./types/skra-ui-field.d.ts",
79
+ "default": "./fesm2022/skra-ui-field.mjs"
80
+ },
81
+ "./icon": {
82
+ "types": "./types/skra-ui-icon.d.ts",
83
+ "default": "./fesm2022/skra-ui-icon.mjs"
84
+ },
85
+ "./input": {
86
+ "types": "./types/skra-ui-input.d.ts",
87
+ "default": "./fesm2022/skra-ui-input.mjs"
88
+ },
89
+ "./kbd": {
90
+ "types": "./types/skra-ui-kbd.d.ts",
91
+ "default": "./fesm2022/skra-ui-kbd.mjs"
92
+ },
93
+ "./layout": {
94
+ "types": "./types/skra-ui-layout.d.ts",
95
+ "default": "./fesm2022/skra-ui-layout.mjs"
96
+ },
97
+ "./link": {
98
+ "types": "./types/skra-ui-link.d.ts",
99
+ "default": "./fesm2022/skra-ui-link.mjs"
100
+ },
101
+ "./loading-indicator": {
102
+ "types": "./types/skra-ui-loading-indicator.d.ts",
103
+ "default": "./fesm2022/skra-ui-loading-indicator.mjs"
104
+ },
105
+ "./menu": {
106
+ "types": "./types/skra-ui-menu.d.ts",
107
+ "default": "./fesm2022/skra-ui-menu.mjs"
108
+ },
109
+ "./multi-select": {
110
+ "types": "./types/skra-ui-multi-select.d.ts",
111
+ "default": "./fesm2022/skra-ui-multi-select.mjs"
112
+ },
113
+ "./native-select": {
114
+ "types": "./types/skra-ui-native-select.d.ts",
115
+ "default": "./fesm2022/skra-ui-native-select.mjs"
116
+ },
117
+ "./popover": {
118
+ "types": "./types/skra-ui-popover.d.ts",
119
+ "default": "./fesm2022/skra-ui-popover.mjs"
120
+ },
121
+ "./progress": {
122
+ "types": "./types/skra-ui-progress.d.ts",
123
+ "default": "./fesm2022/skra-ui-progress.mjs"
124
+ },
125
+ "./radio": {
126
+ "types": "./types/skra-ui-radio.d.ts",
127
+ "default": "./fesm2022/skra-ui-radio.mjs"
128
+ },
129
+ "./rating-display": {
130
+ "types": "./types/skra-ui-rating-display.d.ts",
131
+ "default": "./fesm2022/skra-ui-rating-display.mjs"
132
+ },
133
+ "./select": {
134
+ "types": "./types/skra-ui-select.d.ts",
135
+ "default": "./fesm2022/skra-ui-select.mjs"
136
+ },
137
+ "./skeleton": {
138
+ "types": "./types/skra-ui-skeleton.d.ts",
139
+ "default": "./fesm2022/skra-ui-skeleton.mjs"
140
+ },
141
+ "./star-rating": {
142
+ "types": "./types/skra-ui-star-rating.d.ts",
143
+ "default": "./fesm2022/skra-ui-star-rating.mjs"
144
+ },
145
+ "./status-dot": {
146
+ "types": "./types/skra-ui-status-dot.d.ts",
147
+ "default": "./fesm2022/skra-ui-status-dot.mjs"
148
+ },
149
+ "./switch": {
150
+ "types": "./types/skra-ui-switch.d.ts",
151
+ "default": "./fesm2022/skra-ui-switch.mjs"
152
+ },
153
+ "./tabs": {
154
+ "types": "./types/skra-ui-tabs.d.ts",
155
+ "default": "./fesm2022/skra-ui-tabs.mjs"
156
+ },
157
+ "./textarea": {
158
+ "types": "./types/skra-ui-textarea.d.ts",
159
+ "default": "./fesm2022/skra-ui-textarea.mjs"
160
+ },
161
+ "./toast": {
162
+ "types": "./types/skra-ui-toast.d.ts",
163
+ "default": "./fesm2022/skra-ui-toast.mjs"
164
+ },
165
+ "./tooltip": {
166
+ "types": "./types/skra-ui-tooltip.d.ts",
167
+ "default": "./fesm2022/skra-ui-tooltip.mjs"
168
+ },
169
+ "./typography": {
170
+ "types": "./types/skra-ui-typography.d.ts",
171
+ "default": "./fesm2022/skra-ui-typography.mjs"
172
+ }
173
+ },
174
+ "type": "module"
175
+ }