@joanroucoux/cairn-ui 0.8.2 → 0.9.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 (124) hide show
  1. package/CHANGELOG.md +99 -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 +376 -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 +233 -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 +79 -37
  113. package/types/joanroucoux-cairn-ui-segmented.d.ts +51 -27
  114. package/types/joanroucoux-cairn-ui-select-pill.d.ts +52 -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
package/CHANGELOG.md CHANGED
@@ -1,5 +1,103 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.9.0
4
+
5
+ ### Breaking
6
+
7
+ - `ui-dialog`: the `layout` input (`trade`, `form`, `list`, `confirm`) is replaced by `variant` (`default` |
8
+ `confirm`) and `sheet` (`fit` | `full`). `DIALOG_LAYOUTS` and `DialogLayout` become `DIALOG_VARIANTS`,
9
+ `DIALOG_SHEETS`, `DialogVariant` and `DialogSheet`.
10
+ - Migration: `layout="trade"` and `layout="form"` become the default (remove the attribute); `layout="list"` becomes
11
+ `sheet="full"`; `layout="confirm"` becomes `variant="confirm"`. A list dialog was anchored 96px from the top on a
12
+ desktop: it is now centred like every dialog.
13
+ - `ui-filter-chips`: `role="group"` and `aria-label` move from the host to an inner wrapper around the chips, so a
14
+ leading element sits outside the group.
15
+ - Migration: a selector or a test query on `ui-filter-chips[role=group]` targets the inner `div[role=group]` instead;
16
+ `getByRole('group', { name })` keeps working.
17
+ - `styles/motion.css` no longer ships `ui-enter-panel` nor its `cairn-panel-in` keyframes (an 8px slide for a detail
18
+ panel beside a list). The detail now opens in `ui-drawer`, which plays its own motion.
19
+ - Migration: replace the side panel animated with `animate.enter="ui-enter-panel"` by a `ui-drawer`; for any other
20
+ element, use `ui-enter-fade-up` or `ui-enter-fade`.
21
+ - `ui-toaster`: the message text sits in its own `<span>`, beside the icon, inside the surface.
22
+ - Migration: `getByText(message)` now returns that `<span>`, not the surface; a test that checked the surface through
23
+ it (its classes, its position) reads `getByText(message).parentElement` instead.
24
+
25
+ ### Added
26
+
27
+ - `UiToasts.showError(message, closeLabel = 'Fermer')`: an error toast with the same surface, an alert icon, no timer
28
+ and a 28px cross (a 44px hit area on touch, 36px with a fine pointer); it closes only with the cross. One message
29
+ at a time: an error replaces a confirmation and the other way round. `Toast` becomes a union on `kind`: `'success'`, or `'error'` with its `closeLabel`.
30
+ - `ui-drawer` (`@joanroucoux/cairn-ui/drawer`): a modal side panel on the native `<dialog>`, against the right edge at
31
+ full height, 440px wide by default, on `--card` with a shadow on its left edge, 24px of padding and a
32
+ `rgb(0 0 0 / 0.36)` veil. It scrolls on its own with `overscroll-behavior: contain`, without locking the page.
33
+ Escape, the veil and the optional 36px cross close it; `dismissed` and `closed` (`escape`, `backdrop`, `cross`,
34
+ `programmatic`) follow the protocol of `ui-dialog`, and `busy` keeps it open. Without `heading` it draws no header
35
+ and `label` names it; with neither it throws. It enters with opacity and a 24px slide over `--duration-base` on
36
+ `--ease-out` and leaves the reverse way over `--duration-exit`; under reduced motion it only fades. A `ui-dialog`
37
+ opened from it opens over it and the drawer stays underneath: Escape closes the dialog, then the drawer.
38
+ - `ModalClose` (`@joanroucoux/cairn-ui/dialog`): the close protocol `ui-dialog` and `ui-drawer` share (Escape,
39
+ press-and-release on the veil, `busy`, `dismissed`, then `closed` once the exit transition has played). An
40
+ optional `opening` callback runs just before `showModal()`.
41
+ - `ui-select-pill` (`@joanroucoux/cairn-ui/select-pill`): a compact pill that opens a `ui-menu` of exclusive
42
+ choices, to head a row of filter chips. The projected text is its label and the projected `ui-menu` is what it
43
+ opens, as a sheet on a phone like the `…` menus. Outlined with a chevron at rest, solid primary when `active`,
44
+ where a separate 14px cross (44px hit area on touch, 36px with a fine pointer), named by the required `clearLabel`,
45
+ replaces the chevron and emits `cleared`, and focus goes back to the trigger. `contextLabel` is read before the
46
+ label while active. 34px in a 44px target on touch and 32px with a fine pointer, with a 2px focus outline outside
47
+ the pill at every size, a cross ring in the pill's text colour, and a border of its own in forced colors.
48
+ - `button[uiMenuItem]` accepts `checked`: the item becomes a `menuitemradio` with `aria-checked` and a check mark
49
+ after its label, and the menu focuses the checked item when it opens.
50
+ - `ui-filter-chips` projects an element marked `uiChipsLeading` first in its row, followed by a 1 x 20px `--border`
51
+ rule that only shows when something is projected.
52
+ - `td[ui-group-cell]` is collapsible: `collapsible`, `expanded` (a model), `toggleDisabled` and `controls`. The band
53
+ becomes an `h2 > button[aria-expanded]` with an 18px chevron that turns to -90 degrees in `--duration-fast`, a
54
+ `--soft` hover and a focus ring. With `toggleDisabled` it keeps neither the pointer cursor nor the hover. The page
55
+ owns the fold memory.
56
+ - `tbody[uiGroup]` takes `collapsed`: its rows (`tr[uiTr]`) get `hidden` and stay in the DOM, so a `uiFlipList`
57
+ around the table slides nothing when a group folds. A plain `tr` is not hidden.
58
+ - `ui-group-header` (`@joanroucoux/cairn-ui/group-header`): the header of a grouped card on a phone, with name, meta
59
+ and a projected total. Collapsible, with a 20px chevron and a press scale (neither the scale nor the pointer cursor
60
+ with `toggleDisabled`), or static.
61
+ - `ui-result-group` (`@joanroucoux/cairn-ui/result-group`): one source of a search, a two-tone heading over its rows,
62
+ with a two-row skeleton, a message slot (`resultGroupMessage`) and an inline error whose retry has no icon.
63
+ - `ui-alert` `variant="info"`: a `--muted` box with an 18px info icon, `role="note"`.
64
+ - `ui-row` `trailing="chevron"`: a flush link row with a 16px `--subtle-foreground` chevron and a dimming hover. Rows
65
+ without it are unchanged.
66
+ - `ui-back-link` `size="inline"` and the `button[ui-back-link]` selector: a 14px 500 muted back step, 18px chevron,
67
+ 44px high (36px with a mouse). A button host gets `type="button"` unless it sets its own.
68
+ - `ui-async` `retryIcon` input (default true): `false` draws a text-only retry in the `inline` variant.
69
+ - `ui-line-chart` `deltaSuffix`: a text shown after the change in the tooltip (for example "depuis le début"). It
70
+ stays when the amount is masked.
71
+
72
+ ### Changed
73
+
74
+ - `ui-dialog` has one three-zone structure: header `16 16 16 24`, body `20 24` (the only scroller), footer `16 24`;
75
+ on a sheet `0 8 12 16`, `16` and `12 16` plus the safe area, under a handle. A hairline runs under the header and
76
+ above the footer when `closeLabel` draws the cross. The `confirm` variant has one 24px padding and no hairlines,
77
+ and an empty confirm footer has no top padding.
78
+ - `ui-dialog` is centred on a desktop and capped at `calc(100dvh - 96px)`; the cross icon is 22px in every dialog.
79
+ - `ui-dialog` opened while another modal is open (over a `ui-drawer`) draws a lighter `rgb(0 0 0 / 0.24)` veil over
80
+ that one's; alone it keeps `rgb(0 0 0 / 0.36)`. It decides when it opens, with no input.
81
+ - `ui-dialog` width: the default stays `lg` (560px) and `confirm` defaults to 440px; `width` still takes `md`, `lg`
82
+ or any CSS length.
83
+ - `ui-line-chart` shows its tooltip on a tap: `pointerdown` shows it, `pointermove` follows, `pointerleave` and
84
+ `pointercancel` hide it. The plot is `touch-none` (was `touch-pan-y`), so a vertical swipe on the plot no longer
85
+ scrolls the page; the page still scrolls everywhere else.
86
+ - `uiStaleLink` with `chevron`: the gap before the chevron is 4px on touch and 2px with a mouse (was 2px everywhere).
87
+ - `ui-toaster` is an inverted surface (`--primary-foreground` on `--primary`, no contour, menu shadow, 44px minimum
88
+ height, 280 to 400px wide within the viewport minus 32px) with a 16px check icon, and it is centred at the bottom of
89
+ the content area: from `64rem`, 24px from the bottom and centred between `--sidebar-width` (0 when the app does not
90
+ set it) and the right edge; below, centred 8px above the tab bar as before. It was `--elevated`, bottom right.
91
+ - Stories and docs no longer use the Instruments samples: the `ui-table` `Instruments` story is removed, the
92
+ `ui-empty` sample reads "Aucune ligne ne correspond à ...", the `ui-back-link` small story reads "Comptes". The
93
+ Storybook favicon is the Cairn tile.
94
+
95
+ ### Fixed
96
+
97
+ - `ui-toaster` shows above an open `ui-dialog` or `ui-drawer`: it is a `popover="manual"` in the top layer, shown
98
+ again each time a message arrives. A modal that opens afterwards does not raise it again: the toast never covers a
99
+ dialog's button. Behind a modal the page is inert, so the pause and the error cross do not work over an open modal.
100
+
3
101
  ## 0.8.2
4
102
 
5
103
  ### Changed
@@ -70,6 +168,7 @@ Every symbol that was exported from the root now lives under exactly one subpath
70
168
  - `@joanroucoux/cairn-ui/row`: `ROW_GAPS`, `ROW_PADDINGS`, `ROW_SIZES`, `UiListRow`, `UiRow`, `UiRowItem`, `UiRowTile`, `RowGap`, `RowPadding`, `RowSize`
71
169
  - `@joanroucoux/cairn-ui/segmented`: `SEGMENTED_SIZES`, `UiSegmented`, `SegmentedOption`, `SegmentedSize`
72
170
  - `@joanroucoux/cairn-ui/select`: `UiSelect`
171
+ - `@joanroucoux/cairn-ui/select-pill`: `UiSelectPill`
73
172
  - `@joanroucoux/cairn-ui/skeleton`: `SKELETON_SHAPES`, `UiSkeleton`, `SkeletonShape`
74
173
  - `@joanroucoux/cairn-ui/stale-link`: `STALE_LINK_SIZES`, `UiStaleLink`, `StaleLinkSize`
75
174
  - `@joanroucoux/cairn-ui/stat`: `STAT_SIZES`, `UiStat`, `StatSize`
@@ -1,54 +1,58 @@
1
- import { DOCUMENT } from '@angular/common';
2
- import * as i0 from '@angular/core';
3
- import { inject, ElementRef, DestroyRef, afterNextRender, Component } from '@angular/core';
4
-
5
- const HEIGHT_PROPERTY = '--action-bar-height';
6
- /**
7
- * Bar of actions fixed above the tab bar on iPhone: the primary actions of a detail screen, within
8
- * thumb reach. It sits `--tab-bar-height` (52px plus the safe area) above the bottom edge, so it clears `ui-tab-bar`, and
9
- * it is hidden from `64rem`, where the same actions live in the page itself. Its children share the
10
- * width equally. While it is on the page it publishes its height as `--action-bar-height` on the
11
- * root element, which `ui-toaster` adds to its offset so a confirmation never covers the actions.
12
- *
13
- * @example
14
- * <ui-action-bar>
15
- * <button ui-button variant="outline" size="tall">Sell</button>
16
- * <button ui-button size="tall">Buy</button>
17
- * </ui-action-bar>
18
- */
19
- class UiActionBar {
20
- constructor() {
21
- const host = inject(ElementRef).nativeElement;
22
- const root = inject(DOCUMENT).documentElement;
23
- const destroyRef = inject(DestroyRef);
24
- const publish = () => root.style.setProperty(HEIGHT_PROPERTY, `${host.offsetHeight}px`);
25
- afterNextRender(() => {
26
- publish();
27
- if (typeof ResizeObserver !== 'undefined') {
28
- const observer = new ResizeObserver(publish);
29
- observer.observe(host);
30
- destroyRef.onDestroy(() => observer.disconnect());
31
- }
32
- });
33
- destroyRef.onDestroy(() => root.style.removeProperty(HEIGHT_PROPERTY));
34
- }
35
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: UiActionBar, deps: [], target: i0.ɵɵFactoryTarget.Component });
36
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.1.7", type: UiActionBar, isStandalone: true, selector: "ui-action-bar", host: { classAttribute: "fixed inset-x-0 bottom-[var(--tab-bar-height,calc(52px+env(safe-area-inset-bottom)))] z-40 grid grid-flow-col auto-cols-fr gap-2 bg-(--background) px-(--gutter) py-3 shadow-[0_-1px_0_var(--hairline)] lg:hidden" }, ngImport: i0, template: '<ng-content />', isInline: true });
37
- }
38
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: UiActionBar, decorators: [{
39
- type: Component,
40
- args: [{
41
- selector: 'ui-action-bar',
42
- template: '<ng-content />',
43
- host: {
44
- class: 'fixed inset-x-0 bottom-[var(--tab-bar-height,calc(52px+env(safe-area-inset-bottom)))] z-40 grid grid-flow-col auto-cols-fr gap-2 bg-(--background) px-(--gutter) py-3 shadow-[0_-1px_0_var(--hairline)] lg:hidden',
45
- },
46
- }]
47
- }], ctorParameters: () => [] });
48
-
49
- /**
50
- * Generated bundle index. Do not edit.
51
- */
52
-
1
+ import { DOCUMENT } from "@angular/common";
2
+ import * as i0 from "@angular/core";
3
+ import { Component, DestroyRef, ElementRef, afterNextRender, inject } from "@angular/core";
4
+ const HEIGHT_PROPERTY = "--action-bar-height";
5
+ var UiActionBar = class UiActionBar {
6
+ constructor() {
7
+ const host = inject(ElementRef).nativeElement;
8
+ const root = inject(DOCUMENT).documentElement;
9
+ const destroyRef = inject(DestroyRef);
10
+ const publish = () => root.style.setProperty(HEIGHT_PROPERTY, `${host.offsetHeight}px`);
11
+ afterNextRender(() => {
12
+ publish();
13
+ if (typeof ResizeObserver !== "undefined") {
14
+ const observer = new ResizeObserver(publish);
15
+ observer.observe(host);
16
+ destroyRef.onDestroy(() => observer.disconnect());
17
+ }
18
+ });
19
+ destroyRef.onDestroy(() => root.style.removeProperty(HEIGHT_PROPERTY));
20
+ }
21
+ static ɵfac = i0.ɵɵngDeclareFactory({
22
+ minVersion: "12.0.0",
23
+ version: "22.2.0",
24
+ ngImport: i0,
25
+ type: UiActionBar,
26
+ deps: [],
27
+ target: i0.ɵɵFactoryTarget.Component
28
+ });
29
+ static ɵcmp = i0.ɵɵngDeclareComponent({
30
+ minVersion: "14.0.0",
31
+ version: "22.2.0",
32
+ type: UiActionBar,
33
+ isStandalone: true,
34
+ selector: "ui-action-bar",
35
+ host: { classAttribute: "fixed inset-x-0 bottom-[var(--tab-bar-height,calc(52px+env(safe-area-inset-bottom)))] z-40 grid grid-flow-col auto-cols-fr gap-2 bg-(--background) px-(--gutter) py-3 shadow-[0_-1px_0_var(--hairline)] lg:hidden" },
36
+ ngImport: i0,
37
+ template: "<ng-content />",
38
+ isInline: true
39
+ });
40
+ };
41
+ i0.ɵɵngDeclareClassMetadata({
42
+ minVersion: "12.0.0",
43
+ version: "22.2.0",
44
+ ngImport: i0,
45
+ type: UiActionBar,
46
+ decorators: [{
47
+ type: Component,
48
+ args: [{
49
+ selector: "ui-action-bar",
50
+ template: "<ng-content />",
51
+ host: { class: "fixed inset-x-0 bottom-[var(--tab-bar-height,calc(52px+env(safe-area-inset-bottom)))] z-40 grid grid-flow-col auto-cols-fr gap-2 bg-(--background) px-(--gutter) py-3 shadow-[0_-1px_0_var(--hairline)] lg:hidden" }
52
+ }]
53
+ }],
54
+ ctorParameters: () => []
55
+ });
53
56
  export { UiActionBar };
54
- //# sourceMappingURL=joanroucoux-cairn-ui-action-bar.mjs.map
57
+
58
+ //# sourceMappingURL=joanroucoux-cairn-ui-action-bar.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"joanroucoux-cairn-ui-action-bar.mjs","sources":["../../../projects/ui/action-bar/action-bar.ts","../../../projects/ui/action-bar/joanroucoux-cairn-ui-action-bar.ts"],"sourcesContent":["import { DOCUMENT } from '@angular/common';\nimport { Component, DestroyRef, ElementRef, afterNextRender, inject } from '@angular/core';\n\nconst HEIGHT_PROPERTY = '--action-bar-height';\n\n/**\n * Bar of actions fixed above the tab bar on iPhone: the primary actions of a detail screen, within\n * thumb reach. It sits `--tab-bar-height` (52px plus the safe area) above the bottom edge, so it clears `ui-tab-bar`, and\n * it is hidden from `64rem`, where the same actions live in the page itself. Its children share the\n * width equally. While it is on the page it publishes its height as `--action-bar-height` on the\n * root element, which `ui-toaster` adds to its offset so a confirmation never covers the actions.\n *\n * @example\n * <ui-action-bar>\n * <button ui-button variant=\"outline\" size=\"tall\">Sell</button>\n * <button ui-button size=\"tall\">Buy</button>\n * </ui-action-bar>\n */\n@Component({\n selector: 'ui-action-bar',\n template: '<ng-content />',\n host: {\n class:\n 'fixed inset-x-0 bottom-[var(--tab-bar-height,calc(52px+env(safe-area-inset-bottom)))] z-40 grid grid-flow-col auto-cols-fr gap-2 bg-(--background) px-(--gutter) py-3 shadow-[0_-1px_0_var(--hairline)] lg:hidden',\n },\n})\nexport class UiActionBar {\n constructor() {\n const host = inject<ElementRef<HTMLElement>>(ElementRef).nativeElement;\n const root = inject(DOCUMENT).documentElement;\n const destroyRef = inject(DestroyRef);\n const publish = (): void => root.style.setProperty(HEIGHT_PROPERTY, `${host.offsetHeight}px`);\n\n afterNextRender(() => {\n publish();\n\n if (typeof ResizeObserver !== 'undefined') {\n const observer = new ResizeObserver(publish);\n observer.observe(host);\n destroyRef.onDestroy(() => observer.disconnect());\n }\n });\n\n destroyRef.onDestroy(() => root.style.removeProperty(HEIGHT_PROPERTY));\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;;AAGA,MAAM,eAAe,GAAG,qBAAqB;AAE7C;;;;;;;;;;;;AAYG;MASU,WAAW,CAAA;AACtB,IAAA,WAAA,GAAA;QACE,MAAM,IAAI,GAAG,MAAM,CAA0B,UAAU,CAAC,CAAC,aAAa;QACtE,MAAM,IAAI,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC,eAAe;AAC7C,QAAA,MAAM,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC;AACrC,QAAA,MAAM,OAAO,GAAG,MAAY,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,eAAe,EAAE,CAAA,EAAG,IAAI,CAAC,YAAY,CAAA,EAAA,CAAI,CAAC;QAE7F,eAAe,CAAC,MAAK;AACnB,YAAA,OAAO,EAAE;AAET,YAAA,IAAI,OAAO,cAAc,KAAK,WAAW,EAAE;AACzC,gBAAA,MAAM,QAAQ,GAAG,IAAI,cAAc,CAAC,OAAO,CAAC;AAC5C,gBAAA,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC;gBACtB,UAAU,CAAC,SAAS,CAAC,MAAM,QAAQ,CAAC,UAAU,EAAE,CAAC;YACnD;AACF,QAAA,CAAC,CAAC;AAEF,QAAA,UAAU,CAAC,SAAS,CAAC,MAAM,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,eAAe,CAAC,CAAC;IACxE;uGAlBW,WAAW,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAX,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,WAAW,wTANZ,gBAAgB,EAAA,QAAA,EAAA,IAAA,EAAA,CAAA;;2FAMf,WAAW,EAAA,UAAA,EAAA,CAAA;kBARvB,SAAS;AAAC,YAAA,IAAA,EAAA,CAAA;AACT,oBAAA,QAAQ,EAAE,eAAe;AACzB,oBAAA,QAAQ,EAAE,gBAAgB;AAC1B,oBAAA,IAAI,EAAE;AACJ,wBAAA,KAAK,EACH,mNAAmN;AACtN,qBAAA;AACF,iBAAA;;;ACzBD;;AAEG;;;;"}
1
+ {"version":3,"file":"joanroucoux-cairn-ui-action-bar.mjs","names":[],"sources":["../../../projects/ui/action-bar/action-bar.ts"],"sourcesContent":["import { DOCUMENT } from '@angular/common';\nimport { Component, DestroyRef, ElementRef, afterNextRender, inject } from '@angular/core';\n\nconst HEIGHT_PROPERTY = '--action-bar-height';\n\n/**\n * Bar of actions fixed above the tab bar on iPhone, hidden from `64rem`, where the same actions\n * live in the page itself. Its children share the width equally. While it is on the page it\n * publishes its height as `--action-bar-height` on the root element, which `ui-toaster` clears.\n *\n * @example\n * <ui-action-bar>\n * <button ui-button variant=\"outline\" size=\"tall\">Sell</button>\n * <button ui-button size=\"tall\">Buy</button>\n * </ui-action-bar>\n */\n@Component({\n selector: 'ui-action-bar',\n template: '<ng-content />',\n host: {\n class:\n 'fixed inset-x-0 bottom-[var(--tab-bar-height,calc(52px+env(safe-area-inset-bottom)))] z-40 grid grid-flow-col auto-cols-fr gap-2 bg-(--background) px-(--gutter) py-3 shadow-[0_-1px_0_var(--hairline)] lg:hidden',\n },\n})\nexport class UiActionBar {\n constructor() {\n const host = inject<ElementRef<HTMLElement>>(ElementRef).nativeElement;\n const root = inject(DOCUMENT).documentElement;\n const destroyRef = inject(DestroyRef);\n const publish = (): void => root.style.setProperty(HEIGHT_PROPERTY, `${host.offsetHeight}px`);\n\n afterNextRender(() => {\n publish();\n\n if (typeof ResizeObserver !== 'undefined') {\n const observer = new ResizeObserver(publish);\n observer.observe(host);\n destroyRef.onDestroy(() => observer.disconnect());\n }\n });\n\n destroyRef.onDestroy(() => root.style.removeProperty(HEIGHT_PROPERTY));\n }\n}\n"],"mappings":";;;AAGA,MAAM,kBAAkB;AAqBxB,IAAa,cAAb,MAAa,YAAW;CACtB,cAAA;EACE,MAAM,OAAO,OAAgC,UAAU,CAAC,CAAC;EACzD,MAAM,OAAO,OAAO,QAAQ,CAAC,CAAC;EAC9B,MAAM,aAAa,OAAO,UAAU;EACpC,MAAM,gBAAsB,KAAK,MAAM,YAAY,iBAAiB,GAAG,KAAK,aAAY,GAAI;EAE5F,sBAAqB;GACnB,QAAO;GAEP,IAAI,OAAO,mBAAmB,aAAa;IACzC,MAAM,WAAW,IAAI,eAAe,OAAO;IAC3C,SAAS,QAAQ,IAAI;IACrB,WAAW,gBAAgB,SAAS,WAAU,CAAE;GAClD;EACF,CAAC;EAED,WAAW,gBAAgB,KAAK,MAAM,eAAe,eAAe,CAAC;CACvE;CAlBW,OAAA,OAAA,GAAA,mBAAA;EAAA,YAAA;EAAA,SAAA;EAAA,UAAA;EAAA,MAAA;EAAW,MAAA,CAAA;EAAA,QAAA,GAAA,gBAAA;CAAA,CAAA;CAAX,OAAA,OAAA,GAAA,qBAAA;EAAA,YAAA;EAAA,SAAA;EAAA,MAAA;EAAW,cAAA;EAAA,UAAA;EAAA,MAAA,EAAA,gBAAA,oNAAA;EAAA,UAAA;EAAA,UANZ;EAAgB,UAAA;CAAA,CAAA;;AAMf,GAAA,yBAAA;CAAA,YAAA;CAAA,SAAA;CAAA,UAAA;CAAA,MAAA;CAAW,YAAA,CAAA;EARvB,MAAA;EAAU,MAAA,CAAA;GACT,UAAU;GACV,UAAU;GACV,MAAM,EACJ,OACE,oNACH;EACF,CAAA"}
@@ -1,31 +1,93 @@
1
- import * as i0 from '@angular/core';
2
- import { input, booleanAttribute, computed, Component } from '@angular/core';
3
-
4
- const ALERT_VARIANTS = ['error', 'warning'];
5
- const BASE_CLASSES = 'flex items-start gap-2.5 text-left text-label';
1
+ import * as i0 from "@angular/core";
2
+ import { Component, booleanAttribute, computed, input } from "@angular/core";
3
+ const ALERT_VARIANTS = [
4
+ "error",
5
+ "warning",
6
+ "info"
7
+ ];
8
+ const BASE_CLASSES = "flex items-start gap-2.5 text-left text-label";
6
9
  const VARIANT_CLASSES = {
7
- error: 'rounded-control bg-(--card) px-3.5 py-3 shadow-[inset_0_0_0_1px_var(--border)]',
8
- warning: 'text-(--foreground)',
10
+ error: "rounded-control bg-(--card) px-3.5 py-3 shadow-[inset_0_0_0_1px_var(--border)]",
11
+ warning: "text-(--foreground)",
12
+ info: "rounded-control bg-(--muted) p-3 text-(--foreground)"
13
+ };
14
+ const ROLES = {
15
+ error: "alert",
16
+ warning: "status",
17
+ info: "note"
9
18
  };
10
- /**
11
- * Inline message explaining a failure or a consequence: an icon, an optional heading and a text.
12
- * It fades in when it appears; set `[fadeIn]="false"` on an alert that is part of the page as it
13
- * opens (an error state after a load), which shows without motion.
14
- *
15
- * @example
16
- * <ui-alert heading="Sign-in failed">Try again.</ui-alert>
17
- */
18
- class UiAlert {
19
- variant = input('error', /* @ts-ignore */
20
- ...(ngDevMode ? [{ debugName: "variant" }] : /* istanbul ignore next */ []));
21
- heading = input(/* @ts-ignore */
22
- ...(ngDevMode ? [undefined, { debugName: "heading" }] : /* istanbul ignore next */ []));
23
- fadeIn = input(true, { ...(ngDevMode ? { debugName: "fadeIn" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
24
- classes = computed(() => `${BASE_CLASSES} ${VARIANT_CLASSES[this.variant()]}${this.fadeIn() ? ' ui-enter-fade' : ''}`, /* @ts-ignore */
25
- ...(ngDevMode ? [{ debugName: "classes" }] : /* istanbul ignore next */ []));
26
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: UiAlert, deps: [], target: i0.ɵɵFactoryTarget.Component });
27
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.7", type: UiAlert, isStandalone: true, selector: "ui-alert", inputs: { variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, heading: { classPropertyName: "heading", publicName: "heading", isSignal: true, isRequired: false, transformFunction: null }, fadeIn: { classPropertyName: "fadeIn", publicName: "fadeIn", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "animate.leave": "ui-leave-fade" }, properties: { "class": "classes()", "attr.role": "variant() === 'warning' ? 'status' : 'alert'" } }, ngImport: i0, template: `
28
- @if (variant() === 'warning') {
19
+ var UiAlert = class UiAlert {
20
+ variant = input("error", ...ngDevMode ? [{ debugName: "variant" }] : /* istanbul ignore next */ []);
21
+ heading = input(...ngDevMode ? [void 0, { debugName: "heading" }] : /* istanbul ignore next */ []);
22
+ fadeIn = input(true, {
23
+ ...ngDevMode ? { debugName: "fadeIn" } : /* istanbul ignore next */ {},
24
+ transform: booleanAttribute
25
+ });
26
+ role = computed(() => ROLES[this.variant()], ...ngDevMode ? [{ debugName: "role" }] : /* istanbul ignore next */ []);
27
+ classes = computed(() => `${BASE_CLASSES} ${VARIANT_CLASSES[this.variant()]}${this.fadeIn() ? " ui-enter-fade" : ""}`, ...ngDevMode ? [{ debugName: "classes" }] : /* istanbul ignore next */ []);
28
+ static ɵfac = i0.ɵɵngDeclareFactory({
29
+ minVersion: "12.0.0",
30
+ version: "22.2.0",
31
+ ngImport: i0,
32
+ type: UiAlert,
33
+ deps: [],
34
+ target: i0.ɵɵFactoryTarget.Component
35
+ });
36
+ static ɵcmp = i0.ɵɵngDeclareComponent({
37
+ minVersion: "17.0.0",
38
+ version: "22.2.0",
39
+ type: UiAlert,
40
+ isStandalone: true,
41
+ selector: "ui-alert",
42
+ inputs: {
43
+ variant: {
44
+ classPropertyName: "variant",
45
+ publicName: "variant",
46
+ isSignal: true,
47
+ isRequired: false,
48
+ transformFunction: null
49
+ },
50
+ heading: {
51
+ classPropertyName: "heading",
52
+ publicName: "heading",
53
+ isSignal: true,
54
+ isRequired: false,
55
+ transformFunction: null
56
+ },
57
+ fadeIn: {
58
+ classPropertyName: "fadeIn",
59
+ publicName: "fadeIn",
60
+ isSignal: true,
61
+ isRequired: false,
62
+ transformFunction: null
63
+ }
64
+ },
65
+ host: {
66
+ attributes: { "animate.leave": "ui-leave-fade" },
67
+ properties: {
68
+ "class": "classes()",
69
+ "attr.role": "role()"
70
+ }
71
+ },
72
+ ngImport: i0,
73
+ template: `
74
+ @if (variant() === 'info') {
75
+ <svg
76
+ aria-hidden="true"
77
+ class="mt-px block flex-none stroke-current"
78
+ fill="none"
79
+ height="18"
80
+ stroke-linecap="round"
81
+ stroke-linejoin="round"
82
+ stroke-width="1.75"
83
+ viewBox="0 0 24 24"
84
+ width="18"
85
+ >
86
+ <circle cx="12" cy="12" r="10" />
87
+ <path d="M12 16v-4" />
88
+ <path d="M12 8h.01" />
89
+ </svg>
90
+ } @else if (variant() === 'warning') {
29
91
  <svg
30
92
  aria-hidden="true"
31
93
  class="mt-px block flex-none stroke-(--negative)"
@@ -65,14 +127,37 @@ class UiAlert {
65
127
  }
66
128
  <span class="text-pretty" [class.text-(--muted-foreground)]="heading()"><ng-content /></span>
67
129
  </div>
68
- `, isInline: true });
69
- }
70
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: UiAlert, decorators: [{
71
- type: Component,
72
- args: [{
73
- selector: 'ui-alert',
74
- template: `
75
- @if (variant() === 'warning') {
130
+ `,
131
+ isInline: true
132
+ });
133
+ };
134
+ i0.ɵɵngDeclareClassMetadata({
135
+ minVersion: "12.0.0",
136
+ version: "22.2.0",
137
+ ngImport: i0,
138
+ type: UiAlert,
139
+ decorators: [{
140
+ type: Component,
141
+ args: [{
142
+ selector: "ui-alert",
143
+ template: `
144
+ @if (variant() === 'info') {
145
+ <svg
146
+ aria-hidden="true"
147
+ class="mt-px block flex-none stroke-current"
148
+ fill="none"
149
+ height="18"
150
+ stroke-linecap="round"
151
+ stroke-linejoin="round"
152
+ stroke-width="1.75"
153
+ viewBox="0 0 24 24"
154
+ width="18"
155
+ >
156
+ <circle cx="12" cy="12" r="10" />
157
+ <path d="M12 16v-4" />
158
+ <path d="M12 8h.01" />
159
+ </svg>
160
+ } @else if (variant() === 'warning') {
76
161
  <svg
77
162
  aria-hidden="true"
78
163
  class="mt-px block flex-none stroke-(--negative)"
@@ -113,17 +198,40 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImpor
113
198
  <span class="text-pretty" [class.text-(--muted-foreground)]="heading()"><ng-content /></span>
114
199
  </div>
115
200
  `,
116
- host: {
117
- 'animate.leave': 'ui-leave-fade',
118
- '[class]': 'classes()',
119
- '[attr.role]': "variant() === 'warning' ? 'status' : 'alert'",
120
- },
121
- }]
122
- }], propDecorators: { variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], heading: [{ type: i0.Input, args: [{ isSignal: true, alias: "heading", required: false }] }], fadeIn: [{ type: i0.Input, args: [{ isSignal: true, alias: "fadeIn", required: false }] }] } });
123
-
124
- /**
125
- * Generated bundle index. Do not edit.
126
- */
127
-
201
+ host: {
202
+ "animate.leave": "ui-leave-fade",
203
+ "[class]": "classes()",
204
+ "[attr.role]": "role()"
205
+ }
206
+ }]
207
+ }],
208
+ propDecorators: {
209
+ variant: [{
210
+ type: i0.Input,
211
+ args: [{
212
+ isSignal: true,
213
+ alias: "variant",
214
+ required: false
215
+ }]
216
+ }],
217
+ heading: [{
218
+ type: i0.Input,
219
+ args: [{
220
+ isSignal: true,
221
+ alias: "heading",
222
+ required: false
223
+ }]
224
+ }],
225
+ fadeIn: [{
226
+ type: i0.Input,
227
+ args: [{
228
+ isSignal: true,
229
+ alias: "fadeIn",
230
+ required: false
231
+ }]
232
+ }]
233
+ }
234
+ });
128
235
  export { ALERT_VARIANTS, UiAlert };
129
- //# sourceMappingURL=joanroucoux-cairn-ui-alert.mjs.map
236
+
237
+ //# sourceMappingURL=joanroucoux-cairn-ui-alert.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"joanroucoux-cairn-ui-alert.mjs","sources":["../../../projects/ui/alert/alert.ts","../../../projects/ui/alert/joanroucoux-cairn-ui-alert.ts"],"sourcesContent":["import { Component, booleanAttribute, computed, input } from '@angular/core';\n\nexport const ALERT_VARIANTS = ['error', 'warning'] as const;\nexport type AlertVariant = (typeof ALERT_VARIANTS)[number];\n\nconst BASE_CLASSES = 'flex items-start gap-2.5 text-left text-label';\n\nconst VARIANT_CLASSES: Record<AlertVariant, string> = {\n error: 'rounded-control bg-(--card) px-3.5 py-3 shadow-[inset_0_0_0_1px_var(--border)]',\n warning: 'text-(--foreground)',\n};\n\n/**\n * Inline message explaining a failure or a consequence: an icon, an optional heading and a text.\n * It fades in when it appears; set `[fadeIn]=\"false\"` on an alert that is part of the page as it\n * opens (an error state after a load), which shows without motion.\n *\n * @example\n * <ui-alert heading=\"Sign-in failed\">Try again.</ui-alert>\n */\n@Component({\n selector: 'ui-alert',\n template: `\n @if (variant() === 'warning') {\n <svg\n aria-hidden=\"true\"\n class=\"mt-px block flex-none stroke-(--negative)\"\n fill=\"none\"\n height=\"18\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n stroke-width=\"1.75\"\n viewBox=\"0 0 24 24\"\n width=\"18\"\n >\n <path d=\"m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3\" />\n <path d=\"M12 9v4\" />\n <path d=\"M12 17h.01\" />\n </svg>\n } @else {\n <svg\n aria-hidden=\"true\"\n class=\"block flex-none stroke-(--negative)\"\n fill=\"none\"\n height=\"18\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n stroke-width=\"1.75\"\n viewBox=\"0 0 24 24\"\n width=\"18\"\n [class.mt-px]=\"heading()\"\n >\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <line x1=\"12\" x2=\"12\" y1=\"8\" y2=\"12\" />\n <line x1=\"12\" x2=\"12.01\" y1=\"16\" y2=\"16\" />\n </svg>\n }\n <div class=\"flex flex-col gap-0.5\">\n @if (heading()) {\n <span class=\"font-medium\">{{ heading() }}</span>\n }\n <span class=\"text-pretty\" [class.text-(--muted-foreground)]=\"heading()\"><ng-content /></span>\n </div>\n `,\n host: {\n 'animate.leave': 'ui-leave-fade',\n '[class]': 'classes()',\n '[attr.role]': \"variant() === 'warning' ? 'status' : 'alert'\",\n },\n})\nexport class UiAlert {\n readonly variant = input<AlertVariant>('error');\n readonly heading = input<string>();\n readonly fadeIn = input(true, { transform: booleanAttribute });\n\n protected readonly classes = computed(\n () => `${BASE_CLASSES} ${VARIANT_CLASSES[this.variant()]}${this.fadeIn() ? ' ui-enter-fade' : ''}`,\n );\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;MAEa,cAAc,GAAG,CAAC,OAAO,EAAE,SAAS;AAGjD,MAAM,YAAY,GAAG,+CAA+C;AAEpE,MAAM,eAAe,GAAiC;AACpD,IAAA,KAAK,EAAE,gFAAgF;AACvF,IAAA,OAAO,EAAE,qBAAqB;CAC/B;AAED;;;;;;;AAOG;MAmDU,OAAO,CAAA;IACT,OAAO,GAAG,KAAK,CAAe,OAAO;gFAAC;AACtC,IAAA,OAAO,GAAG,KAAK;2FAAU;IACzB,MAAM,GAAG,KAAK,CAAC,IAAI,8EAAI,SAAS,EAAE,gBAAgB,EAAA,CAAG;AAE3C,IAAA,OAAO,GAAG,QAAQ,CACnC,MAAM,CAAA,EAAG,YAAY,CAAA,CAAA,EAAI,eAAe,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,CAAA,EAAG,IAAI,CAAC,MAAM,EAAE,GAAG,gBAAgB,GAAG,EAAE,CAAA,CAAE;gFACnG;uGAPU,OAAO,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAP,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,OAAO,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,UAAA,EAAA,MAAA,EAAA,EAAA,OAAA,EAAA,EAAA,iBAAA,EAAA,SAAA,EAAA,UAAA,EAAA,SAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,OAAA,EAAA,EAAA,iBAAA,EAAA,SAAA,EAAA,UAAA,EAAA,SAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,MAAA,EAAA,EAAA,iBAAA,EAAA,QAAA,EAAA,UAAA,EAAA,QAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,IAAA,EAAA,EAAA,UAAA,EAAA,EAAA,eAAA,EAAA,eAAA,EAAA,EAAA,UAAA,EAAA,EAAA,OAAA,EAAA,WAAA,EAAA,WAAA,EAAA,8CAAA,EAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EAhDR;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAyCT,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,CAAA;;2FAOU,OAAO,EAAA,UAAA,EAAA,CAAA;kBAlDnB,SAAS;AAAC,YAAA,IAAA,EAAA,CAAA;AACT,oBAAA,QAAQ,EAAE,UAAU;AACpB,oBAAA,QAAQ,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAyCT,EAAA,CAAA;AACD,oBAAA,IAAI,EAAE;AACJ,wBAAA,eAAe,EAAE,eAAe;AAChC,wBAAA,SAAS,EAAE,WAAW;AACtB,wBAAA,aAAa,EAAE,8CAA8C;AAC9D,qBAAA;AACF,iBAAA;;;ACrED;;AAEG;;;;"}
1
+ {"version":3,"file":"joanroucoux-cairn-ui-alert.mjs","names":[],"sources":["../../../projects/ui/alert/alert.ts"],"sourcesContent":["import { Component, booleanAttribute, computed, input } from '@angular/core';\n\nexport const ALERT_VARIANTS = ['error', 'warning', 'info'] as const;\nexport type AlertVariant = (typeof ALERT_VARIANTS)[number];\n\nconst BASE_CLASSES = 'flex items-start gap-2.5 text-left text-label';\n\nconst VARIANT_CLASSES: Record<AlertVariant, string> = {\n error: 'rounded-control bg-(--card) px-3.5 py-3 shadow-[inset_0_0_0_1px_var(--border)]',\n warning: 'text-(--foreground)',\n info: 'rounded-control bg-(--muted) p-3 text-(--foreground)',\n};\n\nconst ROLES: Record<AlertVariant, string> = { error: 'alert', warning: 'status', info: 'note' };\n\n/**\n * Inline message explaining a failure or a consequence, or static help with `info`: an icon, an optional heading and a text.\n * It fades in when it appears; set `[fadeIn]=\"false\"` on an alert that is part of the page as it\n * opens.\n *\n * @example\n * <ui-alert heading=\"Sign-in failed\">Try again.</ui-alert>\n */\n@Component({\n selector: 'ui-alert',\n template: `\n @if (variant() === 'info') {\n <svg\n aria-hidden=\"true\"\n class=\"mt-px block flex-none stroke-current\"\n fill=\"none\"\n height=\"18\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n stroke-width=\"1.75\"\n viewBox=\"0 0 24 24\"\n width=\"18\"\n >\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <path d=\"M12 16v-4\" />\n <path d=\"M12 8h.01\" />\n </svg>\n } @else if (variant() === 'warning') {\n <svg\n aria-hidden=\"true\"\n class=\"mt-px block flex-none stroke-(--negative)\"\n fill=\"none\"\n height=\"18\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n stroke-width=\"1.75\"\n viewBox=\"0 0 24 24\"\n width=\"18\"\n >\n <path d=\"m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3\" />\n <path d=\"M12 9v4\" />\n <path d=\"M12 17h.01\" />\n </svg>\n } @else {\n <svg\n aria-hidden=\"true\"\n class=\"block flex-none stroke-(--negative)\"\n fill=\"none\"\n height=\"18\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n stroke-width=\"1.75\"\n viewBox=\"0 0 24 24\"\n width=\"18\"\n [class.mt-px]=\"heading()\"\n >\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <line x1=\"12\" x2=\"12\" y1=\"8\" y2=\"12\" />\n <line x1=\"12\" x2=\"12.01\" y1=\"16\" y2=\"16\" />\n </svg>\n }\n <div class=\"flex flex-col gap-0.5\">\n @if (heading()) {\n <span class=\"font-medium\">{{ heading() }}</span>\n }\n <span class=\"text-pretty\" [class.text-(--muted-foreground)]=\"heading()\"><ng-content /></span>\n </div>\n `,\n host: {\n 'animate.leave': 'ui-leave-fade',\n '[class]': 'classes()',\n '[attr.role]': 'role()',\n },\n})\nexport class UiAlert {\n readonly variant = input<AlertVariant>('error');\n readonly heading = input<string>();\n readonly fadeIn = input(true, { transform: booleanAttribute });\n\n protected readonly role = computed(() => ROLES[this.variant()]);\n\n protected readonly classes = computed(\n () => `${BASE_CLASSES} ${VARIANT_CLASSES[this.variant()]}${this.fadeIn() ? ' ui-enter-fade' : ''}`,\n );\n}\n"],"mappings":";;AAEA,MAAa,iBAAiB;CAAC;CAAS;CAAW;AAAM;AAGzD,MAAM,eAAe;AAErB,MAAM,kBAAgD;CACpD,OAAO;CACP,SAAS;CACT,MAAM;AACP;AAED,MAAM,QAAsC;CAAE,OAAO;CAAS,SAAS;CAAU,MAAM;AAAM;AA4E7F,IAAa,UAAb,MAAa,QAAO;CACT,UAAU,MAAoB,SAAQ,GAAA,YAAA,CAAA,EAAA,WAAA,UAAA,CAAA,+BAAA,CAAA,CAAA;CACtC,UAAU,MAAe,GAAA,YAAA,CAAA,QAAA,EAAA,WAAA,UAAA,CAAA,+BAAA,CAAA,CAAA;CACzB,SAAS,MAAM,MAAI;EAAA,GAAA,YAAA,EAAA,WAAA,SAAA,+BAAA,CAAA;EAAI,WAAW;CAAgB,CAAA;CAExC,OAAO,eAAe,MAAM,KAAK,QAAO,IAAI,GAAA,YAAA,CAAA,EAAA,WAAA,OAAA,CAAA,+BAAA,CAAA,CAAA;CAE5C,UAAU,eACrB,GAAG,aAAY,GAAI,gBAAgB,KAAK,QAAO,KAAM,KAAK,OAAM,IAAK,mBAAmB,MAC/F,GAAA,YAAA,CAAA,EAAA,WAAA,UAAA,CAAA,+BAAA,CAAA,CAAA;CATU,OAAA,OAAA,GAAA,mBAAA;EAAA,YAAA;EAAA,SAAA;EAAA,UAAA;EAAA,MAAA;EAAO,MAAA,CAAA;EAAA,QAAA,GAAA,gBAAA;CAAA,CAAA;CAAP,OAAA,OAAA,GAAA,qBAAA;EAAA,YAAA;EAAA,SAAA;EAAA,MAAA;EAAO,cAAA;EAAA,UAAA;EAAA,QAAA;GAAA,SAAA;IAAA,mBAAA;IAAA,YAAA;IAAA,UAAA;IAAA,YAAA;IAAA,mBAAA;GAAA;GAAA,SAAA;IAAA,mBAAA;IAAA,YAAA;IAAA,UAAA;IAAA,YAAA;IAAA,mBAAA;GAAA;GAAA,QAAA;IAAA,mBAAA;IAAA,YAAA;IAAA,UAAA;IAAA,YAAA;IAAA,mBAAA;GAAA;EAAA;EAAA,MAAA;GAAA,YAAA,EAAA,iBAAA,gBAAA;GAAA,YAAA;IAAA,SAAA;IAAA,aAAA;GAAA;EAAA;EAAA,UAAA;EAAA,UAhER;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAyDT,UAAA;CAAA,CAAA;;AAOU,GAAA,yBAAA;CAAA,YAAA;CAAA,SAAA;CAAA,UAAA;CAAA,MAAA;CAAO,YAAA,CAAA;EAlEnB,MAAA;EAAU,MAAA,CAAA;GACT,UAAU;GACV,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0DV,MAAM;IACJ,iBAAiB;IACjB,WAAW;IACX,eAAe;GAChB;EACF,CAAA"}