@joanroucoux/cairn-ui 0.8.2 → 0.9.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (124) hide show
  1. package/CHANGELOG.md +114 -0
  2. package/fesm2022/joanroucoux-cairn-ui-action-bar.mjs +57 -53
  3. package/fesm2022/joanroucoux-cairn-ui-action-bar.mjs.map +1 -1
  4. package/fesm2022/joanroucoux-cairn-ui-alert.mjs +155 -47
  5. package/fesm2022/joanroucoux-cairn-ui-alert.mjs.map +1 -1
  6. package/fesm2022/joanroucoux-cairn-ui-amount.mjs +220 -110
  7. package/fesm2022/joanroucoux-cairn-ui-amount.mjs.map +1 -1
  8. package/fesm2022/joanroucoux-cairn-ui-async.mjs +392 -216
  9. package/fesm2022/joanroucoux-cairn-ui-async.mjs.map +1 -1
  10. package/fesm2022/joanroucoux-cairn-ui-avatar.mjs +145 -68
  11. package/fesm2022/joanroucoux-cairn-ui-avatar.mjs.map +1 -1
  12. package/fesm2022/joanroucoux-cairn-ui-back-link.mjs +87 -47
  13. package/fesm2022/joanroucoux-cairn-ui-back-link.mjs.map +1 -1
  14. package/fesm2022/joanroucoux-cairn-ui-badge.mjs +83 -43
  15. package/fesm2022/joanroucoux-cairn-ui-badge.mjs.map +1 -1
  16. package/fesm2022/joanroucoux-cairn-ui-button.mjs +184 -104
  17. package/fesm2022/joanroucoux-cairn-ui-button.mjs.map +1 -1
  18. package/fesm2022/joanroucoux-cairn-ui-card.mjs +232 -137
  19. package/fesm2022/joanroucoux-cairn-ui-card.mjs.map +1 -1
  20. package/fesm2022/joanroucoux-cairn-ui-choice-chips.mjs +298 -102
  21. package/fesm2022/joanroucoux-cairn-ui-choice-chips.mjs.map +1 -1
  22. package/fesm2022/joanroucoux-cairn-ui-control.mjs +4 -17
  23. package/fesm2022/joanroucoux-cairn-ui-control.mjs.map +1 -1
  24. package/fesm2022/joanroucoux-cairn-ui-delta.mjs +150 -83
  25. package/fesm2022/joanroucoux-cairn-ui-delta.mjs.map +1 -1
  26. package/fesm2022/joanroucoux-cairn-ui-dialog.mjs +508 -471
  27. package/fesm2022/joanroucoux-cairn-ui-dialog.mjs.map +1 -1
  28. package/fesm2022/joanroucoux-cairn-ui-donut.mjs +255 -157
  29. package/fesm2022/joanroucoux-cairn-ui-donut.mjs.map +1 -1
  30. package/fesm2022/joanroucoux-cairn-ui-drawer.mjs +303 -0
  31. package/fesm2022/joanroucoux-cairn-ui-drawer.mjs.map +1 -0
  32. package/fesm2022/joanroucoux-cairn-ui-empty.mjs +76 -35
  33. package/fesm2022/joanroucoux-cairn-ui-empty.mjs.map +1 -1
  34. package/fesm2022/joanroucoux-cairn-ui-external-link.mjs +40 -31
  35. package/fesm2022/joanroucoux-cairn-ui-external-link.mjs.map +1 -1
  36. package/fesm2022/joanroucoux-cairn-ui-fact.mjs +188 -79
  37. package/fesm2022/joanroucoux-cairn-ui-fact.mjs.map +1 -1
  38. package/fesm2022/joanroucoux-cairn-ui-field.mjs +309 -173
  39. package/fesm2022/joanroucoux-cairn-ui-field.mjs.map +1 -1
  40. package/fesm2022/joanroucoux-cairn-ui-filter-chips.mjs +165 -87
  41. package/fesm2022/joanroucoux-cairn-ui-filter-chips.mjs.map +1 -1
  42. package/fesm2022/joanroucoux-cairn-ui-group-header.mjs +269 -0
  43. package/fesm2022/joanroucoux-cairn-ui-group-header.mjs.map +1 -0
  44. package/fesm2022/joanroucoux-cairn-ui-input.mjs +205 -85
  45. package/fesm2022/joanroucoux-cairn-ui-input.mjs.map +1 -1
  46. package/fesm2022/joanroucoux-cairn-ui-line-chart.mjs +838 -512
  47. package/fesm2022/joanroucoux-cairn-ui-line-chart.mjs.map +1 -1
  48. package/fesm2022/joanroucoux-cairn-ui-menu.mjs +401 -225
  49. package/fesm2022/joanroucoux-cairn-ui-menu.mjs.map +1 -1
  50. package/fesm2022/joanroucoux-cairn-ui-meter.mjs +143 -57
  51. package/fesm2022/joanroucoux-cairn-ui-meter.mjs.map +1 -1
  52. package/fesm2022/joanroucoux-cairn-ui-motion.mjs +367 -399
  53. package/fesm2022/joanroucoux-cairn-ui-motion.mjs.map +1 -1
  54. package/fesm2022/joanroucoux-cairn-ui-nav-item.mjs +73 -44
  55. package/fesm2022/joanroucoux-cairn-ui-nav-item.mjs.map +1 -1
  56. package/fesm2022/joanroucoux-cairn-ui-result-group.mjs +191 -0
  57. package/fesm2022/joanroucoux-cairn-ui-result-group.mjs.map +1 -0
  58. package/fesm2022/joanroucoux-cairn-ui-row.mjs +408 -146
  59. package/fesm2022/joanroucoux-cairn-ui-row.mjs.map +1 -1
  60. package/fesm2022/joanroucoux-cairn-ui-segmented.mjs +183 -81
  61. package/fesm2022/joanroucoux-cairn-ui-segmented.mjs.map +1 -1
  62. package/fesm2022/joanroucoux-cairn-ui-select-pill.mjs +270 -0
  63. package/fesm2022/joanroucoux-cairn-ui-select-pill.mjs.map +1 -0
  64. package/fesm2022/joanroucoux-cairn-ui-select.mjs +121 -67
  65. package/fesm2022/joanroucoux-cairn-ui-select.mjs.map +1 -1
  66. package/fesm2022/joanroucoux-cairn-ui-skeleton.mjs +129 -51
  67. package/fesm2022/joanroucoux-cairn-ui-skeleton.mjs.map +1 -1
  68. package/fesm2022/joanroucoux-cairn-ui-stale-link.mjs +80 -39
  69. package/fesm2022/joanroucoux-cairn-ui-stale-link.mjs.map +1 -1
  70. package/fesm2022/joanroucoux-cairn-ui-stat.mjs +85 -55
  71. package/fesm2022/joanroucoux-cairn-ui-stat.mjs.map +1 -1
  72. package/fesm2022/joanroucoux-cairn-ui-switch.mjs +48 -35
  73. package/fesm2022/joanroucoux-cairn-ui-switch.mjs.map +1 -1
  74. package/fesm2022/joanroucoux-cairn-ui-tab-bar.mjs +113 -69
  75. package/fesm2022/joanroucoux-cairn-ui-tab-bar.mjs.map +1 -1
  76. package/fesm2022/joanroucoux-cairn-ui-table.mjs +1036 -310
  77. package/fesm2022/joanroucoux-cairn-ui-table.mjs.map +1 -1
  78. package/fesm2022/joanroucoux-cairn-ui-toast.mjs +240 -127
  79. package/fesm2022/joanroucoux-cairn-ui-toast.mjs.map +1 -1
  80. package/fesm2022/joanroucoux-cairn-ui.mjs +0 -4
  81. package/package.json +17 -1
  82. package/styles/motion.css +1 -13
  83. package/styles/tokens.css +35 -64
  84. package/types/joanroucoux-cairn-ui-action-bar.d.ts +9 -14
  85. package/types/joanroucoux-cairn-ui-alert.d.ts +29 -15
  86. package/types/joanroucoux-cairn-ui-amount.d.ts +64 -32
  87. package/types/joanroucoux-cairn-ui-async.d.ts +85 -38
  88. package/types/joanroucoux-cairn-ui-avatar.d.ts +34 -22
  89. package/types/joanroucoux-cairn-ui-back-link.d.ts +20 -15
  90. package/types/joanroucoux-cairn-ui-badge.d.ts +22 -14
  91. package/types/joanroucoux-cairn-ui-button.d.ts +36 -18
  92. package/types/joanroucoux-cairn-ui-card.d.ts +48 -23
  93. package/types/joanroucoux-cairn-ui-choice-chips.d.ts +91 -35
  94. package/types/joanroucoux-cairn-ui-control.d.ts +9 -18
  95. package/types/joanroucoux-cairn-ui-delta.d.ts +46 -24
  96. package/types/joanroucoux-cairn-ui-dialog.d.ts +124 -57
  97. package/types/joanroucoux-cairn-ui-donut.d.ts +83 -46
  98. package/types/joanroucoux-cairn-ui-drawer.d.ts +73 -0
  99. package/types/joanroucoux-cairn-ui-empty.d.ts +20 -13
  100. package/types/joanroucoux-cairn-ui-external-link.d.ts +6 -10
  101. package/types/joanroucoux-cairn-ui-fact.d.ts +49 -25
  102. package/types/joanroucoux-cairn-ui-field.d.ts +72 -49
  103. package/types/joanroucoux-cairn-ui-filter-chips.d.ts +35 -20
  104. package/types/joanroucoux-cairn-ui-group-header.d.ts +58 -0
  105. package/types/joanroucoux-cairn-ui-input.d.ts +59 -37
  106. package/types/joanroucoux-cairn-ui-line-chart.d.ts +199 -89
  107. package/types/joanroucoux-cairn-ui-menu.d.ts +81 -44
  108. package/types/joanroucoux-cairn-ui-meter.d.ts +44 -22
  109. package/types/joanroucoux-cairn-ui-motion.d.ts +61 -75
  110. package/types/joanroucoux-cairn-ui-nav-item.d.ts +15 -13
  111. package/types/joanroucoux-cairn-ui-result-group.d.ts +52 -0
  112. package/types/joanroucoux-cairn-ui-row.d.ts +92 -37
  113. package/types/joanroucoux-cairn-ui-segmented.d.ts +51 -27
  114. package/types/joanroucoux-cairn-ui-select-pill.d.ts +59 -0
  115. package/types/joanroucoux-cairn-ui-select.d.ts +28 -18
  116. package/types/joanroucoux-cairn-ui-skeleton.d.ts +35 -18
  117. package/types/joanroucoux-cairn-ui-stale-link.d.ts +23 -16
  118. package/types/joanroucoux-cairn-ui-stat.d.ts +26 -21
  119. package/types/joanroucoux-cairn-ui-switch.d.ts +7 -11
  120. package/types/joanroucoux-cairn-ui-tab-bar.d.ts +20 -17
  121. package/types/joanroucoux-cairn-ui-table.d.ts +251 -89
  122. package/types/joanroucoux-cairn-ui-toast.d.ts +46 -36
  123. package/types/joanroucoux-cairn-ui.d.ts +1 -2
  124. package/fesm2022/joanroucoux-cairn-ui.mjs.map +0 -1
@@ -1,73 +1,121 @@
1
- import * as i0 from '@angular/core';
2
- import { input, booleanAttribute, model, viewChildren, computed, Component } from '@angular/core';
3
- import { holdTransitionsUntilRendered } from '@joanroucoux/cairn-ui/motion';
4
-
1
+ import * as i0 from "@angular/core";
2
+ import { Component, booleanAttribute, computed, input, model, viewChildren } from "@angular/core";
3
+ import { holdTransitionsUntilRendered } from "@joanroucoux/cairn-ui/motion";
5
4
  const nextId = (() => {
6
- let count = 0;
7
- return () => `ui-segmented-${++count}`;
5
+ let count = 0;
6
+ return () => `ui-segmented-${++count}`;
8
7
  })();
9
8
  const OPTION_CLASSES = "relative z-10 flex-1 cursor-pointer px-3 text-label font-medium transition-[scale] duration-(--duration-press) ease-out after:absolute after:inset-x-0 after:top-1/2 after:h-(--row-min) after:-translate-y-1/2 after:content-[''] focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-(--ring) active:scale-(--press-scale)";
10
- const SEGMENTED_SIZES = ['md', 'sm'];
9
+ const SEGMENTED_SIZES = ["md", "sm"];
11
10
  const SIZE_CLASSES = {
12
- md: 'h-10 pointer-fine:h-8',
13
- sm: 'h-10 pointer-fine:h-[30px]',
11
+ md: "h-10 pointer-fine:h-8",
12
+ sm: "h-10 pointer-fine:h-[30px]"
14
13
  };
15
- const SELECTED_CLASSES = 'text-(--foreground)';
16
- const UNSELECTED_CLASSES = 'text-(--muted-foreground) hover:text-(--foreground)';
17
- /**
18
- * Exclusive choice within a small, known set: a time range, a unit, a mode. The selected option's
19
- * background is a single thumb that slides under it in `transform`, instead of being redrawn.
20
- *
21
- * @example
22
- * <ui-segmented [options]="ranges" label="Time range" [(value)]="range" />
23
- */
24
- class UiSegmented {
25
- options = input.required(/* @ts-ignore */
26
- ...(ngDevMode ? [{ debugName: "options" }] : /* istanbul ignore next */ []));
27
- label = input.required(/* @ts-ignore */
28
- ...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
29
- showLabel = input(false, { ...(ngDevMode ? { debugName: "showLabel" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
30
- labelId = nextId();
31
- value = model.required(/* @ts-ignore */
32
- ...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
33
- size = input('md', /* @ts-ignore */
34
- ...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
35
- radios = viewChildren('radio', /* @ts-ignore */
36
- ...(ngDevMode ? [{ debugName: "radios" }] : /* istanbul ignore next */ []));
37
- thumbIndex = computed(() => {
38
- const index = this.options().findIndex((option) => option.value === this.value());
39
- return index === -1 ? 0 : index + 1;
40
- }, /* @ts-ignore */
41
- ...(ngDevMode ? [{ debugName: "thumbIndex" }] : /* istanbul ignore next */ []));
42
- constructor() {
43
- holdTransitionsUntilRendered();
44
- }
45
- optionClasses(optionValue) {
46
- return `${OPTION_CLASSES} ${SIZE_CLASSES[this.size()]} ${optionValue === this.value() ? SELECTED_CLASSES : UNSELECTED_CLASSES}`;
47
- }
48
- tabIndexFor(optionValue) {
49
- const opts = this.options();
50
- const tabStopValue = opts.some((option) => option.value === this.value()) ? this.value() : opts[0]?.value;
51
- return optionValue === tabStopValue ? 0 : -1;
52
- }
53
- select(optionValue) {
54
- this.value.set(optionValue);
55
- }
56
- onKeydown(event) {
57
- const delta = { ArrowRight: 1, ArrowDown: 1, ArrowLeft: -1, ArrowUp: -1 }[event.key];
58
- if (delta === undefined) {
59
- return;
60
- }
61
- event.preventDefault();
62
- const opts = this.options();
63
- const currentIndex = opts.findIndex((option) => option.value === this.value());
64
- const nextIndex = (currentIndex + delta + opts.length) % opts.length;
65
- const next = opts[nextIndex];
66
- this.value.set(next.value);
67
- this.radios()[nextIndex]?.nativeElement.focus();
68
- }
69
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: UiSegmented, deps: [], target: i0.ɵɵFactoryTarget.Component });
70
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.7", type: UiSegmented, isStandalone: true, selector: "ui-segmented", inputs: { options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: true, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: true, transformFunction: null }, showLabel: { classPropertyName: "showLabel", publicName: "showLabel", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: true, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange" }, viewQueries: [{ propertyName: "radios", predicate: ["radio"], descendants: true, isSignal: true }], ngImport: i0, template: `
14
+ const SELECTED_CLASSES = "text-(--foreground)";
15
+ const UNSELECTED_CLASSES = "text-(--muted-foreground) hover:text-(--foreground)";
16
+ var UiSegmented = class UiSegmented {
17
+ options = input.required(...ngDevMode ? [{ debugName: "options" }] : /* istanbul ignore next */ []);
18
+ label = input.required(...ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []);
19
+ showLabel = input(false, {
20
+ ...ngDevMode ? { debugName: "showLabel" } : /* istanbul ignore next */ {},
21
+ transform: booleanAttribute
22
+ });
23
+ labelId = nextId();
24
+ value = model.required(...ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []);
25
+ size = input("md", ...ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []);
26
+ radios = viewChildren("radio", ...ngDevMode ? [{ debugName: "radios" }] : /* istanbul ignore next */ []);
27
+ thumbIndex = computed(() => {
28
+ const index = this.options().findIndex((option) => option.value === this.value());
29
+ return index === -1 ? 0 : index + 1;
30
+ }, ...ngDevMode ? [{ debugName: "thumbIndex" }] : /* istanbul ignore next */ []);
31
+ constructor() {
32
+ holdTransitionsUntilRendered();
33
+ }
34
+ optionClasses(optionValue) {
35
+ return `${OPTION_CLASSES} ${SIZE_CLASSES[this.size()]} ${optionValue === this.value() ? SELECTED_CLASSES : UNSELECTED_CLASSES}`;
36
+ }
37
+ tabIndexFor(optionValue) {
38
+ const opts = this.options();
39
+ return optionValue === (opts.some((option) => option.value === this.value()) ? this.value() : opts[0]?.value) ? 0 : -1;
40
+ }
41
+ select(optionValue) {
42
+ this.value.set(optionValue);
43
+ }
44
+ onKeydown(event) {
45
+ const delta = {
46
+ ArrowRight: 1,
47
+ ArrowDown: 1,
48
+ ArrowLeft: -1,
49
+ ArrowUp: -1
50
+ }[event.key];
51
+ if (delta === void 0) return;
52
+ event.preventDefault();
53
+ const opts = this.options();
54
+ const nextIndex = (opts.findIndex((option) => option.value === this.value()) + delta + opts.length) % opts.length;
55
+ const next = opts[nextIndex];
56
+ this.value.set(next.value);
57
+ this.radios()[nextIndex]?.nativeElement.focus();
58
+ }
59
+ static ɵfac = i0.ɵɵngDeclareFactory({
60
+ minVersion: "12.0.0",
61
+ version: "22.2.0",
62
+ ngImport: i0,
63
+ type: UiSegmented,
64
+ deps: [],
65
+ target: i0.ɵɵFactoryTarget.Component
66
+ });
67
+ static ɵcmp = i0.ɵɵngDeclareComponent({
68
+ minVersion: "17.0.0",
69
+ version: "22.2.0",
70
+ type: UiSegmented,
71
+ isStandalone: true,
72
+ selector: "ui-segmented",
73
+ inputs: {
74
+ options: {
75
+ classPropertyName: "options",
76
+ publicName: "options",
77
+ isSignal: true,
78
+ isRequired: true,
79
+ transformFunction: null
80
+ },
81
+ label: {
82
+ classPropertyName: "label",
83
+ publicName: "label",
84
+ isSignal: true,
85
+ isRequired: true,
86
+ transformFunction: null
87
+ },
88
+ showLabel: {
89
+ classPropertyName: "showLabel",
90
+ publicName: "showLabel",
91
+ isSignal: true,
92
+ isRequired: false,
93
+ transformFunction: null
94
+ },
95
+ value: {
96
+ classPropertyName: "value",
97
+ publicName: "value",
98
+ isSignal: true,
99
+ isRequired: true,
100
+ transformFunction: null
101
+ },
102
+ size: {
103
+ classPropertyName: "size",
104
+ publicName: "size",
105
+ isSignal: true,
106
+ isRequired: false,
107
+ transformFunction: null
108
+ }
109
+ },
110
+ outputs: { value: "valueChange" },
111
+ viewQueries: [{
112
+ propertyName: "radios",
113
+ predicate: ["radio"],
114
+ descendants: true,
115
+ isSignal: true
116
+ }],
117
+ ngImport: i0,
118
+ template: `
71
119
  <div [class]="showLabel() ? 'flex flex-col gap-1.5' : ''">
72
120
  @if (showLabel()) {
73
121
  <span class="text-label leading-[17px] font-medium text-(--muted-foreground)" [id]="labelId">{{
@@ -107,13 +155,20 @@ class UiSegmented {
107
155
  }
108
156
  </div>
109
157
  </div>
110
- `, isInline: true });
111
- }
112
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: UiSegmented, decorators: [{
113
- type: Component,
114
- args: [{
115
- selector: 'ui-segmented',
116
- template: `
158
+ `,
159
+ isInline: true
160
+ });
161
+ };
162
+ i0.ɵɵngDeclareClassMetadata({
163
+ minVersion: "12.0.0",
164
+ version: "22.2.0",
165
+ ngImport: i0,
166
+ type: UiSegmented,
167
+ decorators: [{
168
+ type: Component,
169
+ args: [{
170
+ selector: "ui-segmented",
171
+ template: `
117
172
  <div [class]="showLabel() ? 'flex flex-col gap-1.5' : ''">
118
173
  @if (showLabel()) {
119
174
  <span class="text-label leading-[17px] font-medium text-(--muted-foreground)" [id]="labelId">{{
@@ -153,13 +208,60 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImpor
153
208
  }
154
209
  </div>
155
210
  </div>
156
- `,
157
- }]
158
- }], ctorParameters: () => [], propDecorators: { options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: true }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: true }] }], showLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "showLabel", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: true }] }, { type: i0.Output, args: ["valueChange"] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], radios: [{ type: i0.ViewChildren, args: ['radio', { isSignal: true }] }] } });
159
-
160
- /**
161
- * Generated bundle index. Do not edit.
162
- */
163
-
211
+ `
212
+ }]
213
+ }],
214
+ ctorParameters: () => [],
215
+ propDecorators: {
216
+ options: [{
217
+ type: i0.Input,
218
+ args: [{
219
+ isSignal: true,
220
+ alias: "options",
221
+ required: true
222
+ }]
223
+ }],
224
+ label: [{
225
+ type: i0.Input,
226
+ args: [{
227
+ isSignal: true,
228
+ alias: "label",
229
+ required: true
230
+ }]
231
+ }],
232
+ showLabel: [{
233
+ type: i0.Input,
234
+ args: [{
235
+ isSignal: true,
236
+ alias: "showLabel",
237
+ required: false
238
+ }]
239
+ }],
240
+ value: [{
241
+ type: i0.Input,
242
+ args: [{
243
+ isSignal: true,
244
+ alias: "value",
245
+ required: true
246
+ }]
247
+ }, {
248
+ type: i0.Output,
249
+ args: ["valueChange"]
250
+ }],
251
+ size: [{
252
+ type: i0.Input,
253
+ args: [{
254
+ isSignal: true,
255
+ alias: "size",
256
+ required: false
257
+ }]
258
+ }],
259
+ radios: [{
260
+ type: i0.ViewChildren,
261
+ args: ["radio", { isSignal: true }]
262
+ }]
263
+ }
264
+ });
164
265
  export { SEGMENTED_SIZES, UiSegmented };
165
- //# sourceMappingURL=joanroucoux-cairn-ui-segmented.mjs.map
266
+
267
+ //# sourceMappingURL=joanroucoux-cairn-ui-segmented.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"joanroucoux-cairn-ui-segmented.mjs","sources":["../../../projects/ui/segmented/segmented.ts","../../../projects/ui/segmented/joanroucoux-cairn-ui-segmented.ts"],"sourcesContent":["import { Component, ElementRef, booleanAttribute, computed, input, model, viewChildren } from '@angular/core';\n\nimport { holdTransitionsUntilRendered } from '@joanroucoux/cairn-ui/motion';\n\nconst nextId = (() => {\n let count = 0;\n\n return () => `ui-segmented-${++count}`;\n})();\n\nexport type SegmentedOption = {\n value: string;\n label: string;\n};\n\nconst OPTION_CLASSES =\n \"relative z-10 flex-1 cursor-pointer px-3 text-label font-medium transition-[scale] duration-(--duration-press) ease-out after:absolute after:inset-x-0 after:top-1/2 after:h-(--row-min) after:-translate-y-1/2 after:content-[''] focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-(--ring) active:scale-(--press-scale)\";\n\nexport const SEGMENTED_SIZES = ['md', 'sm'] as const;\nexport type SegmentedSize = (typeof SEGMENTED_SIZES)[number];\n\nconst SIZE_CLASSES: Record<SegmentedSize, string> = {\n md: 'h-10 pointer-fine:h-8',\n sm: 'h-10 pointer-fine:h-[30px]',\n};\n\nconst SELECTED_CLASSES = 'text-(--foreground)';\n\nconst UNSELECTED_CLASSES = 'text-(--muted-foreground) hover:text-(--foreground)';\n\n/**\n * Exclusive choice within a small, known set: a time range, a unit, a mode. The selected option's\n * background is a single thumb that slides under it in `transform`, instead of being redrawn.\n *\n * @example\n * <ui-segmented [options]=\"ranges\" label=\"Time range\" [(value)]=\"range\" />\n */\n@Component({\n selector: 'ui-segmented',\n template: `\n <div [class]=\"showLabel() ? 'flex flex-col gap-1.5' : ''\">\n @if (showLabel()) {\n <span class=\"text-label leading-[17px] font-medium text-(--muted-foreground)\" [id]=\"labelId\">{{\n label()\n }}</span>\n }\n <div\n class=\"rounded-control relative grid bg-(--muted) p-0.5\"\n role=\"radiogroup\"\n [attr.aria-label]=\"showLabel() ? null : label()\"\n [attr.aria-labelledby]=\"showLabel() ? labelId : null\"\n [style.grid-template-columns]=\"'repeat(' + options().length + ', 1fr)'\"\n >\n @if (thumbIndex(); as index) {\n <span\n aria-hidden=\"true\"\n class=\"absolute top-0.5 bottom-0.5 left-0.5 rounded-[calc(var(--radius-control)-2px)] bg-(--card) shadow-[0_1px_2px_rgb(0_0_0/0.08),inset_0_0_0_1px_var(--border)] transition-transform duration-(--duration-fast) ease-out\"\n data-thumb\n [style.transform]=\"'translateX(' + (index - 1) * 100 + '%)'\"\n [style.width]=\"'calc((100% - 4px) / ' + options().length + ')'\"\n ></span>\n }\n\n @for (option of options(); track option.value) {\n <button\n #radio\n role=\"radio\"\n type=\"button\"\n [attr.aria-checked]=\"option.value === value()\"\n [attr.tabindex]=\"tabIndexFor(option.value)\"\n [class]=\"optionClasses(option.value)\"\n (click)=\"select(option.value)\"\n (keydown)=\"onKeydown($event)\"\n >\n {{ option.label }}\n </button>\n }\n </div>\n </div>\n `,\n})\nexport class UiSegmented {\n readonly options = input.required<SegmentedOption[]>();\n readonly label = input.required<string>();\n readonly showLabel = input(false, { transform: booleanAttribute });\n\n protected readonly labelId = nextId();\n readonly value = model.required<string>();\n readonly size = input<SegmentedSize>('md');\n\n protected readonly radios = viewChildren<ElementRef<HTMLButtonElement>>('radio');\n\n protected readonly thumbIndex = computed(() => {\n const index = this.options().findIndex((option) => option.value === this.value());\n\n return index === -1 ? 0 : index + 1;\n });\n\n constructor() {\n holdTransitionsUntilRendered();\n }\n\n protected optionClasses(optionValue: string): string {\n return `${OPTION_CLASSES} ${SIZE_CLASSES[this.size()]} ${optionValue === this.value() ? SELECTED_CLASSES : UNSELECTED_CLASSES}`;\n }\n\n protected tabIndexFor(optionValue: string): number {\n const opts = this.options();\n const tabStopValue = opts.some((option) => option.value === this.value()) ? this.value() : opts[0]?.value;\n\n return optionValue === tabStopValue ? 0 : -1;\n }\n\n protected select(optionValue: string): void {\n this.value.set(optionValue);\n }\n\n protected onKeydown(event: KeyboardEvent): void {\n const delta = { ArrowRight: 1, ArrowDown: 1, ArrowLeft: -1, ArrowUp: -1 }[event.key];\n if (delta === undefined) {\n return;\n }\n event.preventDefault();\n\n const opts = this.options();\n const currentIndex = opts.findIndex((option) => option.value === this.value());\n const nextIndex = (currentIndex + delta + opts.length) % opts.length;\n const next = opts[nextIndex]!;\n\n this.value.set(next.value);\n this.radios()[nextIndex]?.nativeElement.focus();\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"joanroucoux-cairn-ui-segmented.mjs","names":[],"sources":["../../../projects/ui/segmented/segmented.ts"],"sourcesContent":["import { Component, ElementRef, booleanAttribute, computed, input, model, viewChildren } from '@angular/core';\n\nimport { holdTransitionsUntilRendered } from '@joanroucoux/cairn-ui/motion';\n\nconst nextId = (() => {\n let count = 0;\n\n return () => `ui-segmented-${++count}`;\n})();\n\nexport type SegmentedOption = {\n value: string;\n label: string;\n};\n\nconst OPTION_CLASSES =\n \"relative z-10 flex-1 cursor-pointer px-3 text-label font-medium transition-[scale] duration-(--duration-press) ease-out after:absolute after:inset-x-0 after:top-1/2 after:h-(--row-min) after:-translate-y-1/2 after:content-[''] focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-(--ring) active:scale-(--press-scale)\";\n\nexport const SEGMENTED_SIZES = ['md', 'sm'] as const;\nexport type SegmentedSize = (typeof SEGMENTED_SIZES)[number];\n\nconst SIZE_CLASSES: Record<SegmentedSize, string> = {\n md: 'h-10 pointer-fine:h-8',\n sm: 'h-10 pointer-fine:h-[30px]',\n};\n\nconst SELECTED_CLASSES = 'text-(--foreground)';\n\nconst UNSELECTED_CLASSES = 'text-(--muted-foreground) hover:text-(--foreground)';\n\n/**\n * Exclusive choice within a small, known set: a time range, a unit, a mode.\n *\n * @example\n * <ui-segmented [options]=\"ranges\" label=\"Time range\" [(value)]=\"range\" />\n */\n@Component({\n selector: 'ui-segmented',\n template: `\n <div [class]=\"showLabel() ? 'flex flex-col gap-1.5' : ''\">\n @if (showLabel()) {\n <span class=\"text-label leading-[17px] font-medium text-(--muted-foreground)\" [id]=\"labelId\">{{\n label()\n }}</span>\n }\n <div\n class=\"rounded-control relative grid bg-(--muted) p-0.5\"\n role=\"radiogroup\"\n [attr.aria-label]=\"showLabel() ? null : label()\"\n [attr.aria-labelledby]=\"showLabel() ? labelId : null\"\n [style.grid-template-columns]=\"'repeat(' + options().length + ', 1fr)'\"\n >\n @if (thumbIndex(); as index) {\n <span\n aria-hidden=\"true\"\n class=\"absolute top-0.5 bottom-0.5 left-0.5 rounded-[calc(var(--radius-control)-2px)] bg-(--card) shadow-[0_1px_2px_rgb(0_0_0/0.08),inset_0_0_0_1px_var(--border)] transition-transform duration-(--duration-fast) ease-out\"\n data-thumb\n [style.transform]=\"'translateX(' + (index - 1) * 100 + '%)'\"\n [style.width]=\"'calc((100% - 4px) / ' + options().length + ')'\"\n ></span>\n }\n\n @for (option of options(); track option.value) {\n <button\n #radio\n role=\"radio\"\n type=\"button\"\n [attr.aria-checked]=\"option.value === value()\"\n [attr.tabindex]=\"tabIndexFor(option.value)\"\n [class]=\"optionClasses(option.value)\"\n (click)=\"select(option.value)\"\n (keydown)=\"onKeydown($event)\"\n >\n {{ option.label }}\n </button>\n }\n </div>\n </div>\n `,\n})\nexport class UiSegmented {\n readonly options = input.required<SegmentedOption[]>();\n readonly label = input.required<string>();\n readonly showLabel = input(false, { transform: booleanAttribute });\n\n protected readonly labelId = nextId();\n readonly value = model.required<string>();\n readonly size = input<SegmentedSize>('md');\n\n protected readonly radios = viewChildren<ElementRef<HTMLButtonElement>>('radio');\n\n protected readonly thumbIndex = computed(() => {\n const index = this.options().findIndex((option) => option.value === this.value());\n\n return index === -1 ? 0 : index + 1;\n });\n\n constructor() {\n holdTransitionsUntilRendered();\n }\n\n protected optionClasses(optionValue: string): string {\n return `${OPTION_CLASSES} ${SIZE_CLASSES[this.size()]} ${optionValue === this.value() ? SELECTED_CLASSES : UNSELECTED_CLASSES}`;\n }\n\n protected tabIndexFor(optionValue: string): number {\n const opts = this.options();\n const tabStopValue = opts.some((option) => option.value === this.value()) ? this.value() : opts[0]?.value;\n\n return optionValue === tabStopValue ? 0 : -1;\n }\n\n protected select(optionValue: string): void {\n this.value.set(optionValue);\n }\n\n protected onKeydown(event: KeyboardEvent): void {\n const delta = { ArrowRight: 1, ArrowDown: 1, ArrowLeft: -1, ArrowUp: -1 }[event.key];\n if (delta === undefined) {\n return;\n }\n event.preventDefault();\n\n const opts = this.options();\n const currentIndex = opts.findIndex((option) => option.value === this.value());\n const nextIndex = (currentIndex + delta + opts.length) % opts.length;\n const next = opts[nextIndex]!;\n\n this.value.set(next.value);\n this.radios()[nextIndex]?.nativeElement.focus();\n }\n}\n"],"mappings":"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"}
@@ -0,0 +1,270 @@
1
+ import * as i0 from "@angular/core";
2
+ import { Component, booleanAttribute, computed, contentChild, input, output, viewChild } from "@angular/core";
3
+ import { UiMenu, UiMenuTrigger } from "@joanroucoux/cairn-ui/menu";
4
+ const HOST_CLASSES = "relative flex-none inline-flex h-11 items-center pointer-fine:h-8";
5
+ const DISABLED_HOST_CLASSES = "opacity-40";
6
+ const TRIGGER_CLASSES = "-mx-[5px] flex h-11 cursor-pointer items-center rounded-pill border-x-[5px] border-y-0 border-transparent bg-transparent p-0 font-[inherit] focus-visible:outline-2 focus-visible:-outline-offset-5 focus-visible:outline-(--ring) pointer-fine:mx-0 pointer-fine:h-8 pointer-fine:border-x-0 pointer-fine:focus-visible:outline-offset-0 disabled:pointer-events-none";
7
+ const PILL_CLASSES = "flex h-[34px] items-center rounded-pill pr-[30px] pl-3 text-label font-medium whitespace-nowrap forced-colors:border pointer-fine:h-8";
8
+ const REST_PILL_CLASSES = "bg-(--card) text-(--foreground) shadow-[inset_0_0_0_1px_var(--border)]";
9
+ const ACTIVE_PILL_CLASSES = "bg-(--primary) text-(--primary-foreground)";
10
+ const CLEAR_CLASSES = "absolute end-0 flex size-[34px] cursor-pointer items-center justify-center rounded-pill border-0 bg-transparent p-0 text-(--primary-foreground) focus-visible:outline-2 focus-visible:-outline-offset-7 focus-visible:outline-(--primary-foreground) pointer-fine:size-8 pointer-fine:focus-visible:-outline-offset-6 after:absolute after:-inset-[5px] pointer-fine:after:-inset-0.5";
11
+ var UiSelectPill = class UiSelectPill {
12
+ active = input(false, {
13
+ ...ngDevMode ? { debugName: "active" } : /* istanbul ignore next */ {},
14
+ transform: booleanAttribute
15
+ });
16
+ disabled = input(false, {
17
+ ...ngDevMode ? { debugName: "disabled" } : /* istanbul ignore next */ {},
18
+ transform: booleanAttribute
19
+ });
20
+ clearLabel = input.required(...ngDevMode ? [{ debugName: "clearLabel" }] : /* istanbul ignore next */ []);
21
+ contextLabel = input(...ngDevMode ? [void 0, { debugName: "contextLabel" }] : /* istanbul ignore next */ []);
22
+ cleared = output();
23
+ menu = contentChild.required(UiMenu, ...ngDevMode ? [{ debugName: "menu" }] : /* istanbul ignore next */ []);
24
+ trigger = viewChild.required("trigger", ...ngDevMode ? [{ debugName: "trigger" }] : /* istanbul ignore next */ []);
25
+ hostClasses = computed(() => this.disabled() ? `${HOST_CLASSES} ${DISABLED_HOST_CLASSES}` : HOST_CLASSES, ...ngDevMode ? [{ debugName: "hostClasses" }] : /* istanbul ignore next */ []);
26
+ chevronClasses = computed(() => this.active() ? "text-(--primary-foreground)" : "text-(--foreground)", ...ngDevMode ? [{ debugName: "chevronClasses" }] : /* istanbul ignore next */ []);
27
+ triggerClasses = TRIGGER_CLASSES;
28
+ clearClasses = CLEAR_CLASSES;
29
+ clear() {
30
+ this.cleared.emit();
31
+ this.trigger().nativeElement.focus();
32
+ }
33
+ pillClasses = computed(() => `${PILL_CLASSES} ${this.active() ? ACTIVE_PILL_CLASSES : REST_PILL_CLASSES}`, ...ngDevMode ? [{ debugName: "pillClasses" }] : /* istanbul ignore next */ []);
34
+ static ɵfac = i0.ɵɵngDeclareFactory({
35
+ minVersion: "12.0.0",
36
+ version: "22.2.0",
37
+ ngImport: i0,
38
+ type: UiSelectPill,
39
+ deps: [],
40
+ target: i0.ɵɵFactoryTarget.Component
41
+ });
42
+ static ɵcmp = i0.ɵɵngDeclareComponent({
43
+ minVersion: "17.0.0",
44
+ version: "22.2.0",
45
+ type: UiSelectPill,
46
+ isStandalone: true,
47
+ selector: "ui-select-pill",
48
+ inputs: {
49
+ active: {
50
+ classPropertyName: "active",
51
+ publicName: "active",
52
+ isSignal: true,
53
+ isRequired: false,
54
+ transformFunction: null
55
+ },
56
+ disabled: {
57
+ classPropertyName: "disabled",
58
+ publicName: "disabled",
59
+ isSignal: true,
60
+ isRequired: false,
61
+ transformFunction: null
62
+ },
63
+ clearLabel: {
64
+ classPropertyName: "clearLabel",
65
+ publicName: "clearLabel",
66
+ isSignal: true,
67
+ isRequired: true,
68
+ transformFunction: null
69
+ },
70
+ contextLabel: {
71
+ classPropertyName: "contextLabel",
72
+ publicName: "contextLabel",
73
+ isSignal: true,
74
+ isRequired: false,
75
+ transformFunction: null
76
+ }
77
+ },
78
+ outputs: { cleared: "cleared" },
79
+ host: { properties: { "class": "hostClasses()" } },
80
+ queries: [{
81
+ propertyName: "menu",
82
+ first: true,
83
+ predicate: UiMenu,
84
+ descendants: true,
85
+ isSignal: true
86
+ }],
87
+ viewQueries: [{
88
+ propertyName: "trigger",
89
+ first: true,
90
+ predicate: ["trigger"],
91
+ descendants: true,
92
+ isSignal: true
93
+ }],
94
+ ngImport: i0,
95
+ template: `
96
+ <button
97
+ #trigger
98
+ type="button"
99
+ [attr.aria-disabled]="disabled() || null"
100
+ [class]="triggerClasses"
101
+ [disabled]="disabled()"
102
+ [uiMenuTrigger]="menu()"
103
+ >
104
+ <span data-pill [class]="pillClasses()">
105
+ @if (active() && contextLabel()) {
106
+ <span class="sr-only">{{ contextLabel() }} </span>
107
+ }
108
+ <ng-content
109
+ /></span>
110
+ </button>
111
+ @if (active() && !disabled()) {
112
+ <button data-clear type="button" [attr.aria-label]="clearLabel()" [class]="clearClasses" (click)="clear()">
113
+ <svg
114
+ aria-hidden="true"
115
+ fill="none"
116
+ height="14"
117
+ stroke="currentColor"
118
+ stroke-linecap="round"
119
+ stroke-linejoin="round"
120
+ stroke-width="2"
121
+ viewBox="0 0 24 24"
122
+ width="14"
123
+ >
124
+ <path d="M18 6 6 18M6 6l12 12" />
125
+ </svg>
126
+ </button>
127
+ } @else {
128
+ <svg
129
+ aria-hidden="true"
130
+ class="pointer-events-none absolute right-2.5"
131
+ data-chevron
132
+ fill="none"
133
+ height="14"
134
+ stroke="currentColor"
135
+ stroke-linecap="round"
136
+ stroke-linejoin="round"
137
+ stroke-width="2"
138
+ viewBox="0 0 24 24"
139
+ width="14"
140
+ [class]="chevronClasses()"
141
+ >
142
+ <path d="m6 9 6 6 6-6" />
143
+ </svg>
144
+ }
145
+ <ng-content select="ui-menu" />
146
+ `,
147
+ isInline: true,
148
+ dependencies: [{
149
+ kind: "directive",
150
+ type: UiMenuTrigger,
151
+ selector: "[uiMenuTrigger]",
152
+ inputs: ["uiMenuTrigger"]
153
+ }]
154
+ });
155
+ };
156
+ i0.ɵɵngDeclareClassMetadata({
157
+ minVersion: "12.0.0",
158
+ version: "22.2.0",
159
+ ngImport: i0,
160
+ type: UiSelectPill,
161
+ decorators: [{
162
+ type: Component,
163
+ args: [{
164
+ selector: "ui-select-pill",
165
+ imports: [UiMenuTrigger],
166
+ template: `
167
+ <button
168
+ #trigger
169
+ type="button"
170
+ [attr.aria-disabled]="disabled() || null"
171
+ [class]="triggerClasses"
172
+ [disabled]="disabled()"
173
+ [uiMenuTrigger]="menu()"
174
+ >
175
+ <span data-pill [class]="pillClasses()">
176
+ @if (active() && contextLabel()) {
177
+ <span class="sr-only">{{ contextLabel() }} </span>
178
+ }
179
+ <ng-content
180
+ /></span>
181
+ </button>
182
+ @if (active() && !disabled()) {
183
+ <button data-clear type="button" [attr.aria-label]="clearLabel()" [class]="clearClasses" (click)="clear()">
184
+ <svg
185
+ aria-hidden="true"
186
+ fill="none"
187
+ height="14"
188
+ stroke="currentColor"
189
+ stroke-linecap="round"
190
+ stroke-linejoin="round"
191
+ stroke-width="2"
192
+ viewBox="0 0 24 24"
193
+ width="14"
194
+ >
195
+ <path d="M18 6 6 18M6 6l12 12" />
196
+ </svg>
197
+ </button>
198
+ } @else {
199
+ <svg
200
+ aria-hidden="true"
201
+ class="pointer-events-none absolute right-2.5"
202
+ data-chevron
203
+ fill="none"
204
+ height="14"
205
+ stroke="currentColor"
206
+ stroke-linecap="round"
207
+ stroke-linejoin="round"
208
+ stroke-width="2"
209
+ viewBox="0 0 24 24"
210
+ width="14"
211
+ [class]="chevronClasses()"
212
+ >
213
+ <path d="m6 9 6 6 6-6" />
214
+ </svg>
215
+ }
216
+ <ng-content select="ui-menu" />
217
+ `,
218
+ host: { "[class]": "hostClasses()" }
219
+ }]
220
+ }],
221
+ propDecorators: {
222
+ active: [{
223
+ type: i0.Input,
224
+ args: [{
225
+ isSignal: true,
226
+ alias: "active",
227
+ required: false
228
+ }]
229
+ }],
230
+ disabled: [{
231
+ type: i0.Input,
232
+ args: [{
233
+ isSignal: true,
234
+ alias: "disabled",
235
+ required: false
236
+ }]
237
+ }],
238
+ clearLabel: [{
239
+ type: i0.Input,
240
+ args: [{
241
+ isSignal: true,
242
+ alias: "clearLabel",
243
+ required: true
244
+ }]
245
+ }],
246
+ contextLabel: [{
247
+ type: i0.Input,
248
+ args: [{
249
+ isSignal: true,
250
+ alias: "contextLabel",
251
+ required: false
252
+ }]
253
+ }],
254
+ cleared: [{
255
+ type: i0.Output,
256
+ args: ["cleared"]
257
+ }],
258
+ menu: [{
259
+ type: i0.ContentChild,
260
+ args: [i0.forwardRef(() => UiMenu), { isSignal: true }]
261
+ }],
262
+ trigger: [{
263
+ type: i0.ViewChild,
264
+ args: ["trigger", { isSignal: true }]
265
+ }]
266
+ }
267
+ });
268
+ export { UiSelectPill };
269
+
270
+ //# sourceMappingURL=joanroucoux-cairn-ui-select-pill.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"joanroucoux-cairn-ui-select-pill.mjs","names":[],"sources":["../../../projects/ui/select-pill/select-pill.ts"],"sourcesContent":["import {\n Component,\n ElementRef,\n booleanAttribute,\n computed,\n contentChild,\n input,\n output,\n viewChild,\n} from '@angular/core';\n\nimport { UiMenu, UiMenuTrigger } from '@joanroucoux/cairn-ui/menu';\n\nconst HOST_CLASSES = 'relative flex-none inline-flex h-11 items-center pointer-fine:h-8';\n\nconst DISABLED_HOST_CLASSES = 'opacity-40';\n\nconst TRIGGER_CLASSES =\n '-mx-[5px] flex h-11 cursor-pointer items-center rounded-pill border-x-[5px] border-y-0 border-transparent bg-transparent p-0 font-[inherit] focus-visible:outline-2 focus-visible:-outline-offset-5 focus-visible:outline-(--ring) pointer-fine:mx-0 pointer-fine:h-8 pointer-fine:border-x-0 pointer-fine:focus-visible:outline-offset-0 disabled:pointer-events-none';\n\nconst PILL_CLASSES =\n 'flex h-[34px] items-center rounded-pill pr-[30px] pl-3 text-label font-medium whitespace-nowrap forced-colors:border pointer-fine:h-8';\n\nconst REST_PILL_CLASSES = 'bg-(--card) text-(--foreground) shadow-[inset_0_0_0_1px_var(--border)]';\n\nconst ACTIVE_PILL_CLASSES = 'bg-(--primary) text-(--primary-foreground)';\n\nconst CLEAR_CLASSES =\n 'absolute end-0 flex size-[34px] cursor-pointer items-center justify-center rounded-pill border-0 bg-transparent p-0 text-(--primary-foreground) focus-visible:outline-2 focus-visible:-outline-offset-7 focus-visible:outline-(--primary-foreground) pointer-fine:size-8 pointer-fine:focus-visible:-outline-offset-6 after:absolute after:-inset-[5px] pointer-fine:after:-inset-0.5';\n\n/**\n * A pill that opens a `ui-menu` of exclusive choices, to head a row of filter chips: outlined at rest with a\n * chevron, solid primary when `active`, where a separate 14 px cross replaces the chevron and emits `cleared`.\n * It is 34 px tall inside a 44 px target on touch and 32 px with a fine pointer; its focus ring is an outline\n * 2 px outside the pill; the cross has a 44 px hit area on touch (36 px with a fine pointer). `contextLabel`, when\n * given, is read before the label while active so a screen reader hears what the account is. Clearing moves focus\n * back to the trigger. `disabled` dims it like a disabled button, opens nothing and draws the chevron even when `active`. The projected text is the pill label and the projected `ui-menu` is what it opens.\n *\n * @example\n * <ui-select-pill uiChipsLeading [active]=\"!!account()\" clearLabel=\"Clear the account\" (cleared)=\"account.set('')\">\n * {{ accountName() }}\n * <ui-menu label=\"Account\" sheet>\n * <button uiMenuItem [checked]=\"!account()\" (click)=\"account.set('')\">All accounts</button>\n * </ui-menu>\n * </ui-select-pill>\n */\n@Component({\n selector: 'ui-select-pill',\n imports: [UiMenuTrigger],\n template: `\n <button\n #trigger\n type=\"button\"\n [attr.aria-disabled]=\"disabled() || null\"\n [class]=\"triggerClasses\"\n [disabled]=\"disabled()\"\n [uiMenuTrigger]=\"menu()\"\n >\n <span data-pill [class]=\"pillClasses()\">\n @if (active() && contextLabel()) {\n <span class=\"sr-only\">{{ contextLabel() }} </span>\n }\n <ng-content\n /></span>\n </button>\n @if (active() && !disabled()) {\n <button data-clear type=\"button\" [attr.aria-label]=\"clearLabel()\" [class]=\"clearClasses\" (click)=\"clear()\">\n <svg\n aria-hidden=\"true\"\n fill=\"none\"\n height=\"14\"\n stroke=\"currentColor\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n stroke-width=\"2\"\n viewBox=\"0 0 24 24\"\n width=\"14\"\n >\n <path d=\"M18 6 6 18M6 6l12 12\" />\n </svg>\n </button>\n } @else {\n <svg\n aria-hidden=\"true\"\n class=\"pointer-events-none absolute right-2.5\"\n data-chevron\n fill=\"none\"\n height=\"14\"\n stroke=\"currentColor\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n stroke-width=\"2\"\n viewBox=\"0 0 24 24\"\n width=\"14\"\n [class]=\"chevronClasses()\"\n >\n <path d=\"m6 9 6 6 6-6\" />\n </svg>\n }\n <ng-content select=\"ui-menu\" />\n `,\n host: {\n '[class]': 'hostClasses()',\n },\n})\nexport class UiSelectPill {\n readonly active = input(false, { transform: booleanAttribute });\n readonly disabled = input(false, { transform: booleanAttribute });\n readonly clearLabel = input.required<string>();\n readonly contextLabel = input<string>();\n readonly cleared = output();\n\n protected readonly menu = contentChild.required(UiMenu);\n protected readonly trigger = viewChild.required<ElementRef<HTMLButtonElement>>('trigger');\n\n protected readonly hostClasses = computed(() =>\n this.disabled() ? `${HOST_CLASSES} ${DISABLED_HOST_CLASSES}` : HOST_CLASSES,\n );\n protected readonly chevronClasses = computed(() =>\n this.active() ? 'text-(--primary-foreground)' : 'text-(--foreground)',\n );\n protected readonly triggerClasses = TRIGGER_CLASSES;\n protected readonly clearClasses = CLEAR_CLASSES;\n protected clear(): void {\n this.cleared.emit();\n this.trigger().nativeElement.focus();\n }\n\n protected readonly pillClasses = computed(\n () => `${PILL_CLASSES} ${this.active() ? ACTIVE_PILL_CLASSES : REST_PILL_CLASSES}`,\n );\n}\n"],"mappings":"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"}