@dataengineeringformachinelearning/viking-ui 4.0.4 → 4.0.5

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 (246) hide show
  1. package/README.md +35 -11
  2. package/dist/README.md +35 -11
  3. package/dist/design-tokens.css +300 -85
  4. package/dist/fesm2022/dataengineeringformachinelearning-viking-ui.mjs +100 -64
  5. package/dist/fesm2022/dataengineeringformachinelearning-viking-ui.mjs.map +1 -1
  6. package/dist/icons.js +306 -0
  7. package/dist/package.json +24 -5
  8. package/{src/lib/site-drakkar/site-drakkar.config.ts → dist/site-drakkar.js} +64 -130
  9. package/dist/src/tokens/viking-tokens.json +9 -7
  10. package/dist/types/dataengineeringformachinelearning-viking-ui.d.ts +97 -3
  11. package/dist/viking-components.css +161 -70
  12. package/dist/viking-tokens.json +9 -7
  13. package/dist/viking-ui-elements.js +44 -32
  14. package/dist/viking-ui.css +1 -1
  15. package/dist/web-components.js +44 -32
  16. package/package.json +30 -8
  17. package/dist/scripts/build-web-components.mjs +0 -37
  18. package/dist/src/web/badge/viking-badge-wc.ts +0 -116
  19. package/dist/src/web/button/viking-button-wc.ts +0 -165
  20. package/dist/src/web/callout/viking-callout-wc.ts +0 -105
  21. package/dist/src/web/card/viking-card-wc.ts +0 -67
  22. package/dist/src/web/core/base.ts +0 -56
  23. package/dist/src/web/core/dom.ts +0 -53
  24. package/dist/src/web/core/icons-inline.ts +0 -44
  25. package/dist/src/web/core/styles.ts +0 -1261
  26. package/dist/src/web/core/types.ts +0 -19
  27. package/dist/src/web/field/viking-field-wc.ts +0 -154
  28. package/dist/src/web/index.ts +0 -73
  29. package/dist/src/web/input/viking-input-wc.ts +0 -211
  30. package/dist/src/web/modal/viking-modal-wc.ts +0 -187
  31. package/dist/src/web/search-palette/viking-search-palette-wc.ts +0 -495
  32. package/dist/src/web/select/viking-select-wc.ts +0 -218
  33. package/dist/src/web/suite-header/viking-suite-header-wc.ts +0 -729
  34. package/dist/src/web/suite-search-palette/viking-suite-search-palette-wc.ts +0 -234
  35. package/dist/src/web/theme-toggle/viking-theme-toggle-wc.ts +0 -139
  36. package/dist/src/web/types.ts +0 -37
  37. package/dist/src/web/web-components.spec.ts +0 -297
  38. package/src/assets/drakkar-favicon.svg +0 -17
  39. package/src/assets/fonts/inter/InterVariable-Italic.woff2 +0 -0
  40. package/src/assets/fonts/inter/InterVariable.woff2 +0 -0
  41. package/src/core/brand/deml-lockup.svg +0 -5
  42. package/src/core/brand/deml-mark-compact.svg +0 -4
  43. package/src/core/brand/deml-mark-filled.svg +0 -3
  44. package/src/core/brand/deml-mark-outline.svg +0 -4
  45. package/src/core/brand-icons.ts +0 -62
  46. package/src/core/icons.spec.ts +0 -52
  47. package/src/core/icons.ts +0 -206
  48. package/src/core/integration-brand-icons.ts +0 -77
  49. package/src/core/lucide-paths.generated.ts +0 -130
  50. package/src/core/types.ts +0 -85
  51. package/src/core/uid.ts +0 -7
  52. package/src/elements/button/viking-button.ts +0 -201
  53. package/src/elements/card/viking-card.ts +0 -60
  54. package/src/elements/core/dom.ts +0 -33
  55. package/src/elements/core/styles.ts +0 -28
  56. package/src/elements/modal/viking-modal.ts +0 -154
  57. package/src/index.ts +0 -1
  58. package/src/lib/accordion/accordion.ts +0 -126
  59. package/src/lib/app-header/app-header.scss +0 -274
  60. package/src/lib/app-header/app-header.ts +0 -43
  61. package/src/lib/app-sidebar/app-sidebar.scss +0 -415
  62. package/src/lib/app-sidebar/app-sidebar.ts +0 -29
  63. package/src/lib/auth-panel/auth-panel.spec.ts +0 -132
  64. package/src/lib/auth-panel/auth-panel.ts +0 -228
  65. package/src/lib/autocomplete/autocomplete.ts +0 -223
  66. package/src/lib/avatar/avatar.ts +0 -126
  67. package/src/lib/badge/badge.ts +0 -182
  68. package/src/lib/bar/bar.ts +0 -31
  69. package/src/lib/brand/brand.ts +0 -60
  70. package/src/lib/breadcrumbs/breadcrumbs.ts +0 -81
  71. package/src/lib/button/button-group.ts +0 -40
  72. package/src/lib/button/button.scss +0 -119
  73. package/src/lib/button/button.ts +0 -98
  74. package/src/lib/calendar/calendar.ts +0 -253
  75. package/src/lib/callout/callout.ts +0 -211
  76. package/src/lib/card/card-title.spec.ts +0 -27
  77. package/src/lib/card/card-title.ts +0 -50
  78. package/src/lib/card/card.ts +0 -200
  79. package/src/lib/carousel/carousel.ts +0 -206
  80. package/src/lib/chart/chart-zoom.spec.ts +0 -65
  81. package/src/lib/chart/chart-zoom.ts +0 -71
  82. package/src/lib/chart/chart.ts +0 -1257
  83. package/src/lib/chart-card-header/chart-card-header.ts +0 -80
  84. package/src/lib/chart-empty-state/chart-empty-state.ts +0 -146
  85. package/src/lib/chart-panel/chart-panel.ts +0 -133
  86. package/src/lib/checkbox/checkbox.ts +0 -139
  87. package/src/lib/color-picker/color-picker.ts +0 -148
  88. package/src/lib/command/command.ts +0 -260
  89. package/src/lib/composer/composer.ts +0 -180
  90. package/src/lib/confirm-dialog/confirm-dialog.ts +0 -163
  91. package/src/lib/confirm-dialog/dialog.service.ts +0 -79
  92. package/src/lib/context/context.ts +0 -75
  93. package/src/lib/core/brand-icons.ts +0 -62
  94. package/src/lib/core/cva.ts +0 -33
  95. package/src/lib/core/icons.ts +0 -206
  96. package/src/lib/core/integration-brand-icons.ts +0 -77
  97. package/src/lib/core/lucide-paths.generated.ts +0 -130
  98. package/src/lib/date-picker/date-picker.ts +0 -139
  99. package/src/lib/dropdown/dropdown.ts +0 -188
  100. package/src/lib/editor/editor.ts +0 -170
  101. package/src/lib/empty-state/empty-state.ts +0 -100
  102. package/src/lib/fab/fab.ts +0 -76
  103. package/src/lib/field/field.ts +0 -111
  104. package/src/lib/file-upload/file-upload.ts +0 -208
  105. package/src/lib/footer/footer.scss +0 -162
  106. package/src/lib/footer/footer.ts +0 -28
  107. package/src/lib/form-section/form-section.ts +0 -200
  108. package/src/lib/forms.spec.ts +0 -92
  109. package/src/lib/gauge-arc/gauge-arc.ts +0 -85
  110. package/src/lib/hud-panel/hud-panel.ts +0 -27
  111. package/src/lib/icon/icon.ts +0 -284
  112. package/src/lib/icon-badge/icon-badge.ts +0 -87
  113. package/src/lib/icon-heading/icon-heading.spec.ts +0 -32
  114. package/src/lib/icon-heading/icon-heading.ts +0 -38
  115. package/src/lib/icon-text/icon-text.ts +0 -120
  116. package/src/lib/input/input.ts +0 -119
  117. package/src/lib/kanban/kanban.ts +0 -211
  118. package/src/lib/kbd/kbd.ts +0 -32
  119. package/src/lib/label/label.ts +0 -39
  120. package/src/lib/loading-overlay/loading-overlay.ts +0 -80
  121. package/src/lib/menubar/menubar.ts +0 -77
  122. package/src/lib/metric-card/metric-card.ts +0 -33
  123. package/src/lib/modal/modal.ts +0 -207
  124. package/src/lib/native-select/native-select.ts +0 -124
  125. package/src/lib/navbar/navbar.ts +0 -124
  126. package/src/lib/navigation-menu/navigation-menu.ts +0 -116
  127. package/src/lib/otp-input/otp-input.ts +0 -164
  128. package/src/lib/page-back-link/page-back-link.ts +0 -74
  129. package/src/lib/page-header/page-header.ts +0 -70
  130. package/src/lib/pagination/pagination.ts +0 -157
  131. package/src/lib/pillbox/pillbox.ts +0 -157
  132. package/src/lib/popover/popover.ts +0 -92
  133. package/src/lib/profile/profile.ts +0 -73
  134. package/src/lib/progress/progress.ts +0 -123
  135. package/src/lib/radio/radio.ts +0 -132
  136. package/src/lib/ring-gauge/ring-gauge.ts +0 -75
  137. package/src/lib/scroll-area/scroll-area.ts +0 -57
  138. package/src/lib/search-palette/search-palette.scss +0 -288
  139. package/src/lib/search-palette/search-palette.ts +0 -114
  140. package/src/lib/select/select.ts +0 -292
  141. package/src/lib/separator/separator.ts +0 -59
  142. package/src/lib/sheet/sheet.ts +0 -192
  143. package/src/lib/sidebar-nav/sidebar-nav.scss +0 -218
  144. package/src/lib/sidebar-nav/sidebar-nav.ts +0 -158
  145. package/src/lib/site-drakkar/site-footer.ts +0 -133
  146. package/src/lib/site-drakkar/site-navbar.scss +0 -2
  147. package/src/lib/site-drakkar/site-navbar.ts +0 -286
  148. package/src/lib/site-drakkar/suite-search-items.spec.ts +0 -61
  149. package/src/lib/site-drakkar/suite-search-items.ts +0 -246
  150. package/src/lib/skeleton/skeleton.ts +0 -51
  151. package/src/lib/slider/slider.ts +0 -133
  152. package/src/lib/spinner/spinner.ts +0 -75
  153. package/src/lib/status-metric-row/status-metric-row.ts +0 -74
  154. package/src/lib/suite-search-palette/suite-search-palette.ts +0 -95
  155. package/src/lib/switch/switch.ts +0 -131
  156. package/src/lib/table/table.ts +0 -137
  157. package/src/lib/tabs/tab-panel.ts +0 -61
  158. package/src/lib/tabs/tab.ts +0 -107
  159. package/src/lib/tabs/tabs.ts +0 -109
  160. package/src/lib/textarea/textarea.ts +0 -103
  161. package/src/lib/theme-toggle/theme-toggle.spec.ts +0 -40
  162. package/src/lib/theme-toggle/theme-toggle.ts +0 -40
  163. package/src/lib/time-picker/time-picker.ts +0 -197
  164. package/src/lib/timeline/timeline.ts +0 -152
  165. package/src/lib/toast/toast.ts +0 -196
  166. package/src/lib/toggle/toggle-group.ts +0 -60
  167. package/src/lib/toggle/toggle.ts +0 -101
  168. package/src/lib/tooltip/tooltip.ts +0 -119
  169. package/src/lib/typography/heading.ts +0 -52
  170. package/src/lib/typography/text.ts +0 -51
  171. package/src/lib/uptime-bar/uptime-bar.ts +0 -55
  172. package/src/lib/verification-code-field/verification-code-field.ts +0 -149
  173. package/src/lib/whitepaper-cta/whitepaper-cta.scss +0 -130
  174. package/src/lib/whitepaper-cta/whitepaper-cta.ts +0 -78
  175. package/src/lib/wizard/wizard.ts +0 -80
  176. package/src/public-api.ts +0 -172
  177. package/src/styles/_buttons.scss +0 -386
  178. package/src/styles/_component-primitives.scss +0 -183
  179. package/src/styles/_drakkar-buttons.scss +0 -85
  180. package/src/styles/_fonts.scss +0 -22
  181. package/src/styles/_forms.scss +0 -66
  182. package/src/styles/_input.scss +0 -106
  183. package/src/styles/_layout-enforcement.scss +0 -229
  184. package/src/styles/_layout-rhythm.scss +0 -158
  185. package/src/styles/_legacy-aliases.scss +0 -212
  186. package/src/styles/_series-colors.scss +0 -24
  187. package/src/styles/_static-primitives.scss +0 -857
  188. package/src/styles/_typography.scss +0 -87
  189. package/src/styles/_variables.scss +0 -527
  190. package/src/styles/components/a11y.scss +0 -90
  191. package/src/styles/components/badges.scss +0 -102
  192. package/src/styles/components/extracted-utilities.scss +0 -459
  193. package/src/styles/components/footer.scss +0 -168
  194. package/src/styles/components/icon-heading.scss +0 -47
  195. package/src/styles/components/icon-inline.scss +0 -101
  196. package/src/styles/components/layout.scss +0 -59
  197. package/src/styles/components/utilities.scss +0 -131
  198. package/src/styles/components/viking-inspired.scss +0 -204
  199. package/src/styles/components/whitepaper-cta.scss +0 -130
  200. package/src/styles/components-bundle.scss +0 -9
  201. package/src/styles/components.scss +0 -442
  202. package/src/styles/deml-components.scss +0 -10
  203. package/src/styles/index.scss +0 -8
  204. package/src/styles/layout-shell.scss +0 -111
  205. package/src/styles/page-shell.scss +0 -859
  206. package/src/styles/static-navbar.scss +0 -1250
  207. package/src/styles/surfaces/backend.scss +0 -154
  208. package/src/styles/surfaces/docs-global.scss +0 -73
  209. package/src/styles/surfaces/docs-shell.scss +0 -437
  210. package/src/styles/surfaces/docs-showcase.scss +0 -1153
  211. package/src/styles/surfaces/marketing-cta.scss +0 -62
  212. package/src/styles/surfaces/marketing-docs-bento.scss +0 -67
  213. package/src/styles/surfaces/marketing-global.scss +0 -748
  214. package/src/styles/surfaces/marketing-landing.scss +0 -1526
  215. package/src/styles/surfaces/marketing-publication.scss +0 -535
  216. package/src/styles/surfaces/marketing-theme.scss +0 -14
  217. package/src/styles/surfaces/swagger-ui.scss +0 -1013
  218. package/src/styles/tokens-export.scss +0 -18
  219. package/src/styles/tokens.scss +0 -5
  220. package/src/styles/viking-ui-bundle.scss +0 -23
  221. package/src/styles/viking-ui.scss +0 -272
  222. package/src/tokens/series-presets.ts +0 -15
  223. package/src/tokens/tailwind.preset.js +0 -209
  224. package/src/tokens/viking-tokens.json +0 -318
  225. package/src/viking-ui.spec.ts +0 -416
  226. package/src/web/badge/viking-badge-wc.ts +0 -116
  227. package/src/web/button/viking-button-wc.ts +0 -165
  228. package/src/web/callout/viking-callout-wc.ts +0 -105
  229. package/src/web/card/viking-card-wc.ts +0 -67
  230. package/src/web/core/base.ts +0 -56
  231. package/src/web/core/dom.ts +0 -53
  232. package/src/web/core/icons-inline.ts +0 -44
  233. package/src/web/core/styles.ts +0 -1261
  234. package/src/web/core/types.ts +0 -19
  235. package/src/web/field/viking-field-wc.ts +0 -154
  236. package/src/web/index.ts +0 -73
  237. package/src/web/input/viking-input-wc.ts +0 -211
  238. package/src/web/modal/viking-modal-wc.ts +0 -187
  239. package/src/web/search-palette/viking-search-palette-wc.ts +0 -495
  240. package/src/web/select/viking-select-wc.ts +0 -218
  241. package/src/web/suite-header/viking-suite-header-wc.ts +0 -729
  242. package/src/web/suite-search-palette/viking-suite-search-palette-wc.ts +0 -234
  243. package/src/web/theme-toggle/viking-theme-toggle-wc.ts +0 -139
  244. package/src/web/types.ts +0 -37
  245. package/src/web/web-components.spec.ts +0 -297
  246. package/src/web-components/index.ts +0 -1
@@ -1,288 +0,0 @@
1
- :host {
2
- display: contents;
3
- }
4
-
5
- .viking-search-palette-backdrop {
6
- position: fixed;
7
- inset: 0;
8
- z-index: var(--viking-z-overlay);
9
- display: flex;
10
- align-items: flex-start;
11
- justify-content: center;
12
- padding: 10vh var(--viking-space-2) var(--viking-space-2);
13
- background: var(--viking-overlay-backdrop);
14
- backdrop-filter: blur(8px);
15
- -webkit-backdrop-filter: blur(8px);
16
- border: none;
17
- cursor: default;
18
- animation: viking-backdrop-in var(--viking-duration-fast) var(--viking-ease-out);
19
- }
20
-
21
- .viking-search-palette {
22
- display: flex;
23
- flex-direction: column;
24
- background: var(--viking-surface-glass, color-mix(in srgb, var(--viking-surface) 82%, transparent));
25
- backdrop-filter: blur(var(--viking-surface-glass-blur, 12px));
26
- -webkit-backdrop-filter: blur(var(--viking-surface-glass-blur, 12px));
27
- border: 1px solid var(--viking-border-strong);
28
- border-radius: var(--viking-radius-lg);
29
- box-shadow: var(--viking-shadow-lg);
30
- overflow: hidden;
31
- max-width: 600px;
32
- width: 100%;
33
- margin: 0 auto;
34
- font-family: var(--viking-font-family);
35
- color: var(--viking-text);
36
- animation: viking-modal-in var(--viking-duration) var(--viking-ease-default);
37
- position: relative;
38
- }
39
-
40
- .viking-search-palette::before {
41
- content: '';
42
- position: absolute;
43
- inset: 0 0 auto;
44
- height: 1px;
45
- background: linear-gradient(
46
- 90deg,
47
- transparent,
48
- color-mix(in srgb, var(--viking-metallic-200) 22%, transparent),
49
- transparent
50
- );
51
- pointer-events: none;
52
- z-index: 1;
53
- }
54
-
55
- .viking-search-palette-header {
56
- display: flex;
57
- align-items: center;
58
- padding: var(--viking-space-2);
59
- border-bottom: 1px solid var(--viking-border);
60
- gap: var(--viking-space-1);
61
- background: color-mix(in srgb, var(--viking-bg) 20%, transparent);
62
- }
63
-
64
- .viking-search-palette-header:focus-within {
65
- border-bottom-color: var(--viking-accent);
66
- box-shadow: inset 0 -2px 0 var(--viking-accent-soft);
67
- }
68
-
69
- .viking-search-palette-input {
70
- flex: 1;
71
- background: none;
72
- border: none;
73
- outline: none;
74
- font-size: calc(var(--viking-font-size) * 1.05);
75
- color: var(--viking-text);
76
- font-family: inherit;
77
- }
78
-
79
- .viking-search-palette-close {
80
- display: inline-flex;
81
- align-items: center;
82
- justify-content: center;
83
- min-width: var(--viking-touch-target-comfort);
84
- min-height: var(--viking-touch-target-comfort);
85
- border: none;
86
- background: transparent;
87
- color: var(--viking-text-muted);
88
- cursor: pointer;
89
- padding: var(--viking-space-half);
90
- border-radius: var(--viking-radius);
91
- transition: var(--viking-transition-interactive);
92
- -webkit-tap-highlight-color: transparent;
93
- }
94
-
95
- .viking-search-palette-close:hover {
96
- color: var(--viking-text);
97
- background: var(--viking-accent-soft);
98
- }
99
-
100
- .viking-search-palette-close:focus-visible {
101
- outline: var(--viking-ring-width) solid var(--viking-ring);
102
- outline-offset: var(--viking-ring-offset);
103
- }
104
-
105
- .viking-search-palette-close:active {
106
- transform: scale(var(--viking-state-active-scale));
107
- }
108
-
109
- .viking-search-palette-body {
110
- max-height: 50vh;
111
- overflow-y: auto;
112
- }
113
-
114
- .viking-search-palette-footer {
115
- display: flex;
116
- align-items: center;
117
- justify-content: center;
118
- gap: var(--viking-space-1);
119
- padding: var(--viking-space-1) var(--viking-space-2);
120
- border-top: 1px solid var(--viking-border);
121
- font-size: calc(var(--viking-font-size) * 0.85);
122
- color: var(--viking-text-muted);
123
- }
124
-
125
- ::ng-deep .viking-search-palette-shortcut {
126
- display: inline-flex;
127
- align-items: center;
128
- gap: calc(var(--viking-space-1) / 2);
129
- }
130
-
131
- ::ng-deep .viking-search-palette-shortcut kbd {
132
- font-family: inherit;
133
- font-size: calc(var(--viking-font-size) * 0.75);
134
- padding: 2px 6px;
135
- border-radius: calc(var(--viking-radius) / 2);
136
- border: 1px solid var(--viking-border);
137
- background: var(--viking-surface-alt);
138
- }
139
-
140
- .viking-search-palette-body {
141
- padding: var(--viking-space-2);
142
- }
143
-
144
- ::ng-deep .viking-search-results {
145
- display: flex;
146
- flex-direction: column;
147
- gap: var(--viking-space-1);
148
- }
149
-
150
- ::ng-deep .viking-search-result {
151
- display: flex;
152
- align-items: center;
153
- min-height: var(--viking-control-height-sm);
154
- padding: var(--viking-space-1) var(--viking-space-2);
155
- border-radius: var(--viking-radius);
156
- background: color-mix(in srgb, var(--viking-surface) 2%, transparent);
157
- border: 1px solid transparent;
158
- cursor: pointer;
159
- transition: var(--viking-transition-interactive);
160
- gap: var(--viking-space-1);
161
- -webkit-tap-highlight-color: transparent;
162
- }
163
-
164
- ::ng-deep .viking-search-result.is-selected,
165
- ::ng-deep .viking-search-result.viking-selected,
166
- ::ng-deep .viking-search-result:hover {
167
- background: color-mix(in srgb, var(--viking-accent) 5%, transparent);
168
- border-color: color-mix(in srgb, var(--viking-accent) 30%, transparent);
169
- box-shadow: var(--viking-shadow-sm);
170
- }
171
-
172
- ::ng-deep .viking-search-result:focus-visible {
173
- outline: var(--viking-ring-width) solid var(--viking-ring);
174
- outline-offset: var(--viking-ring-offset);
175
- }
176
-
177
- ::ng-deep .viking-search-result-icon {
178
- display: flex;
179
- align-items: center;
180
- justify-content: center;
181
- color: var(--viking-text-muted);
182
- }
183
-
184
- ::ng-deep .viking-search-result.is-selected .viking-search-result-icon,
185
- ::ng-deep .viking-search-result.viking-selected .viking-search-result-icon,
186
- ::ng-deep .viking-search-result:hover .viking-search-result-icon {
187
- color: var(--viking-accent);
188
- }
189
-
190
- ::ng-deep .viking-search-result-content {
191
- flex: 1;
192
- display: flex;
193
- flex-direction: column;
194
- gap: calc(var(--viking-space-1) / 2);
195
- overflow: hidden;
196
- }
197
-
198
- ::ng-deep .viking-search-result-title {
199
- font-size: var(--viking-font-size);
200
- font-weight: 600;
201
- color: var(--viking-text);
202
- }
203
-
204
- ::ng-deep .viking-search-result-snippet {
205
- font-size: var(--viking-font-size);
206
- color: var(--viking-text-muted);
207
- white-space: nowrap;
208
- overflow: hidden;
209
- text-overflow: ellipsis;
210
- }
211
-
212
- ::ng-deep mark.viking-search-highlight {
213
- background: color-mix(in srgb, var(--viking-accent) 20%, transparent);
214
- color: var(--viking-accent);
215
- border-radius: 0;
216
- padding: 0;
217
- font-weight: 600;
218
- }
219
-
220
- ::ng-deep .viking-search-empty {
221
- display: flex;
222
- flex-direction: column;
223
- align-items: center;
224
- justify-content: center;
225
- padding: calc(var(--viking-space-2) * 2) var(--viking-space-2);
226
- text-align: center;
227
- color: var(--viking-text-muted);
228
- }
229
-
230
- ::ng-deep .viking-search-empty-icon {
231
- opacity: 0.5;
232
- margin-bottom: var(--viking-space-2);
233
- }
234
-
235
- ::ng-deep .viking-search-suggestions {
236
- display: flex;
237
- flex-direction: column;
238
- gap: var(--viking-space-1);
239
- padding: var(--viking-space-1);
240
- }
241
-
242
- ::ng-deep .viking-search-group-label,
243
- ::ng-deep .viking-search-suggestions-heading {
244
- margin: var(--viking-space-1) 0 var(--viking-space-half);
245
- padding: 0 var(--viking-space-1);
246
- font-size: var(--viking-font-size-2xs, var(--viking-font-size-xs));
247
- font-weight: var(--viking-font-weight-semibold, 600);
248
- letter-spacing: var(--viking-letter-spacing-caps);
249
- text-transform: uppercase;
250
- color: var(--viking-text-muted);
251
- }
252
-
253
- ::ng-deep .viking-search-suggestions-grid {
254
- display: grid;
255
- grid-template-columns: 1fr;
256
- gap: var(--viking-space-1);
257
- }
258
-
259
- @media (min-width: 481px) {
260
- ::ng-deep .viking-search-suggestions-grid {
261
- grid-template-columns: 1fr 1fr;
262
- }
263
- }
264
-
265
- ::ng-deep .viking-search-suggestion {
266
- display: flex;
267
- align-items: center;
268
- gap: var(--viking-space-1);
269
- min-height: var(--viking-control-height-sm);
270
- padding: var(--viking-space-1) var(--viking-space-2);
271
- background: color-mix(in srgb, var(--viking-surface) 2%, transparent);
272
- border: 1px solid var(--viking-border);
273
- border-radius: var(--viking-radius);
274
- cursor: pointer;
275
- transition: var(--viking-transition-interactive);
276
- -webkit-tap-highlight-color: transparent;
277
- }
278
-
279
- ::ng-deep .viking-search-suggestion:hover {
280
- background: color-mix(in srgb, var(--viking-accent) 5%, transparent);
281
- border-color: color-mix(in srgb, var(--viking-accent) 30%, transparent);
282
- box-shadow: var(--viking-shadow-sm);
283
- }
284
-
285
- ::ng-deep .viking-search-suggestion:focus-visible {
286
- outline: var(--viking-ring-width) solid var(--viking-ring);
287
- outline-offset: var(--viking-ring-offset);
288
- }
@@ -1,114 +0,0 @@
1
- import {
2
- ChangeDetectionStrategy,
3
- Component,
4
- ElementRef,
5
- effect,
6
- input,
7
- model,
8
- output,
9
- viewChild,
10
- } from "@angular/core";
11
- import { VikingIcon } from "../icon/icon";
12
- import { VikingKbd } from "../kbd/kbd";
13
-
14
- /**
15
- * viking-search-palette — command-palette style search overlay (Product Hunt / Algolia inspired).
16
- * Project custom result lists into the body slot; ⌘K / Ctrl+K wired by host app static widget.
17
- */
18
- @Component({
19
- selector: "viking-search-palette",
20
- imports: [VikingIcon, VikingKbd],
21
- changeDetection: ChangeDetectionStrategy.OnPush,
22
- host: { "(keydown.escape)": "close()" },
23
- template: `
24
- @if (open()) {
25
- <div
26
- class="viking-search-palette-backdrop"
27
- role="presentation"
28
- tabindex="-1"
29
- (click)="close()"
30
- (keydown.escape)="close()"
31
- >
32
- <div
33
- class="viking-search-palette"
34
- role="dialog"
35
- aria-label="Search"
36
- tabindex="-1"
37
- (click)="$event.stopPropagation()"
38
- (keydown)="$event.stopPropagation()"
39
- >
40
- <div class="viking-search-palette-header">
41
- <viking-icon name="search" [size]="24" />
42
- <input
43
- #queryInput
44
- type="text"
45
- class="viking-search-palette-input"
46
- [placeholder]="placeholder()"
47
- [value]="query()"
48
- [attr.aria-label]="placeholder()"
49
- (input)="onQueryInput($event)"
50
- />
51
- <button
52
- type="button"
53
- class="viking-search-palette-close"
54
- aria-label="Close search"
55
- (click)="close()"
56
- >
57
- <viking-icon name="x" [size]="20" />
58
- </button>
59
- </div>
60
- <div
61
- class="viking-search-palette-body"
62
- tabindex="-1"
63
- (keydown)="paletteKeydown.emit($event)"
64
- >
65
- <ng-content />
66
- </div>
67
- <footer class="viking-search-palette-footer">
68
- <ng-content select="[vikingSearchPaletteFooter]" />
69
- <span class="viking-search-palette-shortcut">
70
- <viking-kbd>{{ modKey() }}</viking-kbd
71
- ><viking-kbd>K</viking-kbd> toggle · <viking-kbd>↑</viking-kbd
72
- ><viking-kbd>↓</viking-kbd> navigate ·
73
- <viking-kbd>Enter</viking-kbd> open ·
74
- <viking-kbd>Esc</viking-kbd> close
75
- </span>
76
- </footer>
77
- </div>
78
- </div>
79
- }
80
- `,
81
- styleUrl: "./search-palette.scss",
82
- })
83
- export class VikingSearchPalette {
84
- readonly open = model<boolean>(false);
85
- readonly query = model<string>("");
86
- readonly placeholder = input<string>("Search...");
87
- readonly paletteKeydown = output<KeyboardEvent>();
88
-
89
- private readonly queryInput =
90
- viewChild<ElementRef<HTMLInputElement>>("queryInput");
91
-
92
- constructor() {
93
- effect(() => {
94
- if (this.open()) {
95
- queueMicrotask(() => this.queryInput()?.nativeElement.focus());
96
- }
97
- });
98
- }
99
-
100
- protected onQueryInput(event: Event): void {
101
- this.query.set((event.target as HTMLInputElement).value);
102
- }
103
-
104
- protected close(): void {
105
- this.open.set(false);
106
- }
107
-
108
- /** Platform modifier label for footer shortcut hint. */
109
- protected modKey = (): string =>
110
- typeof navigator !== "undefined" &&
111
- /Mac|iPhone|iPad/i.test(navigator.platform)
112
- ? "⌘"
113
- : "Ctrl";
114
- }
@@ -1,292 +0,0 @@
1
- import {
2
- ChangeDetectionStrategy,
3
- Component,
4
- ElementRef,
5
- computed,
6
- input,
7
- model,
8
- signal,
9
- } from "@angular/core";
10
- import { VikingControl, provideVikingCva } from "../core/cva";
11
- import { VikingIcon } from "../icon/icon";
12
- import { VikingSelectOption } from "../../core/types";
13
-
14
- export type VikingSelectWidth = "full" | "half";
15
-
16
- /**
17
- * viking-select — custom listbox select.
18
- * ControlValueAccessor-compatible with full keyboard support.
19
- */
20
- @Component({
21
- selector: "viking-select",
22
- imports: [VikingIcon],
23
- providers: [provideVikingCva(VikingSelect)],
24
- changeDetection: ChangeDetectionStrategy.OnPush,
25
- host: {
26
- "(document:click)": "onDocumentClick($event)",
27
- "[class.viking-select-full]": "width() === 'full'",
28
- "[class.viking-select-half]": "width() === 'half'",
29
- },
30
- template: `
31
- <button
32
- type="button"
33
- class="viking-control viking-select-trigger"
34
- [disabled]="disabled() || formDisabled()"
35
- [attr.aria-expanded]="open()"
36
- [attr.aria-label]="label() || placeholder()"
37
- aria-haspopup="listbox"
38
- (click)="toggle()"
39
- (keydown)="onKeydown($event)"
40
- >
41
- <span
42
- class="viking-select-value"
43
- [class.viking-select-placeholder]="!selectedLabel()"
44
- >
45
- {{ selectedLabel() || placeholder() }}
46
- </span>
47
- <viking-icon
48
- [name]="open() ? 'chevron-up' : 'chevron-down'"
49
- [size]="18"
50
- />
51
- </button>
52
- @if (open()) {
53
- <div
54
- class="viking-select-panel"
55
- role="listbox"
56
- [attr.aria-label]="label() || placeholder()"
57
- >
58
- @for (option of options(); track option.label; let index = $index) {
59
- <button
60
- type="button"
61
- role="option"
62
- class="viking-select-option"
63
- [class.viking-active]="index === activeIndex()"
64
- [class.viking-selected]="option.value === value()"
65
- [disabled]="option.disabled"
66
- [attr.aria-selected]="option.value === value()"
67
- (click)="pick(option)"
68
- (mouseenter)="activeIndex.set(index)"
69
- >
70
- <span class="viking-select-option-label">{{ option.label }}</span>
71
- @if (option.value === value()) {
72
- <viking-icon name="check" [size]="16" />
73
- }
74
- </button>
75
- }
76
- </div>
77
- }
78
- `,
79
- styles: [
80
- `
81
- :host {
82
- position: relative;
83
- display: block;
84
- min-width: 0;
85
- }
86
- :host(.viking-select-full) {
87
- width: 100%;
88
- }
89
- :host(.viking-select-half) {
90
- width: 100%;
91
- max-width: var(--viking-select-half-max-width, min(100%, 24rem));
92
- }
93
- .viking-select-value {
94
- min-width: 0;
95
- overflow: hidden;
96
- text-overflow: ellipsis;
97
- white-space: nowrap;
98
- }
99
- .viking-select-trigger {
100
- display: flex;
101
- align-items: center;
102
- justify-content: space-between;
103
- gap: var(--viking-space-1);
104
- width: 100%;
105
- min-height: var(--viking-control-height);
106
- padding: 0 var(--viking-space-2);
107
- background: var(--viking-surface);
108
- border: 1px solid var(--viking-border-strong);
109
- border-radius: var(--viking-radius);
110
- box-shadow: var(--viking-shadow-sm);
111
- color: var(--viking-text);
112
- font-family: var(--viking-font-family);
113
- font-size: var(--viking-font-size);
114
- cursor: pointer;
115
- transition: var(--viking-transition-interactive);
116
- text-align: left;
117
- }
118
- .viking-select-trigger:hover:not(:disabled) {
119
- border-color: var(--viking-accent-strong);
120
- box-shadow: var(--viking-shadow-md);
121
- }
122
- .viking-select-trigger:focus-visible {
123
- outline: var(--viking-ring-width) solid var(--viking-ring);
124
- outline-offset: var(--viking-ring-offset);
125
- }
126
- .viking-select-trigger:disabled {
127
- opacity: var(--viking-state-disabled-opacity);
128
- cursor: not-allowed;
129
- }
130
- .viking-select-placeholder {
131
- color: var(--viking-text-muted);
132
- }
133
- .viking-select-panel {
134
- position: absolute;
135
- top: calc(100% + var(--viking-space-half));
136
- left: 0;
137
- width: 100%;
138
- min-width: 100%;
139
- max-width: 100%;
140
- box-sizing: border-box;
141
- display: flex;
142
- flex-direction: column;
143
- gap: 2px;
144
- margin: 0;
145
- padding: var(--viking-space-1);
146
- background-color: var(
147
- --viking-select-panel-bg,
148
- var(--viking-surface-raised)
149
- );
150
- border: 1px solid var(--viking-border-strong);
151
- border-radius: var(--viking-radius);
152
- box-shadow: var(--viking-shadow-lg);
153
- z-index: var(--viking-z-overlay);
154
- max-height: 315px;
155
- overflow: auto;
156
- isolation: isolate;
157
- animation: viking-slide-up var(--viking-duration-fast)
158
- var(--viking-ease-default);
159
- }
160
- .viking-select-option {
161
- display: flex;
162
- align-items: center;
163
- justify-content: space-between;
164
- gap: var(--viking-space-1);
165
- padding: var(--viking-space-1) var(--viking-space-1-5);
166
- border: none;
167
- background: transparent;
168
- text-align: left;
169
- width: 100%;
170
- min-width: 0;
171
- border-radius: var(--viking-radius-sm);
172
- font-family: var(--viking-font-family);
173
- font-size: var(--viking-font-size-sm);
174
- color: var(--viking-text);
175
- cursor: pointer;
176
- transition: var(--viking-transition-interactive);
177
- }
178
- .viking-select-option-label {
179
- min-width: 0;
180
- overflow: hidden;
181
- text-overflow: ellipsis;
182
- white-space: nowrap;
183
- }
184
- .viking-select-option:disabled {
185
- opacity: var(--viking-state-disabled-opacity);
186
- cursor: not-allowed;
187
- }
188
- .viking-select-option:focus-visible {
189
- outline: var(--viking-ring-width) solid var(--viking-ring);
190
- outline-offset: -2px;
191
- }
192
- .viking-active {
193
- background: var(--viking-accent-soft);
194
- color: var(--viking-text);
195
- }
196
- .viking-selected {
197
- font-weight: var(--viking-font-weight-semibold);
198
- color: var(--viking-accent-strong);
199
- background: color-mix(
200
- in srgb,
201
- var(--viking-accent) 14%,
202
- var(--viking-select-panel-bg, var(--viking-surface-raised))
203
- );
204
- }
205
- `,
206
- ],
207
- })
208
- export class VikingSelect extends VikingControl<unknown> {
209
- readonly options = input.required<VikingSelectOption[]>();
210
- readonly value = model<unknown>(null);
211
- readonly placeholder = input<string>("Select…");
212
- readonly label = input<string>("");
213
- readonly disabled = input<boolean>(false);
214
- readonly width = input<VikingSelectWidth>("half");
215
-
216
- constructor(private readonly host: ElementRef<HTMLElement>) {
217
- super();
218
- }
219
-
220
- protected readonly open = signal(false);
221
- protected readonly activeIndex = signal(0);
222
-
223
- protected readonly selectedLabel = computed(
224
- () =>
225
- this.options().find((option) => option.value === this.value())?.label ??
226
- "",
227
- );
228
-
229
- writeValue(value: unknown): void {
230
- this.value.set(value);
231
- }
232
-
233
- protected toggle = (): void => {
234
- this.open.update((value) => !value);
235
- if (this.open()) {
236
- const index = this.options().findIndex(
237
- (option) => option.value === this.value(),
238
- );
239
- this.activeIndex.set(Math.max(0, index));
240
- }
241
- };
242
-
243
- protected pick = (option: VikingSelectOption): void => {
244
- if (option.disabled) {
245
- return;
246
- }
247
- this.value.set(option.value);
248
- this.onChange(option.value);
249
- this.onTouched();
250
- this.open.set(false);
251
- };
252
-
253
- protected onKeydown = (event: KeyboardEvent): void => {
254
- const options = this.options();
255
- if (!this.open()) {
256
- if (["ArrowDown", "ArrowUp", "Enter", " "].includes(event.key)) {
257
- event.preventDefault();
258
- this.toggle();
259
- }
260
- return;
261
- }
262
- switch (event.key) {
263
- case "ArrowDown":
264
- event.preventDefault();
265
- this.activeIndex.update((index) =>
266
- Math.min(options.length - 1, index + 1),
267
- );
268
- break;
269
- case "ArrowUp":
270
- event.preventDefault();
271
- this.activeIndex.update((index) => Math.max(0, index - 1));
272
- break;
273
- case "Enter":
274
- case " ":
275
- event.preventDefault();
276
- this.pick(options[this.activeIndex()]);
277
- break;
278
- case "Escape":
279
- this.open.set(false);
280
- break;
281
- }
282
- };
283
-
284
- protected onDocumentClick = (event: Event): void => {
285
- if (
286
- this.open() &&
287
- !this.host.nativeElement.contains(event.target as Node)
288
- ) {
289
- this.open.set(false);
290
- }
291
- };
292
- }