@letsprogram/ng-oat 0.1.2 → 0.1.3
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 +5 -7
- package/assets/oat/css/utilities.css +4 -0
- package/assets/oat/oat.min.css +16 -0
- package/fesm2022/letsprogram-ng-oat.mjs +714 -74
- package/package.json +1 -1
- package/types/letsprogram-ng-oat.d.ts +202 -32
- package/assets/oat/js/base.js +0 -107
- package/assets/oat/js/dropdown.js +0 -74
- package/assets/oat/js/index.js +0 -12
- package/assets/oat/js/sidebar.js +0 -22
- package/assets/oat/js/tabs.js +0 -94
- package/assets/oat/js/toast.js +0 -144
- package/assets/oat/js/tooltip.js +0 -36
- package/assets/oat/oat.js +0 -342
- package/assets/oat/oat.min.js +0 -267
package/package.json
CHANGED
|
@@ -7,22 +7,13 @@ interface NgOatOptions {
|
|
|
7
7
|
assets?: {
|
|
8
8
|
/**
|
|
9
9
|
* How to load Oat CSS at runtime.
|
|
10
|
-
* - `false` (default) — CSS is loaded via angular.json styles array (recommended).
|
|
10
|
+
* - `false` (default) — CSS is loaded via angular.json styles array or styles.css import (recommended).
|
|
11
11
|
* - `'link'` — dynamically inject a `<link>` tag (requires assets glob in angular.json).
|
|
12
|
-
* - `'import'` — reserved for future use.
|
|
13
12
|
*/
|
|
14
|
-
css?: 'link' |
|
|
15
|
-
/**
|
|
16
|
-
* How to load Oat JS at runtime.
|
|
17
|
-
* - `false` (default) — JS is loaded via angular.json scripts array (recommended).
|
|
18
|
-
* - `'script'` — dynamically inject a `<script>` tag (requires assets glob in angular.json).
|
|
19
|
-
*/
|
|
20
|
-
js?: 'script' | false;
|
|
13
|
+
css?: 'link' | false;
|
|
21
14
|
};
|
|
22
|
-
/** Register ot-tabs/ot-dropdown custom elements from Oat JS (default: true). */
|
|
23
|
-
registerWebComponents?: boolean;
|
|
24
15
|
/**
|
|
25
|
-
* Base path for vendored Oat assets when using dynamic injection (`css: 'link'`
|
|
16
|
+
* Base path for vendored Oat assets when using dynamic CSS injection (`css: 'link'`).
|
|
26
17
|
* Only relevant if you opted into runtime injection AND configured an assets glob
|
|
27
18
|
* to copy files from `node_modules/@letsprogram/ng-oat/assets/oat` to this path.
|
|
28
19
|
* Default: `'assets/oat'`.
|
|
@@ -30,18 +21,19 @@ interface NgOatOptions {
|
|
|
30
21
|
basePath?: string;
|
|
31
22
|
}
|
|
32
23
|
/**
|
|
33
|
-
* Provides
|
|
24
|
+
* Provides ng-oat core initialisation.
|
|
34
25
|
*
|
|
35
|
-
* By default,
|
|
36
|
-
* `angular.json` `styles`
|
|
26
|
+
* By default, no runtime asset injection occurs — add CSS via
|
|
27
|
+
* `angular.json` `styles` array or `@import` in `styles.css` (recommended).
|
|
28
|
+
* Oat JS is no longer needed; all behavior is handled natively by Angular components.
|
|
37
29
|
*
|
|
38
30
|
* ```ts
|
|
39
|
-
* provideNgOat()
|
|
40
|
-
* provideNgOat({ assets: { css: 'link'
|
|
31
|
+
* provideNgOat() // recommended (CSS via angular.json / styles.css)
|
|
32
|
+
* provideNgOat({ assets: { css: 'link' } }) // opt-in runtime CSS injection *
|
|
41
33
|
* ```
|
|
42
34
|
*
|
|
43
|
-
*
|
|
44
|
-
* `{ glob: '
|
|
35
|
+
* \\* Runtime injection requires an assets glob in angular.json to copy files:
|
|
36
|
+
* `{ glob: '**\\/*', input: 'node_modules/@letsprogram/ng-oat/assets/oat', output: '/assets/oat' }`
|
|
45
37
|
*/
|
|
46
38
|
declare function provideNgOat(options?: NgOatOptions): EnvironmentProviders;
|
|
47
39
|
|
|
@@ -337,10 +329,12 @@ declare class NgOatSidebar {
|
|
|
337
329
|
}
|
|
338
330
|
|
|
339
331
|
/**
|
|
340
|
-
* Angular
|
|
332
|
+
* Angular directive that provides native tab behaviour on any element
|
|
333
|
+
* containing `role="tablist"` > `role="tab"` buttons and sibling
|
|
334
|
+
* `role="tabpanel"` containers.
|
|
341
335
|
*
|
|
342
|
-
*
|
|
343
|
-
*
|
|
336
|
+
* Works without oat.js — handles tab activation, ARIA attributes,
|
|
337
|
+
* panel visibility and full keyboard navigation internally.
|
|
344
338
|
*
|
|
345
339
|
* Usage:
|
|
346
340
|
* ```html
|
|
@@ -368,10 +362,13 @@ declare class NgOatTabs {
|
|
|
368
362
|
index: number;
|
|
369
363
|
tab: HTMLElement;
|
|
370
364
|
}>;
|
|
371
|
-
private
|
|
365
|
+
private tabEls;
|
|
366
|
+
private panelEls;
|
|
367
|
+
private cleanupFns;
|
|
372
368
|
constructor();
|
|
373
369
|
/** Programmatically select a tab by index */
|
|
374
370
|
selectTab(index: number): void;
|
|
371
|
+
private activate;
|
|
375
372
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<NgOatTabs, never>;
|
|
376
373
|
static ɵdir: _angular_core.ɵɵDirectiveDeclaration<NgOatTabs, "ot-tabs[ngOatTabs], [ngOatTabs]", ["ngOatTabs"], {}, { "ngOatTabChange": "ngOatTabChange"; }, never, never, true, never>;
|
|
377
374
|
}
|
|
@@ -421,9 +418,9 @@ declare class NgOatDialog {
|
|
|
421
418
|
static ɵdir: _angular_core.ɵɵDirectiveDeclaration<NgOatDialog, "dialog[ngOatDialog]", ["ngOatDialog"], {}, { "ngOatDialogClose": "ngOatDialogClose"; }, never, never, true, never>;
|
|
422
419
|
}
|
|
423
420
|
|
|
424
|
-
/** Toast placement positions
|
|
421
|
+
/** Toast placement positions */
|
|
425
422
|
type NgOatToastPlacement = 'top-left' | 'top-center' | 'top-right' | 'bottom-left' | 'bottom-center' | 'bottom-right';
|
|
426
|
-
/** Toast variants
|
|
423
|
+
/** Toast variants */
|
|
427
424
|
type NgOatToastVariant = 'info' | 'success' | 'danger' | 'warning';
|
|
428
425
|
/** Options for showing a toast */
|
|
429
426
|
interface NgOatToastOptions {
|
|
@@ -437,10 +434,11 @@ interface NgOatToastOptions {
|
|
|
437
434
|
dismissible?: boolean;
|
|
438
435
|
}
|
|
439
436
|
/**
|
|
440
|
-
* Angular service
|
|
437
|
+
* Angular service for Oat-styled toast notifications.
|
|
441
438
|
*
|
|
442
|
-
*
|
|
443
|
-
*
|
|
439
|
+
* Fully native implementation — no dependency on oat.js.
|
|
440
|
+
* Uses the Oat CSS `.toast`, `.toast-container`, `data-entering/data-exiting`
|
|
441
|
+
* animation patterns, and popover API for stacking.
|
|
444
442
|
*
|
|
445
443
|
* Usage:
|
|
446
444
|
* ```ts
|
|
@@ -454,7 +452,8 @@ interface NgOatToastOptions {
|
|
|
454
452
|
declare class NgOatToast {
|
|
455
453
|
private platformId;
|
|
456
454
|
private doc;
|
|
457
|
-
|
|
455
|
+
/** Cache of toast containers keyed by placement */
|
|
456
|
+
private containers;
|
|
458
457
|
success(message: string, title?: string, options?: Omit<NgOatToastOptions, 'variant'>): void;
|
|
459
458
|
info(message: string, title?: string, options?: Omit<NgOatToastOptions, 'variant'>): void;
|
|
460
459
|
warning(message: string, title?: string, options?: Omit<NgOatToastOptions, 'variant'>): void;
|
|
@@ -462,7 +461,6 @@ declare class NgOatToast {
|
|
|
462
461
|
show(message: string, title?: string, options?: NgOatToastOptions): HTMLElement | void;
|
|
463
462
|
/**
|
|
464
463
|
* Show a toast from a DOM element or template element.
|
|
465
|
-
* For Angular TemplateRef, use showTemplate() instead.
|
|
466
464
|
*/
|
|
467
465
|
showElement(element: HTMLElement, options?: NgOatToastOptions): void;
|
|
468
466
|
/**
|
|
@@ -472,6 +470,12 @@ declare class NgOatToast {
|
|
|
472
470
|
showTemplate(templateRef: TemplateRef<any>, vcr: ViewContainerRef, options?: NgOatToastOptions): void;
|
|
473
471
|
/** Dismiss toasts. If placement given, only that position; otherwise all. */
|
|
474
472
|
dismiss(placement?: NgOatToastPlacement): void;
|
|
473
|
+
/** Get or create a toast container for the given placement */
|
|
474
|
+
private getContainer;
|
|
475
|
+
/** Show a prepared element as a toast */
|
|
476
|
+
private showEl;
|
|
477
|
+
/** Remove a toast with exit animation */
|
|
478
|
+
private removeToast;
|
|
475
479
|
/** Add a close button to a toast element */
|
|
476
480
|
private addCloseButton;
|
|
477
481
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<NgOatToast, never>;
|
|
@@ -853,6 +857,9 @@ declare class NgOatDropdownComponent {
|
|
|
853
857
|
open(): void;
|
|
854
858
|
close(): void;
|
|
855
859
|
toggle(): void;
|
|
860
|
+
/** Keyboard navigation for menu items (ArrowDown/Up/Home/End/Escape) */
|
|
861
|
+
private onKeydown;
|
|
862
|
+
private doc;
|
|
856
863
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<NgOatDropdownComponent, never>;
|
|
857
864
|
static ɵcmp: _angular_core.ɵɵComponentDeclaration<NgOatDropdownComponent, "ng-oat-dropdown", never, {}, { "openChange": "openChange"; }, never, ["[trigger]", "*"], true, never>;
|
|
858
865
|
}
|
|
@@ -1522,6 +1529,169 @@ declare class NgOatCardCarousel implements AfterViewInit, OnDestroy {
|
|
|
1522
1529
|
static ɵcmp: _angular_core.ɵɵComponentDeclaration<NgOatCardCarousel, "ng-oat-card-carousel", never, { "heading": { "alias": "heading"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; "items": { "alias": "items"; "required": false; "isSignal": true; }; "showSeeAll": { "alias": "showSeeAll"; "required": false; "isSignal": true; }; "scrollAmount": { "alias": "scrollAmount"; "required": false; "isSignal": true; }; }, { "seeAllClick": "seeAllClick"; "cardClick": "cardClick"; }, never, never, true, never>;
|
|
1523
1530
|
}
|
|
1524
1531
|
|
|
1532
|
+
type NgOatToolbarColor = 'default' | 'primary' | 'accent';
|
|
1533
|
+
/**
|
|
1534
|
+
* Angular toolbar component — like mat-toolbar, built on Oat CSS.
|
|
1535
|
+
*
|
|
1536
|
+
* Renders a fixed-position `<nav data-topnav>` that leverages Oat's built-in
|
|
1537
|
+
* topnav styling (flex, border, shadow). Content-projected slots let you
|
|
1538
|
+
* arrange Logo / nav-links / actions however you like.
|
|
1539
|
+
*
|
|
1540
|
+
* ## Slots
|
|
1541
|
+
* - **`[toolbarStart]`** — Left-aligned content (logo, brand, hamburger)
|
|
1542
|
+
* - **Default `<ng-content>`** — Center / free-form content (nav links, search)
|
|
1543
|
+
* - **`[toolbarEnd]`** — Right-aligned content (user menu, theme toggle, actions)
|
|
1544
|
+
*
|
|
1545
|
+
* ## Layout
|
|
1546
|
+
* The toolbar uses `display:flex; align-items:center` with a spacer between
|
|
1547
|
+
* the default content and the end slot, so start items anchor left and end
|
|
1548
|
+
* items anchor right automatically.
|
|
1549
|
+
*
|
|
1550
|
+
* Usage:
|
|
1551
|
+
* ```html
|
|
1552
|
+
* <ng-oat-toolbar>
|
|
1553
|
+
* <a toolbarStart routerLink="/" class="brand">🌾 MyApp</a>
|
|
1554
|
+
* <nav>
|
|
1555
|
+
* <a routerLink="/home">Home</a>
|
|
1556
|
+
* <a routerLink="/about">About</a>
|
|
1557
|
+
* </nav>
|
|
1558
|
+
* <ng-oat-dropdown toolbarEnd>
|
|
1559
|
+
* <button trigger class="ghost">👤 User ▾</button>
|
|
1560
|
+
* <a role="menuitem">Profile</a>
|
|
1561
|
+
* <a role="menuitem">Settings</a>
|
|
1562
|
+
* <hr />
|
|
1563
|
+
* <a role="menuitem">Logout</a>
|
|
1564
|
+
* </ng-oat-dropdown>
|
|
1565
|
+
* </ng-oat-toolbar>
|
|
1566
|
+
* ```
|
|
1567
|
+
*/
|
|
1568
|
+
declare class NgOatToolbar {
|
|
1569
|
+
readonly color: _angular_core.InputSignal<NgOatToolbarColor>;
|
|
1570
|
+
readonly dense: _angular_core.InputSignal<boolean>;
|
|
1571
|
+
readonly fixed: _angular_core.InputSignal<boolean>;
|
|
1572
|
+
protected attrVariant: _angular_core.Signal<"primary" | "accent" | null>;
|
|
1573
|
+
protected navClass: _angular_core.Signal<string>;
|
|
1574
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<NgOatToolbar, never>;
|
|
1575
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<NgOatToolbar, "ng-oat-toolbar", never, { "color": { "alias": "color"; "required": false; "isSignal": true; }; "dense": { "alias": "dense"; "required": false; "isSignal": true; }; "fixed": { "alias": "fixed"; "required": false; "isSignal": true; }; }, {}, never, ["[toolbarStart]", "*", "[toolbarEnd]"], true, never>;
|
|
1576
|
+
}
|
|
1577
|
+
/**
|
|
1578
|
+
* Toolbar row — use multiple rows stacked inside a toolbar.
|
|
1579
|
+
*
|
|
1580
|
+
* Usage:
|
|
1581
|
+
* ```html
|
|
1582
|
+
* <ng-oat-toolbar>
|
|
1583
|
+
* <ng-oat-toolbar-row>
|
|
1584
|
+
* <a toolbarStart>Brand</a>
|
|
1585
|
+
* <span toolbarEnd>Actions</span>
|
|
1586
|
+
* </ng-oat-toolbar-row>
|
|
1587
|
+
* <ng-oat-toolbar-row dense>
|
|
1588
|
+
* <nav>Sub-navigation tabs</nav>
|
|
1589
|
+
* </ng-oat-toolbar-row>
|
|
1590
|
+
* </ng-oat-toolbar>
|
|
1591
|
+
* ```
|
|
1592
|
+
*/
|
|
1593
|
+
declare class NgOatToolbarRow {
|
|
1594
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<NgOatToolbarRow, never>;
|
|
1595
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<NgOatToolbarRow, "ng-oat-toolbar-row", never, {}, {}, never, ["*"], true, never>;
|
|
1596
|
+
}
|
|
1597
|
+
|
|
1598
|
+
type NgOatTheme = 'light' | 'dark' | 'system';
|
|
1599
|
+
/** Describes one option in the theme selector. */
|
|
1600
|
+
interface NgOatThemeOption {
|
|
1601
|
+
/** The theme value written to localStorage / emitted. */
|
|
1602
|
+
value: NgOatTheme;
|
|
1603
|
+
/** Human-readable label shown in dropdown items. */
|
|
1604
|
+
label: string;
|
|
1605
|
+
/** Optional text/emoji shown instead of the built-in SVG icon. */
|
|
1606
|
+
icon?: string;
|
|
1607
|
+
}
|
|
1608
|
+
/**
|
|
1609
|
+
* Structural directive for fully-custom icon rendering.
|
|
1610
|
+
*
|
|
1611
|
+
* Place inside `<ng-oat-theme-selector>` to replace the built-in SVG icons.
|
|
1612
|
+
* The template context receives the current `NgOatThemeOption` as `$implicit`.
|
|
1613
|
+
*
|
|
1614
|
+
* ```html
|
|
1615
|
+
* <ng-oat-theme-selector>
|
|
1616
|
+
* <ng-template ngOatThemeSelectorIcon let-opt>
|
|
1617
|
+
* <my-icon [name]="opt.value" />
|
|
1618
|
+
* </ng-template>
|
|
1619
|
+
* </ng-oat-theme-selector>
|
|
1620
|
+
* ```
|
|
1621
|
+
*/
|
|
1622
|
+
declare class NgOatThemeSelectorIcon {
|
|
1623
|
+
readonly tpl: TemplateRef<any>;
|
|
1624
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<NgOatThemeSelectorIcon, never>;
|
|
1625
|
+
static ɵdir: _angular_core.ɵɵDirectiveDeclaration<NgOatThemeSelectorIcon, "ng-template[ngOatThemeSelectorIcon]", never, {}, {}, never, never, true, never>;
|
|
1626
|
+
}
|
|
1627
|
+
/**
|
|
1628
|
+
* Theme selector — shadcn-inspired light / dark / system toggle.
|
|
1629
|
+
*
|
|
1630
|
+
* Applies `colorScheme` on `<html>` and persists the choice to `localStorage`.
|
|
1631
|
+
* When "system" is selected it respects `prefers-color-scheme`.
|
|
1632
|
+
*
|
|
1633
|
+
* Usage:
|
|
1634
|
+
* ```html
|
|
1635
|
+
* <!-- Dropdown-style (default) -->
|
|
1636
|
+
* <ng-oat-theme-selector />
|
|
1637
|
+
*
|
|
1638
|
+
* <!-- Inline toggle group style -->
|
|
1639
|
+
* <ng-oat-theme-selector mode="toggle" />
|
|
1640
|
+
*
|
|
1641
|
+
* <!-- Listen for changes -->
|
|
1642
|
+
* <ng-oat-theme-selector (themeChange)="onTheme($event)" />
|
|
1643
|
+
* ```
|
|
1644
|
+
*/
|
|
1645
|
+
declare class NgOatThemeSelector implements OnInit {
|
|
1646
|
+
/** Display mode: dropdown menu or inline toggle group */
|
|
1647
|
+
readonly mode: _angular_core.InputSignal<"dropdown" | "toggle">;
|
|
1648
|
+
/** Initial theme (overrides localStorage if set) */
|
|
1649
|
+
readonly initialTheme: _angular_core.InputSignal<NgOatTheme | undefined>;
|
|
1650
|
+
/**
|
|
1651
|
+
* Custom theme options. Override labels, provide emoji icons, or
|
|
1652
|
+
* change the set entirely.
|
|
1653
|
+
*
|
|
1654
|
+
* ```html
|
|
1655
|
+
* <ng-oat-theme-selector
|
|
1656
|
+
* [themes]="[
|
|
1657
|
+
* { value: 'light', label: 'Day', icon: '🌅' },
|
|
1658
|
+
* { value: 'dark', label: 'Night', icon: '🌃' },
|
|
1659
|
+
* { value: 'system', label: 'Auto', icon: '🖥️' },
|
|
1660
|
+
* ]" />
|
|
1661
|
+
* ```
|
|
1662
|
+
*/
|
|
1663
|
+
readonly themes: _angular_core.InputSignal<NgOatThemeOption[]>;
|
|
1664
|
+
/** Emits when the user picks a theme */
|
|
1665
|
+
readonly themeChange: _angular_core.OutputEmitterRef<NgOatTheme>;
|
|
1666
|
+
/** Current active theme */
|
|
1667
|
+
readonly current: _angular_core.WritableSignal<NgOatTheme>;
|
|
1668
|
+
readonly open: _angular_core.WritableSignal<boolean>;
|
|
1669
|
+
/** Content-projected custom icon template */
|
|
1670
|
+
protected readonly iconTpl: _angular_core.Signal<NgOatThemeSelectorIcon | undefined>;
|
|
1671
|
+
/** Resolved themes (input or defaults) */
|
|
1672
|
+
protected resolvedThemes: _angular_core.Signal<NgOatThemeOption[]>;
|
|
1673
|
+
/** The currently active option object */
|
|
1674
|
+
protected activeOption: _angular_core.Signal<NgOatThemeOption>;
|
|
1675
|
+
private doc;
|
|
1676
|
+
private platformId;
|
|
1677
|
+
private mediaQuery;
|
|
1678
|
+
private mediaListener;
|
|
1679
|
+
/** Toggle the dropdown open/closed */
|
|
1680
|
+
toggleOpen(): void;
|
|
1681
|
+
/** Pick a theme and close the dropdown */
|
|
1682
|
+
pick(theme: NgOatTheme): void;
|
|
1683
|
+
/** Keyboard handler for Escape and arrow-key navigation inside the menu */
|
|
1684
|
+
onHostKey(e: KeyboardEvent): void;
|
|
1685
|
+
ngOnInit(): void;
|
|
1686
|
+
setTheme(theme: NgOatTheme): void;
|
|
1687
|
+
private applyResolved;
|
|
1688
|
+
private onDocClick;
|
|
1689
|
+
/** @internal */
|
|
1690
|
+
ngOnDestroy(): void;
|
|
1691
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<NgOatThemeSelector, never>;
|
|
1692
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<NgOatThemeSelector, "ng-oat-theme-selector", never, { "mode": { "alias": "mode"; "required": false; "isSignal": true; }; "initialTheme": { "alias": "initialTheme"; "required": false; "isSignal": true; }; "themes": { "alias": "themes"; "required": false; "isSignal": true; }; }, { "themeChange": "themeChange"; }, ["iconTpl"], never, true, never>;
|
|
1693
|
+
}
|
|
1694
|
+
|
|
1525
1695
|
type NgOatInputType = 'text' | 'email' | 'password' | 'number' | 'tel' | 'url' | 'search' | 'date' | 'datetime-local' | 'time' | 'month' | 'week' | 'color';
|
|
1526
1696
|
/**
|
|
1527
1697
|
* Oat-styled text input implementing `FormValueControl<string>`.
|
|
@@ -1750,5 +1920,5 @@ interface TooltipPositioner {
|
|
|
1750
1920
|
/** DI token for tooltip positioning strategy */
|
|
1751
1921
|
declare const TOOLTIP_POSITIONER: InjectionToken<TooltipPositioner>;
|
|
1752
1922
|
|
|
1753
|
-
export { NG_OAT_CHIP_GROUP, NG_OAT_TOGGLE_GROUP, NgOatAccordion, NgOatAlert, NgOatAvatar, NgOatBadge, NgOatBreadcrumb, NgOatButton, NgOatCard, NgOatCardCarousel, NgOatCardFooter, NgOatCardHeader, NgOatCarousel, NgOatCheckbox, NgOatChip, NgOatChipGroup, NgOatChipInput, NgOatDialog, NgOatDialogComponent, NgOatDropdown, NgOatDropdownComponent, NgOatFileUpload, NgOatFormError, NgOatInput, NgOatInputOtp, NgOatMeter, NgOatPagination, NgOatProgress, NgOatRadioGroup, NgOatSearchInput, NgOatSelect, NgOatSeparator, NgOatSidebar, NgOatSidebarComponent, NgOatSkeleton, NgOatSpinner, NgOatSplitButton, NgOatSwitch, NgOatTable, NgOatTabs, NgOatTabsComponent, NgOatTextarea, NgOatThemeRef, NgOatToast, NgOatToggle, NgOatToggleGroup, NgOatTooltip, NgOatTooltipComponent, OAT_TOKEN_MAP, OAT_VERSION, OAT_VERSION_TOKEN, TOOLTIP_POSITIONER, provideNgOat, provideNgOatTheme };
|
|
1754
|
-
export type { NgOatAccordionItem, NgOatAlertVariant, NgOatAvatarSize, NgOatBadgeVariant, NgOatButtonSize, NgOatButtonStyle, NgOatButtonVariant, NgOatCarouselAspectRatio, NgOatCarouselOrientation, NgOatCarouselSlide, NgOatChipGroupHost, NgOatChipSize, NgOatChipVariant, NgOatInputType, NgOatOptions, NgOatProductCard, NgOatRadioOption, NgOatSelectOption, NgOatSeparatorOrientation, NgOatSkeletonType, NgOatSpinnerSize, NgOatTabItem, NgOatTableColumn, NgOatThemeConfig, NgOatToastOptions, NgOatToastPlacement, NgOatToastVariant, NgOatToggleGroupHost, NgOatToggleGroupSize, NgOatToggleGroupVariant, NgOatToggleSize, NgOatToggleVariant, OatBreadcrumbItem, OatTokens, Placement, TooltipPositioner };
|
|
1923
|
+
export { NG_OAT_CHIP_GROUP, NG_OAT_TOGGLE_GROUP, NgOatAccordion, NgOatAlert, NgOatAvatar, NgOatBadge, NgOatBreadcrumb, NgOatButton, NgOatCard, NgOatCardCarousel, NgOatCardFooter, NgOatCardHeader, NgOatCarousel, NgOatCheckbox, NgOatChip, NgOatChipGroup, NgOatChipInput, NgOatDialog, NgOatDialogComponent, NgOatDropdown, NgOatDropdownComponent, NgOatFileUpload, NgOatFormError, NgOatInput, NgOatInputOtp, NgOatMeter, NgOatPagination, NgOatProgress, NgOatRadioGroup, NgOatSearchInput, NgOatSelect, NgOatSeparator, NgOatSidebar, NgOatSidebarComponent, NgOatSkeleton, NgOatSpinner, NgOatSplitButton, NgOatSwitch, NgOatTable, NgOatTabs, NgOatTabsComponent, NgOatTextarea, NgOatThemeRef, NgOatThemeSelector, NgOatThemeSelectorIcon, NgOatToast, NgOatToggle, NgOatToggleGroup, NgOatToolbar, NgOatToolbarRow, NgOatTooltip, NgOatTooltipComponent, OAT_TOKEN_MAP, OAT_VERSION, OAT_VERSION_TOKEN, TOOLTIP_POSITIONER, provideNgOat, provideNgOatTheme };
|
|
1924
|
+
export type { NgOatAccordionItem, NgOatAlertVariant, NgOatAvatarSize, NgOatBadgeVariant, NgOatButtonSize, NgOatButtonStyle, NgOatButtonVariant, NgOatCarouselAspectRatio, NgOatCarouselOrientation, NgOatCarouselSlide, NgOatChipGroupHost, NgOatChipSize, NgOatChipVariant, NgOatInputType, NgOatOptions, NgOatProductCard, NgOatRadioOption, NgOatSelectOption, NgOatSeparatorOrientation, NgOatSkeletonType, NgOatSpinnerSize, NgOatTabItem, NgOatTableColumn, NgOatTheme, NgOatThemeConfig, NgOatThemeOption, NgOatToastOptions, NgOatToastPlacement, NgOatToastVariant, NgOatToggleGroupHost, NgOatToggleGroupSize, NgOatToggleGroupVariant, NgOatToggleSize, NgOatToggleVariant, NgOatToolbarColor, OatBreadcrumbItem, OatTokens, Placement, TooltipPositioner };
|
package/assets/oat/js/base.js
DELETED
|
@@ -1,107 +0,0 @@
|
|
|
1
|
-
// oat - Base Web Component Class
|
|
2
|
-
// Provides lifecycle management, event handling, and utilities.
|
|
3
|
-
|
|
4
|
-
export class OtBase extends HTMLElement {
|
|
5
|
-
#initialized = false;
|
|
6
|
-
|
|
7
|
-
// Called when element is added to DOM.
|
|
8
|
-
connectedCallback() {
|
|
9
|
-
if (this.#initialized) return;
|
|
10
|
-
|
|
11
|
-
// Wait for DOM to be ready.
|
|
12
|
-
if (document.readyState === 'loading') {
|
|
13
|
-
document.addEventListener('DOMContentLoaded', () => this.#setup(), { once: true });
|
|
14
|
-
} else {
|
|
15
|
-
this.#setup();
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
// Private setup to ensure that init() is only called once.
|
|
20
|
-
#setup() {
|
|
21
|
-
if (this.#initialized) return;
|
|
22
|
-
this.#initialized = true;
|
|
23
|
-
this.init();
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
// Called when element is removed from DOM.
|
|
27
|
-
disconnectedCallback() {
|
|
28
|
-
this.cleanup();
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
// Override in subclass for cleanup logic.
|
|
32
|
-
cleanup() {}
|
|
33
|
-
|
|
34
|
-
// Central event handler - enables automatic cleanup.
|
|
35
|
-
// Usage: element.addEventListener('click', this)
|
|
36
|
-
handleEvent(event) {
|
|
37
|
-
const handler = this[`on${event.type}`];
|
|
38
|
-
if (handler) handler.call(this, event);
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
// Given a keyboard event (left, right, home, end), the current selection idx
|
|
42
|
-
// total items in a list, return 0-n index of the next/previous item
|
|
43
|
-
// for doing a roving keyboard nav.
|
|
44
|
-
keyNav(event, idx, len, prevKey, nextKey, homeEnd = false) {
|
|
45
|
-
const { key } = event;
|
|
46
|
-
let next = -1;
|
|
47
|
-
|
|
48
|
-
if (key === nextKey) {
|
|
49
|
-
next = (idx + 1) % len;
|
|
50
|
-
} else if (key === prevKey) {
|
|
51
|
-
next = (idx - 1 + len) % len;
|
|
52
|
-
} else if (homeEnd) {
|
|
53
|
-
if (key === 'Home') {
|
|
54
|
-
next = 0;
|
|
55
|
-
} else if (key === 'End') {
|
|
56
|
-
next = len - 1;
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
if (next >= 0) event.preventDefault();
|
|
61
|
-
return next;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
// Emit a custom event.
|
|
65
|
-
emit(name, detail = null) {
|
|
66
|
-
return this.dispatchEvent(new CustomEvent(name, {
|
|
67
|
-
bubbles: true,
|
|
68
|
-
composed: true,
|
|
69
|
-
cancelable: true,
|
|
70
|
-
detail
|
|
71
|
-
}));
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
// Query selector within this element.
|
|
75
|
-
$(selector) {
|
|
76
|
-
return this.querySelector(selector);
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
// Query selector all within this element.
|
|
80
|
-
$$(selector) {
|
|
81
|
-
return Array.from(this.querySelectorAll(selector));
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
// Generate a unique ID string.
|
|
85
|
-
uid() {
|
|
86
|
-
return Math.random().toString(36).slice(2, 10);
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
// Polyfill for command/commandfor (Safari)
|
|
91
|
-
if (!('commandForElement' in HTMLButtonElement.prototype)) {
|
|
92
|
-
document.addEventListener('click', e => {
|
|
93
|
-
const btn = e.target.closest('button[commandfor]');
|
|
94
|
-
if (!btn) return;
|
|
95
|
-
|
|
96
|
-
const target = document.getElementById(btn.getAttribute('commandfor'));
|
|
97
|
-
if (!target) return;
|
|
98
|
-
|
|
99
|
-
const command = btn.getAttribute('command') || 'toggle';
|
|
100
|
-
|
|
101
|
-
if (target instanceof HTMLDialogElement) {
|
|
102
|
-
if (command === 'show-modal') target.showModal();
|
|
103
|
-
else if (command === 'close') target.close();
|
|
104
|
-
else target.open ? target.close() : target.showModal();
|
|
105
|
-
}
|
|
106
|
-
});
|
|
107
|
-
}
|
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* oat - Dropdown Component
|
|
3
|
-
* Provides positioning, keyboard navigation, and ARIA state management.
|
|
4
|
-
*
|
|
5
|
-
* Usage:
|
|
6
|
-
* <ot-dropdown>
|
|
7
|
-
* <button popovertarget="menu-id">Options</button>
|
|
8
|
-
* <menu popover id="menu-id">
|
|
9
|
-
* <button role="menuitem">Item 1</button>
|
|
10
|
-
* <button role="menuitem">Item 2</button>
|
|
11
|
-
* </menu>
|
|
12
|
-
* </ot-dropdown>
|
|
13
|
-
*/
|
|
14
|
-
|
|
15
|
-
import { OtBase } from './base.js';
|
|
16
|
-
|
|
17
|
-
class OtDropdown extends OtBase {
|
|
18
|
-
#menu;
|
|
19
|
-
#trigger;
|
|
20
|
-
#position;
|
|
21
|
-
#items;
|
|
22
|
-
|
|
23
|
-
init() {
|
|
24
|
-
this.#menu = this.$('[popover]');
|
|
25
|
-
this.#trigger = this.$('[popovertarget]');
|
|
26
|
-
|
|
27
|
-
if (!this.#menu || !this.#trigger) return;
|
|
28
|
-
|
|
29
|
-
this.#menu.addEventListener('toggle', this);
|
|
30
|
-
this.#menu.addEventListener('keydown', this);
|
|
31
|
-
|
|
32
|
-
this.#position = () => {
|
|
33
|
-
// Position has to be calculated and applied manually because
|
|
34
|
-
// popover positioning is like fixed, relative to the window.
|
|
35
|
-
const r = this.#trigger.getBoundingClientRect();
|
|
36
|
-
const m = this.#menu.getBoundingClientRect();
|
|
37
|
-
|
|
38
|
-
// Flip if menu overflows viewport.
|
|
39
|
-
this.#menu.style.top = `${r.bottom + m.height > window.innerHeight ? r.top - m.height : r.bottom}px`;
|
|
40
|
-
this.#menu.style.left = `${r.left + m.width > window.innerWidth ? r.right - m.width : r.left}px`;
|
|
41
|
-
};
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
ontoggle(e) {
|
|
45
|
-
if (e.newState === 'open') {
|
|
46
|
-
this.#position();
|
|
47
|
-
window.addEventListener('scroll', this.#position, true);
|
|
48
|
-
window.addEventListener('resize', this.#position);
|
|
49
|
-
this.#items = this.$$('[role="menuitem"]');
|
|
50
|
-
this.#items[0]?.focus();
|
|
51
|
-
this.#trigger.ariaExpanded = 'true';
|
|
52
|
-
} else {
|
|
53
|
-
this.cleanup();
|
|
54
|
-
this.#items = null;
|
|
55
|
-
this.#trigger.ariaExpanded = 'false';
|
|
56
|
-
this.#trigger.focus();
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
onkeydown(e) {
|
|
61
|
-
if (!e.target.matches('[role="menuitem"]')) return;
|
|
62
|
-
|
|
63
|
-
const idx = this.#items.indexOf(e.target);
|
|
64
|
-
const next = this.keyNav(e, idx, this.#items.length, 'ArrowUp', 'ArrowDown', true);
|
|
65
|
-
if (next >= 0) this.#items[next].focus();
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
cleanup() {
|
|
69
|
-
window.removeEventListener('scroll', this.#position, true);
|
|
70
|
-
window.removeEventListener('resize', this.#position);
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
customElements.define('ot-dropdown', OtDropdown);
|
package/assets/oat/js/index.js
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import './base.js';
|
|
2
|
-
import './tabs.js';
|
|
3
|
-
import './dropdown.js';
|
|
4
|
-
import './tooltip.js';
|
|
5
|
-
import './sidebar.js';
|
|
6
|
-
import { toast, toastEl, toastClear } from './toast.js';
|
|
7
|
-
|
|
8
|
-
// Register the global window.ot.* APIs.
|
|
9
|
-
const ot = window.ot || (window.ot = {});
|
|
10
|
-
ot.toast = toast;
|
|
11
|
-
ot.toast.el = toastEl;
|
|
12
|
-
ot.toast.clear = toastClear;
|
package/assets/oat/js/sidebar.js
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Sidebar toggle handler
|
|
3
|
-
* Toggles data-sidebar-open on layout when toggle button is clicked
|
|
4
|
-
*/
|
|
5
|
-
document.addEventListener('click', (e) => {
|
|
6
|
-
const toggle = e.target.closest('[data-sidebar-toggle]');
|
|
7
|
-
if (toggle) {
|
|
8
|
-
const layout = toggle.closest('[data-sidebar-layout]');
|
|
9
|
-
layout?.toggleAttribute('data-sidebar-open');
|
|
10
|
-
return;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
// Dismiss sidebar when clicking outside (when sidebar is not an overlay).
|
|
14
|
-
if (!e.target.closest('[data-sidebar]')) {
|
|
15
|
-
const layout = document.querySelector('[data-sidebar-layout][data-sidebar-open]');
|
|
16
|
-
// Hardcode breakpoint (for now) as there's no way to use a CSS variable in
|
|
17
|
-
// the @media{} query which could've been picked up here.
|
|
18
|
-
if (layout && window.matchMedia('(max-width: 768px)').matches) {
|
|
19
|
-
layout.removeAttribute('data-sidebar-open');
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
});
|
package/assets/oat/js/tabs.js
DELETED
|
@@ -1,94 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* oat - Tabs Component
|
|
3
|
-
* Provides keyboard navigation and ARIA state management.
|
|
4
|
-
*
|
|
5
|
-
* Usage:
|
|
6
|
-
* <ot-tabs>
|
|
7
|
-
* <div role="tablist">
|
|
8
|
-
* <button role="tab">Tab 1</button>
|
|
9
|
-
* <button role="tab">Tab 2</button>
|
|
10
|
-
* </div>
|
|
11
|
-
* <div role="tabpanel">Content 1</div>
|
|
12
|
-
* <div role="tabpanel">Content 2</div>
|
|
13
|
-
* </ot-tabs>
|
|
14
|
-
*/
|
|
15
|
-
|
|
16
|
-
import { OtBase } from './base.js';
|
|
17
|
-
|
|
18
|
-
class OtTabs extends OtBase {
|
|
19
|
-
#tabs = [];
|
|
20
|
-
#panels = [];
|
|
21
|
-
|
|
22
|
-
init() {
|
|
23
|
-
const tablist = this.$(':scope > [role="tablist"]');
|
|
24
|
-
this.#tabs = tablist ? [...tablist.querySelectorAll('[role="tab"]')] : [];
|
|
25
|
-
this.#panels = this.$$(':scope > [role="tabpanel"]');
|
|
26
|
-
|
|
27
|
-
if (this.#tabs.length === 0 || this.#panels.length === 0) {
|
|
28
|
-
console.warn('ot-tabs: Missing tab or tabpanel elements');
|
|
29
|
-
return;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
// Generate IDs and set up ARIA.
|
|
33
|
-
this.#tabs.forEach((tab, i) => {
|
|
34
|
-
const panel = this.#panels[i];
|
|
35
|
-
if (!panel) return;
|
|
36
|
-
|
|
37
|
-
const tabId = tab.id || `ot-tab-${this.uid()}`;
|
|
38
|
-
const panelId = panel.id || `ot-panel-${this.uid()}`;
|
|
39
|
-
|
|
40
|
-
tab.id = tabId;
|
|
41
|
-
panel.id = panelId;
|
|
42
|
-
tab.setAttribute('aria-controls', panelId);
|
|
43
|
-
panel.setAttribute('aria-labelledby', tabId);
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
tablist.addEventListener('click', this);
|
|
47
|
-
tablist.addEventListener('keydown', this);
|
|
48
|
-
|
|
49
|
-
// Find initially active tab or default to first.
|
|
50
|
-
const activeTab = this.#tabs.findIndex(t => t.ariaSelected === 'true');
|
|
51
|
-
this.#activate(activeTab >= 0 ? activeTab : 0);
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
onclick(e) {
|
|
55
|
-
const index = this.#tabs.indexOf(e.target.closest('[role="tab"]'));
|
|
56
|
-
if (index >= 0) this.#activate(index);
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
onkeydown(e) {
|
|
60
|
-
if (!e.target.closest('[role="tab"]')) return;
|
|
61
|
-
|
|
62
|
-
const next = this.keyNav(e, this.activeIndex, this.#tabs.length, 'ArrowLeft', 'ArrowRight');
|
|
63
|
-
if (next >= 0) {
|
|
64
|
-
this.#activate(next);
|
|
65
|
-
this.#tabs[next].focus();
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
#activate(idx) {
|
|
70
|
-
this.#tabs.forEach((tab, i) => {
|
|
71
|
-
const isActive = i === idx;
|
|
72
|
-
tab.ariaSelected = String(isActive);
|
|
73
|
-
tab.tabIndex = isActive ? 0 : -1;
|
|
74
|
-
});
|
|
75
|
-
|
|
76
|
-
this.#panels.forEach((panel, i) => {
|
|
77
|
-
panel.hidden = i !== idx;
|
|
78
|
-
});
|
|
79
|
-
|
|
80
|
-
this.emit('ot-tab-change', { index: idx, tab: this.#tabs[idx] });
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
get activeIndex() {
|
|
84
|
-
return this.#tabs.findIndex(t => t.ariaSelected === 'true');
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
set activeIndex(value) {
|
|
88
|
-
if (value >= 0 && value < this.#tabs.length) {
|
|
89
|
-
this.#activate(value);
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
customElements.define('ot-tabs', OtTabs);
|