@sinequa/galactik 2.1.1 → 2.2.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.
package/README.md CHANGED
@@ -5,7 +5,9 @@ Angular UI primitives built on top of [`@angular/aria`](https://www.npmjs.com/pa
5
5
  ## Requirements
6
6
 
7
7
  - Angular `^22.0.0`
8
- - `@angular/aria` `^22.0.0`
8
+ - `@angular/aria` `^22.2.0`
9
+ - [`cn`](https://www.npmjs.com/package/cn) `^0.2.5` (class-name merging, a peer dependency)
10
+ - Tailwind CSS v4 — components are styled with galactik design tokens through Tailwind utilities
9
11
 
10
12
  ## Installation
11
13
 
@@ -24,10 +26,14 @@ one from `@sinequa/ui`.
24
26
 
25
27
  Public API surface (see `public-api.ts`):
26
28
 
27
- - **Menu** — `MenuComponent`, `MenuContentComponent`, `MenuItemComponent`, `SubMenuComponent`, `MenuTriggerDirective`
28
- - **Tabs** — `TabsComponent`, `TabListComponent`, `TabComponent`, `TabPanelComponent`
29
- - **Popover** — `DropdownDirective` (alias of `PopoverDirective`, kept for backward compatibility)
30
- - **Utils** — `cn` helper for merging Tailwind class names
29
+ - **Actions** — `ButtonComponent`, `ToggleComponent`, `ToggleGroupComponent`, `LinkComponent`
30
+ - **Form controls** — `InputComponent`, `TextareaComponent`, `CheckboxComponent`, `RadioComponent`, `SwitchComponent`, `SelectComponent`, `AutocompleteComponent`, `TagInputComponent`, `SearchInputComponent`, `SearchBarComponent`
31
+ - **Display** — `TagComponent`, `TagRemoveComponent`, `BadgeComponent`, `BulletComponent`, `KbdComponent`, `AvatarComponent`
32
+ - **Lists and navigation** — `ListComponent`, `TreeComponent`, `RowGridComponent`, `RowFeedComponent`, `TabsComponent`, `MenuComponent`, `SidebarComponent`
33
+ - **Overlays** — `DialogComponent`, `SheetComponent`, `PopoverDirective` (alias `DropdownDirective`), `TooltipDirective`, `injectFloatingPanel`, `createCallable` (dialogs opened from code)
34
+ - **Layout** — `ResizablePanelGroupComponent`, `ResizablePanelComponent`, `ResizableHandleComponent`
35
+ - **Services** — `BreakpointObserverService`
36
+ - **Icons** — the icon catalogue is re-exported from the main entry point (for example `CheckIcon`)
31
37
 
32
38
  ## Usage
33
39
 
@@ -119,7 +125,7 @@ import { TabsComponent, TabListComponent, TabComponent, TabPanelComponent } from
119
125
  `,
120
126
  })
121
127
  export class TabsExampleComponent {
122
- onTabChange(value: string) {
128
+ onTabChange(value: string | undefined) {
123
129
  console.log("Selected tab:", value);
124
130
  }
125
131
  }
@@ -146,6 +152,216 @@ import { DropdownDirective } from "@sinequa/galactik";
146
152
  export class PopoverExampleComponent {}
147
153
  ```
148
154
 
155
+ ### Button
156
+
157
+ `ButtonComponent` is a directive on the native `<button>` selector: importing it restyles every
158
+ `<button>` the component's own template renders, and leaves `type`, `disabled` and keyboard behaviour
159
+ to the platform.
160
+
161
+ ```ts
162
+ import { Component } from "@angular/core";
163
+ import { ButtonComponent } from "@sinequa/galactik";
164
+
165
+ @Component({
166
+ selector: "app-button-example",
167
+ imports: [ButtonComponent],
168
+ template: `
169
+ <button type="button" variant="primary" size="md" (click)="save()">Save</button>
170
+ <button type="button" variant="secondary" size="md">Cancel</button>
171
+ `,
172
+ })
173
+ export class ButtonExampleComponent {
174
+ save() {
175
+ /* ... */
176
+ }
177
+ }
178
+ ```
179
+
180
+ ### Input
181
+
182
+ `InputComponent` (`<input-group>`) wraps a native `<input input-control>`; focus, disabled and read-only
183
+ styles come from the input's own state.
184
+
185
+ ```ts
186
+ import { Component } from "@angular/core";
187
+ import { InputComponent, InputControlDirective } from "@sinequa/galactik";
188
+
189
+ @Component({
190
+ selector: "app-input-example",
191
+ imports: [InputComponent, InputControlDirective],
192
+ template: `
193
+ <input-group>
194
+ <input input-control type="text" placeholder="Enter your name" />
195
+ </input-group>
196
+ `,
197
+ })
198
+ export class InputExampleComponent {}
199
+ ```
200
+
201
+ ### Select
202
+
203
+ `SelectComponent` (`<SelectMenu>`) is a single- or multiple-choice dropdown built on the accessible
204
+ `@angular/aria` combobox. It implements the Signal Forms `FormValueControl` contract, so it binds with
205
+ `[(value)]` or `[formField]`.
206
+
207
+ ```ts
208
+ import { Component, signal } from "@angular/core";
209
+ import { SelectComponent } from "@sinequa/galactik";
210
+
211
+ @Component({
212
+ selector: "app-select-example",
213
+ imports: [SelectComponent],
214
+ template: `
215
+ <SelectMenu
216
+ [options]="fruits"
217
+ [(value)]="fruit"
218
+ fieldLabel="Fruit"
219
+ placeholder="Choose a fruit…"
220
+ hint="Pick your favorite." />
221
+ `,
222
+ })
223
+ export class SelectExampleComponent {
224
+ fruits = ["Apple", "Banana", "Cherry", "Date", "Elderberry"];
225
+ fruit = signal<string | null>(null);
226
+ }
227
+ ```
228
+
229
+ ### Dialog
230
+
231
+ Bind a dialog component once with `createCallable`, then `await` it from anywhere. Register
232
+ `provideCallable()` once in the application providers.
233
+
234
+ ```ts title="confirm-dialog.ts"
235
+ import { afterNextRender, Component, viewChild } from "@angular/core";
236
+ import {
237
+ ButtonComponent,
238
+ createCallable,
239
+ DialogBodyComponent,
240
+ DialogComponent,
241
+ DialogContentComponent,
242
+ DialogDescriptionComponent,
243
+ DialogFooterComponent,
244
+ DialogHeaderComponent,
245
+ DialogTitleComponent,
246
+ injectCallRef,
247
+ } from "@sinequa/galactik";
248
+
249
+ @Component({
250
+ selector: "confirm-dialog",
251
+ imports: [
252
+ DialogComponent,
253
+ DialogContentComponent,
254
+ DialogHeaderComponent,
255
+ DialogTitleComponent,
256
+ DialogBodyComponent,
257
+ DialogDescriptionComponent,
258
+ DialogFooterComponent,
259
+ ButtonComponent,
260
+ ],
261
+ template: `
262
+ <dialog #dialog="dialog" (closed)="call.end($event === 'dialog-confirm')">
263
+ <DialogContent size="sm">
264
+ <DialogHeader>
265
+ <DialogTitle>Please confirm</DialogTitle>
266
+ </DialogHeader>
267
+ <DialogBody>
268
+ <DialogDescription>{{ call.props().message }}</DialogDescription>
269
+ </DialogBody>
270
+ <DialogFooter>
271
+ <button variant="secondary" size="md" (click)="dialog.close('dialog-cancel')">Cancel</button>
272
+ <button variant="primary" size="md" (click)="dialog.close('dialog-confirm')">Confirm</button>
273
+ </DialogFooter>
274
+ </DialogContent>
275
+ </dialog>
276
+ `,
277
+ })
278
+ export class ConfirmDialog {
279
+ protected readonly call = injectCallRef<{ message: string }, boolean>();
280
+ private readonly dialog = viewChild.required(DialogComponent);
281
+
282
+ constructor() {
283
+ afterNextRender(() => this.dialog().showModal());
284
+ }
285
+ }
286
+
287
+ export const Confirm = createCallable<{ message: string }, boolean>(ConfirmDialog);
288
+ ```
289
+
290
+ ```ts title="delete-item.component.ts"
291
+ import { Component, signal } from "@angular/core";
292
+ import { ButtonComponent } from "@sinequa/galactik";
293
+ import { Confirm } from "./confirm-dialog";
294
+
295
+ @Component({
296
+ selector: "app-delete-item",
297
+ imports: [ButtonComponent],
298
+ template: `
299
+ <button variant="primary" size="md" (click)="deleteItem()">Delete item…</button>
300
+ @if (deleted()) {
301
+ <p>Item was deleted.</p>
302
+ }
303
+ `,
304
+ })
305
+ export class DeleteItemComponent {
306
+ protected readonly deleted = signal(false);
307
+
308
+ protected async deleteItem() {
309
+ const confirmed = await Confirm.call({ message: "Delete this item? This cannot be undone." });
310
+ if (confirmed) this.deleted.set(true);
311
+ }
312
+ }
313
+ ```
314
+
315
+ ### Tooltip
316
+
317
+ `TooltipDirective` (`[tooltip]`) opens on hover and on keyboard focus, and closes on `Escape`. It
318
+ describes the element, it does not name it: an icon-only button still needs an `aria-label`.
319
+
320
+ ```ts
321
+ import { Component } from "@angular/core";
322
+ import { TooltipDirective } from "@sinequa/galactik";
323
+
324
+ @Component({
325
+ selector: "app-tooltip-example",
326
+ imports: [TooltipDirective],
327
+ template: `
328
+ <button type="button" aria-label="Delete" tooltip="Delete this item" tooltipPosition="top">Delete</button>
329
+ `,
330
+ })
331
+ export class TooltipExampleComponent {}
332
+ ```
333
+
334
+ ## Releases
335
+
336
+ A summary of the changes published for `@sinequa/galactik`. Versioning follows [SemVer](https://semver.org/): a **major** version may break the API, a **minor** version
337
+ adds backward-compatible features, a **patch** fixes bugs.
338
+
339
+ **2.1.1**
340
+
341
+ - A non-native `DialogComponent` (`[dialog]`) now takes the focus when it opens, makes the page
342
+ behind it inert, keeps Tab from leaving the modal and gives the focus back to the element that
343
+ opened it on close.
344
+
345
+ **2.1.0**
346
+
347
+ - New `KeyboardIcon`.
348
+
349
+ **2.0.0** — first published version of the library
350
+
351
+ - Components added: `Autocomplete` (replaces `SearchSelect`), `Sheet`, `Sidebar`, `Textarea`,
352
+ `TagInput`, `TagRemove`, `Tree` (built on `@angular/aria/tree`), `RowGrid`, `RowFeed`, `Bullet`,
353
+ `Resizable*`, `Kbd`, `TooltipDirective` (opens on keyboard focus, closes on `Escape`),
354
+ `injectFloatingPanel()`, `BreakpointObserverService`, checkable menu items, decorative `Switch`.
355
+ - Icon catalogue (over 120 icons) re-exported from the main barrel; icons now follow the size
356
+ imposed by their container.
357
+ - Accessibility: focus rings that are actually painted, `SelectMenu` named from its label,
358
+ translatable `closeLabel` on `Dialog` / `Sheet`, `ariaLabel` on `SearchBar`, `fieldLabelLang` on
359
+ `Autocomplete`.
360
+ - ⚠️ Behaviour changes: list item text is no longer truncated by default; content projected into
361
+ `SearchBar` renders between the clear button and the send button (use `slot="trailing"` to keep
362
+ it at the end of the field); `Tooltip`: `life` defaults to 0.
363
+ - Compatible with `@angular/aria` 22.2 (`ToggleGroup` owns its selection).
364
+
149
365
  ## Development
150
366
 
151
367
  This library is part of the `atomic-angular` workspace and is built with the Angular CLI: