@sinequa/galactik 2.1.1 → 2.3.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 +222 -6
- package/fesm2022/sinequa-galactik.mjs +1042 -643
- package/fesm2022/sinequa-galactik.mjs.map +1 -1
- package/package.json +1 -1
- package/types/sinequa-galactik.d.ts +258 -109
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.
|
|
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
|
-
- **
|
|
28
|
-
- **
|
|
29
|
-
- **
|
|
30
|
-
- **
|
|
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:
|