@redvars/peacock 3.5.1 → 3.6.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 (225) hide show
  1. package/dist/{BaseButton-DuASuVth.js → BaseButton-BNFAYn-S.js} +2 -2
  2. package/dist/{BaseButton-DuASuVth.js.map → BaseButton-BNFAYn-S.js.map} +1 -1
  3. package/dist/BaseInput-14YmcfK7.js +27 -0
  4. package/dist/BaseInput-14YmcfK7.js.map +1 -0
  5. package/dist/banner.js +2 -3
  6. package/dist/banner.js.map +1 -1
  7. package/dist/{button-DouvOfEU.js → button-colors-Ccys3hvS.js} +5 -294
  8. package/dist/button-colors-Ccys3hvS.js.map +1 -0
  9. package/dist/button-group.js +226 -6
  10. package/dist/button-group.js.map +1 -1
  11. package/dist/button.js +294 -8
  12. package/dist/button.js.map +1 -1
  13. package/dist/calendar-column-view.js +634 -0
  14. package/dist/calendar-column-view.js.map +1 -0
  15. package/dist/calendar-event-BrQ_SEKD.js +199 -0
  16. package/dist/calendar-event-BrQ_SEKD.js.map +1 -0
  17. package/dist/calendar-month-view.js +376 -0
  18. package/dist/calendar-month-view.js.map +1 -0
  19. package/dist/calendar.js +339 -0
  20. package/dist/calendar.js.map +1 -0
  21. package/dist/canvas.js +361 -0
  22. package/dist/canvas.js.map +1 -0
  23. package/dist/cb-compound-expression.js +125 -0
  24. package/dist/cb-compound-expression.js.map +1 -0
  25. package/dist/cb-divider.js +150 -0
  26. package/dist/cb-divider.js.map +1 -0
  27. package/dist/cb-expression.js +75 -0
  28. package/dist/cb-expression.js.map +1 -0
  29. package/dist/cb-predicate.js +137 -0
  30. package/dist/cb-predicate.js.map +1 -0
  31. package/dist/code-editor.js +2 -1
  32. package/dist/code-editor.js.map +1 -1
  33. package/dist/code-highlighter.js +1 -1
  34. package/dist/code-highlighter.js.map +1 -1
  35. package/dist/condition-builder.js +58 -0
  36. package/dist/condition-builder.js.map +1 -0
  37. package/dist/custom-elements-jsdocs.json +8479 -3965
  38. package/dist/custom-elements.json +15228 -7544
  39. package/dist/dropdown-button.js +216 -0
  40. package/dist/dropdown-button.js.map +1 -0
  41. package/dist/event-manager-D-QCmUgR.js +113 -0
  42. package/dist/event-manager-D-QCmUgR.js.map +1 -0
  43. package/dist/fab.js +1 -1
  44. package/dist/flow-designer-DvTUrDp5.js +1656 -0
  45. package/dist/flow-designer-DvTUrDp5.js.map +1 -0
  46. package/dist/flow-designer-node-BWrPuxAR.js +548 -0
  47. package/dist/flow-designer-node-BWrPuxAR.js.map +1 -0
  48. package/dist/flow-designer-node.js +4 -0
  49. package/dist/flow-designer-node.js.map +1 -0
  50. package/dist/flow-designer.js +16 -0
  51. package/dist/flow-designer.js.map +1 -0
  52. package/dist/html-editor.js +27516 -0
  53. package/dist/html-editor.js.map +1 -0
  54. package/dist/icon-button-CK1ZuE-2.js +247 -0
  55. package/dist/icon-button-CK1ZuE-2.js.map +1 -0
  56. package/dist/index.js +29 -6
  57. package/dist/index.js.map +1 -1
  58. package/dist/{is-dark-mode-DicqGkCJ.js → is-dark-mode-DOcaw4Yq.js} +2 -27
  59. package/dist/is-dark-mode-DOcaw4Yq.js.map +1 -0
  60. package/dist/modal.js +412 -0
  61. package/dist/modal.js.map +1 -0
  62. package/dist/{navigation-rail-Lxetd5-Z.js → navigation-rail-DTTkqohi.js} +1049 -2391
  63. package/dist/navigation-rail-DTTkqohi.js.map +1 -0
  64. package/dist/notification-manager.js +268 -0
  65. package/dist/notification-manager.js.map +1 -0
  66. package/dist/peacock-loader.js +93 -8
  67. package/dist/peacock-loader.js.map +1 -1
  68. package/dist/popover-NC7b1lTq.js +1971 -0
  69. package/dist/popover-NC7b1lTq.js.map +1 -0
  70. package/dist/popover-content.js +125 -0
  71. package/dist/popover-content.js.map +1 -0
  72. package/dist/popover.js +4 -0
  73. package/dist/popover.js.map +1 -0
  74. package/dist/split-button.js +388 -0
  75. package/dist/split-button.js.map +1 -0
  76. package/dist/src/__controllers/floating-controller.d.ts +35 -0
  77. package/dist/src/calendar/base-event.d.ts +10 -0
  78. package/dist/src/calendar/calendar-column-view.d.ts +41 -0
  79. package/dist/src/calendar/calendar-event.d.ts +7 -0
  80. package/dist/src/calendar/calendar-month-view.d.ts +31 -0
  81. package/dist/src/calendar/calendar.d.ts +65 -0
  82. package/dist/src/calendar/event-manager.d.ts +17 -0
  83. package/dist/src/calendar/index.d.ts +4 -0
  84. package/dist/src/calendar/types.d.ts +13 -0
  85. package/dist/src/calendar/utils.d.ts +31 -0
  86. package/dist/src/canvas/canvas.d.ts +92 -0
  87. package/dist/src/canvas/index.d.ts +2 -0
  88. package/dist/src/condition-builder/cb-compound-expression.d.ts +31 -0
  89. package/dist/src/condition-builder/cb-divider.d.ts +26 -0
  90. package/dist/src/condition-builder/cb-expression.d.ts +31 -0
  91. package/dist/src/condition-builder/cb-predicate.d.ts +30 -0
  92. package/dist/src/condition-builder/condition-builder.d.ts +27 -0
  93. package/dist/src/condition-builder/index.d.ts +5 -0
  94. package/dist/src/dropdown-button/dropdown-button.d.ts +68 -0
  95. package/dist/src/dropdown-button/index.d.ts +1 -0
  96. package/dist/src/flow-designer/commands.d.ts +66 -0
  97. package/dist/src/flow-designer/flow-designer-node.d.ts +46 -0
  98. package/dist/src/flow-designer/flow-designer.d.ts +133 -0
  99. package/dist/src/flow-designer/index.d.ts +7 -0
  100. package/dist/src/flow-designer/layout.d.ts +30 -0
  101. package/dist/src/flow-designer/types.d.ts +142 -0
  102. package/dist/src/flow-designer/validation.d.ts +43 -0
  103. package/dist/src/flow-designer/workflow-utils.d.ts +40 -0
  104. package/dist/src/html-editor/html-editor.d.ts +89 -0
  105. package/dist/src/html-editor/index.d.ts +2 -0
  106. package/dist/src/index.d.ts +15 -0
  107. package/dist/src/list/index.d.ts +2 -0
  108. package/dist/src/list/list-item.d.ts +35 -0
  109. package/dist/src/list/list.d.ts +28 -0
  110. package/dist/src/menu/menu/menu.d.ts +5 -7
  111. package/dist/src/menu/menu-item/menu-item.d.ts +14 -13
  112. package/dist/src/modal/index.d.ts +1 -0
  113. package/dist/src/modal/modal.d.ts +57 -0
  114. package/dist/src/navigation-rail/navigation-rail.d.ts +3 -7
  115. package/dist/src/notification-manager/index.d.ts +1 -0
  116. package/dist/src/notification-manager/notification-manager.d.ts +44 -0
  117. package/dist/src/number-field/number-field.d.ts +2 -2
  118. package/dist/src/popover/index.d.ts +2 -0
  119. package/dist/src/popover/popover-content.d.ts +29 -0
  120. package/dist/src/popover/popover.d.ts +62 -0
  121. package/dist/src/split-button/index.d.ts +1 -0
  122. package/dist/src/split-button/split-button.d.ts +72 -0
  123. package/dist/src/svg/index.d.ts +1 -0
  124. package/dist/src/svg/svg.d.ts +38 -0
  125. package/dist/src/toolbar/toolbar.d.ts +3 -3
  126. package/dist/src/tooltip/tooltip.d.ts +2 -15
  127. package/dist/test/flow-designer.test.d.ts +1 -0
  128. package/dist/toolbar.js +3 -3
  129. package/dist/toolbar.js.map +1 -1
  130. package/dist/tsconfig.tsbuildinfo +1 -1
  131. package/package.json +10 -2
  132. package/readme.md +3 -3
  133. package/src/__controllers/floating-controller.ts +237 -0
  134. package/src/banner/banner.scss +2 -3
  135. package/src/button/button/button.ts +1 -0
  136. package/src/calendar/base-event.ts +49 -0
  137. package/src/calendar/calendar-column-view.scss +326 -0
  138. package/src/calendar/calendar-column-view.ts +392 -0
  139. package/src/calendar/calendar-event.ts +20 -0
  140. package/src/calendar/calendar-month-view.scss +192 -0
  141. package/src/calendar/calendar-month-view.ts +244 -0
  142. package/src/calendar/calendar.scss +71 -0
  143. package/src/calendar/calendar.ts +298 -0
  144. package/src/calendar/event-manager.ts +117 -0
  145. package/src/calendar/index.ts +4 -0
  146. package/src/calendar/types.ts +14 -0
  147. package/src/calendar/utils.ts +180 -0
  148. package/src/canvas/canvas.scss +60 -0
  149. package/src/canvas/canvas.ts +391 -0
  150. package/src/canvas/index.ts +2 -0
  151. package/src/code-highlighter/code-highlighter.ts +1 -1
  152. package/src/condition-builder/cb-compound-expression.scss +37 -0
  153. package/src/condition-builder/cb-compound-expression.ts +80 -0
  154. package/src/condition-builder/cb-divider.scss +93 -0
  155. package/src/condition-builder/cb-divider.ts +56 -0
  156. package/src/condition-builder/cb-expression.scss +14 -0
  157. package/src/condition-builder/cb-expression.ts +49 -0
  158. package/src/condition-builder/cb-predicate.scss +35 -0
  159. package/src/condition-builder/cb-predicate.ts +102 -0
  160. package/src/condition-builder/condition-builder.scss +13 -0
  161. package/src/condition-builder/condition-builder.ts +38 -0
  162. package/src/condition-builder/index.ts +5 -0
  163. package/src/dropdown-button/demo/index.html +110 -0
  164. package/src/dropdown-button/dropdown-button.scss +22 -0
  165. package/src/dropdown-button/dropdown-button.ts +206 -0
  166. package/src/dropdown-button/index.ts +1 -0
  167. package/src/flow-designer/DEMO.md +239 -0
  168. package/src/flow-designer/commands.ts +278 -0
  169. package/src/flow-designer/flow-designer-node.ts +172 -0
  170. package/src/flow-designer/flow-designer.scss +457 -0
  171. package/src/flow-designer/flow-designer.ts +611 -0
  172. package/src/flow-designer/index.ts +41 -0
  173. package/src/flow-designer/layout.ts +357 -0
  174. package/src/flow-designer/types.ts +166 -0
  175. package/src/flow-designer/validation.ts +284 -0
  176. package/src/flow-designer/workflow-utils.ts +282 -0
  177. package/src/html-editor/html-editor.scss +188 -0
  178. package/src/html-editor/html-editor.ts +491 -0
  179. package/src/html-editor/index.ts +3 -0
  180. package/src/index.ts +27 -1
  181. package/src/list/index.ts +2 -0
  182. package/src/list/list-item.scss +111 -0
  183. package/src/list/list-item.ts +175 -0
  184. package/src/list/list.scss +24 -0
  185. package/src/list/list.ts +51 -0
  186. package/src/menu/menu/menu.scss +2 -2
  187. package/src/menu/menu/menu.ts +91 -101
  188. package/src/menu/menu-item/menu-item.scss +4 -0
  189. package/src/menu/menu-item/menu-item.ts +82 -78
  190. package/src/modal/index.ts +1 -0
  191. package/src/modal/modal.scss +206 -0
  192. package/src/modal/modal.ts +195 -0
  193. package/src/navigation-rail/navigation-rail-item.scss +7 -38
  194. package/src/navigation-rail/navigation-rail-item.ts +1 -2
  195. package/src/navigation-rail/navigation-rail.scss +17 -21
  196. package/src/navigation-rail/navigation-rail.ts +6 -9
  197. package/src/notification-manager/index.ts +1 -0
  198. package/src/notification-manager/notification-manager.scss +113 -0
  199. package/src/notification-manager/notification-manager.ts +199 -0
  200. package/src/number-field/number-field.ts +2 -2
  201. package/src/peacock-loader.ts +83 -0
  202. package/src/popover/index.ts +2 -0
  203. package/src/popover/popover-content.scss +69 -0
  204. package/src/popover/popover-content.ts +51 -0
  205. package/src/popover/popover.scss +7 -0
  206. package/src/popover/popover.ts +170 -0
  207. package/src/split-button/index.ts +1 -0
  208. package/src/split-button/split-button-colors.scss +56 -0
  209. package/src/split-button/split-button-sizes.scss +28 -0
  210. package/src/split-button/split-button.scss +79 -0
  211. package/src/split-button/split-button.ts +236 -0
  212. package/src/svg/index.ts +1 -0
  213. package/src/svg/svg.scss +91 -0
  214. package/src/svg/svg.ts +160 -0
  215. package/src/table/table.ts +2 -2
  216. package/src/toolbar/toolbar.ts +3 -3
  217. package/src/tooltip/tooltip.scss +4 -3
  218. package/src/tooltip/tooltip.ts +46 -104
  219. package/dist/button-DouvOfEU.js.map +0 -1
  220. package/dist/button-group-CEdMwvJJ.js +0 -464
  221. package/dist/button-group-CEdMwvJJ.js.map +0 -1
  222. package/dist/is-dark-mode-DicqGkCJ.js.map +0 -1
  223. package/dist/navigation-rail-Lxetd5-Z.js.map +0 -1
  224. package/dist/src/menu/menu/MenuSurfaceController.d.ts +0 -18
  225. package/src/menu/menu/MenuSurfaceController.ts +0 -61
@@ -0,0 +1,206 @@
1
+ @use "../../scss/mixin";
2
+
3
+ @include mixin.base-styles;
4
+
5
+ :host {
6
+ display: contents;
7
+
8
+ --modal-container-color: var(--color-surface-container-high, #ece6f0);
9
+ --modal-scrim-color: rgba(0, 0, 0, 0.32);
10
+ --modal-shape: var(--shape-corner-extra-large, 28px);
11
+ --modal-min-width: 280px;
12
+ --modal-max-width: 560px;
13
+ --modal-max-height: 90dvh;
14
+ --modal-transition-duration: var(--duration-medium2, 300ms);
15
+ --modal-transition-easing: var(--easing-emphasized, cubic-bezier(0.2, 0, 0, 1));
16
+ --modal-heading-color: var(--color-on-surface, #1c1b1f);
17
+ --modal-subheading-color: var(--color-on-surface-variant, #49454f);
18
+ --modal-content-color: var(--color-on-surface-variant, #49454f);
19
+ --modal-divider-color: var(--color-outline-variant, #cac4d0);
20
+ --modal-elevation: var(--elevation-level3, 0 4px 8px 3px rgba(0, 0, 0, 0.15), 0 1px 3px rgba(0, 0, 0, 0.3));
21
+ }
22
+
23
+ /* Scrim backdrop */
24
+ .scrim {
25
+ background-color: var(--modal-scrim-color);
26
+ inset: 0;
27
+ opacity: 0;
28
+ pointer-events: none;
29
+ position: fixed;
30
+ transition: opacity var(--modal-transition-duration) var(--modal-transition-easing);
31
+ z-index: 1000;
32
+ }
33
+
34
+ .scrim.visible {
35
+ opacity: 1;
36
+ pointer-events: auto;
37
+ }
38
+
39
+ /* Dialog wrapper — centres the dialog on screen */
40
+ .dialog-wrapper {
41
+ align-items: center;
42
+ display: flex;
43
+ inset: 0;
44
+ justify-content: center;
45
+ overflow-y: auto;
46
+ padding: var(--spacing-400, 2rem) var(--spacing-200, 1rem);
47
+ position: fixed;
48
+ z-index: 1001;
49
+ }
50
+
51
+ /* Dialog container */
52
+ .dialog {
53
+ background-color: var(--modal-container-color);
54
+ border-radius: var(--modal-shape);
55
+ box-shadow: var(--modal-elevation);
56
+ display: flex;
57
+ flex-direction: column;
58
+ max-height: var(--modal-max-height);
59
+ max-width: var(--modal-max-width);
60
+ min-width: var(--modal-min-width);
61
+ opacity: 0;
62
+ outline: none;
63
+ overflow: hidden;
64
+ position: relative;
65
+ transform: scale(0.9);
66
+ width: 100%;
67
+
68
+ &.open {
69
+ animation: modal-enter var(--modal-transition-duration) var(--modal-transition-easing) forwards;
70
+ }
71
+
72
+ &:not(.open) {
73
+ animation: modal-exit var(--modal-transition-duration) var(--modal-transition-easing) forwards;
74
+ }
75
+ }
76
+
77
+ /* Sizes */
78
+ .dialog.size-xs {
79
+ --modal-max-width: 320px;
80
+ }
81
+
82
+ .dialog.size-sm {
83
+ --modal-max-width: 420px;
84
+ }
85
+
86
+ .dialog.size-md {
87
+ --modal-max-width: 560px;
88
+ }
89
+
90
+ .dialog.size-lg {
91
+ --modal-max-width: 800px;
92
+ }
93
+
94
+ .dialog.size-fullscreen {
95
+ --modal-max-width: 100%;
96
+ --modal-max-height: 100%;
97
+ border-radius: 0;
98
+ max-height: 100dvh;
99
+ max-width: 100vw;
100
+ }
101
+
102
+ .dialog-wrapper:has(.dialog.size-fullscreen) {
103
+ padding: 0;
104
+ }
105
+
106
+ /* Header */
107
+ .dialog-header {
108
+ align-items: flex-start;
109
+ display: flex;
110
+ gap: var(--spacing-200, 1rem);
111
+ padding: var(--spacing-300, 1.5rem) var(--spacing-300, 1.5rem) var(--spacing-200, 1rem);
112
+ }
113
+
114
+ .dialog-heading-section {
115
+ flex: 1;
116
+ min-width: 0;
117
+ }
118
+
119
+ .dialog-subheading {
120
+ color: var(--modal-subheading-color);
121
+ font-family: var(--typography-label-medium-font-family, sans-serif);
122
+ font-size: var(--typography-label-medium-font-size, 0.75rem);
123
+ font-weight: var(--typography-label-medium-font-weight, 500);
124
+ letter-spacing: var(--typography-label-medium-letter-spacing, 0.05em);
125
+ line-height: var(--typography-label-medium-line-height, 1.25rem);
126
+ margin: 0 0 var(--spacing-050, 0.25rem);
127
+ text-transform: uppercase;
128
+ }
129
+
130
+ .dialog-heading {
131
+ color: var(--modal-heading-color);
132
+ font-family: var(--typography-headline-small-font-family, sans-serif);
133
+ font-size: var(--typography-headline-small-font-size, 1.5rem);
134
+ font-weight: var(--typography-headline-small-font-weight, 400);
135
+ letter-spacing: var(--typography-headline-small-letter-spacing, 0);
136
+ line-height: var(--typography-headline-small-line-height, 2rem);
137
+ margin: 0;
138
+ }
139
+
140
+ .dialog-close {
141
+ flex-shrink: 0;
142
+ margin-block-start: -0.25rem;
143
+ margin-inline-end: -0.25rem;
144
+ }
145
+
146
+ /* Body content */
147
+ .dialog-content {
148
+ color: var(--modal-content-color);
149
+ flex: 1 1 auto;
150
+ overflow-y: auto;
151
+ padding: 0 var(--spacing-300, 1.5rem) var(--spacing-300, 1.5rem);
152
+ }
153
+
154
+ /* When there is no header */
155
+ .dialog:not(:has(.dialog-header)) .dialog-content {
156
+ padding-top: var(--spacing-300, 1.5rem);
157
+ }
158
+
159
+ /* Footer */
160
+ .dialog-footer {
161
+ border-top: 1px solid transparent;
162
+ }
163
+
164
+ .dialog-footer:has(slot:not(:empty)),
165
+ .dialog-footer slot::slotted(*) {
166
+ border-top-color: var(--modal-divider-color);
167
+ }
168
+
169
+ /* Loading overlay */
170
+ .dialog-loader {
171
+ align-items: center;
172
+ display: flex;
173
+ inset: 0;
174
+ justify-content: center;
175
+ position: absolute;
176
+ }
177
+
178
+ .dialog-loader-scrim {
179
+ background-color: var(--modal-container-color);
180
+ inset: 0;
181
+ opacity: 0.72;
182
+ position: absolute;
183
+ }
184
+
185
+ /* Animations */
186
+ @keyframes modal-enter {
187
+ from {
188
+ opacity: 0;
189
+ transform: scale(0.9);
190
+ }
191
+ to {
192
+ opacity: 1;
193
+ transform: scale(1);
194
+ }
195
+ }
196
+
197
+ @keyframes modal-exit {
198
+ from {
199
+ opacity: 1;
200
+ transform: scale(1);
201
+ }
202
+ to {
203
+ opacity: 0;
204
+ transform: scale(0.9);
205
+ }
206
+ }
@@ -0,0 +1,195 @@
1
+ import { LitElement, html, nothing } from 'lit';
2
+ import { property, state } from 'lit/decorators.js';
3
+ import { classMap } from 'lit/directives/class-map.js';
4
+ import IndividualComponent from '../IndividualComponent.js';
5
+ import styles from './modal.scss';
6
+
7
+ type ModalSize = 'xs' | 'sm' | 'md' | 'lg' | 'fullscreen';
8
+
9
+ /**
10
+ * @label Modal
11
+ * @tag wc-modal
12
+ * @rawTag modal-wc
13
+ * @summary A Material Design 3 dialog/modal for displaying content in a layer above the page, with optional header, body, and footer slots.
14
+ *
15
+ * @cssprop --modal-container-color - Background color of the dialog container.
16
+ * @cssprop --modal-scrim-color - Color of the scrim backdrop.
17
+ * @cssprop --modal-shape - Corner radius of the dialog container.
18
+ * @cssprop --modal-min-width - Minimum width of the dialog.
19
+ * @cssprop --modal-max-width - Maximum width of the dialog.
20
+ * @cssprop --modal-max-height - Maximum height of the dialog.
21
+ *
22
+ * @example
23
+ * ```html
24
+ * MODAL
25
+ * ```
26
+ * @tags overlay, dialog, feedback
27
+ */
28
+ @IndividualComponent
29
+ export class Modal extends LitElement {
30
+ static styles = [styles];
31
+
32
+ /** Whether the modal is open. */
33
+ @property({ type: Boolean, reflect: true }) open = false;
34
+
35
+ /** Heading text shown in the modal header. */
36
+ @property({ type: String, reflect: true }) heading = '';
37
+
38
+ /** Optional subheading / label text shown above the heading. */
39
+ @property({ type: String, reflect: true }) subheading = '';
40
+
41
+ /**
42
+ * Size of the modal dialog.
43
+ * - `"xs"`: Extra-small.
44
+ * - `"sm"`: Small.
45
+ * - `"md"`: Medium (default).
46
+ * - `"lg"`: Large.
47
+ * - `"fullscreen"`: Full-screen dialog.
48
+ */
49
+ @property({ type: String, reflect: true }) size: ModalSize = 'md';
50
+
51
+ /** When true, hides the close button in the header. */
52
+ @property({ type: Boolean, reflect: true, attribute: 'hide-close' })
53
+ hideClose = false;
54
+
55
+ /** When true, renders a loading overlay inside the modal. */
56
+ @property({ type: Boolean, reflect: true, attribute: 'show-loader' })
57
+ showLoader = false;
58
+
59
+ /** When true, clicking the scrim will not close the modal. */
60
+ @property({ type: Boolean, attribute: 'no-scrim-close' }) noScrimClose = false;
61
+
62
+ @state() private _visible = false;
63
+
64
+ show() {
65
+ this.open = true;
66
+ }
67
+
68
+ hide() {
69
+ this._close('programmatic');
70
+ }
71
+
72
+ private _close(reason: string) {
73
+ if (!this.open) return;
74
+ this.open = false;
75
+ this.dispatchEvent(
76
+ new CustomEvent('modal-close', {
77
+ detail: { reason },
78
+ bubbles: true,
79
+ composed: true,
80
+ }),
81
+ );
82
+ }
83
+
84
+ private _handleScrimClick() {
85
+ if (!this.noScrimClose) {
86
+ this._close('scrim');
87
+ }
88
+ }
89
+
90
+ private _handleCloseClick() {
91
+ this._close('close-button');
92
+ }
93
+
94
+ private readonly _handleKeydown = (e: KeyboardEvent) => {
95
+ if (e.key === 'Escape') {
96
+ this._close('escape');
97
+ }
98
+ };
99
+
100
+ protected updated(changedProperties: Map<string, unknown>) {
101
+ if (changedProperties.has('open')) {
102
+ if (this.open) {
103
+ this._visible = true;
104
+ document.body.style.overflow = 'hidden';
105
+ document.addEventListener('keydown', this._handleKeydown);
106
+ } else {
107
+ document.body.style.overflow = '';
108
+ document.removeEventListener('keydown', this._handleKeydown);
109
+ }
110
+ }
111
+ }
112
+
113
+ disconnectedCallback() {
114
+ super.disconnectedCallback();
115
+ document.body.style.overflow = '';
116
+ document.removeEventListener('keydown', this._handleKeydown);
117
+ }
118
+
119
+ private _handleAnimationEnd(e: AnimationEvent) {
120
+ if (e.animationName === 'modal-exit') {
121
+ this._visible = false;
122
+ }
123
+ }
124
+
125
+ render() {
126
+ if (!this.open && !this._visible) return nothing;
127
+
128
+ const hasHeader = this.heading || this.subheading || !this.hideClose;
129
+
130
+ return html`
131
+ <div
132
+ class=${classMap({ scrim: true, visible: this.open })}
133
+ @click=${this._handleScrimClick}
134
+ aria-hidden="true"
135
+ ></div>
136
+
137
+ <div class="dialog-wrapper" role="presentation">
138
+ <div
139
+ class=${classMap({
140
+ dialog: true,
141
+ open: this.open,
142
+ [`size-${this.size}`]: true,
143
+ 'show-loader': this.showLoader,
144
+ })}
145
+ role="dialog"
146
+ aria-modal="true"
147
+ aria-labelledby=${this.heading ? 'modal-heading' : nothing}
148
+ @animationend=${this._handleAnimationEnd}
149
+ >
150
+ ${hasHeader
151
+ ? html`
152
+ <div class="dialog-header">
153
+ <div class="dialog-heading-section">
154
+ ${this.subheading
155
+ ? html`<p class="dialog-subheading">${this.subheading}</p>`
156
+ : nothing}
157
+ ${this.heading
158
+ ? html`<h2 id="modal-heading" class="dialog-heading">
159
+ ${this.heading}
160
+ </h2>`
161
+ : nothing}
162
+ </div>
163
+ ${!this.hideClose
164
+ ? html`<wc-icon-button
165
+ class="dialog-close"
166
+ variant="text"
167
+ aria-label="Close dialog"
168
+ @click=${this._handleCloseClick}
169
+ >
170
+ <wc-icon name="close"></wc-icon>
171
+ </wc-icon-button>`
172
+ : nothing}
173
+ </div>
174
+ `
175
+ : nothing}
176
+
177
+ <div class="dialog-content">
178
+ <slot></slot>
179
+ </div>
180
+
181
+ <div class="dialog-footer">
182
+ <slot name="footer"></slot>
183
+ </div>
184
+
185
+ ${this.showLoader
186
+ ? html`<div class="dialog-loader" aria-hidden="true">
187
+ <div class="dialog-loader-scrim"></div>
188
+ <wc-spinner></wc-spinner>
189
+ </div>`
190
+ : nothing}
191
+ </div>
192
+ </div>
193
+ `;
194
+ }
195
+ }
@@ -64,6 +64,13 @@
64
64
  flex-shrink: 0;
65
65
  transition: background-color var(--duration-short4, 200ms) var(--easing-standard, ease);
66
66
 
67
+ .ripple {
68
+ inset: 0;
69
+ z-index: 0;
70
+ --ripple-pressed-color: var(--_state-color);
71
+ border-radius: inherit;
72
+ }
73
+
67
74
  .icon-container {
68
75
  display: flex;
69
76
  align-items: center;
@@ -81,29 +88,6 @@
81
88
  }
82
89
  }
83
90
 
84
- /* State layer for hover/press */
85
- .state-layer {
86
- position: absolute;
87
- top: 0.25rem;
88
- left: 50%;
89
- transform: translateX(-50%);
90
- width: var(--_indicator-width);
91
- height: var(--_indicator-height);
92
- pointer-events: none;
93
- background-color: var(--_state-color);
94
- opacity: 0;
95
- z-index: 0;
96
- border-radius: var(--_indicator-shape);
97
- transition: opacity var(--duration-short4, 200ms) var(--easing-standard, ease);
98
- }
99
-
100
- .ripple {
101
- z-index: 1;
102
- --ripple-pressed-color: var(--_state-color);
103
- --ripple-state-opacity: 0;
104
- border-radius: var(--shape-corner-small, 4px);
105
- }
106
-
107
91
  /* Label */
108
92
  .label {
109
93
  @include mixin.get-typography('label-medium');
@@ -166,20 +150,6 @@
166
150
  }
167
151
  }
168
152
 
169
- /* Hover state */
170
- &:hover:not(.disabled) {
171
- .state-layer {
172
- opacity: 0.08;
173
- }
174
- }
175
-
176
- /* Pressed state */
177
- &.pressed:not(.disabled) {
178
- .state-layer {
179
- opacity: 0.12;
180
- }
181
- }
182
-
183
153
  /* Disabled state */
184
154
  &.disabled {
185
155
  cursor: not-allowed;
@@ -208,7 +178,6 @@
208
178
  @media (prefers-reduced-motion: reduce) {
209
179
  .item {
210
180
  .indicator,
211
- .state-layer,
212
181
  .label {
213
182
  transition: none;
214
183
  }
@@ -155,11 +155,10 @@ export class NavigationRailItem extends LitElement {
155
155
  __renderItemContent() {
156
156
  return html`
157
157
  <wc-focus-ring class="focus-ring" for='item'></wc-focus-ring>
158
- <div class="state-layer"></div>
159
- <wc-ripple class="ripple"></wc-ripple>
160
158
 
161
159
  <div class="item-content">
162
160
  <div class="indicator">
161
+ <wc-ripple class="ripple"></wc-ripple>
163
162
  <div class="icon-container">
164
163
  <slot name="active-icon" class="active-icon-slot"></slot>
165
164
  <slot name="icon" class="icon-slot"></slot>
@@ -26,6 +26,21 @@
26
26
  align-items: center;
27
27
  width: 100%;
28
28
  flex-shrink: 0;
29
+ padding-block-end: 2.5rem;
30
+
31
+ &:empty {
32
+ display: none;
33
+ }
34
+ }
35
+
36
+ .footer {
37
+ display: flex;
38
+ flex-direction: column;
39
+ align-items: center;
40
+ justify-content: flex-end;
41
+ width: 100%;
42
+ flex-shrink: 0;
43
+ margin-top: auto;
29
44
 
30
45
  &:empty {
31
46
  display: none;
@@ -34,7 +49,6 @@
34
49
 
35
50
  wc-divider {
36
51
  width: calc(100% - 1rem);
37
- margin-block: 0.5rem;
38
52
  flex-shrink: 0;
39
53
  }
40
54
 
@@ -44,29 +58,11 @@
44
58
  align-items: center;
45
59
  width: 100%;
46
60
  gap: 0.75rem; /* 12dp between items */
47
- flex: 1;
61
+ flex: 1 1 auto;
62
+ min-height: 0;
48
63
 
49
64
  ::slotted(wc-navigation-rail-item) {
50
65
  width: 100%;
51
66
  }
52
67
  }
53
-
54
- /* Alignment variants */
55
- &.align-top {
56
- .items {
57
- justify-content: flex-start;
58
- }
59
- }
60
-
61
- &.align-center {
62
- .items {
63
- justify-content: center;
64
- }
65
- }
66
-
67
- &.align-bottom {
68
- .items {
69
- justify-content: flex-end;
70
- }
71
- }
72
68
  }
@@ -14,6 +14,9 @@ import { NavigationRailItem } from './navigation-rail-item.js';
14
14
  * <p>Navigation rail provides access to primary destinations in an app using icons—with or without labels—on a vertical rail.</p>
15
15
  * <p>Use navigation rail on medium-sized screens (tablets) with 3–7 destinations.</p>
16
16
  *
17
+ * @slot header - Content displayed above the rail items.
18
+ * @slot footer - Content pinned to the bottom of the rail.
19
+ *
17
20
  * @cssprop --nav-rail-width - Width of the rail container. Defaults to 5rem (80dp).
18
21
  * @cssprop --nav-rail-container-color - Background color of the rail. Defaults to surface color.
19
22
  * @cssprop --nav-rail-indicator-color - Color of the active indicator. Defaults to secondary-container.
@@ -49,14 +52,6 @@ export class NavigationRail extends LitElement {
49
52
 
50
53
  static Item = NavigationRailItem;
51
54
 
52
- /**
53
- * Vertical alignment of items within the rail.
54
- * - `"top"`: Items align to the top.
55
- * - `"center"`: Items are centered (default).
56
- * - `"bottom"`: Items align to the bottom.
57
- */
58
- @property({ reflect: true }) alignment: 'top' | 'center' | 'bottom' = 'center';
59
-
60
55
  /**
61
56
  * Display mode of the navigation rail.
62
57
  * - `"expanded"`: shows labels.
@@ -130,7 +125,6 @@ export class NavigationRail extends LitElement {
130
125
  render() {
131
126
  const cssClasses = {
132
127
  rail: true,
133
- [`align-${this.alignment}`]: true,
134
128
  [`mode-${this.mode}`]: true,
135
129
  };
136
130
 
@@ -143,6 +137,9 @@ export class NavigationRail extends LitElement {
143
137
  <nav class="items" role="presentation">
144
138
  <slot @slotchange=${this._syncItemMode}></slot>
145
139
  </nav>
140
+ <div class="footer">
141
+ <slot name="footer"></slot>
142
+ </div>
146
143
  </div>
147
144
  `;
148
145
  }
@@ -0,0 +1 @@
1
+ export { NotificationManager } from './notification-manager.js';
@@ -0,0 +1,113 @@
1
+ @use '../../scss/mixin';
2
+
3
+ @include mixin.base-styles;
4
+
5
+ @keyframes reveal-top {
6
+ 0% {
7
+ opacity: 0;
8
+ transform: translateY(-1rem);
9
+ max-height: 0;
10
+ }
11
+
12
+ 100% {
13
+ max-height: 500px;
14
+ opacity: 1;
15
+ transform: translateY(0);
16
+ }
17
+ }
18
+
19
+ @keyframes reveal-bottom {
20
+ 0% {
21
+ opacity: 0;
22
+ transform: translateY(1rem);
23
+ max-height: 0;
24
+ }
25
+
26
+ 100% {
27
+ max-height: 500px;
28
+ opacity: 1;
29
+ transform: translateY(0);
30
+ }
31
+ }
32
+
33
+ :host {
34
+ display: block;
35
+ position: var(--notification-manager-position, absolute);
36
+ width: 20rem;
37
+ z-index: var(--z-index-notification-manager, 9000);
38
+ pointer-events: none;
39
+ }
40
+
41
+ .notification-manager {
42
+ pointer-events: none;
43
+ display: flex;
44
+ flex-direction: column;
45
+ gap: var(--spacing-100);
46
+ margin: var(--spacing-150);
47
+ }
48
+
49
+ .notification {
50
+ pointer-events: auto;
51
+ max-height: 500px;
52
+ transition: max-height 0.5s ease-out, opacity 0.5s ease-out;
53
+ overflow: hidden;
54
+ }
55
+
56
+ .notification.hidden {
57
+ max-height: 0;
58
+ opacity: 0;
59
+ }
60
+
61
+ /* Position variants */
62
+
63
+ :host([position='bottom-right']) {
64
+ bottom: 0;
65
+ right: 0;
66
+
67
+ .notification-manager {
68
+ align-items: flex-end;
69
+ }
70
+
71
+ .notification {
72
+ animation: reveal-bottom 0.5s ease-in;
73
+ }
74
+ }
75
+
76
+ :host([position='bottom-left']) {
77
+ bottom: 0;
78
+ left: 0;
79
+
80
+ .notification-manager {
81
+ align-items: flex-start;
82
+ }
83
+
84
+ .notification {
85
+ animation: reveal-bottom 0.5s ease-in;
86
+ }
87
+ }
88
+
89
+ :host([position='top-right']) {
90
+ top: 0;
91
+ right: 0;
92
+
93
+ .notification-manager {
94
+ align-items: flex-end;
95
+ }
96
+
97
+ .notification {
98
+ animation: reveal-top 0.5s ease-in;
99
+ }
100
+ }
101
+
102
+ :host([position='top-left']) {
103
+ top: 0;
104
+ left: 0;
105
+
106
+ .notification-manager {
107
+ align-items: flex-start;
108
+ }
109
+
110
+ .notification {
111
+ animation: reveal-top 0.5s ease-in;
112
+ }
113
+ }