@nanahoshi/mona-ui 0.18.5 → 0.18.6

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.
@@ -2,6 +2,7 @@ import { NgTemplateOutlet } from '@angular/common';
2
2
  import * as i0 from '@angular/core';
3
3
  import { Directive, inject, DestroyRef, ElementRef, computed, contentChild, TemplateRef, input, output, model, afterNextRender, Component } from '@angular/core';
4
4
  import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
5
+ import { RouterLink } from '@angular/router';
5
6
  import { LucideCircleX } from '@lucide/angular';
6
7
  import { ButtonDirective } from '@nanahoshi/mona-ui/button';
7
8
  import { fromEvent, filter } from 'rxjs';
@@ -26,7 +27,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImpor
26
27
 
27
28
  const chipThemeVariants = cva(`
28
29
  inline-flex shrink-0 items-center justify-between gap-1.5
29
- cursor-pointer text-xs font-medium
30
+ text-xs font-medium
30
31
  shadow-(--shadow-control) outline-none
31
32
  transition-colors duration-(--mona-motion-fast) ease-in-out
32
33
  `, {
@@ -35,63 +36,23 @@ const chipThemeVariants = cva(`
35
36
  true: "pointer-events-none opacity-50 cursor-not-allowed select-none",
36
37
  false: ""
37
38
  },
39
+ interactive: {
40
+ true: "cursor-pointer",
41
+ false: ""
42
+ },
38
43
  look: {
39
44
  default: `
40
45
  ${themeRaisedSurfaceClasses} text-foreground
41
46
  border border-border
42
- hover:bg-hover hover:text-foreground
43
- active:bg-(--color-selected-active) active:text-(--color-selected-active-foreground)
44
- focus-visible:ring-2 focus-visible:ring-focus-indicator/35
45
- `,
46
- primary: `
47
- bg-primary text-primary-foreground
48
- hover:bg-primary-hover hover:text-primary-foreground
49
- active:bg-primary-active active:text-primary-foreground
50
- focus-visible:ring-2 focus-visible:ring-focus-indicator/35
51
- `,
52
- success: `
53
- bg-success text-success-foreground
54
- hover:bg-success-hover hover:text-success-foreground
55
- active:bg-success-active active:text-success-foreground
56
- focus-visible:ring-2 focus-visible:ring-focus-indicator/35
57
- `,
58
- error: `
59
- bg-error text-error-foreground
60
- hover:bg-error-hover hover:text-error-foreground
61
- active:bg-error-active active:text-error-foreground
62
- focus-visible:ring-2 focus-visible:ring-focus-indicator/35
63
47
  `,
64
- warning: `
65
- bg-warning text-warning-foreground
66
- hover:bg-warning-hover hover:text-warning-foreground
67
- active:bg-warning-active active:text-warning-foreground
68
- focus-visible:ring-2 focus-visible:ring-focus-indicator/35
69
- `,
70
- info: `
71
- bg-info text-info-foreground
72
- hover:bg-info-hover hover:text-info-foreground
73
- active:bg-info-active active:text-info-foreground
74
- focus-visible:ring-2 focus-visible:ring-focus-indicator/35
75
- `,
76
- outline: `
77
- bg-transparent text-foreground
78
- border border-input-border
79
- hover:bg-hover hover:text-foreground
80
- active:bg-(--color-selected-active) active:text-(--color-selected-active-foreground)
81
- focus-visible:ring-2 focus-visible:ring-focus-indicator/35
82
- `,
83
- secondary: `
84
- bg-secondary text-secondary-foreground
85
- hover:bg-secondary-hover hover:text-secondary-foreground
86
- active:bg-secondary-active active:text-secondary-foreground
87
- focus-visible:ring-2 focus-visible:ring-focus-indicator/35
88
- `,
89
- ghost: `
90
- bg-transparent text-foreground shadow-none
91
- hover:bg-hover hover:text-foreground
92
- active:bg-(--color-selected-active) active:text-(--color-selected-active-foreground)
93
- focus-visible:ring-2 focus-visible:ring-focus-indicator/35
94
- `
48
+ primary: "bg-primary text-primary-foreground",
49
+ success: "bg-success text-success-foreground",
50
+ error: "bg-error text-error-foreground",
51
+ warning: "bg-warning text-warning-foreground",
52
+ info: "bg-info text-info-foreground",
53
+ outline: "bg-transparent text-foreground border border-input-border",
54
+ secondary: "bg-secondary text-secondary-foreground",
55
+ ghost: "bg-transparent text-foreground shadow-none"
95
56
  },
96
57
  rounded: {
97
58
  full: "rounded-full",
@@ -102,17 +63,17 @@ const chipThemeVariants = cva(`
102
63
  },
103
64
  size: {
104
65
  small: `
105
- ps-1 pe-1 py-0.5
66
+ px-1 py-0.5
106
67
  [&_button[data-chip-remove='true']]:w-3
107
68
  [&_button[data-chip-remove='true']]:h-3
108
69
  `,
109
70
  medium: `
110
- ps-1.5 pe-1.5 py-1
71
+ px-1.5 py-1
111
72
  [&_button[data-chip-remove='true']]:w-4
112
73
  [&_button[data-chip-remove='true']]:h-4
113
74
  `,
114
75
  large: `
115
- ps-2 pe-2 py-1.5
76
+ px-2 py-1.5
116
77
  [&_button[data-chip-remove='true']]:w-5
117
78
  [&_button[data-chip-remove='true']]:h-5
118
79
  `
@@ -126,86 +87,231 @@ const chipThemeVariants = cva(`
126
87
  {
127
88
  look: "default",
128
89
  selected: true,
90
+ class: "bg-(--color-selected) text-(--color-selected-foreground)"
91
+ },
92
+ {
93
+ look: "primary",
94
+ selected: true,
95
+ class: "bg-primary-selected text-primary-foreground"
96
+ },
97
+ {
98
+ look: "secondary",
99
+ selected: true,
100
+ class: "bg-secondary-selected text-secondary-foreground"
101
+ },
102
+ {
103
+ look: "success",
104
+ selected: true,
105
+ class: "bg-success-selected text-success-foreground"
106
+ },
107
+ {
108
+ look: "error",
109
+ selected: true,
110
+ class: "bg-error-selected text-error-foreground"
111
+ },
112
+ {
113
+ look: "warning",
114
+ selected: true,
115
+ class: "bg-warning-selected text-warning-foreground"
116
+ },
117
+ {
118
+ look: "info",
119
+ selected: true,
120
+ class: "bg-info-selected text-info-foreground"
121
+ },
122
+ {
123
+ look: "outline",
124
+ selected: true,
125
+ class: "bg-(--color-selected) text-(--color-selected-foreground)"
126
+ },
127
+ {
128
+ look: "ghost",
129
+ selected: true,
130
+ class: "bg-(--color-selected) text-(--color-selected-foreground)"
131
+ },
132
+ {
133
+ look: "default",
134
+ interactive: true,
135
+ selected: false,
136
+ class: `
137
+ hover:bg-hover hover:text-foreground
138
+ active:bg-(--color-selected-active) active:text-(--color-selected-active-foreground)
139
+ focus-visible:ring-2 focus-visible:ring-focus-indicator/35
140
+ `
141
+ },
142
+ {
143
+ look: "primary",
144
+ interactive: true,
145
+ selected: false,
146
+ class: `
147
+ hover:bg-primary-hover hover:text-primary-foreground
148
+ active:bg-primary-active active:text-primary-foreground
149
+ focus-visible:ring-2 focus-visible:ring-focus-indicator/35
150
+ `
151
+ },
152
+ {
153
+ look: "secondary",
154
+ interactive: true,
155
+ selected: false,
156
+ class: `
157
+ hover:bg-secondary-hover hover:text-secondary-foreground
158
+ active:bg-secondary-active active:text-secondary-foreground
159
+ focus-visible:ring-2 focus-visible:ring-focus-indicator/35
160
+ `
161
+ },
162
+ {
163
+ look: "success",
164
+ interactive: true,
165
+ selected: false,
166
+ class: `
167
+ hover:bg-success-hover hover:text-success-foreground
168
+ active:bg-success-active active:text-success-foreground
169
+ focus-visible:ring-2 focus-visible:ring-focus-indicator/35
170
+ `
171
+ },
172
+ {
173
+ look: "error",
174
+ interactive: true,
175
+ selected: false,
176
+ class: `
177
+ hover:bg-error-hover hover:text-error-foreground
178
+ active:bg-error-active active:text-error-foreground
179
+ focus-visible:ring-2 focus-visible:ring-focus-indicator/35
180
+ `
181
+ },
182
+ {
183
+ look: "warning",
184
+ interactive: true,
185
+ selected: false,
186
+ class: `
187
+ hover:bg-warning-hover hover:text-warning-foreground
188
+ active:bg-warning-active active:text-warning-foreground
189
+ focus-visible:ring-2 focus-visible:ring-focus-indicator/35
190
+ `
191
+ },
192
+ {
193
+ look: "info",
194
+ interactive: true,
195
+ selected: false,
196
+ class: `
197
+ hover:bg-info-hover hover:text-info-foreground
198
+ active:bg-info-active active:text-info-foreground
199
+ focus-visible:ring-2 focus-visible:ring-focus-indicator/35
200
+ `
201
+ },
202
+ {
203
+ look: "outline",
204
+ interactive: true,
205
+ selected: false,
206
+ class: `
207
+ hover:bg-hover hover:text-foreground
208
+ active:bg-(--color-selected-active) active:text-(--color-selected-active-foreground)
209
+ focus-visible:ring-2 focus-visible:ring-focus-indicator/35
210
+ `
211
+ },
212
+ {
213
+ look: "ghost",
214
+ interactive: true,
215
+ selected: false,
216
+ class: `
217
+ hover:bg-hover hover:text-foreground
218
+ active:bg-(--color-selected-active) active:text-(--color-selected-active-foreground)
219
+ focus-visible:ring-2 focus-visible:ring-focus-indicator/35
220
+ `
221
+ },
222
+ {
223
+ look: "default",
224
+ interactive: true,
225
+ selected: true,
129
226
  class: `
130
- bg-(--color-selected) text-(--color-selected-foreground)
131
227
  hover:bg-(--color-selected-hover) hover:text-(--color-selected-hover-foreground)
132
228
  active:bg-(--color-selected-active) active:text-(--color-selected-active-foreground)
229
+ focus-visible:ring-2 focus-visible:ring-focus-indicator/35
133
230
  `
134
231
  },
135
232
  {
136
233
  look: "primary",
234
+ interactive: true,
137
235
  selected: true,
138
236
  class: `
139
- bg-primary-selected text-primary-foreground
140
237
  hover:bg-primary-selected/95 hover:text-primary-foreground
141
238
  active:bg-primary-selected/100 active:text-primary-foreground
239
+ focus-visible:ring-2 focus-visible:ring-focus-indicator/35
142
240
  `
143
241
  },
144
242
  {
145
243
  look: "secondary",
244
+ interactive: true,
146
245
  selected: true,
147
246
  class: `
148
- bg-secondary-selected text-secondary-foreground
149
247
  hover:bg-secondary-selected/95 hover:text-secondary-foreground
150
248
  active:bg-secondary-selected/100 active:text-secondary-foreground
249
+ focus-visible:ring-2 focus-visible:ring-focus-indicator/35
151
250
  `
152
251
  },
153
252
  {
154
253
  look: "success",
254
+ interactive: true,
155
255
  selected: true,
156
256
  class: `
157
- bg-success-selected text-success-foreground
158
257
  hover:bg-success-selected/95 hover:text-success-foreground
159
258
  active:bg-success-selected/100 active:text-success-foreground
259
+ focus-visible:ring-2 focus-visible:ring-focus-indicator/35
160
260
  `
161
261
  },
162
262
  {
163
263
  look: "error",
264
+ interactive: true,
164
265
  selected: true,
165
266
  class: `
166
- bg-error-selected text-error-foreground
167
267
  hover:bg-error-selected/95 hover:text-error-foreground
168
268
  active:bg-error-selected/100 active:text-error-foreground
269
+ focus-visible:ring-2 focus-visible:ring-focus-indicator/35
169
270
  `
170
271
  },
171
272
  {
172
273
  look: "warning",
274
+ interactive: true,
173
275
  selected: true,
174
276
  class: `
175
- bg-warning-selected text-warning-foreground
176
277
  hover:bg-warning-selected/95 hover:text-warning-foreground
177
278
  active:bg-warning-selected/100 active:text-warning-foreground
279
+ focus-visible:ring-2 focus-visible:ring-focus-indicator/35
178
280
  `
179
281
  },
180
282
  {
181
283
  look: "info",
284
+ interactive: true,
182
285
  selected: true,
183
286
  class: `
184
- bg-info-selected text-info-foreground
185
287
  hover:bg-info-selected/95 hover:text-info-foreground
186
288
  active:bg-info-selected/100 active:text-info-foreground
289
+ focus-visible:ring-2 focus-visible:ring-focus-indicator/35
187
290
  `
188
291
  },
189
292
  {
190
293
  look: "outline",
294
+ interactive: true,
191
295
  selected: true,
192
296
  class: `
193
- bg-(--color-selected) text-(--color-selected-foreground)
194
297
  hover:bg-(--color-selected-hover) hover:text-(--color-selected-hover-foreground)
195
298
  active:bg-(--color-selected-active) active:text-(--color-selected-active-foreground)
299
+ focus-visible:ring-2 focus-visible:ring-focus-indicator/35
196
300
  `
197
301
  },
198
302
  {
199
303
  look: "ghost",
304
+ interactive: true,
200
305
  selected: true,
201
306
  class: `
202
- bg-(--color-selected) text-(--color-selected-foreground)
203
307
  hover:bg-(--color-selected-hover) hover:text-(--color-selected-hover-foreground)
204
308
  active:bg-(--color-selected-active) active:text-(--color-selected-active-foreground)
309
+ focus-visible:ring-2 focus-visible:ring-focus-indicator/35
205
310
  `
206
311
  }
207
312
  ],
208
313
  defaultVariants: {
314
+ interactive: false,
209
315
  rounded: "medium",
210
316
  selected: false
211
317
  }
@@ -214,9 +320,11 @@ const chipThemeVariants = cva(`
214
320
  class ChipComponent {
215
321
  #destroyRef;
216
322
  #elementRef;
323
+ #routerLink;
217
324
  constructor() {
218
325
  this.#destroyRef = inject(DestroyRef);
219
326
  this.#elementRef = inject(ElementRef);
327
+ this.#routerLink = inject(RouterLink, { optional: true });
220
328
  this.ariaChecked = computed(() => {
221
329
  if (!this.toggleable()) {
222
330
  return undefined;
@@ -226,15 +334,18 @@ class ChipComponent {
226
334
  ...(ngDevMode ? [{ debugName: "ariaChecked" }] : /* istanbul ignore next */ []));
227
335
  this.baseClass = computed(() => {
228
336
  const disabled = this.disabled();
337
+ const interactive = this.bodyInteractive();
229
338
  const look = this.look();
230
339
  const rounded = this.rounded();
231
340
  const size = this.size();
232
341
  const selected = this.selected();
233
342
  const userClass = this.userClass();
234
- const variantClasses = chipThemeVariants({ disabled, look, rounded, size, selected });
343
+ const variantClasses = chipThemeVariants({ disabled, interactive, look, rounded, size, selected });
235
344
  return twMerge(variantClasses, userClass);
236
345
  }, /* @ts-ignore */
237
346
  ...(ngDevMode ? [{ debugName: "baseClass" }] : /* istanbul ignore next */ []));
347
+ this.bodyInteractive = computed(() => !this.disabled() && (this.toggleable() || this.isLink()), /* @ts-ignore */
348
+ ...(ngDevMode ? [{ debugName: "bodyInteractive" }] : /* istanbul ignore next */ []));
238
349
  this.effectiveAriaLabel = computed(() => {
239
350
  const explicitLabel = this.ariaLabel();
240
351
  if (explicitLabel) {
@@ -255,7 +366,7 @@ class ChipComponent {
255
366
  if (explicitTabindex != null) {
256
367
  return explicitTabindex;
257
368
  }
258
- if (this.toggleable() || this.removable()) {
369
+ if (this.toggleable() || this.isLink()) {
259
370
  return 0;
260
371
  }
261
372
  return -1;
@@ -275,6 +386,8 @@ class ChipComponent {
275
386
  }
276
387
  }, /* @ts-ignore */
277
388
  ...(ngDevMode ? [{ debugName: "iconSize" }] : /* istanbul ignore next */ []));
389
+ this.isLink = computed(() => !!this.#routerLink, /* @ts-ignore */
390
+ ...(ngDevMode ? [{ debugName: "isLink" }] : /* istanbul ignore next */ []));
278
391
  this.prefixTemplate = contentChild(ChipPrefixTemplateDirective, { ...(ngDevMode ? { debugName: "prefixTemplate" } : /* istanbul ignore next */ {}), read: TemplateRef });
279
392
  this.role = computed(() => {
280
393
  if (this.toggleable()) {
@@ -290,8 +403,8 @@ class ChipComponent {
290
403
  */
291
404
  this.ariaLabel = input("", { ...(ngDevMode ? { debugName: "ariaLabel" } : /* istanbul ignore next */ {}), alias: "aria-label" });
292
405
  /**
293
- * @description Emitted when the chip body is clicked or activated via Enter or Space.
294
- * Not emitted when the remove button is activated.
406
+ * @description Emitted when a toggleable chip body is activated via click, Enter, or Space.
407
+ * Not emitted when the remove button is activated or for non-toggleable chips.
295
408
  */
296
409
  this.contentClick = output();
297
410
  /**
@@ -358,7 +471,7 @@ class ChipComponent {
358
471
  ...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
359
472
  /**
360
473
  * @description Tab index override for the chip host element. When not set, computed automatically:
361
- * `0` when `toggleable` or `removable` is `true`, `-1` otherwise. Overridden to `-1` when `disabled` is `true`.
474
+ * `0` when `toggleable` is `true` or functioning as a link, `-1` otherwise. Overridden to `-1` when `disabled` is `true`.
362
475
  * @default undefined
363
476
  */
364
477
  this.tabindex = input(/* @ts-ignore */
@@ -394,15 +507,16 @@ class ChipComponent {
394
507
  this.remove.emit(event);
395
508
  }
396
509
  #handleActivation() {
397
- if (this.toggleable()) {
398
- this.selected.set(!this.selected());
510
+ if (!this.toggleable() || this.disabled()) {
511
+ return;
399
512
  }
513
+ this.selected.set(!this.selected());
400
514
  this.contentClick.emit();
401
515
  }
402
516
  #setSubscriptions() {
403
517
  const element = this.#elementRef.nativeElement;
404
518
  fromEvent(element, "keydown")
405
- .pipe(filter(event => !this.disabled() && (event.key === "Enter" || event.key === " ")), takeUntilDestroyed(this.#destroyRef))
519
+ .pipe(filter(event => !this.disabled() && this.toggleable() && (event.key === "Enter" || event.key === " ")), takeUntilDestroyed(this.#destroyRef))
406
520
  .subscribe(event => {
407
521
  const target = event.target;
408
522
  if (target.closest("button[data-chip-remove]")) {
@@ -412,7 +526,7 @@ class ChipComponent {
412
526
  this.#handleActivation();
413
527
  });
414
528
  fromEvent(element, "click")
415
- .pipe(filter(() => !this.disabled()), takeUntilDestroyed(this.#destroyRef))
529
+ .pipe(filter(() => !this.disabled() && this.toggleable()), takeUntilDestroyed(this.#destroyRef))
416
530
  .subscribe(() => {
417
531
  this.#handleActivation();
418
532
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nanahoshi/mona-ui",
3
- "version": "0.18.5",
3
+ "version": "0.18.6",
4
4
  "description": "A very light Angular UI framework",
5
5
  "author": "Nanahoshi",
6
6
  "repository": {
@@ -6,21 +6,24 @@ import { VariantProps } from 'class-variance-authority';
6
6
 
7
7
  declare const chipThemeVariants: (props?: ({
8
8
  disabled?: boolean | null | undefined;
9
+ interactive?: boolean | null | undefined;
9
10
  look?: "default" | "primary" | "success" | "error" | "warning" | "info" | "outline" | "secondary" | "ghost" | null | undefined;
10
11
  rounded?: "full" | "large" | "medium" | "none" | "small" | null | undefined;
11
12
  size?: "large" | "medium" | "small" | null | undefined;
12
13
  selected?: boolean | null | undefined;
13
14
  } & class_variance_authority_types.ClassProp) | undefined) => string;
14
15
  type ChipVariantProps = VariantProps<typeof chipThemeVariants>;
15
- type ChipVariantInputs = VariantInputs<ChipVariantProps>;
16
+ type ChipVariantInputs = VariantInputs<Omit<ChipVariantProps, "interactive">>;
16
17
 
17
18
  declare class ChipComponent implements ChipVariantInputs {
18
19
  #private;
19
20
  protected readonly ariaChecked: _angular_core.Signal<"true" | "false" | undefined>;
20
21
  protected readonly baseClass: _angular_core.Signal<string>;
22
+ protected readonly bodyInteractive: _angular_core.Signal<boolean>;
21
23
  protected readonly effectiveAriaLabel: _angular_core.Signal<string | undefined>;
22
24
  protected readonly effectiveTabIndex: _angular_core.Signal<string | number>;
23
25
  protected readonly iconSize: _angular_core.Signal<13 | 14 | 16>;
26
+ protected readonly isLink: _angular_core.Signal<boolean>;
24
27
  protected readonly prefixTemplate: _angular_core.Signal<TemplateRef<any> | undefined>;
25
28
  protected readonly role: _angular_core.Signal<"checkbox" | undefined>;
26
29
  /**
@@ -30,8 +33,8 @@ declare class ChipComponent implements ChipVariantInputs {
30
33
  */
31
34
  readonly ariaLabel: _angular_core.InputSignal<string>;
32
35
  /**
33
- * @description Emitted when the chip body is clicked or activated via Enter or Space.
34
- * Not emitted when the remove button is activated.
36
+ * @description Emitted when a toggleable chip body is activated via click, Enter, or Space.
37
+ * Not emitted when the remove button is activated or for non-toggleable chips.
35
38
  */
36
39
  readonly contentClick: _angular_core.OutputEmitterRef<void>;
37
40
  /**
@@ -89,7 +92,7 @@ declare class ChipComponent implements ChipVariantInputs {
89
92
  readonly size: _angular_core.InputSignal<"large" | "medium" | "small" | null | undefined>;
90
93
  /**
91
94
  * @description Tab index override for the chip host element. When not set, computed automatically:
92
- * `0` when `toggleable` or `removable` is `true`, `-1` otherwise. Overridden to `-1` when `disabled` is `true`.
95
+ * `0` when `toggleable` is `true` or functioning as a link, `-1` otherwise. Overridden to `-1` when `disabled` is `true`.
93
96
  * @default undefined
94
97
  */
95
98
  readonly tabindex: _angular_core.InputSignal<string | number | undefined>;