@ngstarter-ui/components 1.0.34 → 1.0.36

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.
@@ -13,11 +13,12 @@
13
13
  "recipes": [
14
14
  {
15
15
  "name": "admin-dashboard",
16
- "description": "Build admin dashboards from NgStarter UI primitives instead of hand-rolled shell, cards, forms, tables, and pagination.",
16
+ "description": "Build admin dashboards from NgStarter UI primitives instead of hand-rolled shell, cards, forms, datatables, static tables, and pagination.",
17
17
  "mustUse": [
18
18
  "@ngstarter-ui/components/sidenav",
19
19
  "@ngstarter-ui/components/navigation",
20
20
  "@ngstarter-ui/components/card",
21
+ "@ngstarter-ui/components/data-view",
21
22
  "@ngstarter-ui/components/table",
22
23
  "@ngstarter-ui/components/form-field",
23
24
  "@ngstarter-ui/components/input",
@@ -43,7 +44,13 @@
43
44
  "CardContent",
44
45
  "CardFooter"
45
46
  ],
46
- "table": [
47
+ "datatables": [
48
+ "DataView"
49
+ ],
50
+ "operationalDatasets": [
51
+ "DataView"
52
+ ],
53
+ "staticTables": [
47
54
  "Table",
48
55
  "ColumnDef",
49
56
  "HeaderCell",
@@ -76,7 +83,9 @@
76
83
  ]
77
84
  },
78
85
  "mustNot": [
79
- "Do not build admin tables with role=\"table\" div grids when ngs-table fits.",
86
+ "Do not build datatables or operational admin datasets with role=\"table\", plain table markup, or div grids when DataView fits.",
87
+ "Do not use DataView for purely static/read-only tabular content when ngs-table fits.",
88
+ "Do not build static/read-only tables with role=\"table\" div grids when ngs-table fits.",
80
89
  "Do not build search fields with plain input when ngs-form-field and ngsInput fit.",
81
90
  "Do not build navigation menus with plain button lists when ngs-navigation fits.",
82
91
  "Do not build KPI cards with plain article/div cards when ngs-card fits.",
@@ -2556,8 +2565,8 @@
2556
2565
  "sourceRoot": "projects/components/core/src",
2557
2566
  "docsPath": null,
2558
2567
  "docsOverviewSource": null,
2559
- "purpose": "Provide shared primitives, utilities, pipes, directives, theming services, and low-level behavior used by NgStarter components.",
2560
- "useWhen": "Import from core for theme setup, shared directives, utility pipes, ripple, focus helpers, and library infrastructure.",
2568
+ "purpose": "Provide infrastructure primitives, theme setup, services, directives, pipes, tokens, and low-level utilities.",
2569
+ "useWhen": "Use @ngstarter-ui/components/core for infrastructure, not for building screens directly. Use provideNgsTheme in app config to set theme, colorScheme, density, radius, primaryColor, persistence, and storageKey. Inject ThemeManagerService for runtime theme, color scheme, density, radius, and primary color changes. Use utility directives such as ngsRipple, ngsAutoFocus, ngsFocusElement, ngsTextareaAutoSize, and ngsDebounceTime when a specific low-level behavior is needed. Use pipes such as InitialsPipe, FormatFileSizePipe, SafeHtmlPipe, SafeResourceUrlPipe, OrderByPipe, FilterByPropertyPipe, and SearchByPropertyPipe when they fit. Use ErrorStateMatcher or ShowOnDirtyErrorStateMatcher for form error behavior, and observer/services/utils only for low-level infrastructure. Do not use core as a replacement for real UI components. Do not build admin screens from core primitives; choose concrete components such as Button, Card, DataView, Table, FormField, Dialog, Navigation, Layout, or other component entry points. Do not import Option from core directly for ordinary option lists when Select, Autocomplete, or another component owns the option pattern.",
2561
2570
  "exampleTopics": [],
2562
2571
  "minimalExample": null,
2563
2572
  "exampleFiles": [],
@@ -2854,7 +2863,7 @@
2854
2863
  "docsPath": "/libraries/data-view",
2855
2864
  "docsOverviewSource": "projects/docs/src/app/libraries/data-view/overview/overview.html",
2856
2865
  "purpose": "Build operational data grids for records that users need to inspect, organize, select, and act on.",
2857
- "useWhen": "Use for admin screens, CRM and ERP records, users, orders, invoices, logs, tasks, assets, and any dataset where the table is the main work surface. DataView is configured with columnDefs plus local data or a server-side datasource, and supports sorting, search/filter state, pagination, row selection, loading states, empty states, column resizing, column visibility and order, pinned or sticky columns, custom cell renderers, refresh, snapshots, and ngsDataViewActionBar. Do not use for small static tables or simple read-only tabular content; use Table. Do not use as a card list, layout grid, chart widget, report summary, or form editor.",
2866
+ "useWhen": "Use for datatables and working data surfaces in admin screens, CRM and ERP records, users, orders, invoices, logs, tasks, assets, and any dataset where the table is the main interactive work surface. Choose DataView when users need row actions, selection, sorting, search/filter state, pagination, loading or empty states, column resizing, column visibility/order, pinned or sticky columns, custom cell renderers, refresh, snapshots, server-side data, or ngsDataViewActionBar. DataView is configured with columnDefs plus local data or a server-side datasource. Do not use for small static tables or simple read-only tabular content; use Table. Do not use as a card list, layout grid, chart widget, report summary, or form editor.",
2858
2867
  "exampleTopics": [
2859
2868
  "Data View",
2860
2869
  "Basic data view",
@@ -4123,8 +4132,8 @@
4123
4132
  "sourceRoot": "projects/components/grid/src",
4124
4133
  "docsPath": "/components/grid",
4125
4134
  "docsOverviewSource": "projects/docs/src/app/components/grid/overview/overview.html",
4126
- "purpose": "Render configuration-driven dashboard widgets in a 12-column grid.",
4127
- "useWhen": "Use for admin dashboards, configurable widget layouts, analytics home screens, portal start pages, and nested dashboard sections where widget components are selected from configuration or data. Provide configs that map item types to lazy-loaded components and optional skeletons, and items with id, type, columns, height, content, skeletonHeight, and children. Widgets can inject GRID and call markItemAsLoaded(id), especially with waitWhenAllItemsLoaded. Do not use Grid as a normal CSS layout helper for forms, pages, cards, or repeated elements; use TailwindCSS grid/flex classes. Do not use for tables or datasets; use Table or DataView. Do not use for file/media grids; use upload/media components. Do not use as a drag-and-drop dashboard builder when interactive rearranging/resizing is required.",
4135
+ "purpose": "Render static dashboard widgets in a predefined 12-column layout.",
4136
+ "useWhen": "Use ngs-grid when the application defines a static dashboard or widget layout and users do not need to rearrange, customize, or save the dashboard order. Provide configs that map item types to components and items with id, type, columns, height, content, skeletonHeight, and children. Widgets can inject GRID and call markItemAsLoaded(id), especially with waitWhenAllItemsLoaded. Use Grid for fixed analytics sections, portal start pages, and nested dashboard sections where the structure is known. Do not use Grid as a normal CSS layout helper for forms, pages, cards, or repeated elements; use TailwindCSS grid/flex classes. Do not use Grid for dashboards users can rearrange or change; use Tiles. Do not use for tables or datasets; use Table or DataView. Do not use for file/media grids; use upload/media components.",
4128
4137
  "exampleTopics": [],
4129
4138
  "minimalExample": null,
4130
4139
  "exampleFiles": [],
@@ -4905,8 +4914,8 @@
4905
4914
  "sourceRoot": "projects/components/input-mask/src",
4906
4915
  "docsPath": "/forms/input-mask",
4907
4916
  "docsOverviewSource": "projects/docs/src/app/forms/input-mask/overview/overview.html",
4908
- "purpose": "Constrain text entry to a specific pattern.",
4909
- "useWhen": "Use for phone numbers, IDs, codes, formatted numbers, and structured text.",
4917
+ "purpose": "Format credit card input fields while the user types with ready-made mask directives.",
4918
+ "useWhen": "Use on native inputs, usually with ngsInput inside ngs-form-field, for payment or billing fields that need credit card formatting. Available directives are ngsCreditCardNumberMask for grouped card numbers, ngsCreditCardExpiryDateMask for MM/YY expiry, and ngsCreditCardCvvMask for CVV/CVC. The directives format the visible input, set useful mobile keyboard and autocomplete attributes where applicable, and keep the Angular form value cleaned for card number and expiry. Do not use as a universal mask engine, validator, payment security layer, or compliance solution. Do not use for phone numbers; use PhoneInput. Do not use for custom IDs, tax numbers, IBAN, postal codes, arbitrary structured text, date pickers, selects, currency fields, country fields, or formatting saved display values; use dedicated components, validators, backend checks, or a custom mask directive.",
4910
4919
  "exampleTopics": [
4911
4920
  "Credit card number input mask",
4912
4921
  "Credit card expiry date input mask",
@@ -4964,16 +4973,19 @@
4964
4973
  "sourceRoot": "projects/components/input-validator/src",
4965
4974
  "docsPath": "/forms/input-validator",
4966
4975
  "docsOverviewSource": "projects/docs/src/app/forms/input-validator/overview/overview.html",
4967
- "purpose": "Validate user input and show validation feedback.",
4968
- "useWhen": "Use for forms that need reusable client-side validation behavior.",
4976
+ "purpose": "Provide ready-made Angular ValidatorFn helpers for common reusable form validation rules.",
4977
+ "useWhen": "Use in reactive forms with ngs-form-field, ngsInput, Angular Validators, and ngs-error when a preset client-side validator fits. Current payment presets include creditCardNumberValidator() for cleaned card number length and Luhn checksum, expiryDateValidator() for MMYY expiry format, valid month, and not-in-past checks, and creditCardCvvValidator() for numeric CVV/CVC length with optional minLength and maxLength. Pair these validators with InputMask directives when the user also needs formatted payment input. Do not use InputValidator as a UI component, input formatter, input mask, replacement for Angular built-in validators, backend validation, payment processor validation, or security/compliance layer. Do not use for arbitrary custom business rules unless a dedicated preset exists; write a project validator.",
4969
4978
  "exampleTopics": [
4970
- "Credit card input validator"
4979
+ "Credit card input validators"
4971
4980
  ],
4972
4981
  "minimalExample": null,
4973
4982
  "exampleFiles": [],
4974
4983
  "previewAsset": "projects/components/input-validator/preview.svg",
4975
4984
  "selectors": [],
4976
4985
  "exportedSymbols": [
4986
+ "creditCardCvvValidator",
4987
+ "CreditCardCvvValidatorOptions",
4988
+ "creditCardNumberValidator",
4977
4989
  "expiryDateValidator"
4978
4990
  ],
4979
4991
  "inputs": [],
@@ -4992,9 +5004,11 @@
4992
5004
  "sourceRoot": "projects/components/kanban-board/src",
4993
5005
  "docsPath": "/libraries/kanban-board",
4994
5006
  "docsOverviewSource": "projects/docs/src/app/libraries/kanban-board/overview/overview.html",
4995
- "purpose": "Organize items into draggable workflow columns.",
4996
- "useWhen": "Use for tasks, deals, issues, content pipelines, and status-based workflows.",
4997
- "exampleTopics": [],
5007
+ "purpose": "Render a horizontal workflow board with status columns and draggable cards.",
5008
+ "useWhen": "Use ngs-kanban-board for tasks, issues, CRM deals, hiring pipelines, content workflows, support tickets, and other status-based boards where users drag items within a column or between columns. Provide columns with id, name, color, and items; each item should include at least name and position. Render cards through a custom ngsKanbanItemDef template and compose card content with NgStarter components such as Avatar, Badge, Icon, Button, and text. The board mutates local arrays with CDK moveItemInArray and transferArrayItem and emits itemSorted, itemTransferred, itemDropped, itemClick, itemAdd, columnEdit, and columnDelete; the app must persist the new order, status, and business data to the backend. Do not use for simple record tables; use Table or DataView. Do not use for static lists; use List. Do not use for dashboard widget layouts; use Grid. Do not use for calendars, timelines, arbitrary drag-and-drop builders, or screens without real workflow/status columns.",
5009
+ "exampleTopics": [
5010
+ "Kanban Board"
5011
+ ],
4998
5012
  "minimalExample": null,
4999
5013
  "exampleFiles": [],
5000
5014
  "previewAsset": "projects/components/kanban-board/preview.svg",
@@ -5042,8 +5056,8 @@
5042
5056
  "sourceRoot": "projects/components/kbd/src",
5043
5057
  "docsPath": "/components/kbd",
5044
5058
  "docsOverviewSource": "projects/docs/src/app/components/kdb/overview/overview.html",
5045
- "purpose": "Render keyboard keys or shortcuts.",
5046
- "useWhen": "Use in help text, command menus, docs, and power-user workflows.",
5059
+ "purpose": "Display visual keyboard keys and shortcut hints.",
5060
+ "useWhen": "Use ngs-kbd for a single key such as Cmd, Shift, K, Esc, or an arrow key, and ngs-kbd-group for key combinations with plus signs between keys. Use in menus, command palettes, toolbars, help text, onboarding, documentation, and shortcut hints next to commands. Kbd is visual only: it does not register shortcuts, handle keyboard events, trigger actions, or provide command logic. Do not use as a clickable button; use Button or IconButton. Do not use for statuses or counts; use Badge. Do not use for tags or categories; use Chips. Do not use as normal body text or for actions that do not have a real shortcut handled elsewhere.",
5047
5061
  "exampleTopics": [
5048
5062
  "Basic Keyboard",
5049
5063
  "Keyboard group",
@@ -5102,8 +5116,8 @@
5102
5116
  "sourceRoot": "projects/components/layout/src",
5103
5117
  "docsPath": "/components/layout",
5104
5118
  "docsOverviewSource": "projects/docs/src/app/components/layout/overview/overview.html",
5105
- "purpose": "Compose common app layout regions for admin and dashboard screens.",
5106
- "useWhen": "Use for shells, page scaffolding, content/sidebar layouts, and structural UI.",
5119
+ "purpose": "Provide the base top-level shell for an application, admin area, dashboard, or large workspace page.",
5120
+ "useWhen": "Use ngs-layout as the outer structural frame when the whole screen needs topbar, header, sidebar, scrollable content, aside, or footer regions. Use root for a full viewport application shell. Use ngs-layout-content for the main scroll container, and LayoutApiService with layoutId when the sidebar must be shown, hidden, or toggled. Nested layouts are appropriate when a large app shell contains another structured workspace with its own header/content/footer. Do not use Layout as a small wrapper, card, spacing helper, form grouping tool, or generic grid system. Use TailwindCSS grid, flex, and spacing classes inside layout regions. Use Grid for static dashboard widgets, Tiles for dashboards users can rearrange or customize, DataView or Table for datasets, Drawer for overlay side panels, and Navigation, Sidebar, or Sidenav components inside sidebars.",
5107
5121
  "exampleTopics": [
5108
5122
  "Layout header",
5109
5123
  "Layout sidebar",
@@ -5183,8 +5197,8 @@
5183
5197
  "sourceRoot": "projects/components/list/src",
5184
5198
  "docsPath": "/components/list",
5185
5199
  "docsOverviewSource": "projects/docs/src/app/components/list/overview/overview.html",
5186
- "purpose": "Display repeated rows of related content or actions.",
5187
- "useWhen": "Use for navigation-adjacent lists, settings rows, activity feeds, and item collections.",
5200
+ "purpose": "Display a vertical group of related rows with consistent icon, avatar, title, line, meta, action, and selection structure.",
5201
+ "useWhen": "Use ngs-list with ngs-list-item for settings rows, files, messages, activity feed items, compact collections, simple action rows, and small repeated row groups. Use ngs-selection-list with ngs-list-option when users choose one or more rows. Use ngs-nav-list for simple navigation rows in sidebars or compact navigation areas. Use ngs-action-list for vertical action groups that are not dropdown menus. Compose each row with ngsListItemIcon or ngsListItemAvatar, ngsListItemTitle, ngsListItemLine, and ngsListItemMeta. Do not use List for large tabular datasets, columns, sorting, pagination, or bulk operations; use Table or DataView. Do not use for trigger-based dropdown or context actions; use Menu. Do not use as a full app navigation system when Navigation fits better. Do not use as a generic layout container.",
5188
5202
  "exampleTopics": [
5189
5203
  "Basic List",
5190
5204
  "List With Sections",
@@ -5299,8 +5313,8 @@
5299
5313
  "sourceRoot": "projects/components/logo/src",
5300
5314
  "docsPath": null,
5301
5315
  "docsOverviewSource": null,
5302
- "purpose": "Render NgStarter or product logo variants.",
5303
- "useWhen": "Use in app shells, headers, auth pages, and branding areas.",
5316
+ "purpose": "Render a product or brand logo as a composed mark, name, and optional description.",
5317
+ "useWhen": "Use ngs-logo or a[ngs-logo] in app shells, headers, sidebars, auth screens, splash screens, and branding areas. Compose it with ngs-logo-shape for the brand mark or image, ngs-logo-text for the product name with size small, default, or large, and ngs-logo-description for a short subtitle, version, or status. Use a[ngs-logo] when the logo navigates to the home page. Do not use Logo for user or team identity; use Avatar. Do not use for standalone action icons; use Icon inside Button or IconButton. Do not use for product thumbnails, decorative images, empty states, arbitrary SVG illustrations, or general image display.",
5304
5318
  "exampleTopics": [],
5305
5319
  "minimalExample": null,
5306
5320
  "exampleFiles": [],
@@ -5347,8 +5361,8 @@
5347
5361
  "sourceRoot": "projects/components/marquee/src",
5348
5362
  "docsPath": "/components/marquee",
5349
5363
  "docsOverviewSource": "projects/docs/src/app/components/marquee/overview/overview.html",
5350
- "purpose": "Animate a horizontal stream of repeated content.",
5351
- "useWhen": "Use for compact announcements, logos, highlights, and non-critical decorative motion.",
5364
+ "purpose": "Display an infinite horizontal stream of repeated non-critical content.",
5365
+ "useWhen": "Use ngs-marquee for motion content that can move and repeat without losing meaning: promo text, short highlights, logos, badges, partner names, compact news, and decorative content showcases. Use reverse to change direction. Use pauseOnHover when users may need more time to read or interact with the moving content. Do not use Marquee for important system notices, errors, warnings, required actions, or content the user must read; use Announcement, Alert, ActionRequired, or Incidents. Do not use for navigation, tables, task lists, precise ticker data, forms, or interactive work surfaces.",
5352
5366
  "exampleTopics": [
5353
5367
  "Basic marquee",
5354
5368
  "Marquee reverse",
@@ -5409,8 +5423,8 @@
5409
5423
  "sourceRoot": "projects/components/menu/src",
5410
5424
  "docsPath": "/components/menu",
5411
5425
  "docsOverviewSource": "projects/docs/src/app/components/menu/overview/overview.html",
5412
- "purpose": "Show contextual action lists anchored to a trigger.",
5413
- "useWhen": "Use for row actions, overflow menus, user menus, context menus, and toolbars.",
5426
+ "purpose": "Show a short contextual set of commands in an overlay opened from a trigger or right-click area.",
5427
+ "useWhen": "Use ngs-menu for row actions, overflow more actions, user menus, context menus, toolbar actions, and nested command groups. Put ngsMenuTriggerFor on a button ngsButton, button ngsIconButton, row action, or toolbar control. Use ngsContextMenuTriggerFor for right-click menus. Use button ngs-menu-item for commands, and ngs-menu-divider, ngs-menu-heading, ngs-menu-header, and ngs-menu-footer for structure. Use nested menus when a command opens a secondary command group. Use ngsMenuContent with ngsMenuTriggerData when the same menu template must render lazily for a specific row, user, or item. Do not use Menu for selecting form values; use Select, Autocomplete, ColorSwitcher, Datepicker, or another dedicated form control. Do not use for persistent navigation; use Navigation, Sidebar, Sidenav, or NavList. Do not use for long lists, tables, filters, forms, modal workflows, command palettes, or bulk action bars; use List, Table/DataView, Dialog, CommandBar, or Overlay/Popover as appropriate.",
5414
5428
  "exampleTopics": [
5415
5429
  "Basic Menu",
5416
5430
  "Menu With Icons",
@@ -5555,8 +5569,8 @@
5555
5569
  "sourceRoot": "projects/components/micro-chart/src",
5556
5570
  "docsPath": "/micro-charts",
5557
5571
  "docsOverviewSource": null,
5558
- "purpose": "Render compact inline charts for small dashboard metrics.",
5559
- "useWhen": "Use in KPI cards, table cells, summaries, and dense analytics panels.",
5572
+ "purpose": "Render compact line, bar, and pie charts for small trends, comparisons, and proportional breakdowns.",
5573
+ "useWhen": "Use ngs-mchart-line for a small trend over time or ordered values, ngs-mchart-bar for a compact comparison of several numeric values, and ngs-mchart-pie for a small proportional breakdown. Use MicroChart inside KPI cards, dashboard summaries, table cells, list rows, reports, and dense admin panels. It can also be used as a simple standalone dashboard chart when the chart type and level of detail match what MicroChart can display. Provide fixed dimensions with TailwindCSS classes such as w-*, h-*, or size-* because the chart renders inside its container. Use ngs-mchart-tooltip, ngs-mchart-tooltip-title, and ngs-mchart-tooltip-body when hover context is needed. Do not use MicroChart for complex analytics, detailed axes, advanced legends, drilldown, zooming, financial charting, or advanced interactions; use ECharts for complex charts. Do not use instead of ProgressBar or Gauge for a single progress percentage, Badge for status, or DataView/Table for tabular data.",
5560
5574
  "exampleTopics": [],
5561
5575
  "minimalExample": null,
5562
5576
  "exampleFiles": [],
@@ -5655,8 +5669,8 @@
5655
5669
  "sourceRoot": "projects/components/navigation/src",
5656
5670
  "docsPath": "/navigation/navigation",
5657
5671
  "docsOverviewSource": "projects/docs/src/app/navigation/nav/overview/overview.html",
5658
- "purpose": "Render primary or secondary navigation structures.",
5659
- "useWhen": "Use in app shells, sidebars, product sections, and nested admin navigation.",
5672
+ "purpose": "Render a persistent product navigation structure when ngs-sidebar is not used.",
5673
+ "useWhen": "Use ngs-navigation for custom navigation areas, section navigation, settings navigation, admin navigation, and nested navigation groups when the screen needs product links but does not use ngs-sidebar. ngs-sidebar has its own navigation model, so do not duplicate ngs-navigation inside ngs-sidebar. Use ngs-navigation-item or [ngs-navigation-item] for destinations, key with activeKey for active state, activateByRoute for URL-based activation, autoScrollToActiveItem for long navigation, ngs-navigation-heading for sections, ngs-navigation-divider for group separation, and ngs-navigation-group with ngs-navigation-group-toggle and ngs-navigation-group-menu for expandable nested destinations. Use ngsNavigationItemIcon, ngsNavigationGroupToggleIcon, and ngsNavigationItemBadge for icons, toggles, and badges. Use dataSource with ngsNavigationItemDef when navigation comes from config or backend data. Do not use Navigation for trigger-based action menus; use Menu. Do not use for ordinary row lists; use List or NavList. Do not use for breadcrumbs, tabs, wizard steps, command palettes, form selection, table row actions, or bulk actions.",
5660
5674
  "exampleTopics": [
5661
5675
  "Basic Navigation",
5662
5676
  "Navigation with heading",
@@ -5858,8 +5872,8 @@
5858
5872
  "sourceRoot": "projects/components/notifications/src",
5859
5873
  "docsPath": "/components/notifications",
5860
5874
  "docsOverviewSource": "projects/docs/src/app/components/notifications/overview/overview.html",
5861
- "purpose": "Display notification lists, notification items, or notification surfaces.",
5862
- "useWhen": "Use for user alerts, activity updates, inbox-style feeds, and app header popovers.",
5875
+ "purpose": "Display user-facing notification events in a structured feed or inbox.",
5876
+ "useWhen": "Use Notifications for events addressed to the current user: comments, mentions, invitations, assignments, access requests, status changes, completed processes, and user-specific updates. Use ngs-notification for one event, ngsNotificationAvatar for the source avatar or icon, ngs-notification-message for the main sentence, ngs-notification-actor for the actor, ngs-notification-content for nested context such as a comment, file, quote, card, or preview, and ngs-notification-time for time. Use isUnread for unread state. Use ngs-notification-list with ngsNotificationDef when notifications come from an array and each type needs its own template. Use ngsNotificationControlsDef for per-notification controls such as mute, delete, or mark as read, often with Menu. Do not use Notifications for page-level system messages; use Alert or Announcement. Do not use for critical required actions; use ActionRequired. Do not use for service health; use Incidents. Do not use for generic activity feeds that are not user notifications; use List. Do not use for transient toast/snackbar messages.",
5863
5877
  "exampleTopics": [
5864
5878
  "Basic notifications",
5865
5879
  "Notification list"
@@ -5951,8 +5965,8 @@
5951
5965
  "sourceRoot": "projects/components/number-input/src",
5952
5966
  "docsPath": "/forms/number-input",
5953
5967
  "docsOverviewSource": "projects/docs/src/app/forms/number-input/overview/overview.html",
5954
- "purpose": "Capture numeric values with appropriate controls and formatting.",
5955
- "useWhen": "Use for quantities, limits, pricing, thresholds, and numeric settings.",
5968
+ "purpose": "Capture a numeric form value with typing, stepper controls, min/max limits, and Angular forms integration.",
5969
+ "useWhen": "Use ngs-number-input inside one ngs-form-field when users need to type a number or adjust it with increase/decrease controls. Good for quantities, limits, thresholds, durations, percentages, ratings, numeric settings, seat counts, day counts, and budget-like numeric values. Use ngModel or formControlName, min and max for allowed bounds, step for increment/decrement size, readonly/disabled/required as normal form states, and ngsDecreaseControl or ngsIncreaseControl only when custom control icons are needed. Use TailwindCSS classes on ngs-form-field or surrounding layout for width and grouping. Do not use for normal text; use ngsInput. Do not use for phone numbers; use PhoneInput. Do not use for OTP, MFA, passcodes, or invite codes; use PinInput. Do not use for selecting currency; use CurrencySelect plus a numeric amount field when needed. Do not use for sliders/ranges, display-only KPI values, progress, or charts; use the dedicated component such as Gauge, ProgressBar, MicroChart, or a text/KPI layout.",
5956
5970
  "exampleTopics": [
5957
5971
  "Basic Number Input",
5958
5972
  "Custom Controls",
@@ -6043,8 +6057,8 @@
6043
6057
  "sourceRoot": "projects/components/option/src",
6044
6058
  "docsPath": null,
6045
6059
  "docsOverviewSource": null,
6046
- "purpose": "Provide reusable option primitives for select-like controls.",
6047
- "useWhen": "Use internally or alongside option-based components such as select and autocomplete.",
6060
+ "purpose": "Provide a low-level selectable option primitive for Select, Autocomplete, and other option-parent controls.",
6061
+ "useWhen": "Use ngs-option inside ngs-select, ngs-autocomplete, and other NgStarter dropdown/listbox controls that explicitly expect options, such as CountrySelect, CurrencySelect, DateFormatSelect, Timepicker, FilterBuilder, and similar controls. Use [value] for the form value and disabled when the option cannot be selected. Use ngs-optgroup to group related options under a label. Keep option text short and readable because the viewValue is derived from the rendered text. Do not use ngs-option as a generic list row, button, menu item, navigation item, table row, card, or custom layout block. Use MenuItem or Button for actions, Navigation/List/NavList for navigation and lists, RadioCard for rich card selection, and ColorSwitcher for fixed color choices. Agents usually should not import Option separately unless they are composing Select, Autocomplete, or another option-based component.",
6048
6062
  "exampleTopics": [],
6049
6063
  "minimalExample": null,
6050
6064
  "exampleFiles": [],
@@ -6118,8 +6132,8 @@
6118
6132
  "sourceRoot": "projects/components/overlay/src",
6119
6133
  "docsPath": null,
6120
6134
  "docsOverviewSource": null,
6121
- "purpose": "Position floating UI relative to an anchor.",
6122
- "useWhen": "Use for custom popovers, dropdowns, panels, menus, and floating surfaces.",
6135
+ "purpose": "Provide low-level shared positioning utilities for components that create Angular CDK floating overlays.",
6136
+ "useWhen": "Use Overlay only when implementing a new NgStarter component or custom directive that directly manages Angular CDK Overlay, portal rendering, backdrop or outside-click behavior, close behavior, keyboard/focus handling, and anchored positioning. Use OverlayPosition values such as below-start, below-center, below-end, above-*, before-*, and after-*. Use new PositionManager().build(position) to create fallback ConnectedPosition[] pairs. Do not use Overlay directly when building a normal admin page or feature screen. Prefer higher-level components: Menu for action dropdowns and context menus, Popover for lightweight anchored content, Dialog for modal workflows, Drawer for side overlays, Select/Autocomplete/Datepicker/ColorPicker for form dropdowns, and Tooltip for simple hints.",
6123
6137
  "exampleTopics": [],
6124
6138
  "minimalExample": null,
6125
6139
  "exampleFiles": [],
@@ -6145,8 +6159,8 @@
6145
6159
  "sourceRoot": "projects/components/page-loading-bar/src",
6146
6160
  "docsPath": null,
6147
6161
  "docsOverviewSource": null,
6148
- "purpose": "Show route or page-level loading progress.",
6149
- "useWhen": "Use during navigation, large async page transitions, or app-wide loading states.",
6162
+ "purpose": "Show a global thin loading bar during Angular Router navigation.",
6163
+ "useWhen": "Use ngs-page-loading-bar once in the top-level app shell or root layout, usually near the root layout or router outlet, to provide navigation feedback. It listens to Angular Router events automatically: NavigationStart shows the bar, and NavigationEnd, NavigationCancel, or NavigationError finish it. Use fixed when the bar should stay attached to the viewport. Do not use PageLoadingBar for loading a specific block, table, card, form, submit/save/upload operation, or async work inside a page. Use ProgressBar, ProgressSpinner, BlockLoader, Skeleton, ScreenLoader, or the component-specific loading state for local loading. Do not use it as a real task completion percentage; it is route navigation feedback only.",
6150
6164
  "exampleTopics": [],
6151
6165
  "minimalExample": null,
6152
6166
  "exampleFiles": [],
@@ -6178,8 +6192,8 @@
6178
6192
  "sourceRoot": "projects/components/paginator/src",
6179
6193
  "docsPath": "/components/paginator",
6180
6194
  "docsOverviewSource": "projects/docs/src/app/components/paginator/overview/overview.html",
6181
- "purpose": "Navigate paged datasets.",
6182
- "useWhen": "Use with tables, data views, lists, and server-side record browsing.",
6195
+ "purpose": "Control pages of a dataset with range label, previous/next navigation, optional first/last buttons, and page size selection.",
6196
+ "useWhen": "Use ngs-paginator next to paged tables, DataView screens, search results, record lists, and server-side browsing. Provide length for total records, pageSize for records per page, zero-based pageIndex for the current page, and pageSizeOptions for allowed page sizes. Handle the page event to update local data or request the next page from an API; PageEvent includes previousPageIndex, pageIndex, pageSize, and length. Use hidePageSize when the page size is fixed. Use showFirstLastButtons when users need quick first/last navigation. Use PaginatorIntl to localize labels and range text. Do not use Paginator for app route navigation; use Navigation, Tabs, or Breadcrumbs. Do not use for wizard or onboarding steps; use Stepper or HeadlessStepper. Do not use for carousel slides, media browsing, or standalone UI without a paged dataset. If DataView already owns pagination, use its pagination model instead of adding a separate paginator.",
6183
6197
  "exampleTopics": [
6184
6198
  "Basic Paginator",
6185
6199
  "Configurable Paginator"
@@ -6256,8 +6270,8 @@
6256
6270
  "sourceRoot": "projects/components/panel/src",
6257
6271
  "docsPath": "/components/panel",
6258
6272
  "docsOverviewSource": "projects/docs/src/app/components/panel/overview/overview.html",
6259
- "purpose": "Group content inside a structured panel surface.",
6260
- "useWhen": "Use for dashboard sections, settings panels, details, and repeated admin modules.",
6273
+ "purpose": "Create a local structured work area with header, subheader, sidebar, scrollable content, aside, and footer regions.",
6274
+ "useWhen": "Use ngs-panel inside a page or workspace for admin modules, settings areas, editors, detail panes, inspectors, dashboard sections, and local surfaces that need their own header, footer, side columns, and scrollable body. Use ngs-panel-header for local title, toolbar, or actions; ngs-panel-subheader for filters or secondary status; ngs-panel-sidebar for a local left column; ngs-panel-content for the main scrollable area; ngs-panel-aside for a local right column; and ngs-panel-footer for local footer actions or status. Use absolute when the panel should fill the parent bounds. Use TailwindCSS classes for sizing, borders, spacing, and inner layout. Do not use Panel as the top-level application shell; use Layout. Do not use for small content blocks; use Card. Do not use for overlay side panels; use Drawer. Do not use as a generic spacing wrapper or form grid; use TailwindCSS grid/flex and FormField.",
6261
6275
  "exampleTopics": [
6262
6276
  "Basic panel",
6263
6277
  "Basic with extra columns (sidebar and aside)",
@@ -6322,8 +6336,8 @@
6322
6336
  "sourceRoot": "projects/components/password-strength/src",
6323
6337
  "docsPath": "/forms/password-strength",
6324
6338
  "docsOverviewSource": "projects/docs/src/app/forms/password-strength/overview/overview.html",
6325
- "purpose": "Show password quality feedback while users type.",
6326
- "useWhen": "Use in signup, reset password, account security, and credential forms.",
6339
+ "purpose": "Show real-time password strength feedback and requirement status while users create or change a password.",
6340
+ "useWhen": "Use PasswordStrength in signup, reset password, change password, account security, and credential setup forms. Use input type=\"password\" ngsInput inside one ngs-form-field for the actual password field, then place ngs-password-strength [password]=\"password.value\" below it for the strength bar. Use ngs-password-strength-info with a template reference to the strength component when users need to see requirement status for lowercase, uppercase, digit, special character, min length, or custom rules. Use ngs-pass-toggle-visibility as a suffix control inside the password form field when users need show/hide password behavior. Configure min, max, enableLengthRule, enableDigitRule, enableSpecialCharRule, and customValidator as needed, and listen to strengthChanged when the screen needs the score. Do not use PasswordStrength for OTP, MFA, invite codes, or passcodes; use PinInput. Do not use for generic text validation. Do not use for a login password field unless the user is creating or changing a password and strength feedback is useful. Do not rely on it as the only password security policy; backend validation is still required.",
6327
6341
  "exampleTopics": [
6328
6342
  "Basic password strength",
6329
6343
  "Password strength info",
@@ -6415,8 +6429,8 @@
6415
6429
  "sourceRoot": "projects/components/phone-input/src",
6416
6430
  "docsPath": "/forms/phone-input",
6417
6431
  "docsOverviewSource": "projects/docs/src/app/forms/phone-input/overview/overview.html",
6418
- "purpose": "Capture phone numbers with country-aware formatting and validation.",
6419
- "useWhen": "Use in profiles, billing, contact forms, onboarding, and support workflows.",
6432
+ "purpose": "Capture real phone numbers with country selection, flag, dial code, formatting, and libphonenumber-js validation.",
6433
+ "useWhen": "Use ngs-phone-input inside one ngs-form-field for profile, contact, billing, onboarding, checkout, support, invite, and contact forms when the value must be a real phone number. Use formControlName or ngModel, show invalidPhone with ngs-error, set defaultSelectedCountryCode when the initial country should not be us, use onlyCountries to restrict available countries, preferredCountries to pin common countries to the top, format=\"default | national | international\" for display formatting, and countryChanged when the screen needs to react to country changes. Do not use plain ngsInput, NumberInput, or InputMask for country-aware phone numbers. Do not use CountrySelect instead of PhoneInput; CountrySelect chooses a country but does not capture a phone number. Do not use for OTP, MFA, passcodes, or invite codes; use PinInput.",
6420
6434
  "exampleTopics": [
6421
6435
  "Basic phone input",
6422
6436
  "Phone input with custom country list",
@@ -6491,8 +6505,8 @@
6491
6505
  "sourceRoot": "projects/components/pin-input/src",
6492
6506
  "docsPath": "/forms/pin-input",
6493
6507
  "docsOverviewSource": "projects/docs/src/app/forms/pin-input/overview/overview.html",
6494
- "purpose": "Capture short multi-digit verification or security codes.",
6495
- "useWhen": "Use for OTP, MFA, invite codes, passcodes, and verification flows.",
6508
+ "purpose": "Capture short one-character-per-cell codes for verification and secure access flows.",
6509
+ "useWhen": "Use ngs-pin-input as a standalone form control for OTP, MFA, SMS or email verification codes, invite codes, passcodes, payment verification, and secure access codes. Use ngModel or formControlName, length for the number of cells, placeholder for the empty-cell hint, acceptOnly for allowed symbols with digits as the default, and disabled for disabled state. The component manages one-character cells and focus movement between them. Do not use PinInput for phone numbers; use PhoneInput. Do not use for creating or changing passwords; use ngsInput with PasswordStrength. Do not use for numeric settings or quantities; use NumberInput. Do not use for long codes, serial numbers, coupons, or arbitrary text; use a normal ngsInput. Do not wrap it in ngs-form-field as if it were a single text input; the component renders its own internal form fields.",
6496
6510
  "exampleTopics": [
6497
6511
  "Basic Pin Input",
6498
6512
  "Placeholder",
@@ -6561,8 +6575,8 @@
6561
6575
  "sourceRoot": "projects/components/popover/src",
6562
6576
  "docsPath": "/components/popover",
6563
6577
  "docsOverviewSource": "projects/docs/src/app/components/popover/overview/overview.html",
6564
- "purpose": "Show lightweight contextual content anchored to another element.",
6565
- "useWhen": "Use for quick details, simple forms, explanations, and non-modal contextual UI.",
6578
+ "purpose": "Show lightweight contextual content in an overlay anchored to a trigger element.",
6579
+ "useWhen": "Use Popover for short details, previews, small interactive content, compact forms, and richer explanations that need more than a plain tooltip but do not require a modal workflow. Put ngsPopoverTriggerFor on the trigger element and point it to ngs-popover or a TemplateRef. Use trigger=\"click\" for explicit opening and trigger=\"hover\" only for preview-style content that can disappear safely. Use position for below/above/before/after placement. Use ngsPopoverContext with ngsPopoverContent for lazy content that needs trigger data. Use a raw TemplateRef only when the standard ngs-popover-panel wrapper should be replaced. Use hasBackdrop, closeOnOriginClick, closeOnOriginMouseLeave, and origin only when custom close or anchoring behavior is needed. Do not use Popover for command lists; use Menu. Do not use for short plain hints; use Tooltip. Do not use for modal workflows, confirmations, or complex forms; use Dialog or Confirm. Do not use for side panels; use Drawer. Do not use for form dropdowns; use Select, Autocomplete, Datepicker, or ColorPicker. Do not use low-level Overlay directly when Popover fits.",
6566
6580
  "exampleTopics": [
6567
6581
  "Basic Popover",
6568
6582
  "Show popover by hover",
@@ -6649,8 +6663,8 @@
6649
6663
  "sourceRoot": "projects/components/progress-bar/src",
6650
6664
  "docsPath": "/components/progress-bar",
6651
6665
  "docsOverviewSource": "projects/docs/src/app/components/progress-bar/overview/overview.html",
6652
- "purpose": "Show linear progress or completion state.",
6653
- "useWhen": "Use for uploads, long-running tasks, setup completion, and bounded progress.",
6666
+ "purpose": "Show linear progress for an operation or process.",
6667
+ "useWhen": "Use ngs-progress-bar for uploads, downloads, imports, setup completion, sync, processing, form completion, buffering, and other horizontal progress states. Use mode=\"determinate\" with value from 0 to 100 when the percentage is known. Use mode=\"indeterminate\" when work is happening but the percentage is unknown. Use mode=\"buffer\" with value and bufferValue when both primary and buffered progress should be visible. Use mode=\"query\" while waiting before known progress starts. Use animationEnd only when the screen must react after the transition finishes. Do not use ProgressBar for Angular Router navigation; use PageLoadingBar. Do not use to block a whole area; use BlockLoader. Do not use for skeleton content loading; use Skeleton. Do not use for circular KPI or percent metrics; use Gauge. Do not use for mini trends or charts; use MicroChart. Do not use as a status label; use Badge or text.",
6654
6668
  "exampleTopics": [
6655
6669
  "Basic Progress Bar",
6656
6670
  "Intermediate Progress Bar",
@@ -6716,8 +6730,8 @@
6716
6730
  "sourceRoot": "projects/components/radio/src",
6717
6731
  "docsPath": "/forms/radio",
6718
6732
  "docsOverviewSource": "projects/docs/src/app/forms/radio/overview/overview.html",
6719
- "purpose": "Let users choose exactly one option from a visible set.",
6720
- "useWhen": "Use for short mutually exclusive choices in forms and settings.",
6733
+ "purpose": "Let users choose exactly one option from a small visible set of mutually exclusive choices.",
6734
+ "useWhen": "Use ngs-radio-group with ngs-radio-button for simple text options in forms, settings, filters, and preference screens where all options should be visible and the user can choose only one. Put value on each radio button and bind the group value with value, ngModel, or formControlName. Use name when native form grouping matters, disabled on the group or individual radio button when needed, and change when the screen must react to selection changes. Do not use Radio for multiple selection; use Checkbox. Do not use for long option lists; use Select or Autocomplete. Do not use for rich options with descriptions, icons, or large clickable blocks; use RadioCard. Do not use as a segmented view switcher; use Segmented or ButtonToggle. Do not use for yes/no boolean settings when SlideToggle or Checkbox better matches the meaning.",
6721
6735
  "exampleTopics": [
6722
6736
  "Basic Radios",
6723
6737
  "Radio Card",
@@ -6785,8 +6799,8 @@
6785
6799
  "sourceRoot": "projects/components/radio-card/src",
6786
6800
  "docsPath": null,
6787
6801
  "docsOverviewSource": null,
6788
- "purpose": "Let users choose one option from richer card-like choices.",
6789
- "useWhen": "Use for plans, templates, payment methods, layouts, or options needing descriptions.",
6802
+ "purpose": "Let users choose exactly one option from a small set of rich card-like choices.",
6803
+ "useWhen": "Use ngs-radio-card-group as a form control group and ngs-radio-card for each option when every option needs a large clickable card with title, icon, description, or supporting content. Use ngs-radio-card-title for the option name and optional icon, ngs-radio-card-content for details, value on each card, and formControlName or ngModel on the group. Use TailwindCSS grid or flex around the group to lay cards out in columns or rows. Good for plan selection, privacy modes, template choices, payment methods, layout options, delivery methods, onboarding choices, and settings choices with explanation. Do not use for simple short text options; use Radio. Do not use for multiple selection; use Checkbox or a dedicated checkbox-card pattern when available. Do not use for long lists; use Select or Autocomplete. Do not use as a normal content card without selection; use Card. Do not use as a segmented mode switch; use Segmented or ButtonToggle.",
6790
6804
  "exampleTopics": [],
6791
6805
  "minimalExample": null,
6792
6806
  "exampleFiles": [],
@@ -6839,8 +6853,8 @@
6839
6853
  "sourceRoot": "projects/components/rail-nav/src",
6840
6854
  "docsPath": "/navigation/rail-nav",
6841
6855
  "docsOverviewSource": "projects/docs/src/app/navigation/rail-nav/overview/overview.html",
6842
- "purpose": "Provide compact vertical navigation with icons and labels.",
6843
- "useWhen": "Use in dense app shells where sidebar space is constrained.",
6856
+ "purpose": "Provide a compact vertical navigation rail with icons and short labels.",
6857
+ "useWhen": "Use ngs-rail-nav when an app or workspace shell needs compact vertical navigation but there is not enough space for a full sidebar. Use ngs-rail-nav-item or [ngs-rail-nav-item] for destinations, ngsRailNavItemIcon for icons, key on each item, activeKey on the rail, and railNav.api.isActive(key) when the active item should change icon or styling. Good for narrow editor or workspace navigation, secondary product navigation, compact admin shells, and switching between primary sections. Do not use when you need a full sidebar with groups, nested navigation, or supporting content; use Sidebar or Sidenav. Do not use inside ngs-sidebar because Sidebar has its own navigation. Do not use for normal section navigation in content; use Navigation. Do not use for tabs, breadcrumbs, menu actions, segmented controls, or one-off icon buttons.",
6844
6858
  "exampleTopics": [
6845
6859
  "Basic rail navigation",
6846
6860
  "Rail navigation customization",
@@ -6923,8 +6937,8 @@
6923
6937
  "sourceRoot": "projects/components/resizable-container/src",
6924
6938
  "docsPath": "/components/resizable-container",
6925
6939
  "docsOverviewSource": "projects/docs/src/app/components/resizable-container/overview/overview.html",
6926
- "purpose": "Let users resize a container or panel.",
6927
- "useWhen": "Use for editors, inspectors, side panels, split workspaces, and dashboards.",
6940
+ "purpose": "Let users manually resize the width of one container with a vertical drag handle.",
6941
+ "useWhen": "Use ngs-resizable-container around content when the user should manually adjust the width of a single block. Good for resizable preview panes, editor canvas or containers, inspector or detail panels, side content areas, responsive demo areas, chart previews, and docs playgrounds. Use minWidth for the minimum allowed width, resized to persist or synchronize the new width, and TailwindCSS classes for border, height, initial width, layout, and inner content. Do not use as a full split layout between two panels; use Split or a dedicated splitter when available. Do not use for image resizing; use ImageResizer. Do not use for table or DataView column resizing; use the table/DataView resizing feature. Do not use as a normal responsive container when users should not manually resize it; use TailwindCSS responsive utilities or container queries. Do not use for Drawer or Sidebar resizing when those components own their sizing model.",
6928
6942
  "exampleTopics": [
6929
6943
  "Basic Resizable Container"
6930
6944
  ],
@@ -6967,8 +6981,8 @@
6967
6981
  "sourceRoot": "projects/components/screen-loader/src",
6968
6982
  "docsPath": "/components/screen-loader",
6969
6983
  "docsOverviewSource": "projects/docs/src/app/components/screen-loader/overview/overview.html",
6970
- "purpose": "Show a full-screen or page-level loading state.",
6971
- "useWhen": "Use while initial app, route, or major page data is loading.",
6984
+ "purpose": "Show a full-screen blocking loading state for large global operations.",
6985
+ "useWhen": "Use ScreenLoader when the user must wait and should not interact with the app: initial app load, major route or page data loading, account switching, tenant switching, auth or session restore, heavy backend tasks, and large global operations. Prefer ScreenLoaderService.open(messageOrTemplate) for programmatic full-screen overlays, keep the returned ScreenLoaderRef, and always call ref.close() when the operation finishes. Use afterOpened() and afterClosed() only for side effects. Use ngs-screen-loader with opened and message only when the open state is controlled directly in a template. message can be a short string or TemplateRef. Do not use ScreenLoader for local block, card, table, or form loading; use BlockLoader, Skeleton, ProgressSpinner, ProgressBar, or component-specific loading states. Do not use for route navigation progress; use PageLoadingBar. Do not use for known percentage progress; use ProgressBar. Do not leave a service-opened loader without closing its ref.",
6972
6986
  "exampleTopics": [
6973
6987
  "Basic screen loader"
6974
6988
  ],
@@ -7011,8 +7025,8 @@
7011
7025
  "sourceRoot": "projects/components/scroll-spy/src",
7012
7026
  "docsPath": null,
7013
7027
  "docsOverviewSource": null,
7014
- "purpose": "Track page sections and provide in-page navigation.",
7015
- "useWhen": "Use in long docs pages, settings pages, and detail screens with many sections.",
7028
+ "purpose": "Provide in-page navigation for sections inside a long scrollable page or local scroll container.",
7029
+ "useWhen": "Use ScrollSpy when a long page or panel has stable section ids and needs a table-of-contents style navigation that highlights the active section while scrolling and smooth-scrolls to sections on click. Use ngs-scroll-spy-nav as the nav container, ngs-scroll-spy-on with targetId matching a section id, ngs-scroll-spy-title for the nav heading, and ngs-scroll-spy-back-to-top for a top shortcut. It uses ngs-layout-content or ngs-panel-content as the scroll container when present, otherwise document body. Good for docs pages, long settings pages, profile or detail pages with many sections, policy/help pages, long form review pages, and article-like admin pages. Do not use for primary product navigation; use Navigation, Sidebar, Sidenav, or RailNav. Do not use for tabs between views; use Tabs. Do not use for route breadcrumbs; use Breadcrumbs. Do not use for wizard steps; use Stepper or HeadlessStepper. Do not use on short pages without real scrolling or without stable section ids.",
7016
7030
  "exampleTopics": [],
7017
7031
  "minimalExample": null,
7018
7032
  "exampleFiles": [],
@@ -7060,8 +7074,8 @@
7060
7074
  "sourceRoot": "projects/components/scrollbar-area/src",
7061
7075
  "docsPath": null,
7062
7076
  "docsOverviewSource": null,
7063
- "purpose": "Provide a styled scrollable region.",
7064
- "useWhen": "Use when a panel, menu, list, or surface needs controlled scrolling.",
7077
+ "purpose": "Provide a styled scroll container for bounded UI regions.",
7078
+ "useWhen": "Use ngs-scrollbar-area when a sized panel, grid body, editor sidebar, asset list, menu, or similar surface needs consistent NgStarter scrollbars instead of native browser scrollbars. It hides native scrollbars, renders vertical and horizontal thumbs, supports auto-hide, thumb dragging, resize and mutation tracking, scrollbarWidth, autoHide, absolute fill mode, and scrolled output. Use [absolute]=\"true\" when the scroll area should fill a positioned parent region such as ngs-panel-content or a DataView viewport; make sure the parent already has a stable height and width. Do not use as a generic layout wrapper, spacing helper, page-level replacement for normal browser scrolling, carousel or scroll-snap component, virtualization engine, or a workaround for missing parent sizing.",
7065
7079
  "exampleTopics": [],
7066
7080
  "minimalExample": null,
7067
7081
  "exampleFiles": [],
@@ -7103,8 +7117,8 @@
7103
7117
  "sourceRoot": "projects/components/segmented/src",
7104
7118
  "docsPath": "/forms/segmented",
7105
7119
  "docsOverviewSource": "projects/docs/src/app/forms/segmented/overview/overview.html",
7106
- "purpose": "Switch between compact mutually exclusive modes or filters.",
7107
- "useWhen": "Use for view modes, time ranges, filter states, and short setting groups.",
7120
+ "purpose": "Let users choose one value from a compact set of mutually exclusive modes or options.",
7121
+ "useWhen": "Use ngs-segmented with ngs-segmented-button when a short set of options should stay visible and only one value can be selected. Good for view modes, time ranges, display density, selection mode, chart or table mode, compact filters, and short settings. It works as an Angular form control through value, valueChange, ngModel, or formControlName, supports disabled state, sizes, text buttons, icons with ngsSegmentedIcon, and iconOnly buttons. Do not use Segmented for route or page navigation; use Tabs, Navigation, Sidebar, Sidenav, or RailNav. Do not use for independent on/off toggles; use ButtonToggle or SlideToggle. Do not use for long lists, rich option cards, dropdown choices, or fixed color palettes; use Radio, RadioCard, Select, Autocomplete, or ColorSwitcher.",
7108
7122
  "exampleTopics": [
7109
7123
  "Basic segmented control",
7110
7124
  "Segmented control sizes",
@@ -7208,8 +7222,8 @@
7208
7222
  "sourceRoot": "projects/components/select/src",
7209
7223
  "docsPath": "/forms/select",
7210
7224
  "docsOverviewSource": "projects/docs/src/app/forms/select/overview/overview.html",
7211
- "purpose": "Let users choose one or more options from a dropdown list.",
7212
- "useWhen": "Use for forms and filters when options are known and fit in a menu.",
7225
+ "purpose": "Let users choose one or multiple values from a known dropdown list.",
7226
+ "useWhen": "Use ngs-select inside one ngs-form-field when a form, filter, setting, table filter, DataView filter, or admin configuration field should choose from predefined options. Use ngs-option for options, ngs-optgroup for visible grouping, multiple for array values, placeholder, required, disabled, Angular forms, value, and selectionChange for state. Use ngs-select-trigger to customize the closed label, and ngs-select-header, ngs-select-body, or ngs-select-footer when the dropdown panel needs search, custom scrolling, or supporting controls. Do not use Select as a command menu or action list; use Menu. Do not use for route or page navigation; use Navigation, Tabs, Sidebar, Sidenav, or RailNav. Do not use for compact visible mode switching; use Segmented. Do not use for simple visible choices or rich card choices; use Radio or RadioCard. Do not use for arbitrary free text or large remote search suggestion flows; use Autocomplete or a dedicated async picker. Do not use generic Select when a domain-specific control exists, such as CountrySelect, CurrencySelect, DateFormatSelect, or TimezoneSelect.",
7213
7227
  "exampleTopics": [
7214
7228
  "Basic Select",
7215
7229
  "Getting and setting the select value",
@@ -7318,8 +7332,8 @@
7318
7332
  "sourceRoot": "projects/components/side-panel/src",
7319
7333
  "docsPath": "/navigation/side-panel",
7320
7334
  "docsOverviewSource": "projects/docs/src/app/navigation/side-panel/overview/overview.html",
7321
- "purpose": "Show secondary detail or task content beside the main page.",
7322
- "useWhen": "Use for inspectors, edit panels, previews, and contextual details.",
7335
+ "purpose": "Provide an embedded side utility panel with tabbed tools beside the main content.",
7336
+ "useWhen": "Use ngs-side-panel inside an app or workspace layout when the page needs persistent secondary tools or inspectors next to the primary content. Add ngs-side-panel-tab for each tab with tabId, label, and an optional Iconify icon name or custom icon TemplateRef. Good for info, outline, layers, activity, comments, assets, properties, preview settings, contextual inspectors, and quick tools in editors or admin workspaces. It can be positioned left or right and emits opened and closed. Do not use SidePanel as a temporary overlay; use Drawer. Do not use for modal workflows or confirmations; use Dialog or Confirm. Do not use as a generic page section; use Panel or Card. Do not use for primary app navigation; use Sidebar, Sidenav, Navigation, or RailNav. Do not use for tabs inside normal content; use Tabs. Do not use for simple action lists; use Menu.",
7323
7337
  "exampleTopics": [
7324
7338
  "Basic side panel"
7325
7339
  ],
@@ -7376,25 +7390,25 @@
7376
7390
  "sourceRoot": "projects/components/sidebar/src",
7377
7391
  "docsPath": "/navigation/sidebar",
7378
7392
  "docsOverviewSource": "projects/docs/src/app/navigation/sidebar/overview/overview.html",
7379
- "purpose": "Provide vertical app navigation and supporting sidebar content.",
7380
- "useWhen": "Use for admin app shells, workspace navigation, and persistent sections.",
7393
+ "purpose": "Provide a complete vertical app or workspace sidebar with its own navigation system.",
7394
+ "useWhen": "Use ngs-sidebar as the content inside a shell sidebar region, usually inside Sidenav or LayoutSidebar, when an admin app or workspace needs persistent sidebar navigation and supporting sidebar content. Compose it with ngs-sidebar-header, ngs-sidebar-body, ngs-sidebar-footer, ngs-sidebar-nav, ngs-sidebar-nav-item, ngs-sidebar-nav-group, ngs-sidebar-nav-group-toggle, ngs-sidebar-nav-group-menu, ngs-sidebar-nav-heading, ngs-sidebar-divider, ngsSidebarNavItemIcon, ngsSidebarNavItemBadge, and ngsSidebarNavGroupToggleIcon. Good for brand or workspace header, main app navigation, grouped routes, badges, active item state through activeKey, autoScrollToActiveItem, and data-driven nav templates. Sidebar owns navigation; when ngs-sidebar is not used and persistent navigation is needed, use Navigation. Do not use Sidebar as a generic left column, card, drawer content, inspector, page section, tabs, menu, or compact icon rail. Use Sidenav for responsive open, collapse, or overlay shell behavior, RailNav for compact icon navigation, SidePanel for secondary tabbed tools, Drawer for temporary overlay side content, and Panel or Card for content grouping.",
7381
7395
  "exampleTopics": [
7382
7396
  "Basic sidebar",
7383
7397
  "Sidebar with custom icons"
7384
7398
  ],
7385
- "minimalExample": "<div class=\"h-[600px] w-[300px] relative\">\n <ngs-sidebar class=\"border border-muted rounded-2xl\">\n <ngs-sidebar-header class=\"flex h-14 items-center px-4 font-bold text-primary border-b border-b-muted\">\n NGSTARTER\n </ngs-sidebar-header>\n <ngs-sidebar-body>\n <ngs-sidebar-nav activeKey=\"home\" class=\"p-4\">\n @for (navItem of navItems; track navItem) {\n @switch (navItem.type) {\n @case ('group') {\n <ngs-sidebar-nav-group>\n <ngs-sidebar-nav-group-toggle>\n <ng-container ngsSidebarNavItemIcon>\n @if (navItem.icon) {\n <ngs-icon name=\"fluent:{{ navItem.icon }}\"/>\n }\n </ng-container>\n {{ navItem.label }}\n <ngs-icon name=\"fluent:chevron-down-24-regular\" ngsSidebarNavGroupToggleIcon/>\n </ngs-sidebar-nav-group-toggle>\n <ngs-sidebar-nav-group-menu>\n @for (childNavItem of navItem.children; track childNavItem) {\n <ngs-sidebar-nav-item [key]=\"childNavItem.key\">\n <ng-container ngsSidebarNavItemIcon>\n @if (childNavItem.icon) {\n <ngs-icon name=\"fluent:{{ navItem.icon }}\"/>\n }\n </ng-container>\n {{ navItem.label }}\n </ngs-sidebar-nav-item>\n }\n </ngs-sidebar-nav-group-menu>\n </ngs-sidebar-nav-group>\n }\n @case ('heading')\n...",
7399
+ "minimalExample": "<div class=\"h-[600px] w-[300px] relative\">\n <ngs-sidebar class=\"border border-muted rounded-2xl\">\n <ngs-sidebar-header class=\"flex h-14 items-center px-4 font-bold text-primary border-b border-b-muted\">\n NGSTARTER\n </ngs-sidebar-header>\n <ngs-sidebar-body>\n <ngs-sidebar-nav activeKey=\"home\" class=\"p-4\">\n @for (navItem of navItems; track navItem) {\n @switch (navItem.type) {\n @case ('group') {\n <ngs-sidebar-nav-group>\n <ngs-sidebar-nav-group-toggle>\n <ng-container ngsSidebarNavItemIcon>\n @if (navItem.icon) {\n <ngs-icon name=\"fluent:{{ navItem.icon }}\"/>\n }\n </ng-container>\n {{ navItem.label }}\n <ngs-icon name=\"fluent:chevron-down-24-regular\" ngsSidebarNavGroupToggleIcon/>\n </ngs-sidebar-nav-group-toggle>\n <ngs-sidebar-nav-group-menu>\n @for (childNavItem of navItem.children; track childNavItem) {\n <ngs-sidebar-nav-item [key]=\"childNavItem.key\">\n <ng-container ngsSidebarNavItemIcon>\n @if (childNavItem.icon) {\n <ngs-icon name=\"fluent:{{ childNavItem.icon }}\"/>\n }\n </ng-container>\n {{ childNavItem.label }}\n </ngs-sidebar-nav-item>\n }\n </ngs-sidebar-nav-group-menu>\n </ngs-sidebar-nav-group>\n }\n @case (\n...",
7386
7400
  "exampleFiles": [
7387
7401
  {
7388
7402
  "name": "basic-sidebar-example",
7389
7403
  "title": "Basic sidebar",
7390
7404
  "file": "projects/docs/src/app/navigation/sidebar/_examples/basic-sidebar-example/basic-sidebar-example.html",
7391
- "source": "<div class=\"h-[600px] w-[300px] relative\">\n <ngs-sidebar class=\"border border-muted rounded-2xl\">\n <ngs-sidebar-header class=\"flex h-14 items-center px-4 font-bold text-primary border-b border-b-muted\">\n NGSTARTER\n </ngs-sidebar-header>\n <ngs-sidebar-body>\n <ngs-sidebar-nav activeKey=\"home\" class=\"p-4\">\n @for (navItem of navItems; track navItem) {\n @switch (navItem.type) {\n @case ('group') {\n <ngs-sidebar-nav-group>\n <ngs-sidebar-nav-group-toggle>\n <ng-container ngsSidebarNavItemIcon>\n @if (navItem.icon) {\n <ngs-icon name=\"fluent:{{ navItem.icon }}\"/>\n }\n </ng-container>\n {{ navItem.label }}\n <ngs-icon name=\"fluent:chevron-down-24-regular\" ngsSidebarNavGroupToggleIcon/>\n </ngs-sidebar-nav-group-toggle>\n <ngs-sidebar-nav-group-menu>\n @for (childNavItem of navItem.children; track childNavItem) {\n <ngs-sidebar-nav-item [key]=\"childNavItem.key\">\n <ng-container ngsSidebarNavItemIcon>\n @if (childNavItem.icon) {\n <ngs-icon name=\"fluent:{{ navItem.icon }}\"/>\n }\n </ng-container>\n {{ navItem.label }}\n </ngs-sidebar-nav-item>\n }\n </ngs-sidebar-nav-group-menu>\n </ngs-sidebar-nav-group>\n }\n @case ('heading')\n..."
7405
+ "source": "<div class=\"h-[600px] w-[300px] relative\">\n <ngs-sidebar class=\"border border-muted rounded-2xl\">\n <ngs-sidebar-header class=\"flex h-14 items-center px-4 font-bold text-primary border-b border-b-muted\">\n NGSTARTER\n </ngs-sidebar-header>\n <ngs-sidebar-body>\n <ngs-sidebar-nav activeKey=\"home\" class=\"p-4\">\n @for (navItem of navItems; track navItem) {\n @switch (navItem.type) {\n @case ('group') {\n <ngs-sidebar-nav-group>\n <ngs-sidebar-nav-group-toggle>\n <ng-container ngsSidebarNavItemIcon>\n @if (navItem.icon) {\n <ngs-icon name=\"fluent:{{ navItem.icon }}\"/>\n }\n </ng-container>\n {{ navItem.label }}\n <ngs-icon name=\"fluent:chevron-down-24-regular\" ngsSidebarNavGroupToggleIcon/>\n </ngs-sidebar-nav-group-toggle>\n <ngs-sidebar-nav-group-menu>\n @for (childNavItem of navItem.children; track childNavItem) {\n <ngs-sidebar-nav-item [key]=\"childNavItem.key\">\n <ng-container ngsSidebarNavItemIcon>\n @if (childNavItem.icon) {\n <ngs-icon name=\"fluent:{{ childNavItem.icon }}\"/>\n }\n </ng-container>\n {{ childNavItem.label }}\n </ngs-sidebar-nav-item>\n }\n </ngs-sidebar-nav-group-menu>\n </ngs-sidebar-nav-group>\n }\n @case (\n..."
7392
7406
  },
7393
7407
  {
7394
7408
  "name": "sidebar-with-custom-icons-example",
7395
7409
  "title": "Sidebar with custom icons",
7396
7410
  "file": "projects/docs/src/app/navigation/sidebar/_examples/sidebar-with-custom-icons-example/sidebar-with-custom-icons-example.html",
7397
- "source": "<div class=\"h-[600px] w-[300px] relative\">\n <ngs-sidebar class=\"border border-muted rounded-2xl\">\n <ngs-sidebar-header class=\"flex h-14 items-center px-4 font-bold border-b border-b-muted text-primary\">\n NgStarter\n </ngs-sidebar-header>\n <ngs-sidebar-body>\n <ngs-sidebar-nav activeKey=\"home\" class=\"p-4\">\n @for (navItem of navItems; track navItem) {\n @switch (navItem.type) {\n @case ('group') {\n <ngs-sidebar-nav-group>\n <ngs-sidebar-nav-group-toggle>\n <ng-container ngsSidebarNavItemIcon>\n @if (navItem.icon) {\n <ngs-icon [name]=\"navItem.icon\"/>\n }\n </ng-container>\n {{ navItem.label }}\n <ngs-icon ngsSidebarNavGroupToggleIcon name=\"fluent:add-24-regular\"/>\n </ngs-sidebar-nav-group-toggle>\n <ngs-sidebar-nav-group-menu>\n @for (childNavItem of navItem.children; track childNavItem) {\n <ngs-sidebar-nav-item [key]=\"childNavItem.key\">\n <ng-container ngsSidebarNavItemIcon>\n @if (childNavItem.icon) {\n <ngs-icon [name]=\"navItem.icon\"/>\n }\n </ng-container>\n {{ navItem.label }}\n </ngs-sidebar-nav-item>\n }\n </ngs-sidebar-nav-group-menu>\n </ngs-sidebar-nav-group>\n }\n @case ('heading') {\n <ngs-sidebar-n\n..."
7411
+ "source": "<div class=\"h-[600px] w-[300px] relative\">\n <ngs-sidebar class=\"border border-muted rounded-2xl\">\n <ngs-sidebar-header class=\"flex h-14 items-center px-4 font-bold border-b border-b-muted text-primary\">\n NgStarter\n </ngs-sidebar-header>\n <ngs-sidebar-body>\n <ngs-sidebar-nav activeKey=\"home\" class=\"p-4\">\n @for (navItem of navItems; track navItem) {\n @switch (navItem.type) {\n @case ('group') {\n <ngs-sidebar-nav-group>\n <ngs-sidebar-nav-group-toggle>\n <ng-container ngsSidebarNavItemIcon>\n @if (navItem.icon) {\n <ngs-icon [name]=\"navItem.icon\"/>\n }\n </ng-container>\n {{ navItem.label }}\n <ngs-icon ngsSidebarNavGroupToggleIcon name=\"fluent:add-24-regular\"/>\n </ngs-sidebar-nav-group-toggle>\n <ngs-sidebar-nav-group-menu>\n @for (childNavItem of navItem.children; track childNavItem) {\n <ngs-sidebar-nav-item [key]=\"childNavItem.key\">\n <ng-container ngsSidebarNavItemIcon>\n @if (childNavItem.icon) {\n <ngs-icon [name]=\"childNavItem.icon\"/>\n }\n </ng-container>\n {{ childNavItem.label }}\n </ngs-sidebar-nav-item>\n }\n </ngs-sidebar-nav-group-menu>\n </ngs-sidebar-nav-group>\n }\n @case ('heading') {\n <ngs\n..."
7398
7412
  }
7399
7413
  ],
7400
7414
  "previewAsset": "projects/components/sidebar/preview.svg",
@@ -7589,8 +7603,8 @@
7589
7603
  "sourceRoot": "projects/components/sidenav/src",
7590
7604
  "docsPath": "/components/sidenav",
7591
7605
  "docsOverviewSource": "projects/docs/src/app/components/sidenav/overview/overview.html",
7592
- "purpose": "Provide side navigation that can be persistent or toggleable.",
7593
- "useWhen": "Use for responsive layouts and app navigation shells.",
7606
+ "purpose": "Provide a responsive shell container for side surfaces that can open, close, collapse, overlay, or push content.",
7607
+ "useWhen": "Use ngs-sidenav-container with ngs-sidenav and ngs-sidenav-content when a page or app shell needs a side region with behavior: opened state, open/close/toggle methods, mode over/push/side, position start/end, collapsed icon-width state, disableClose, backdrop and backdropClick, adaptive mobile mode through adaptive and adaptiveBreakpoint, fixedWidth, autosize, and autoFocus. Use ngsSidenavCollapsed and ngsSidenavExpanded templates to render different content while collapsed or expanded. In admin shells, put ngs-sidebar inside ngs-sidenav when the side region is primary navigation; Sidebar owns the actual navigation items. Do not use Sidenav as the navigation structure itself; use Sidebar or Navigation inside it. Do not use for temporary task panels; use Drawer. Do not use for persistent tabbed utility tools; use SidePanel. Do not use for static local columns or content sections; use LayoutSidebar, Panel, or Tailwind layout. Do not use for modal workflows, confirmations, or action menus; use Dialog, Confirm, or Menu.",
7594
7608
  "exampleTopics": [
7595
7609
  "Basic sidenav"
7596
7610
  ],
@@ -7663,8 +7677,8 @@
7663
7677
  "sourceRoot": "projects/components/signature-pad/src",
7664
7678
  "docsPath": "/components/signature-pad",
7665
7679
  "docsOverviewSource": "projects/docs/src/app/components/signature-pad/overview/overview.html",
7666
- "purpose": "Capture a drawn signature.",
7667
- "useWhen": "Use for approvals, contracts, confirmations, forms, and consent flows.",
7680
+ "purpose": "Capture a handwritten signature and emit it as a PNG data URL.",
7681
+ "useWhen": "Use ngs-signature-pad in approval, contract, consent, delivery confirmation, onboarding, checkout, legal acknowledgement, or internal workflow forms where the user must draw a signature. It supports mouse, touch, or pen input, penColor, colors for the fixed allowed pen palette, lineWidth, backgroundColor, lazy brush smoothing through lazyRadius/lazyFriction/lazyEnabled, clear(), save(), signatureSaved with a base64 PNG data URL, and signatureCleared. Use the emitted PNG in app code to store or attach the signature to the workflow or document. Do not use SignaturePad as a general drawing canvas, image editor, annotation tool, sketch board, whiteboard, file upload, typed-name field, or legal validation system by itself. App code still needs to require the signature when needed, persist it, and enforce backend or legal rules.",
7668
7682
  "exampleTopics": [
7669
7683
  "Basic signature pad"
7670
7684
  ],
@@ -7721,8 +7735,8 @@
7721
7735
  "sourceRoot": "projects/components/skeleton/src",
7722
7736
  "docsPath": "/components/skeleton",
7723
7737
  "docsOverviewSource": "projects/docs/src/app/components/skeleton/overview/overview.html",
7724
- "purpose": "Show placeholder shapes while content is loading.",
7725
- "useWhen": "Use for cards, lists, tables, and pages where layout is known before data arrives.",
7738
+ "purpose": "Show placeholder blocks for loading content when the final layout is already known.",
7739
+ "useWhen": "Use ngs-skeleton to preserve layout while cards, lists, table rows, dashboard widgets, chart areas, avatars, text lines, or media blocks are loading. Shape and size each skeleton with TailwindCSS utilities such as h-*, w-*, size-*, flex, grid, gap, and wrapper layouts so it roughly matches the UI that will replace it. Use roundedFull for circular placeholders such as avatars or icon circles. Do not use Skeleton for unknown long operations where progress matters; use ProgressBar. Do not use for global route or app loading; use PageLoadingBar or ScreenLoader. Do not use for blocking a local section; use BlockLoader. Do not use for empty results; use EmptyState. Do not use for image fallback after load failure; use ImagePlaceholder. Do not use random grey blocks that do not resemble the final content.",
7726
7740
  "exampleTopics": [
7727
7741
  "Basic Skeleton"
7728
7742
  ],
@@ -7769,8 +7783,8 @@
7769
7783
  "sourceRoot": "projects/components/slide-toggle/src",
7770
7784
  "docsPath": "/forms/slide-toggle",
7771
7785
  "docsOverviewSource": "projects/docs/src/app/forms/slide-toggle/overview/overview.html",
7772
- "purpose": "Capture a binary on/off setting.",
7773
- "useWhen": "Use for preferences, feature toggles, visibility, and immediate boolean settings.",
7786
+ "purpose": "Capture a boolean on/off setting where checked means enabled.",
7787
+ "useWhen": "Use ngs-slide-toggle for settings and preferences where checked=true means the feature or state is enabled. Good for live updates, notifications, dark mode option, visibility, sidebar expanded or collapsed, animation on/off, table options, enable Wi-Fi, show archived, and allow comments. It is an Angular form control with checked, disabled, required, ngModel, formControlName, change, and toggleChange, and has its own label pattern, so do not wrap it in ngs-form-field. Do not use SlideToggle for choosing one value from many; use Radio, Segmented, or Select. Do not use for multiple independent selections in a list; use Checkbox. Do not use for button-like mode groups; use ButtonToggle. Do not use for actions, commands, navigation, or rich option cards; use Button, Navigation, or RadioCard. For “I agree” or “accept terms” confirmations, prefer Checkbox because the user is confirming, not enabling a setting.",
7774
7788
  "exampleTopics": [
7775
7789
  "Basic Slide Toggle",
7776
7790
  "Disabled Slide Toggle",
@@ -7852,8 +7866,8 @@
7852
7866
  "sourceRoot": "projects/components/slider/src",
7853
7867
  "docsPath": "/components/slider",
7854
7868
  "docsOverviewSource": "projects/docs/src/app/components/slider/overview/overview.html",
7855
- "purpose": "Let users choose a numeric value from a continuous or stepped range.",
7856
- "useWhen": "Use for volume, size, thresholds, opacity, ranges, and visual settings.",
7869
+ "purpose": "Let users choose one numeric value or a start/end range by dragging thumb controls.",
7870
+ "useWhen": "Use ngs-slider when approximate visual numeric adjustment is better than typing. Good for volume, opacity, zoom, size, threshold, percentage, rating or score, price range, numeric date or age range, chart settings, visual tuning, and filter ranges. Use input ngsSliderThumb for one value, or input ngsSliderStartThumb plus input ngsSliderEndThumb for a range. Configure min, max, step, disabled, discrete, showTickMarks, displayWith, Angular forms, and valueChange on thumbs. Do not use Slider to show progress or status; use ProgressBar or Gauge. Do not use when exact numeric entry is primary; use NumberInput or pair NumberInput with Slider. Do not use for named categories; use Select, Radio, or Segmented. Do not use for before/after image comparison; use ComparisonSlider. Do not use for pagination or table sorting/filter builder logic; use Paginator, Sort, or FilterBuilder.",
7857
7871
  "exampleTopics": [
7858
7872
  "Basic Slider",
7859
7873
  "Custom Thumb Label Formatting",
@@ -7939,8 +7953,8 @@
7939
7953
  "sourceRoot": "projects/components/snack-bar/src",
7940
7954
  "docsPath": "/components/snackbar",
7941
7955
  "docsOverviewSource": "projects/docs/src/app/components/snackbar/overview/overview.html",
7942
- "purpose": "Show short transient feedback after an action.",
7943
- "useWhen": "Use for save confirmations, undo prompts, background results, and non-blocking messages.",
7956
+ "purpose": "Show short transient overlay feedback after an action or background result.",
7957
+ "useWhen": "Use the SnackBar service for brief non-blocking messages such as Saved, Copied, Invite sent, Refresh complete, Export started, or Deleted, with an optional quick action such as Undo or View. Open with snackBar.open(message, action?, config?), openFromComponent, or openFromTemplate. Configure duration, horizontalPosition, verticalPosition, data, panelClass, custom component or template content, and use SnackBarRef.dismiss(), afterOpened(), and afterDismissed() for lifecycle handling. SnackBar should be short, temporary, and safe to miss. Do not use for field validation errors; use FormField errors. Do not use for persistent inline messages; use Alert. Do not use for global important header messages; use Announcement. Do not use for critical required actions; use ActionRequired. Do not use for confirmations before destructive actions; use Confirm. Do not use for modal workflows; use Dialog. Do not use for long-lived notification inboxes or event feeds; use Notifications. Do not use for incident/status banners or loading/progress states; use Incidents, ProgressBar, ScreenLoader, BlockLoader, or PageLoadingBar.",
7944
7958
  "exampleTopics": [
7945
7959
  "Basic Snackbar",
7946
7960
  "Snackbar With Custom Component",
@@ -8007,8 +8021,8 @@
8007
8021
  "sourceRoot": "projects/components/sort/src",
8008
8022
  "docsPath": null,
8009
8023
  "docsOverviewSource": null,
8010
- "purpose": "Provide sorting behavior for table-like data.",
8011
- "useWhen": "Use with tables, data views, and sortable column headers.",
8024
+ "purpose": "Provide sortable header behavior and sort state for table-like data.",
8025
+ "useWhen": "Use ngsSort on a sortable table/list/data container and ngs-sort-header=\"fieldName\" on header cells that should cycle through sort states. Sort tracks active column and direction (asc, desc, or cleared), supports ngsSortActive, ngsSortDirection, ngsSortStart, ngsSortDisableClear, ngsSortDisabled, per-header disabled state, sortActionDescription, and emits ngsSortChange with { active, direction }. Use it with Table sortable column headers, custom table-like data surfaces, and when wiring sort state into a local TableDataSource or server/API query. For DataView, usually prefer its built-in sortable column config and sortChange instead of manually adding ngs-sort-header. Do not use Sort as a visual sort icon only, filter builder, search, grouping, drag reorder, tab sorting, or generic “sort these cards” button. Sort only manages header state and emits the selected sort; the app/data source still applies local sorting or sends the sort state to the backend.",
8012
8026
  "exampleTopics": [],
8013
8027
  "minimalExample": null,
8014
8028
  "exampleFiles": [],
@@ -8053,8 +8067,8 @@
8053
8067
  "sourceRoot": "projects/components/spinner/src",
8054
8068
  "docsPath": "/components/progress-spinner",
8055
8069
  "docsOverviewSource": "projects/docs/src/app/components/progress-spinner/overview/overview.html",
8056
- "purpose": "Use Spinner for basic progress spinner, configurable progress spinner, configurable spinner.",
8057
- "useWhen": "Choose Spinner when the workflow matches examples such as Basic Progress Spinner, Configurable Progress Spinner, Configurable spinner.",
8070
+ "purpose": "Show a circular indicator for an ongoing operation.",
8071
+ "useWhen": "Use ngs-progress-spinner when a compact circular loading indicator is needed inside a button, overlay, media viewer, widget, small page area, or next to an action. Use mode=\"indeterminate\" when the remaining time or amount of work is unknown. Use mode=\"determinate\" with value from 0 to 100 when progress is known. Configure diameter, strokeWidth, and color for the surface. Do not use ProgressSpinner for linear progress; use ProgressBar. Do not use it for known loading layouts; use Skeleton. Do not use it for router or page transition loading; use PageLoadingBar. Do not use it as a full-screen or blocking state by itself; use ScreenLoader or BlockLoader. Do not use it as a KPI or metric display; use Gauge or ProgressBar based on context.",
8058
8072
  "exampleTopics": [
8059
8073
  "Basic Progress Spinner",
8060
8074
  "Configurable Progress Spinner",
@@ -8113,8 +8127,8 @@
8113
8127
  "sourceRoot": "projects/components/splash-screen/src",
8114
8128
  "docsPath": null,
8115
8129
  "docsOverviewSource": null,
8116
- "purpose": "Show an initial branded loading screen.",
8117
- "useWhen": "Use while the application bootstraps or waits for essential startup data.",
8130
+ "purpose": "Show one full-screen branded startup overlay during the initial app bootstrap moment.",
8131
+ "useWhen": "Use ngs-splash-screen once near the root app template while Angular, routing, theme, auth/session, tenant, or essential startup data initializes. Project ngs-logo or custom branded content into it. It hides automatically after the first NavigationEnd with hideDelay, fades with animationDuration, and can be controlled through SplashScreenStore.show() and SplashScreenStore.hide(). Do not use SplashScreen for normal page loading after startup; use PageLoadingBar. Do not use for full-screen blocking operations after the app is running; use ScreenLoader. Do not use for local card, table, form, or widget loading; use BlockLoader, Skeleton, ProgressBar, or component-specific loading states. Do not use for empty states, route skeletons, modal workflows, or marketing hero screens. SplashScreen should be one per app and short-lived at the beginning, not shown for every action.",
8118
8132
  "exampleTopics": [],
8119
8133
  "minimalExample": null,
8120
8134
  "exampleFiles": [],
@@ -8150,8 +8164,8 @@
8150
8164
  "sourceRoot": "projects/components/split/src",
8151
8165
  "docsPath": "/components/split-pane",
8152
8166
  "docsOverviewSource": "projects/docs/src/app/components/split-pane/overview/overview.html",
8153
- "purpose": "Divide an interface into resizable panes.",
8154
- "useWhen": "Use for editors, master-detail screens, inspectors, and multi-pane workspaces.",
8167
+ "purpose": "Create a resizable multi-pane layout with draggable gutters between panes.",
8168
+ "useWhen": "Use ngs-split with multiple ngs-split-pane regions when a workspace needs two or more panes that users can manually resize. Good for editors, IDE-like screens, analytics workspaces, master-detail-detail layouts, source and preview views, inspector plus canvas plus logs, and dense multi-pane tools. Supports horizontal or vertical direction, nested splits, unit percent or pixel, size, minSize, maxSize, lockSize, visible, order, withHandle dotted gutter affordance, restrictMove, disabled, gutterSize, gutterStep, dragStart, dragEnd, gutterClick, gutterDblClick, transitionEnd, getVisibleAreaSizes(), and setVisibleAreaSizes() for persistence. Do not use Split for ordinary responsive layout or static two-column admin pages; use TailwindCSS grid or flex. Do not use for one manually resized box; use ResizableContainer. Do not use for side navigation shells; use Sidenav or Sidebar. Do not use for temporary side overlays; use Drawer. Do not use for local structured page sections; use Panel. Do not use for table column resizing or image resizing; use table features or ImageResizer. The parent must have a stable height and width.",
8155
8169
  "exampleTopics": [
8156
8170
  "Basic Split Pane",
8157
8171
  "Split Pane with Handle",
@@ -8265,8 +8279,8 @@
8265
8279
  "sourceRoot": "projects/components/stepper/src",
8266
8280
  "docsPath": "/components/stepper",
8267
8281
  "docsOverviewSource": "projects/docs/src/app/components/stepper/overview/overview.html",
8268
- "purpose": "Guide users through a multi-step process.",
8269
- "useWhen": "Use for onboarding, setup, checkout, configuration, and wizard-style forms.",
8282
+ "purpose": "Render a ready-made visual wizard for several connected steps in one process.",
8283
+ "useWhen": "Use ngs-stepper with ngs-step when users must move through related steps and see their current progress. Good for onboarding, checkout, setup, import/export flows, account or tenant creation, review flows, and multi-step forms. Use linear mode with stepControl when each step must be valid before the user continues. Use ngsStepperNext and ngsStepperPrevious on NgStarter buttons for standard wizard navigation, ngsStepLabel or label for step labels, optional/completed/error states for step status, and horizontal or vertical orientation for responsive layouts. Do not use Stepper when you only need step state and validation logic without the default visual UI; use HeadlessStepper. Do not use for independent page sections; use Tabs or ExpansionPanel. Do not use for app route navigation; use Navigation, Breadcrumbs, Sidebar, or routing. Do not use for showing only a percentage; use ProgressBar. Do not use for product tours over existing UI; use GuidedTour.",
8270
8284
  "exampleTopics": [
8271
8285
  "Basic Stepper",
8272
8286
  "Stepper Vertical",
@@ -8350,8 +8364,8 @@
8350
8364
  "sourceRoot": "projects/components/suggestions/src",
8351
8365
  "docsPath": "/components/suggestions",
8352
8366
  "docsOverviewSource": "projects/docs/src/app/components/suggestions/overview/overview.html",
8353
- "purpose": "Display suggested actions, values, or next steps.",
8354
- "useWhen": "Use for assistant-like recommendations, empty states, search, and productivity hints.",
8367
+ "purpose": "Render a grouped visual list of contextual suggestions, search results, recent items, or shortcuts.",
8368
+ "useWhen": "Use ngs-suggestions as the visual list inside search dropdowns, assistant inputs, command-like panels, or contextual suggestion popovers. Group related rows with ngs-suggestion-block, use ngs-suggestion for each clickable row, place icons with ngsSuggestionIcon, thumbnails or avatars with ngsSuggestionThumb, and use inline blocks for quick actions such as create buttons. Good for recently viewed items, users, files, pages, matching search results, and quick create shortcuts. Do not use Suggestions as a form value picker; use Autocomplete or Select. Do not use it for a short contextual command menu; use Menu. Do not use it for persistent app navigation; use Navigation, Sidebar, Sidenav, or RailNav. Do not use it as a complete command palette by itself; it can provide the grouped visual result list, but search state, keyboard handling, filtering, and command execution belong to the surrounding feature. Do not use it for page-level empty-state recommendations or assistant cards; compose those with EmptyState, Card, Alert, or the page layout.",
8355
8369
  "exampleTopics": [
8356
8370
  "Basic suggestions"
8357
8371
  ],
@@ -8418,8 +8432,8 @@
8418
8432
  "sourceRoot": "projects/components/tab-panel/src",
8419
8433
  "docsPath": "/navigation/tab-panel",
8420
8434
  "docsOverviewSource": "projects/docs/src/app/navigation/tab-panel/overview/overview.html",
8421
- "purpose": "Organize related content into tabbed panels.",
8422
- "useWhen": "Use for settings, details, and pages where sections share the same context.",
8435
+ "purpose": "Create a compact vertical tool or navigation panel with a linked aside content area.",
8436
+ "useWhen": "Use ngs-tab-panel when a workspace or editor needs a vertical set of icon/text items that controls adjacent aside content. Use ngs-tab-panel-content with ngs-tab-panel-nav and ngs-tab-panel-item for the rail, bind items to content with matching for values and ngsTabPanelAsideContent ids inside ngs-tab-panel-aside, and use activeItemId to choose the active item. Good for image editors, design tools, asset panels, layers, inspectors, workspace switchers, tool palettes, and settings/tools inside dense work surfaces. Use compact for icon-only rails with tooltips, header/content/footer regions to group items, and ngs-tab-panel-custom-item for custom items such as avatars, workspaces, or add actions. Do not use TabPanel for ordinary horizontal page tabs; use Tabs. Do not use it for primary app navigation; use Sidebar, Navigation, Sidenav, or RailNav. Do not use it for temporary overlay side content; use Drawer. Do not use it for a structured page section; use Panel. Do not use it for workflow steps; use Stepper. Do not use it for contextual command lists; use Menu.",
8423
8437
  "exampleTopics": [
8424
8438
  "Basic tab panel",
8425
8439
  "Tab panel with panel inside",
@@ -8529,8 +8543,8 @@
8529
8543
  "sourceRoot": "projects/components/table/src",
8530
8544
  "docsPath": "/components/table",
8531
8545
  "docsOverviewSource": "projects/docs/src/app/components/table/overview/overview.html",
8532
- "purpose": "Render structured tabular data with columns, rows, headers, sorting, selection, and sticky regions.",
8533
- "useWhen": "Use for predictable tabular layouts; use Data View when users need richer dataset operations.",
8546
+ "purpose": "Render static or simple template-defined tabular data with known columns.",
8547
+ "useWhen": "Use table[ngs-table] or ngs-table for static or simple tabular data where columns are known in Angular templates: read-only tables, documentation tables, settings summaries, static comparison rows, lightweight report tables, and small non-interactive admin tables. Define columns with ngsColumnDef, header/body/footer cells with ngsHeaderCellDef, ngsCellDef, and ngsFooterCellDef, and rows with ngsHeaderRowDef, ngsRowDef, and ngsFooterRowDef. Use TableDataSource only for lightweight local table behavior, not as a replacement for a real datatable. Use sticky/stickyEnd for fixed columns and sticky row defs for sticky header or footer. Use table[ngs-native-table] only for static HTML tables without a data source. Do not build tables with div role=\"table\" or custom grid markup when ngs-table fits. Use DataView instead when the UI is a datatable or working data surface with row actions, selection, sorting, search/filter state, pagination, column sizing/settings, saved views, server-driven data, or complex record management. Use List for simple vertical rows without real columns. Use Tree for hierarchical rows. Use Grid or Tiles for dashboard layouts. Use Sort only for sort state behavior; it does not replace Table.",
8534
8548
  "exampleTopics": [
8535
8549
  "Native Table",
8536
8550
  "Basic Table",
@@ -8665,8 +8679,8 @@
8665
8679
  "sourceRoot": "projects/components/tabs/src",
8666
8680
  "docsPath": "/components/tabs",
8667
8681
  "docsOverviewSource": "projects/docs/src/app/components/tabs/overview/overview.html",
8668
- "purpose": "Switch between related views within the same page context.",
8669
- "useWhen": "Use for compact section switching, detail page subsections, and alternate views.",
8682
+ "purpose": "Switch between peer views inside one page or section context, with only one panel visible at a time.",
8683
+ "useWhen": "Use ngs-tab-group with ngs-tab for local content tabs that do not require routing. Use ngs-tab-nav-bar with a[ngs-tab-link] and ngs-tab-nav-panel for route-linked tabs inside one section, such as documentation overview/API pages or detail subsections. Good for entity details, settings subsections, overview/activity/files/settings pages, alternate views of one object, or peer panels that share the same context. Supports selectedIndex, selectedIndexChange, selectedTabChange, disabled tabs, custom ngsTabLabel templates, explicit ngsTabContent templates, preserveContent, stretchTabs, alignTabs, headerPosition above/below, overflow pagination controls, and animationDuration/custom animations. Do not use Tabs for compact mode or value switches; use Segmented. Do not use for wizard or process steps; use Stepper. Do not use for vertical tool panels with linked aside content; use TabPanel. Do not use for primary app navigation; use Navigation, Sidebar, Sidenav, or RailNav. Do not use for collapsible sections; use ExpansionPanel. Do not use for route paths; use Breadcrumbs. Do not use for choosing a form value; use Select, Radio, RadioCard, Checkbox, or ButtonToggle depending on the interaction.",
8670
8684
  "exampleTopics": [
8671
8685
  "Basic Tabs",
8672
8686
  "Tabs with aligned labels",
@@ -8780,8 +8794,8 @@
8780
8794
  "sourceRoot": "projects/components/text-editor/src",
8781
8795
  "docsPath": "/components/text-editor",
8782
8796
  "docsOverviewSource": "projects/docs/src/app/components/text-editor/overview/overview.html",
8783
- "purpose": "Provide a rich text editing control.",
8784
- "useWhen": "Use for formatted descriptions, messages, notes, articles, and user-generated content.",
8797
+ "purpose": "Provide a full Tiptap-based WYSIWYG rich text editor for formatted HTML content.",
8798
+ "useWhen": "Use ngs-text-editor when users need to create or edit rich HTML content with headings, bold, italic, strike, lists, blockquotes, inline code, code blocks, horizontal rules, links, images, YouTube embeds, toolbar commands, bubble menus, or floating menus. Good for product descriptions, project/task descriptions, CMS-like fields, articles, notes, changelog entries, release notes, knowledge base content, help content, and rich admin content bodies. Provide initial HTML through content, listen to contentChange for updated HTML, add custom Tiptap extensions through extensions, and use imageUploadFn to upload images and resolve a URL. Compose controls with ngs-text-editor-toolbar, ngs-text-editor-bubble-menu, ngs-text-editor-floating-menu, ngs-text-editor-divider, and ngsTextEditorCommand* directives. Do not use TextEditor for short comments, threads, or quick replies; use CommentEditor. Do not use it for block-based CMS/page building; use ContentEditor. Do not use it for plain text fields; use ngsInput inside FormField. Do not use it for inline renaming; use InlineTextEdit. Do not use it for read-only code or snippets; use CodeHighlighter.",
8785
8799
  "exampleTopics": [
8786
8800
  "Basic Text Editor",
8787
8801
  "Text Editor with floating menu",
@@ -8920,8 +8934,8 @@
8920
8934
  "sourceRoot": "projects/components/thumbnail-maker/src",
8921
8935
  "docsPath": "/components/thumbnail-maker",
8922
8936
  "docsOverviewSource": "projects/docs/src/app/components/thumbnail-maker/overview/overview.html",
8923
- "purpose": "Create or adjust thumbnails from media.",
8924
- "useWhen": "Use for video/image previews, content management, and media publishing workflows.",
8937
+ "purpose": "Create a square 300x300 thumbnail bitmap from an image with drag positioning and zoom controls.",
8938
+ "useWhen": "Use ngs-thumbnail-maker when users need to position and zoom an image inside a fixed square frame, then save the finished thumbnail as a data URL, Blob, or canvas. Good for avatars, profile images, CMS thumbnails, media library previews, product/user/project card images, and simple square preview generation. Provide the image URL or data URL through src, add helperText when users need drag instructions, and call api.getDataUrl(), api.toBlob(callback), or api.getCanvas() when saving. Combine with Upload or ngsUploadTrigger when users must select a local image first. Do not use ThumbnailMaker when the app needs arbitrary crop shapes, crop rectangles, circles, or crop coordinates; use Crop. Do not use it only to change displayed image width; use ImageResizer. Do not use it to view images; use ImageViewer or ImageZoomViewer. Do not use it as an image placeholder; use ImagePlaceholder. Do not use it for full canvas editing, layers, text, effects, or templates; use ImageDesigner. Do not use it as a plain upload picker without editing; use Upload.",
8925
8939
  "exampleTopics": [
8926
8940
  "Basic thumbnail maker",
8927
8941
  "Thumbnail maker with helper text",
@@ -8985,8 +8999,8 @@
8985
8999
  "sourceRoot": "projects/components/tiles/src",
8986
9000
  "docsPath": "/components/tiles",
8987
9001
  "docsOverviewSource": "projects/docs/src/app/components/tiles/overview/overview.html",
8988
- "purpose": "Lay out resizable tile-based content.",
8989
- "useWhen": "Use for dashboards, visual builders, and configurable grid-like workspaces.",
9002
+ "purpose": "Lay out responsive dashboard tiles and support user-driven tile reordering/customization.",
9003
+ "useWhen": "Use ngs-tiles with ngs-tile when users can rearrange dashboard cards or widgets, customize a dashboard, or save a changed widget order. Good for editable dashboards, portal home pages, workspace widgets, configurable analytics cards, media/card boards, and dashboard builders. Tiles can be the layout host for config-driven dashboard renderers: the app can render lazy widget components inside each ngs-tile, show Skeleton while widgets load, and persist the final item order from orderChanged or layoutChanged. Use width, height, width.sm/md/lg/xl, and height.sm/md/lg/xl to define responsive tile spans, and ngsTileHandle for drag handles. Provide items so reorder events can map visual order back to app data. Use Grid only for static predefined dashboard/widget layouts that users do not rearrange. Do not use Tiles for ordinary static responsive page layout; use TailwindCSS grid/flex. Do not use for split panes with gutters; use Split. Do not use for one manually resized box; use ResizableContainer. Do not use for simple cards, lists, tables, or datasets without tile reordering; use Card, List, Table, or DataView. Do not use for status-column workflows; use KanbanBoard.",
8990
9004
  "exampleTopics": [
8991
9005
  "Basic tiles"
8992
9006
  ],
@@ -9065,8 +9079,8 @@
9065
9079
  "sourceRoot": "projects/components/timeline/src",
9066
9080
  "docsPath": "/components/timeline",
9067
9081
  "docsOverviewSource": "projects/docs/src/app/components/timeline/overview/overview.html",
9068
- "purpose": "Show events or activities in chronological order.",
9069
- "useWhen": "Use for audit logs, histories, workflows, tracking, and activity feeds.",
9082
+ "purpose": "Show a vertical chronological history of events.",
9083
+ "useWhen": "Use ngs-timeline when users need to understand a sequence of events over time: audit logs, activity history, entity change history, project milestones, order or shipment history, workflow history, tracking events, and user actions. Use ngs-timeline-header to group events by date, month, phase, or period. Use ngs-timeline-item with ngs-timeline-timestamp, ngs-timeline-title, ngs-timeline-subtitle, ngs-timeline-description, ngs-timeline-attributes, and ngs-timeline-content to structure each event. Use ngsTimelineItemIndicator when the marker should show an actor, icon, status, or event type. Do not use Timeline for a realtime notification inbox or actionable notification feed; use Notifications. Do not use for a simple vertical collection without time/order meaning; use List. Do not use for tabular audit logs that need sorting, filtering, or many columns; use Table or DataView. Do not use for workflow steps the user must complete; use Stepper. Do not use for status columns; use KanbanBoard. Do not use for calendar/scheduler views or for a single operation status; use ProgressBar, Badge, or Status as appropriate.",
9070
9084
  "exampleTopics": [
9071
9085
  "Basic Timeline",
9072
9086
  "Timeline With Timestamp",
@@ -9171,8 +9185,8 @@
9171
9185
  "sourceRoot": "projects/components/timepicker/src",
9172
9186
  "docsPath": "/components/timepicker",
9173
9187
  "docsOverviewSource": "projects/docs/src/app/components/timepicker/overview/overview.html",
9174
- "purpose": "Let users choose a time value.",
9175
- "useWhen": "Use for scheduling, reminders, availability, reports, and time-based filters.",
9188
+ "purpose": "Let users choose or type a time of day in a form field.",
9189
+ "useWhen": "Use input[ngsTimepicker] inside one ngs-form-field, connected to an ngs-timepicker instance, when a form needs a time of day: meeting time, event time, booking time, reminder time, deadline time, availability slot, report time filter, or schedule setting. Add ngs-timepicker-toggle as an icon suffix when users should open the dropdown explicitly. Use interval to control option steps such as 15, 30, or 60 minutes. Use min and max to limit selectable times. The input supports manual typing and localized display, while the model value can be a HH:mm-like string or a Date with the selected time merged into it. Combine Datepicker and Timepicker as separate controls when users need both date and time. Do not use Timepicker to choose a date; use Datepicker. Do not use it to choose a timezone; use TimezoneSelect. Do not use it for duration or numeric amounts of hours/minutes; use NumberInput or Slider. Do not use it for plain text without time validation; use ngsInput. Do not use it as a calendar, scheduler, or day-slot planner.",
9176
9190
  "exampleTopics": [
9177
9191
  "Basic time picker",
9178
9192
  "Integration with Datepicker",
@@ -9254,8 +9268,8 @@
9254
9268
  "sourceRoot": "projects/components/timezone-select/src",
9255
9269
  "docsPath": "/forms/timezone",
9256
9270
  "docsOverviewSource": "projects/docs/src/app/forms/timezone/overview/overview.html",
9257
- "purpose": "Let users choose a timezone.",
9258
- "useWhen": "Use in profile, scheduling, localization, and tenant settings.",
9271
+ "purpose": "Let users choose an IANA time zone id in a form field.",
9272
+ "useWhen": "Use ngs-timezone-select inside one ngs-form-field when a form must store a real time zone id such as Europe/Warsaw or America/New_York. Good for profile timezone, account preferences, organization or tenant default timezone, scheduling settings, calendar settings, report default timezone, localization preferences, and admin settings where backend data needs an IANA timezone string. The control is searchable, groups time zones by region, supports Angular forms, required, disabled, placeholder, locale-aware labels, opened, and closed. Do not use TimezoneSelect to choose a time of day; use Timepicker. Do not use it to choose a date; use Datepicker. Do not use it to choose a country or region; use CountrySelect. Do not use it for language or locale selection; use a dedicated locale/language control or Select. Do not use it for generic custom options; use Select. Do not use it for durations, numeric offsets, or timezone math; use NumberInput, Slider, or app logic. Do not use timezone as a date format setting; use DateFormatSelect for display formats.",
9259
9273
  "exampleTopics": [
9260
9274
  "Basic timezone select"
9261
9275
  ],
@@ -9306,8 +9320,8 @@
9306
9320
  "sourceRoot": "projects/components/toolbar/src",
9307
9321
  "docsPath": "/components/toolbar",
9308
9322
  "docsOverviewSource": "projects/docs/src/app/components/toolbar/overview/overview.html",
9309
- "purpose": "Group frequently used page, editor, or content actions.",
9310
- "useWhen": "Use above tables, editors, canvases, dashboards, and tool surfaces.",
9323
+ "purpose": "Provide a persistent command area for a page, panel, table, editor, canvas, or workspace surface.",
9324
+ "useWhen": "Use ngs-toolbar when a local surface needs a title, short local navigation, and frequently used actions in a stable horizontal or multi-row command area. Use ngs-toolbar-title for the local title, ngs-toolbar-spacer to separate groups, ngs-toolbar-row for multi-row command areas, ngs-toolbar-item for actions that should participate in responsive overflow, and ngs-toolbar-nav with ngs-toolbar-nav-link for short local links inside the toolbar. Good places include table headers, panel headers, admin page headers, editor surfaces, dashboards, canvas tools, and workspace tool surfaces. Do not use Toolbar as a generic flex layout for arbitrary content. Do not use it for floating contextual actions on selected rows or objects; use CommandBar. Do not use it for dropdown command lists; use Menu. Do not use it for primary application navigation; use Sidebar, Sidenav, or Navigation. Do not replace specialized TextEditor or CommentEditor toolbars with the generic Toolbar.",
9311
9325
  "exampleTopics": [
9312
9326
  "Basic Toolbar",
9313
9327
  "Multi-row Toolbar",
@@ -9394,8 +9408,8 @@
9394
9408
  "sourceRoot": "projects/components/tooltip/src",
9395
9409
  "docsPath": "/components/tooltip",
9396
9410
  "docsOverviewSource": "projects/docs/src/app/components/tooltip/overview/overview.html",
9397
- "purpose": "Show short contextual help on hover or focus.",
9398
- "useWhen": "Use for icon buttons, disabled explanations, abbreviations, and dense controls.",
9411
+ "purpose": "Show a short helper message for one interface element on hover, focus, or touch.",
9412
+ "useWhen": "Use ngsTooltip as a directive on a trigger element when a short non-interactive helper message should explain an icon button, abbreviation, disabled state, dense control, compact label, or unclear affordance. Configure ngsTooltipPosition, ngsTooltipShowDelay, ngsTooltipHideDelay, ngsTooltipOffset, ngsTooltipDisabled, ngsTooltipClass, or ngsTooltipPositionAtOrigin when placement and timing need tuning. Export the directive as ngsTooltip when app logic must call show(), hide(), or toggle(). Keep tooltip text short and plain. Do not use Tooltip for interactive content, forms, action lists, rich previews, or long explanations; use Popover. Do not use it for command menus; use Menu. Do not use it for visible page messages; use Alert, Announcement, ActionRequired, or Incidents based on scope. Do not use it for form helper or validation text; use FormField hint and error. Do not use it for onboarding flows; use GuidedTour.",
9399
9413
  "exampleTopics": [
9400
9414
  "Basic Tooltip",
9401
9415
  "Tooltip With a Custom Position",
@@ -9480,7 +9494,7 @@
9480
9494
  "docsPath": "/components/tree",
9481
9495
  "docsOverviewSource": "projects/docs/src/app/components/tree/overview/overview.html",
9482
9496
  "purpose": "Display hierarchical data with expandable parent and child nodes.",
9483
- "useWhen": "Use for folders, permissions, categories, org charts, and nested navigation.",
9497
+ "useWhen": "Use ngs-tree when users need to inspect or navigate hierarchical data where parent and child levels matter: folders and files, categories, permissions, taxonomies, organization structures, nested settings, product/entity hierarchies, and other expandable trees. Use dataSource with childrenAccessor for nested/static data, or treeControl with a custom DataSource for flat trees and dynamic loading. Define node templates with *ngsTreeNodeDef and use when for different node types. Use ngsTreeNodePadding for indentation and ngsTreeNodeToggle for expand/collapse controls. Use ProgressBar or Skeleton inside node templates when children load on demand. Do not use Tree for a simple vertical collection; use List. Do not use it for primary application navigation; use Sidebar, Sidenav, Navigation, or RailNav. Do not use it for FAQ or settings sections; use ExpansionPanel. Do not use it for dense row data with columns, sorting, filters, or bulk actions; use Table or DataView. Do not use it for step-by-step workflows; use Stepper.",
9484
9498
  "exampleTopics": [
9485
9499
  "Basic tree",
9486
9500
  "Tree with dynamic data"
@@ -9556,8 +9570,8 @@
9556
9570
  "sourceRoot": "projects/components/upload/src",
9557
9571
  "docsPath": "/components/upload",
9558
9572
  "docsOverviewSource": "projects/docs/src/app/components/upload/overview/overview.html",
9559
- "purpose": "Let users select, preview, and upload files.",
9560
- "useWhen": "Use for attachments, documents, media, imports, and profile assets.",
9573
+ "purpose": "Provide UI for selecting files, drag-and-drop upload areas, and file progress displays.",
9574
+ "useWhen": "Use Upload components when users need to choose local files, drop files into an upload area, or see selected/uploading files with progress, errors, retry, remove, or cancel actions. Use ngsUploadTrigger on a button or clickable element to open the native file picker. Use ngs-upload-area for drag-and-drop with ngsUploadAreaMainState, ngsUploadAreaDropState, ngsUploadAreaInvalidState, and ngsUploadAreaIcon. Use accept and multiple to control allowed file types and multi-select. Use ngs-upload-container with ngs-upload-allowed-types and ngs-upload-max-file-size for upload hints. Use ngs-file-list with ngs-file for vertical file rows, or ngs-files-grid with ngs-grid-file for compact file cards. Use ngs-file-control and ngsGridFileControl for file-level actions. The component emits fileSelected with the selected File objects; the application must perform validation, backend upload, retry, deletion, persistence, and security checks. Do not treat Upload as a backend uploader, storage manager, or import wizard by itself. Do not use it for editing selected images; use Crop, ImageResizer, ThumbnailMaker, or ImageDesigner after selection. Do not use it for rich editor image upload flows; use the TextEditor or CommentEditor upload APIs. Do not use it to manage an existing document table with sorting and filtering; use Table or DataView.",
9561
9575
  "exampleTopics": [
9562
9576
  "Basic Upload",
9563
9577
  "Upload area",
@@ -9705,9 +9719,11 @@
9705
9719
  "sourceRoot": "projects/components/video-player/src",
9706
9720
  "docsPath": "/libraries/video-player",
9707
9721
  "docsOverviewSource": "projects/docs/src/app/libraries/video-player/overview/overview.html",
9708
- "purpose": "Play video content with application-level controls.",
9709
- "useWhen": "Use for media libraries, lessons, previews, and product content.",
9710
- "exampleTopics": [],
9722
+ "purpose": "Play video inline inside the current page, card, carousel, media preview, lesson, or workspace layout.",
9723
+ "useWhen": "Use ngs-video-player when video should stay embedded in the current layout with NgStarter-controlled playback UI. Pass src for the video source, optional thumbnailUrl for the poster preview, and orientation or payload.orientation for landscape, portrait, or square aspect ratio. Configure autoPlay, muted, disableClickToPlay, withCredentials, showPlayButton, showSpeaker, showFullscreen, and showDurationSlider to match the surface. Listen to play, pause, ended, loaded, and error for application state. Good for media previews, lessons, product videos, content previews, cards, carousel slides, and dashboard/workspace media blocks. The player wraps video.js and supports HLS m3u8 sources through video.js. Do not use VideoPlayer when the video should open as a focused overlay or lightbox; use VideoViewer. Do not use it as a gallery or list by itself; compose it with Carousel, Card, Grid, VideoViewer, or a layout component. Do not use it for YouTube, Vimeo, or other iframe-provider embeds when the provider player is required. Do not use it as a content editing API directly; use the ContentEditor video block for editable content.",
9724
+ "exampleTopics": [
9725
+ "Video Player"
9726
+ ],
9711
9727
  "minimalExample": null,
9712
9728
  "exampleFiles": [],
9713
9729
  "previewAsset": "projects/components/video-player/preview.svg",
@@ -9755,8 +9771,8 @@
9755
9771
  "sourceRoot": "projects/components/video-viewer/src",
9756
9772
  "docsPath": "/components/video-viewer",
9757
9773
  "docsOverviewSource": "projects/docs/src/app/components/video-viewer/overview/overview.html",
9758
- "purpose": "Display videos in a focused viewer experience.",
9759
- "useWhen": "Use for video attachments, previews, galleries, and media detail pages.",
9774
+ "purpose": "Open videos in a focused overlay or lightbox above the current page.",
9775
+ "useWhen": "Use VideoViewer when a thumbnail, preview card, compact inline player, attachment, gallery item, or media library item should open a larger focused video viewing experience. Put ngsVideoViewer on the preview container and ngsVideoViewerVideo on each clickable preview item. Pass sourceUrl for the video source, plus optional title, caption, description, or template directives ngsVideoViewerVideoTitle, ngsVideoViewerVideoCaption, and ngsVideoViewerVideoDescription. Configure orientation, payload, autoPlay, muted, showPlayButton, showSpeaker, showFullscreen, and showDurationSlider to control the underlying VideoPlayer in the overlay. Good for video attachments, media previews, galleries, lessons, product videos, and media detail flows. Do not use VideoViewer when video should stay inline in the current layout; use VideoPlayer. Do not use it as a carousel, grid, or gallery layout by itself; compose previews with Card, Grid, Carousel, or another layout. Do not use it as a generic modal or form dialog; use Dialog or Drawer. Do not use it for YouTube, Vimeo, or iframe-provider embeds when the provider player is required.",
9760
9776
  "exampleTopics": [
9761
9777
  "Basic Video Viewer"
9762
9778
  ],
@@ -9834,9 +9850,11 @@
9834
9850
  "sourceRoot": "projects/components/visual-builder/src",
9835
9851
  "docsPath": "/libraries/visual-builder",
9836
9852
  "docsOverviewSource": "projects/docs/src/app/libraries/visual-builder/overview/overview.html",
9837
- "purpose": "Provide a visual composition or builder workspace.",
9838
- "useWhen": "Use for no-code/low-code editing, layouts, templates, and visual design workflows.",
9839
- "exampleTopics": [],
9853
+ "purpose": "Experimental scaffold for a future no-code or low-code visual workspace.",
9854
+ "useWhen": "Do not use ngs-visual-builder for production admin screens, dashboards, visual editors, page builders, or real no-code/low-code workflows yet. The current component is only a placeholder: it has no inputs, outputs, layout regions, canvas, drag and drop, inspector, persistence, or editable block model. Mention it only as an experimental scaffold for future visual builder work. Use ContentEditor for block-based CMS/page content, ImageDesigner for creative image composition, Tiles for editable dashboard widgets or config-driven dashboard renderers, Grid for static dashboard layouts, FormRenderer for backend-driven forms, KanbanBoard for workflow columns, and normal NgStarter layout/components for admin screens.",
9855
+ "exampleTopics": [
9856
+ "Visual Builder"
9857
+ ],
9840
9858
  "minimalExample": null,
9841
9859
  "exampleFiles": [],
9842
9860
  "previewAsset": "projects/components/visual-builder/preview.svg",
@@ -41,13 +41,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImpor
41
41
 
42
42
  class CardHeader {
43
43
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: CardHeader, deps: [], target: i0.ɵɵFactoryTarget.Component });
44
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.4", type: CardHeader, isStandalone: true, selector: "ngs-card-header", host: { classAttribute: "ngs-card-header" }, ngImport: i0, template: "<div class=\"flex items-center gap-3\">\n <ng-content select=\"ngs-card-avatar, [ngs-card-avatar], [ngsCardAvatar]\"/>\n <div class=\"ngs-card-header-text\">\n <div>\n <ng-content select=\"ngs-card-title, [ngs-card-title], [ngsCardTitle]\"/>\n <ng-content select=\"ngs-card-subtitle, [ngs-card-subtitle], [ngsCardSubtitle]\"/>\n </div>\n <ng-content/>\n </div>\n</div>\n<div class=\"aside\">\n <ng-content select=\"ngs-card-aside, [ngs-card-aside], [ngsCardAside]\"/>\n</div>\n", styles: [":host{display:flex;flex-direction:row;align-items:center;justify-content:space-between;padding:var(--ngs-card-padding, calc(var(--spacing, .25rem) * 3));gap:calc(var(--spacing, .25rem) * 3);flex:none}:host .aside:empty{display:none}:host .aside{flex:none}\n/*! tailwindcss v4.2.2 | MIT License | https://tailwindcss.com */\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
44
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.4", type: CardHeader, isStandalone: true, selector: "ngs-card-header", host: { classAttribute: "ngs-card-header" }, ngImport: i0, template: "<div class=\"flex h-full items-center gap-3\">\n <ng-content select=\"ngs-card-avatar, [ngs-card-avatar], [ngsCardAvatar]\"/>\n <div class=\"ngs-card-header-text\">\n <div>\n <ng-content select=\"ngs-card-title, [ngs-card-title], [ngsCardTitle]\"/>\n <ng-content select=\"ngs-card-subtitle, [ngs-card-subtitle], [ngsCardSubtitle]\"/>\n </div>\n <ng-content/>\n </div>\n</div>\n<div class=\"aside\">\n <ng-content select=\"ngs-card-aside, [ngs-card-aside], [ngsCardAside]\"/>\n</div>\n", styles: [":host{display:flex;flex-direction:row;align-items:center;justify-content:space-between;padding:var(--ngs-card-padding, calc(var(--spacing, .25rem) * 3));gap:calc(var(--spacing, .25rem) * 3);flex:none}:host .aside:empty{display:none}:host .aside{flex:none}\n/*! tailwindcss v4.2.2 | MIT License | https://tailwindcss.com */\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
45
45
  }
46
46
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: CardHeader, decorators: [{
47
47
  type: Component,
48
48
  args: [{ selector: 'ngs-card-header', standalone: true, imports: [], changeDetection: ChangeDetectionStrategy.OnPush, host: {
49
49
  'class': 'ngs-card-header'
50
- }, template: "<div class=\"flex items-center gap-3\">\n <ng-content select=\"ngs-card-avatar, [ngs-card-avatar], [ngsCardAvatar]\"/>\n <div class=\"ngs-card-header-text\">\n <div>\n <ng-content select=\"ngs-card-title, [ngs-card-title], [ngsCardTitle]\"/>\n <ng-content select=\"ngs-card-subtitle, [ngs-card-subtitle], [ngsCardSubtitle]\"/>\n </div>\n <ng-content/>\n </div>\n</div>\n<div class=\"aside\">\n <ng-content select=\"ngs-card-aside, [ngs-card-aside], [ngsCardAside]\"/>\n</div>\n", styles: [":host{display:flex;flex-direction:row;align-items:center;justify-content:space-between;padding:var(--ngs-card-padding, calc(var(--spacing, .25rem) * 3));gap:calc(var(--spacing, .25rem) * 3);flex:none}:host .aside:empty{display:none}:host .aside{flex:none}\n/*! tailwindcss v4.2.2 | MIT License | https://tailwindcss.com */\n"] }]
50
+ }, template: "<div class=\"flex h-full items-center gap-3\">\n <ng-content select=\"ngs-card-avatar, [ngs-card-avatar], [ngsCardAvatar]\"/>\n <div class=\"ngs-card-header-text\">\n <div>\n <ng-content select=\"ngs-card-title, [ngs-card-title], [ngsCardTitle]\"/>\n <ng-content select=\"ngs-card-subtitle, [ngs-card-subtitle], [ngsCardSubtitle]\"/>\n </div>\n <ng-content/>\n </div>\n</div>\n<div class=\"aside\">\n <ng-content select=\"ngs-card-aside, [ngs-card-aside], [ngsCardAside]\"/>\n</div>\n", styles: [":host{display:flex;flex-direction:row;align-items:center;justify-content:space-between;padding:var(--ngs-card-padding, calc(var(--spacing, .25rem) * 3));gap:calc(var(--spacing, .25rem) * 3);flex:none}:host .aside:empty{display:none}:host .aside{flex:none}\n/*! tailwindcss v4.2.2 | MIT License | https://tailwindcss.com */\n"] }]
51
51
  }] });
52
52
 
53
53
  class CardTitle {
@@ -1 +1 @@
1
- {"version":3,"file":"ngstarter-ui-components-card.mjs","sources":["../../../projects/components/card/src/card-footer/card-footer.ts","../../../projects/components/card/src/card-footer/card-footer.html","../../../projects/components/card/src/config.ts","../../../projects/components/card/src/card/card.ts","../../../projects/components/card/src/card/card.html","../../../projects/components/card/src/card-header/card-header.ts","../../../projects/components/card/src/card-header/card-header.html","../../../projects/components/card/src/card-title/card-title.ts","../../../projects/components/card/src/card-title/card-title.html","../../../projects/components/card/src/card-subtitle/card-subtitle.ts","../../../projects/components/card/src/card-subtitle/card-subtitle.html","../../../projects/components/card/src/card-content/card-content.ts","../../../projects/components/card/src/card-content/card-content.html","../../../projects/components/card/src/card-actions/card-actions.ts","../../../projects/components/card/src/card-actions/card-actions.html","../../../projects/components/card/src/card-aside/card-aside.ts","../../../projects/components/card/src/card-aside/card-aside.html","../../../projects/components/card/src/card-image/card-image.ts","../../../projects/components/card/src/card-image/card-image.html","../../../projects/components/card/src/card-avatar/card-avatar.ts","../../../projects/components/card/ngstarter-ui-components-card.ts"],"sourcesContent":["import { Component, ChangeDetectionStrategy } from '@angular/core';\n\n@Component({\n selector: 'ngs-card-footer, [ngs-card-footer], [ngsCardFooter]',\n templateUrl: './card-footer.html',\n styleUrl: './card-footer.scss',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n 'class': 'ngs-card-footer'\n }\n})\nexport class CardFooter {}\n","<ng-content />\n","import { InjectionToken, makeEnvironmentProviders, EnvironmentProviders } from '@angular/core';\n\nexport type CardAppearance = 'raised' | 'outlined' | 'filled';\n\nexport interface CardConfig {\n appearance?: CardAppearance;\n}\n\nexport const CARD_CONFIG = new InjectionToken<CardConfig>('CARD_CONFIG');\n\nexport function provideCard(config: CardConfig): EnvironmentProviders {\n return makeEnvironmentProviders([\n { provide: CARD_CONFIG, useValue: config }\n ]);\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n inject,\n input,\n contentChild,\n} from '@angular/core';\nimport { CardFooter } from '../card-footer/card-footer';\nimport { CARD_CONFIG, CardAppearance } from '../config';\n\n@Component({\n selector: 'ngs-card',\n exportAs: 'ngsCard',\n templateUrl: './card.html',\n styleUrl: './card.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n 'class': 'ngs-card not-prose',\n '[class.ngs-card-outlined]': 'appearance() === \"outlined\"',\n '[class.ngs-card-filled]': 'appearance() === \"filled\"',\n '[class.ngs-card-raised]': 'appearance() === \"raised\"',\n },\n})\nexport class Card {\n private _config = inject(CARD_CONFIG, { optional: true });\n\n appearance = input<CardAppearance>(this._config?.appearance || 'outlined');\n\n readonly _footer = contentChild(CardFooter);\n\n get hasFooter(): boolean {\n return !!this._footer();\n }\n}\n","<ng-content/>\n@if (hasFooter) {\n <ng-content select=\"ngs-card-footer\"/>\n}\n","import { ChangeDetectionStrategy, Component } from '@angular/core';\n\n@Component({\n selector: 'ngs-card-header',\n standalone: true,\n imports: [\n ],\n templateUrl: './card-header.html',\n styleUrl: './card-header.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n 'class': 'ngs-card-header'\n }\n})\nexport class CardHeader {}\n","<div class=\"flex items-center gap-3\">\n <ng-content select=\"ngs-card-avatar, [ngs-card-avatar], [ngsCardAvatar]\"/>\n <div class=\"ngs-card-header-text\">\n <div>\n <ng-content select=\"ngs-card-title, [ngs-card-title], [ngsCardTitle]\"/>\n <ng-content select=\"ngs-card-subtitle, [ngs-card-subtitle], [ngsCardSubtitle]\"/>\n </div>\n <ng-content/>\n </div>\n</div>\n<div class=\"aside\">\n <ng-content select=\"ngs-card-aside, [ngs-card-aside], [ngsCardAside]\"/>\n</div>\n","import { ChangeDetectionStrategy, Component } from '@angular/core';\n\n@Component({\n selector: 'ngs-card-title, [ngs-card-title], [ngsCardTitle]',\n exportAs: 'ngsCardTitle',\n standalone: true,\n templateUrl: './card-title.html',\n styleUrls: ['./card-title.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n 'class': 'ngs-card-title'\n }\n})\nexport class CardTitle {}\n","<ng-content />\n","import { ChangeDetectionStrategy, Component } from '@angular/core';\n\n@Component({\n selector: 'ngs-card-subtitle, [ngs-card-subtitle], [ngsCardSubtitle]',\n exportAs: 'ngsCardSubtitle',\n standalone: true,\n templateUrl: './card-subtitle.html',\n styleUrl: './card-subtitle.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n 'class': 'ngs-card-subtitle'\n }\n})\nexport class CardSubtitle {}\n","<ng-content />\n","import { booleanAttribute, ChangeDetectionStrategy, Component, input } from '@angular/core';\n\n@Component({\n selector: 'ngs-card-content, [ngs-card-content], [ngsCardContent]',\n exportAs: 'ngsCardContent',\n standalone: true,\n templateUrl: './card-content.html',\n styleUrls: ['./card-content.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n 'class': 'ngs-card-content',\n '[class.without-padding]': 'withoutPadding()',\n }\n})\nexport class CardContent {\n withoutPadding = input(false, {\n transform: booleanAttribute\n })\n}\n","<ng-content />\n","import { ChangeDetectionStrategy, Component, input } from '@angular/core';\n\nexport type CardActionsPosition = 'start' | 'center' | 'end' | 'between';\n\n@Component({\n selector: 'ngs-card-actions, [ngs-card-actions], [ngsCardActions]',\n standalone: true,\n templateUrl: './card-actions.html',\n styleUrl: './card-actions.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n 'class': 'ngs-card-actions',\n '[class.ngs-card-actions-align-end]': 'align() === \"end\"',\n '[class.ngs-card-actions-align-center]': 'align() === \"center\"',\n '[class.ngs-card-actions-align-between]': 'align() === \"between\"',\n }\n})\nexport class CardActions {\n align = input<CardActionsPosition>('start');\n}\n","<ng-content/>\n","import { Component } from '@angular/core';\n\n@Component({\n selector: 'ngs-card-aside, [ngs-card-aside], ngsCardAside',\n imports: [],\n templateUrl: './card-aside.html',\n styleUrl: './card-aside.scss',\n})\nexport class CardAside {\n\n}\n","<ng-content/>\n","import { ChangeDetectionStrategy, Component, Directive } from '@angular/core';\n\n@Component({\n selector: 'ngs-card-image, [ngs-card-image], [ngsCardImage]',\n standalone: true,\n templateUrl: './card-image.html',\n styleUrl: './card-image.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n 'class': 'ngs-card-image'\n }\n})\nexport class CardImage {}\n\n@Directive({\n selector: '[ngs-card-sm-image], [ngsCardImageSmall]',\n standalone: true,\n host: {\n 'class': 'ngs-card-image ngs-card-sm-image'\n }\n})\nexport class CardImageSmall {}\n\n@Directive({\n selector: '[ngs-card-md-image], [ngsCardImageMedium]',\n standalone: true,\n host: {\n 'class': 'ngs-card-image ngs-card-md-image'\n }\n})\nexport class CardImageMedium {}\n\n@Directive({\n selector: '[ngs-card-lg-image], [ngsCardImageLarge]',\n standalone: true,\n host: {\n 'class': 'ngs-card-image ngs-card-lg-image'\n }\n})\nexport class CardImageLarge {}\n\n@Directive({\n selector: '[ngs-card-xl-image], [ngsCardImageXLarge]',\n standalone: true,\n host: {\n 'class': 'ngs-card-image ngs-card-xl-image'\n }\n})\nexport class CardImageXLarge {}\n","<ng-content />\n","import { Directive } from '@angular/core';\n\n@Directive({\n selector: 'ngs-card-avatar, [ngs-card-avatar], [ngsCardAvatar]',\n standalone: true,\n host: {\n 'class': 'ngs-card-avatar'\n },\n})\nexport class CardAvatar {}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ngstarter-ui-components-card.mjs","sources":["../../../projects/components/card/src/card-footer/card-footer.ts","../../../projects/components/card/src/card-footer/card-footer.html","../../../projects/components/card/src/config.ts","../../../projects/components/card/src/card/card.ts","../../../projects/components/card/src/card/card.html","../../../projects/components/card/src/card-header/card-header.ts","../../../projects/components/card/src/card-header/card-header.html","../../../projects/components/card/src/card-title/card-title.ts","../../../projects/components/card/src/card-title/card-title.html","../../../projects/components/card/src/card-subtitle/card-subtitle.ts","../../../projects/components/card/src/card-subtitle/card-subtitle.html","../../../projects/components/card/src/card-content/card-content.ts","../../../projects/components/card/src/card-content/card-content.html","../../../projects/components/card/src/card-actions/card-actions.ts","../../../projects/components/card/src/card-actions/card-actions.html","../../../projects/components/card/src/card-aside/card-aside.ts","../../../projects/components/card/src/card-aside/card-aside.html","../../../projects/components/card/src/card-image/card-image.ts","../../../projects/components/card/src/card-image/card-image.html","../../../projects/components/card/src/card-avatar/card-avatar.ts","../../../projects/components/card/ngstarter-ui-components-card.ts"],"sourcesContent":["import { Component, ChangeDetectionStrategy } from '@angular/core';\n\n@Component({\n selector: 'ngs-card-footer, [ngs-card-footer], [ngsCardFooter]',\n templateUrl: './card-footer.html',\n styleUrl: './card-footer.scss',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n 'class': 'ngs-card-footer'\n }\n})\nexport class CardFooter {}\n","<ng-content />\n","import { InjectionToken, makeEnvironmentProviders, EnvironmentProviders } from '@angular/core';\n\nexport type CardAppearance = 'raised' | 'outlined' | 'filled';\n\nexport interface CardConfig {\n appearance?: CardAppearance;\n}\n\nexport const CARD_CONFIG = new InjectionToken<CardConfig>('CARD_CONFIG');\n\nexport function provideCard(config: CardConfig): EnvironmentProviders {\n return makeEnvironmentProviders([\n { provide: CARD_CONFIG, useValue: config }\n ]);\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n inject,\n input,\n contentChild,\n} from '@angular/core';\nimport { CardFooter } from '../card-footer/card-footer';\nimport { CARD_CONFIG, CardAppearance } from '../config';\n\n@Component({\n selector: 'ngs-card',\n exportAs: 'ngsCard',\n templateUrl: './card.html',\n styleUrl: './card.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n 'class': 'ngs-card not-prose',\n '[class.ngs-card-outlined]': 'appearance() === \"outlined\"',\n '[class.ngs-card-filled]': 'appearance() === \"filled\"',\n '[class.ngs-card-raised]': 'appearance() === \"raised\"',\n },\n})\nexport class Card {\n private _config = inject(CARD_CONFIG, { optional: true });\n\n appearance = input<CardAppearance>(this._config?.appearance || 'outlined');\n\n readonly _footer = contentChild(CardFooter);\n\n get hasFooter(): boolean {\n return !!this._footer();\n }\n}\n","<ng-content/>\n@if (hasFooter) {\n <ng-content select=\"ngs-card-footer\"/>\n}\n","import { ChangeDetectionStrategy, Component } from '@angular/core';\n\n@Component({\n selector: 'ngs-card-header',\n standalone: true,\n imports: [\n ],\n templateUrl: './card-header.html',\n styleUrl: './card-header.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n 'class': 'ngs-card-header'\n }\n})\nexport class CardHeader {}\n","<div class=\"flex h-full items-center gap-3\">\n <ng-content select=\"ngs-card-avatar, [ngs-card-avatar], [ngsCardAvatar]\"/>\n <div class=\"ngs-card-header-text\">\n <div>\n <ng-content select=\"ngs-card-title, [ngs-card-title], [ngsCardTitle]\"/>\n <ng-content select=\"ngs-card-subtitle, [ngs-card-subtitle], [ngsCardSubtitle]\"/>\n </div>\n <ng-content/>\n </div>\n</div>\n<div class=\"aside\">\n <ng-content select=\"ngs-card-aside, [ngs-card-aside], [ngsCardAside]\"/>\n</div>\n","import { ChangeDetectionStrategy, Component } from '@angular/core';\n\n@Component({\n selector: 'ngs-card-title, [ngs-card-title], [ngsCardTitle]',\n exportAs: 'ngsCardTitle',\n standalone: true,\n templateUrl: './card-title.html',\n styleUrls: ['./card-title.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n 'class': 'ngs-card-title'\n }\n})\nexport class CardTitle {}\n","<ng-content />\n","import { ChangeDetectionStrategy, Component } from '@angular/core';\n\n@Component({\n selector: 'ngs-card-subtitle, [ngs-card-subtitle], [ngsCardSubtitle]',\n exportAs: 'ngsCardSubtitle',\n standalone: true,\n templateUrl: './card-subtitle.html',\n styleUrl: './card-subtitle.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n 'class': 'ngs-card-subtitle'\n }\n})\nexport class CardSubtitle {}\n","<ng-content />\n","import { booleanAttribute, ChangeDetectionStrategy, Component, input } from '@angular/core';\n\n@Component({\n selector: 'ngs-card-content, [ngs-card-content], [ngsCardContent]',\n exportAs: 'ngsCardContent',\n standalone: true,\n templateUrl: './card-content.html',\n styleUrls: ['./card-content.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n 'class': 'ngs-card-content',\n '[class.without-padding]': 'withoutPadding()',\n }\n})\nexport class CardContent {\n withoutPadding = input(false, {\n transform: booleanAttribute\n })\n}\n","<ng-content />\n","import { ChangeDetectionStrategy, Component, input } from '@angular/core';\n\nexport type CardActionsPosition = 'start' | 'center' | 'end' | 'between';\n\n@Component({\n selector: 'ngs-card-actions, [ngs-card-actions], [ngsCardActions]',\n standalone: true,\n templateUrl: './card-actions.html',\n styleUrl: './card-actions.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n 'class': 'ngs-card-actions',\n '[class.ngs-card-actions-align-end]': 'align() === \"end\"',\n '[class.ngs-card-actions-align-center]': 'align() === \"center\"',\n '[class.ngs-card-actions-align-between]': 'align() === \"between\"',\n }\n})\nexport class CardActions {\n align = input<CardActionsPosition>('start');\n}\n","<ng-content/>\n","import { Component } from '@angular/core';\n\n@Component({\n selector: 'ngs-card-aside, [ngs-card-aside], ngsCardAside',\n imports: [],\n templateUrl: './card-aside.html',\n styleUrl: './card-aside.scss',\n})\nexport class CardAside {\n\n}\n","<ng-content/>\n","import { ChangeDetectionStrategy, Component, Directive } from '@angular/core';\n\n@Component({\n selector: 'ngs-card-image, [ngs-card-image], [ngsCardImage]',\n standalone: true,\n templateUrl: './card-image.html',\n styleUrl: './card-image.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n 'class': 'ngs-card-image'\n }\n})\nexport class CardImage {}\n\n@Directive({\n selector: '[ngs-card-sm-image], [ngsCardImageSmall]',\n standalone: true,\n host: {\n 'class': 'ngs-card-image ngs-card-sm-image'\n }\n})\nexport class CardImageSmall {}\n\n@Directive({\n selector: '[ngs-card-md-image], [ngsCardImageMedium]',\n standalone: true,\n host: {\n 'class': 'ngs-card-image ngs-card-md-image'\n }\n})\nexport class CardImageMedium {}\n\n@Directive({\n selector: '[ngs-card-lg-image], [ngsCardImageLarge]',\n standalone: true,\n host: {\n 'class': 'ngs-card-image ngs-card-lg-image'\n }\n})\nexport class CardImageLarge {}\n\n@Directive({\n selector: '[ngs-card-xl-image], [ngsCardImageXLarge]',\n standalone: true,\n host: {\n 'class': 'ngs-card-image ngs-card-xl-image'\n }\n})\nexport class CardImageXLarge {}\n","<ng-content />\n","import { Directive } from '@angular/core';\n\n@Directive({\n selector: 'ngs-card-avatar, [ngs-card-avatar], [ngsCardAvatar]',\n standalone: true,\n host: {\n 'class': 'ngs-card-avatar'\n },\n})\nexport class CardAvatar {}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
@@ -1,11 +1,48 @@
1
+ const onlyDigits = (value) => {
2
+ return String(value ?? '').replace(/\D/g, '');
3
+ };
4
+ const isValidLuhn = (value) => {
5
+ let sum = 0;
6
+ let shouldDouble = false;
7
+ for (let i = value.length - 1; i >= 0; i--) {
8
+ let digit = Number(value[i]);
9
+ if (shouldDouble) {
10
+ digit *= 2;
11
+ if (digit > 9) {
12
+ digit -= 9;
13
+ }
14
+ }
15
+ sum += digit;
16
+ shouldDouble = !shouldDouble;
17
+ }
18
+ return sum % 10 === 0;
19
+ };
20
+ function creditCardNumberValidator() {
21
+ return (control) => {
22
+ const value = onlyDigits(control.value);
23
+ if (!value) {
24
+ return null;
25
+ }
26
+ if (value.length < 12 || value.length > 19 || !isValidLuhn(value)) {
27
+ return { creditCardNumberInvalid: true };
28
+ }
29
+ return null;
30
+ };
31
+ }
1
32
  function expiryDateValidator() {
2
33
  return (control) => {
3
- const value = control.value;
4
- if (!value || value.length !== 4) {
34
+ const value = onlyDigits(control.value);
35
+ if (!value) {
5
36
  return null;
6
37
  }
38
+ if (value.length !== 4) {
39
+ return { expiryDateInvalid: true };
40
+ }
7
41
  const month = parseInt(value.substring(0, 2), 10);
8
42
  const year = parseInt(value.substring(2, 4), 10);
43
+ if (month < 1 || month > 12) {
44
+ return { expiryDateInvalid: true };
45
+ }
9
46
  const currentDate = new Date();
10
47
  const currentMonth = currentDate.getMonth() + 1;
11
48
  const currentYear = parseInt(currentDate.getFullYear().toString().substring(2, 4));
@@ -15,10 +52,29 @@ function expiryDateValidator() {
15
52
  return null;
16
53
  };
17
54
  }
55
+ function creditCardCvvValidator(options = {}) {
56
+ const minLength = options.minLength ?? 3;
57
+ const maxLength = options.maxLength ?? 4;
58
+ return (control) => {
59
+ const value = onlyDigits(control.value);
60
+ if (!value) {
61
+ return null;
62
+ }
63
+ if (value.length < minLength || value.length > maxLength) {
64
+ return {
65
+ creditCardCvvInvalid: {
66
+ minLength,
67
+ maxLength,
68
+ },
69
+ };
70
+ }
71
+ return null;
72
+ };
73
+ }
18
74
 
19
75
  /**
20
76
  * Generated bundle index. Do not edit.
21
77
  */
22
78
 
23
- export { expiryDateValidator };
79
+ export { creditCardCvvValidator, creditCardNumberValidator, expiryDateValidator };
24
80
  //# sourceMappingURL=ngstarter-ui-components-input-validator.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"ngstarter-ui-components-input-validator.mjs","sources":["../../../projects/components/input-validator/src/expiry-date-validator.ts","../../../projects/components/input-validator/ngstarter-ui-components-input-validator.ts"],"sourcesContent":["import { AbstractControl, ValidationErrors, ValidatorFn } from '@angular/forms';\n\nexport function expiryDateValidator(): ValidatorFn {\n return (control: AbstractControl): ValidationErrors | null => {\n const value = control.value as string;\n\n if (!value || value.length !== 4) {\n return null;\n }\n\n const month = parseInt(value.substring(0, 2), 10);\n const year = parseInt(value.substring(2, 4), 10);\n const currentDate = new Date();\n const currentMonth = currentDate.getMonth() + 1;\n const currentYear = parseInt(currentDate.getFullYear().toString().substring(2, 4));\n\n if (year < currentYear || (year === currentYear && month < currentMonth)) {\n return { expiryDateInPast: true };\n }\n\n return null;\n };\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"SAEgB,mBAAmB,GAAA;IACjC,OAAO,CAAC,OAAwB,KAA6B;AAC3D,QAAA,MAAM,KAAK,GAAG,OAAO,CAAC,KAAe;QAErC,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE;AAChC,YAAA,OAAO,IAAI;QACb;AAEA,QAAA,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC;AACjD,QAAA,MAAM,IAAI,GAAG,QAAQ,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC;AAChD,QAAA,MAAM,WAAW,GAAG,IAAI,IAAI,EAAE;QAC9B,MAAM,YAAY,GAAG,WAAW,CAAC,QAAQ,EAAE,GAAG,CAAC;AAC/C,QAAA,MAAM,WAAW,GAAG,QAAQ,CAAC,WAAW,CAAC,WAAW,EAAE,CAAC,QAAQ,EAAE,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AAElF,QAAA,IAAI,IAAI,GAAG,WAAW,KAAK,IAAI,KAAK,WAAW,IAAI,KAAK,GAAG,YAAY,CAAC,EAAE;AACxE,YAAA,OAAO,EAAE,gBAAgB,EAAE,IAAI,EAAE;QACnC;AAEA,QAAA,OAAO,IAAI;AACb,IAAA,CAAC;AACH;;ACtBA;;AAEG;;;;"}
1
+ {"version":3,"file":"ngstarter-ui-components-input-validator.mjs","sources":["../../../projects/components/input-validator/src/expiry-date-validator.ts","../../../projects/components/input-validator/ngstarter-ui-components-input-validator.ts"],"sourcesContent":["import { AbstractControl, ValidationErrors, ValidatorFn } from '@angular/forms';\n\nconst onlyDigits = (value: unknown): string => {\n return String(value ?? '').replace(/\\D/g, '');\n};\n\nconst isValidLuhn = (value: string): boolean => {\n let sum = 0;\n let shouldDouble = false;\n\n for (let i = value.length - 1; i >= 0; i--) {\n let digit = Number(value[i]);\n\n if (shouldDouble) {\n digit *= 2;\n if (digit > 9) {\n digit -= 9;\n }\n }\n\n sum += digit;\n shouldDouble = !shouldDouble;\n }\n\n return sum % 10 === 0;\n};\n\nexport function creditCardNumberValidator(): ValidatorFn {\n return (control: AbstractControl): ValidationErrors | null => {\n const value = onlyDigits(control.value);\n\n if (!value) {\n return null;\n }\n\n if (value.length < 12 || value.length > 19 || !isValidLuhn(value)) {\n return { creditCardNumberInvalid: true };\n }\n\n return null;\n };\n}\n\nexport function expiryDateValidator(): ValidatorFn {\n return (control: AbstractControl): ValidationErrors | null => {\n const value = onlyDigits(control.value);\n\n if (!value) {\n return null;\n }\n\n if (value.length !== 4) {\n return { expiryDateInvalid: true };\n }\n\n const month = parseInt(value.substring(0, 2), 10);\n const year = parseInt(value.substring(2, 4), 10);\n\n if (month < 1 || month > 12) {\n return { expiryDateInvalid: true };\n }\n\n const currentDate = new Date();\n const currentMonth = currentDate.getMonth() + 1;\n const currentYear = parseInt(currentDate.getFullYear().toString().substring(2, 4));\n\n if (year < currentYear || (year === currentYear && month < currentMonth)) {\n return { expiryDateInPast: true };\n }\n\n return null;\n };\n}\n\nexport interface CreditCardCvvValidatorOptions {\n minLength?: number;\n maxLength?: number;\n}\n\nexport function creditCardCvvValidator(options: CreditCardCvvValidatorOptions = {}): ValidatorFn {\n const minLength = options.minLength ?? 3;\n const maxLength = options.maxLength ?? 4;\n\n return (control: AbstractControl): ValidationErrors | null => {\n const value = onlyDigits(control.value);\n\n if (!value) {\n return null;\n }\n\n if (value.length < minLength || value.length > maxLength) {\n return {\n creditCardCvvInvalid: {\n minLength,\n maxLength,\n },\n };\n }\n\n return null;\n };\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@ngstarter-ui/components",
3
3
  "description": "NgStarter - AI-friendly Enterprise Angular UI Components and Admin Panel",
4
- "version": "1.0.34",
4
+ "version": "1.0.36",
5
5
  "repository": {
6
6
  "type": "git",
7
7
  "url": "https://github.com/elementarlabsdev/ngstarter.git"
@@ -1,5 +1,12 @@
1
1
  import { ValidatorFn } from '@angular/forms';
2
2
 
3
+ declare function creditCardNumberValidator(): ValidatorFn;
3
4
  declare function expiryDateValidator(): ValidatorFn;
5
+ interface CreditCardCvvValidatorOptions {
6
+ minLength?: number;
7
+ maxLength?: number;
8
+ }
9
+ declare function creditCardCvvValidator(options?: CreditCardCvvValidatorOptions): ValidatorFn;
4
10
 
5
- export { expiryDateValidator };
11
+ export { creditCardCvvValidator, creditCardNumberValidator, expiryDateValidator };
12
+ export type { CreditCardCvvValidatorOptions };