@smilodon/core 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. package/dist/index.cjs +3685 -0
  2. package/dist/index.cjs.map +1 -0
  3. package/dist/index.js +3643 -0
  4. package/dist/index.js.map +1 -0
  5. package/dist/index.min.js +2 -0
  6. package/dist/index.min.js.map +1 -0
  7. package/dist/index.umd.js +3691 -0
  8. package/dist/index.umd.js.map +1 -0
  9. package/dist/index.umd.min.js +2 -0
  10. package/dist/index.umd.min.js.map +1 -0
  11. package/dist/types/src/components/enhanced-select.d.ts +136 -0
  12. package/dist/types/src/components/native-select.d.ts +41 -0
  13. package/dist/types/src/components/select-option.d.ts +77 -0
  14. package/dist/types/src/config/global-config.d.ts +194 -0
  15. package/dist/types/src/index.d.ts +14 -0
  16. package/dist/types/src/renderers/contracts.d.ts +5 -0
  17. package/dist/types/src/themes/importer.d.ts +112 -0
  18. package/dist/types/src/types.d.ts +85 -0
  19. package/dist/types/src/utils/csp-styles.d.ts +74 -0
  20. package/dist/types/src/utils/data-source.d.ts +37 -0
  21. package/dist/types/src/utils/dom-pool.d.ts +79 -0
  22. package/dist/types/src/utils/fenwick-tree.d.ts +71 -0
  23. package/dist/types/src/utils/security.d.ts +131 -0
  24. package/dist/types/src/utils/telemetry.d.ts +95 -0
  25. package/dist/types/src/utils/virtualizer.d.ts +53 -0
  26. package/dist/types/src/utils/worker-manager.d.ts +106 -0
  27. package/dist/types/tests/csp.spec.d.ts +5 -0
  28. package/dist/types/tests/interaction.spec.d.ts +1 -0
  29. package/dist/types/tests/setup.d.ts +6 -0
  30. package/dist/types/tests/shadow-dom.spec.d.ts +5 -0
  31. package/dist/types/tests/smoke.spec.d.ts +1 -0
  32. package/dist/types/tests/stress.spec.d.ts +5 -0
  33. package/dist/types/tests/virtualizer.spec.d.ts +1 -0
  34. package/package.json +52 -0
@@ -0,0 +1,41 @@
1
+ import { OptionRenderer, OptionTemplate } from '../renderers/contracts';
2
+ export declare class NativeSelectElement extends HTMLElement {
3
+ static get observedAttributes(): string[];
4
+ private _options;
5
+ private _shadow;
6
+ private _listRoot;
7
+ private _items;
8
+ private _helpers;
9
+ private _virtualizer?;
10
+ private _selectedSet;
11
+ private _selectedItems;
12
+ private _activeIndex;
13
+ private _multi;
14
+ private _typeBuffer;
15
+ private _typeTimeout?;
16
+ private _liveRegion?;
17
+ constructor();
18
+ connectedCallback(): void;
19
+ disconnectedCallback(): void;
20
+ attributeChangedCallback(name: string, _oldValue: string | null, newValue: string | null): void;
21
+ set items(items: unknown[]);
22
+ get items(): unknown[];
23
+ set multi(value: boolean);
24
+ get multi(): boolean;
25
+ get selectedIndices(): number[];
26
+ get selectedItems(): unknown[];
27
+ set optionTemplate(template: OptionTemplate | undefined);
28
+ set optionRenderer(renderer: OptionRenderer | undefined);
29
+ render(): void;
30
+ private _applyOptionAttrs;
31
+ private _applyAriaToAll;
32
+ private _emit;
33
+ private _onSelect;
34
+ private _onKeydown;
35
+ private _moveActive;
36
+ private _setActive;
37
+ private _scrollToActive;
38
+ private _onType;
39
+ private _announce;
40
+ focus(): void;
41
+ }
@@ -0,0 +1,77 @@
1
+ /**
2
+ * Independent Option Component
3
+ * High cohesion, low coupling - handles its own selection state and events
4
+ */
5
+ export interface OptionConfig {
6
+ /** The data item this option represents */
7
+ item: unknown;
8
+ /** The index of this option */
9
+ index: number;
10
+ /** Whether this option is selected */
11
+ selected: boolean;
12
+ /** Whether this option is disabled */
13
+ disabled?: boolean;
14
+ /** Whether this option is focused/active */
15
+ active?: boolean;
16
+ /** Custom value accessor */
17
+ getValue?: (item: unknown) => unknown;
18
+ /** Custom label accessor */
19
+ getLabel?: (item: unknown) => string;
20
+ /** Custom renderer */
21
+ render?: (item: unknown, index: number) => HTMLElement | string;
22
+ /** Custom style */
23
+ style?: Partial<CSSStyleDeclaration>;
24
+ /** Custom class names */
25
+ className?: string;
26
+ /** Show remove button (for multi-select) */
27
+ showRemoveButton?: boolean;
28
+ }
29
+ export interface OptionEventDetail {
30
+ item: unknown;
31
+ index: number;
32
+ value: unknown;
33
+ label: string;
34
+ selected: boolean;
35
+ }
36
+ export declare class SelectOption extends HTMLElement {
37
+ private _config;
38
+ private _shadow;
39
+ private _container;
40
+ private _removeButton?;
41
+ constructor(config: OptionConfig);
42
+ private _initializeStyles;
43
+ private _render;
44
+ private _attachEventListeners;
45
+ private _handleSelect;
46
+ private _handleRemove;
47
+ private _getValue;
48
+ private _getLabel;
49
+ /**
50
+ * Update option configuration and re-render
51
+ */
52
+ updateConfig(updates: Partial<OptionConfig>): void;
53
+ /**
54
+ * Get current configuration
55
+ */
56
+ getConfig(): Readonly<OptionConfig>;
57
+ /**
58
+ * Get option value
59
+ */
60
+ getValue(): unknown;
61
+ /**
62
+ * Get option label
63
+ */
64
+ getLabel(): string;
65
+ /**
66
+ * Set selected state
67
+ */
68
+ setSelected(selected: boolean): void;
69
+ /**
70
+ * Set active state
71
+ */
72
+ setActive(active: boolean): void;
73
+ /**
74
+ * Set disabled state
75
+ */
76
+ setDisabled(disabled: boolean): void;
77
+ }
@@ -0,0 +1,194 @@
1
+ /**
2
+ * Global Configuration System for Select Components
3
+ * Allows users to define default behaviors that can be overridden at component level
4
+ */
5
+ export interface ScrollToSelectedConfig {
6
+ /** Whether to scroll to selected item when dropdown opens/closes */
7
+ enabled: boolean;
8
+ /** Which selected item to scroll to in multi-select mode: 'first' | 'last' */
9
+ multiSelectTarget: 'first' | 'last';
10
+ /** Scroll behavior */
11
+ behavior?: ScrollBehavior;
12
+ /** Scroll block alignment */
13
+ block?: ScrollLogicalPosition;
14
+ }
15
+ export interface LoadMoreConfig {
16
+ /** Enable load more functionality */
17
+ enabled: boolean;
18
+ /** Number of items to load per increment */
19
+ itemsPerLoad: number;
20
+ /** Threshold (in pixels from bottom) to trigger auto-load */
21
+ threshold?: number;
22
+ /** Show loading indicator */
23
+ showLoader?: boolean;
24
+ }
25
+ export interface BusyBucketConfig {
26
+ /** Enable busy/loading state bucket */
27
+ enabled: boolean;
28
+ /** Show spinner in bucket */
29
+ showSpinner?: boolean;
30
+ /** Custom loading message */
31
+ message?: string;
32
+ /** Minimum display time (ms) to prevent flashing */
33
+ minDisplayTime?: number;
34
+ }
35
+ export interface SelectionConfig {
36
+ /** Single or multi-select mode */
37
+ mode: 'single' | 'multi';
38
+ /** Allow deselection in single-select mode */
39
+ allowDeselect?: boolean;
40
+ /** Maximum selections in multi-select (0 = unlimited) */
41
+ maxSelections?: number;
42
+ /** Show remove button on selected options in multi-select */
43
+ showRemoveButton?: boolean;
44
+ /** Close dropdown after selection in single-select */
45
+ closeOnSelect?: boolean;
46
+ }
47
+ export interface StyleConfig {
48
+ /** Container styles */
49
+ container?: Partial<CSSStyleDeclaration>;
50
+ /** Dropdown styles */
51
+ dropdown?: Partial<CSSStyleDeclaration>;
52
+ /** Option item styles */
53
+ option?: Partial<CSSStyleDeclaration>;
54
+ /** Selected option styles */
55
+ selectedOption?: Partial<CSSStyleDeclaration>;
56
+ /** Disabled option styles */
57
+ disabledOption?: Partial<CSSStyleDeclaration>;
58
+ /** Hover option styles */
59
+ hoverOption?: Partial<CSSStyleDeclaration>;
60
+ /** Input field styles */
61
+ input?: Partial<CSSStyleDeclaration>;
62
+ /** Loading indicator styles */
63
+ loader?: Partial<CSSStyleDeclaration>;
64
+ /** Custom CSS class names */
65
+ classNames?: {
66
+ container?: string;
67
+ dropdown?: string;
68
+ option?: string;
69
+ selectedOption?: string;
70
+ disabledOption?: string;
71
+ input?: string;
72
+ loader?: string;
73
+ removeButton?: string;
74
+ };
75
+ }
76
+ export interface ServerSideConfig {
77
+ /** Enable server-side data management */
78
+ enabled: boolean;
79
+ /** Initial selected value(s) from server */
80
+ initialSelectedValues?: unknown[];
81
+ /** Initial selected indices from server */
82
+ initialSelectedIndices?: number[];
83
+ /** Function to fetch pre-selected items not in current page */
84
+ fetchSelectedItems?: (values: unknown[]) => Promise<unknown[]>;
85
+ /** Value accessor function */
86
+ getValueFromItem?: (item: unknown) => unknown;
87
+ /** Label accessor function */
88
+ getLabelFromItem?: (item: unknown) => string;
89
+ }
90
+ export interface InfiniteScrollConfig {
91
+ /** Enable infinite scroll */
92
+ enabled: boolean;
93
+ /** Page size for pagination */
94
+ pageSize: number;
95
+ /** Initial page */
96
+ initialPage?: number;
97
+ /** Cache loaded pages */
98
+ cachePages?: boolean;
99
+ /** Maximum cached pages (LRU eviction) */
100
+ maxCachedPages?: number;
101
+ /** Preload adjacent pages */
102
+ preloadAdjacent?: boolean;
103
+ /** Scroll restoration strategy for selected items on distant pages */
104
+ scrollRestoration?: 'auto' | 'manual' | 'disabled';
105
+ }
106
+ export interface CallbackConfig {
107
+ /** Called when option is selected/deselected */
108
+ onSelect?: (data: {
109
+ item: unknown;
110
+ index: number;
111
+ value: unknown;
112
+ label: string;
113
+ selected: boolean;
114
+ }) => void;
115
+ /** Called when dropdown opens */
116
+ onOpen?: () => void;
117
+ /** Called when dropdown closes */
118
+ onClose?: () => void;
119
+ /** Called when search query changes */
120
+ onSearch?: (query: string) => void;
121
+ /** Called when more items are loaded */
122
+ onLoadMore?: (page: number) => void;
123
+ /** Called when selection changes */
124
+ onChange?: (selectedItems: unknown[], selectedValues: unknown[]) => void;
125
+ /** Called on error */
126
+ onError?: (error: Error) => void;
127
+ }
128
+ export interface GlobalSelectConfig {
129
+ /** Selection behavior */
130
+ selection: SelectionConfig;
131
+ /** Scroll to selected configuration */
132
+ scrollToSelected: ScrollToSelectedConfig;
133
+ /** Load more configuration */
134
+ loadMore: LoadMoreConfig;
135
+ /** Busy bucket configuration */
136
+ busyBucket: BusyBucketConfig;
137
+ /** Style customization */
138
+ styles: StyleConfig;
139
+ /** Server-side configuration */
140
+ serverSide: ServerSideConfig;
141
+ /** Infinite scroll configuration */
142
+ infiniteScroll: InfiniteScrollConfig;
143
+ /** Callbacks */
144
+ callbacks: CallbackConfig;
145
+ /** Enable/disable entire component */
146
+ enabled: boolean;
147
+ /** Enable search/filter */
148
+ searchable?: boolean;
149
+ /** Placeholder text */
150
+ placeholder?: string;
151
+ /** Virtualization */
152
+ virtualize?: boolean;
153
+ /** Estimated item height for virtualization */
154
+ estimatedItemHeight?: number;
155
+ }
156
+ /**
157
+ * Global configuration instance
158
+ */
159
+ declare class SelectConfigManager {
160
+ private config;
161
+ constructor();
162
+ /**
163
+ * Get current global configuration
164
+ */
165
+ getConfig(): Readonly<GlobalSelectConfig>;
166
+ /**
167
+ * Update global configuration (deep merge)
168
+ */
169
+ updateConfig(updates: Partial<GlobalSelectConfig>): void;
170
+ /**
171
+ * Reset to default configuration
172
+ */
173
+ resetConfig(): void;
174
+ /**
175
+ * Merge component-level config with global config
176
+ * Component-level config takes precedence
177
+ */
178
+ mergeWithComponentConfig(componentConfig: Partial<GlobalSelectConfig>): GlobalSelectConfig;
179
+ private deepClone;
180
+ private deepMerge;
181
+ }
182
+ /**
183
+ * Singleton instance
184
+ */
185
+ export declare const selectConfig: SelectConfigManager;
186
+ /**
187
+ * Helper function to configure select globally
188
+ */
189
+ export declare function configureSelect(config: Partial<GlobalSelectConfig>): void;
190
+ /**
191
+ * Helper function to reset select configuration
192
+ */
193
+ export declare function resetSelectConfig(): void;
194
+ export {};
@@ -0,0 +1,14 @@
1
+ export * from './types.js';
2
+ export * from './renderers/contracts.js';
3
+ export * from './components/native-select.js';
4
+ export * from './components/enhanced-select.js';
5
+ export * from './components/select-option.js';
6
+ export * from './config/global-config.js';
7
+ export { FenwickTree } from './utils/fenwick-tree.js';
8
+ export { DOMPool } from './utils/dom-pool.js';
9
+ export { WorkerManager, getWorkerManager } from './utils/worker-manager.js';
10
+ export { PerformanceTelemetry, getTelemetry, measureAsync, measureSync } from './utils/telemetry.js';
11
+ export { Virtualizer } from './utils/virtualizer.js';
12
+ export { setHTMLSanitizer, getHTMLSanitizer, sanitizeHTML, createElement, setCSSProperties, CSPFeatures, detectEnvironment, containsSuspiciousPatterns, escapeHTML, escapeAttribute, validateTemplate, createTextNode, setTextContent } from './utils/security.js';
13
+ export { applyClasses, toggleClass, setCustomProperties, getCustomProperty, removeCustomProperty, defaultTheme, applyDefaultTheme, shadowDOMStyles, injectShadowStyles, hasOverflowHiddenAncestor, warnCSPViolation } from './utils/csp-styles.js';
14
+ export type { HTMLSanitizer, EnvironmentCapabilities } from './utils/security.js';
@@ -0,0 +1,5 @@
1
+ import type { RendererHelpers } from '../types';
2
+ export type OptionTemplate = (item: unknown, index: number) => string;
3
+ export type OptionRenderer = (item: unknown, index: number, helpers: RendererHelpers) => HTMLElement;
4
+ export declare const createRendererHelpers: (onSelect: (item: unknown, index: number) => void) => RendererHelpers;
5
+ export declare function renderTemplate(container: HTMLElement, items: unknown[], optionTemplate: OptionTemplate): void;
@@ -0,0 +1,112 @@
1
+ /**
2
+ * Design Token Importer
3
+ * Convert design tokens from Figma, Adobe XD, and other design tools to CSS variables
4
+ *
5
+ * Supports:
6
+ * - Figma Variables API
7
+ * - Adobe XD Design Tokens
8
+ * - Design Tokens Format (W3C Community Group spec)
9
+ * - Style Dictionary format
10
+ *
11
+ * Usage:
12
+ * import { importTokens, applyTokens } from '@smilodon/core/themes/importer';
13
+ *
14
+ * const tokens = await importTokens('figma', figmaData);
15
+ * applyTokens(selectElement, tokens);
16
+ */
17
+ /**
18
+ * Design token types
19
+ */
20
+ export interface DesignToken {
21
+ $type?: string;
22
+ $value: string | number | DesignToken;
23
+ $description?: string;
24
+ }
25
+ export interface DesignTokens {
26
+ [key: string]: DesignToken | DesignTokens;
27
+ }
28
+ export interface CSSVariable {
29
+ name: string;
30
+ value: string;
31
+ category?: string;
32
+ description?: string;
33
+ }
34
+ /**
35
+ * Import design tokens from various sources
36
+ */
37
+ export declare function importTokens(source: 'figma' | 'adobe-xd' | 'tokens-studio' | 'style-dictionary' | 'json', data: any): Promise<Map<string, CSSVariable>>;
38
+ /**
39
+ * Import Figma Variables API format
40
+ *
41
+ * Example Figma export:
42
+ * {
43
+ * "colors": {
44
+ * "primary": { "$type": "color", "$value": "#007aff" },
45
+ * "background": { "$type": "color", "$value": "#ffffff" }
46
+ * },
47
+ * "spacing": {
48
+ * "sm": { "$type": "dimension", "$value": "8px" }
49
+ * }
50
+ * }
51
+ */
52
+ export declare function importFigmaTokens(data: any): Map<string, CSSVariable>;
53
+ /**
54
+ * Import Adobe XD design tokens
55
+ *
56
+ * Example Adobe XD export:
57
+ * {
58
+ * "colors": [
59
+ * { "name": "Primary Blue", "value": "#007aff" }
60
+ * ],
61
+ * "textStyles": [
62
+ * { "name": "Body", "fontSize": 16, "fontFamily": "SF Pro" }
63
+ * ]
64
+ * }
65
+ */
66
+ export declare function importAdobeXDTokens(data: any): Map<string, CSSVariable>;
67
+ /**
68
+ * Import Tokens Studio (Figma plugin) format
69
+ */
70
+ export declare function importTokensStudioTokens(data: any): Map<string, CSSVariable>;
71
+ /**
72
+ * Import Style Dictionary format
73
+ *
74
+ * Example:
75
+ * {
76
+ * "color": {
77
+ * "primary": { "value": "#007aff" }
78
+ * }
79
+ * }
80
+ */
81
+ export declare function importStyleDictionaryTokens(data: any): Map<string, CSSVariable>;
82
+ /**
83
+ * Import generic JSON token format
84
+ */
85
+ export declare function importGenericTokens(data: any): Map<string, CSSVariable>;
86
+ /**
87
+ * Apply CSS variables to an element
88
+ */
89
+ export declare function applyTokens(element: HTMLElement, tokens: Map<string, CSSVariable>, options?: {
90
+ prefix?: string;
91
+ scope?: 'element' | 'root';
92
+ }): void;
93
+ /**
94
+ * Generate CSS stylesheet from tokens
95
+ */
96
+ export declare function generateCSS(tokens: Map<string, CSSVariable>, options?: {
97
+ selector?: string;
98
+ groupByCategory?: boolean;
99
+ includeComments?: boolean;
100
+ }): string;
101
+ /**
102
+ * Export tokens to various formats
103
+ */
104
+ export declare function exportTokens(tokens: Map<string, CSSVariable>, format: 'css' | 'json' | 'scss' | 'js' | 'ts'): string;
105
+ /**
106
+ * CLI tool for token conversion
107
+ *
108
+ * Usage:
109
+ * npx @smilodon/tokens import figma tokens.json --output theme.css
110
+ * npx @smilodon/tokens import adobe-xd design.json --output vars.css
111
+ */
112
+ export declare function cli(args: string[]): Promise<void>;
@@ -0,0 +1,85 @@
1
+ export type Placement = 'top' | 'bottom' | 'left' | 'right' | 'top-start' | 'top-end' | 'bottom-start' | 'bottom-end' | 'left-start' | 'left-end' | 'right-start' | 'right-end';
2
+ export type Strategy = 'fixed' | 'absolute';
3
+ export interface GroupedItem {
4
+ label: string;
5
+ options: unknown[];
6
+ }
7
+ export interface RemoteConfig {
8
+ endpoint: string;
9
+ pageSize?: number;
10
+ headers?: Record<string, string>;
11
+ transformer?: (resp: unknown) => unknown[] | Promise<unknown[]>;
12
+ cacheTTL?: number;
13
+ }
14
+ export interface SelectEventDetail<T = unknown> {
15
+ item: T;
16
+ index: number;
17
+ value: unknown;
18
+ label: string;
19
+ selected: boolean;
20
+ multi?: boolean;
21
+ }
22
+ export interface OpenEventDetail {
23
+ }
24
+ export interface CloseEventDetail {
25
+ }
26
+ export interface SearchEventDetail {
27
+ query: string;
28
+ results?: unknown[];
29
+ count?: number;
30
+ }
31
+ export interface PageLoadedEventDetail {
32
+ page: number;
33
+ count: number;
34
+ }
35
+ export interface ErrorEventDetail {
36
+ message: string;
37
+ cause?: unknown;
38
+ }
39
+ export interface ChangeEventDetail {
40
+ selectedItems: unknown[];
41
+ selectedValues: unknown[];
42
+ selectedIndices: number[];
43
+ }
44
+ export interface LoadMoreEventDetail {
45
+ page: number;
46
+ items: unknown[];
47
+ }
48
+ export interface RemoveEventDetail {
49
+ item: unknown;
50
+ index: number;
51
+ }
52
+ export interface SelectEventsDetailMap {
53
+ select: SelectEventDetail;
54
+ open: OpenEventDetail;
55
+ close: CloseEventDetail;
56
+ search: SearchEventDetail;
57
+ pageLoaded: PageLoadedEventDetail;
58
+ error: ErrorEventDetail;
59
+ change: ChangeEventDetail;
60
+ loadMore: LoadMoreEventDetail;
61
+ remove: RemoveEventDetail;
62
+ }
63
+ export type SelectEventName = keyof SelectEventsDetailMap;
64
+ export interface RendererHelpers {
65
+ onSelect: (item: unknown, index: number) => void;
66
+ getIndex: (node: Element | null) => number | null;
67
+ keyboardFocus: (index: number) => void;
68
+ }
69
+ export interface NativeSelectOptions {
70
+ placement?: Placement;
71
+ strategy?: Strategy;
72
+ portal?: boolean;
73
+ offset?: [number, number];
74
+ flip?: boolean;
75
+ shift?: boolean;
76
+ boundary?: Element | Document;
77
+ optionRenderer?: (item: unknown, index: number, helpers: RendererHelpers) => HTMLElement;
78
+ optionTemplate?: (item: unknown, index: number) => string;
79
+ remote?: RemoteConfig | null;
80
+ loadMode?: 'full' | 'lazy';
81
+ infinite?: boolean;
82
+ virtualize?: boolean;
83
+ estimatedItemHeight?: number;
84
+ bufferSize?: number;
85
+ }
@@ -0,0 +1,74 @@
1
+ /**
2
+ * CSP-compliant styling utilities.
3
+ * No inline styles or runtime style tag injection.
4
+ * Uses CSS custom properties and class names only.
5
+ */
6
+ /**
7
+ * Apply CSS classes to an element (CSP-safe).
8
+ */
9
+ export declare function applyClasses(element: HTMLElement, classes: string[]): void;
10
+ /**
11
+ * Toggle a CSS class (CSP-safe).
12
+ */
13
+ export declare function toggleClass(element: HTMLElement, className: string, force?: boolean): void;
14
+ /**
15
+ * Set CSS custom properties (CSP-safe dynamic styling).
16
+ * All properties must start with -- (CSS variables).
17
+ *
18
+ * @example
19
+ * setCustomProperties(element, {
20
+ * '--item-height': '48px',
21
+ * '--selected-bg': '#0066cc'
22
+ * });
23
+ */
24
+ export declare function setCustomProperties(element: HTMLElement, properties: Record<string, string>): void;
25
+ /**
26
+ * Get a CSS custom property value.
27
+ */
28
+ export declare function getCustomProperty(element: HTMLElement, propertyName: string): string;
29
+ /**
30
+ * Remove a CSS custom property.
31
+ */
32
+ export declare function removeCustomProperty(element: HTMLElement, propertyName: string): void;
33
+ /**
34
+ * Predefined theme as CSS custom properties.
35
+ * Can be overridden by consumers via CSS.
36
+ */
37
+ export declare const defaultTheme: {
38
+ '--ns-item-height': string;
39
+ '--ns-item-padding': string;
40
+ '--ns-item-bg': string;
41
+ '--ns-item-hover-bg': string;
42
+ '--ns-item-selected-bg': string;
43
+ '--ns-item-active-bg': string;
44
+ '--ns-item-color': string;
45
+ '--ns-item-selected-color': string;
46
+ '--ns-border-color': string;
47
+ '--ns-border-radius': string;
48
+ '--ns-focus-outline': string;
49
+ '--ns-font-size': string;
50
+ '--ns-font-family': string;
51
+ };
52
+ /**
53
+ * Apply the default theme to an element.
54
+ */
55
+ export declare function applyDefaultTheme(element: HTMLElement): void;
56
+ /**
57
+ * Static CSS for shadow DOM (no runtime injection).
58
+ * This CSS is CSP-safe because it's defined at build time as a string constant,
59
+ * not generated at runtime.
60
+ */
61
+ export declare const shadowDOMStyles = "\n:host {\n display: block;\n box-sizing: border-box;\n font-family: var(--ns-font-family, system-ui, -apple-system, sans-serif);\n font-size: var(--ns-font-size, 14px);\n}\n\n* {\n box-sizing: border-box;\n}\n\n.ns-list {\n position: relative;\n overflow: auto;\n max-height: var(--ns-max-height, 300px);\n border: 1px solid var(--ns-border-color, #ccc);\n border-radius: var(--ns-border-radius, 4px);\n background: var(--ns-bg, white);\n outline: none;\n}\n\n.ns-list:focus {\n outline: var(--ns-focus-outline, 2px solid #0066cc);\n outline-offset: -2px;\n}\n\n.ns-item {\n padding: var(--ns-item-padding, 8px 12px);\n min-height: var(--ns-item-height, 40px);\n color: var(--ns-item-color, inherit);\n background: var(--ns-item-bg, transparent);\n cursor: pointer;\n user-select: none;\n display: flex;\n align-items: center;\n transition: background-color 0.15s ease;\n}\n\n.ns-item:hover {\n background: var(--ns-item-hover-bg, rgba(0, 0, 0, 0.05));\n}\n\n.ns-item[aria-selected=\"true\"] {\n background: var(--ns-item-selected-bg, rgba(0, 102, 204, 0.1));\n color: var(--ns-item-selected-color, #0066cc);\n}\n\n.ns-item[data-active=\"true\"] {\n background: var(--ns-item-active-bg, rgba(0, 102, 204, 0.2));\n}\n\n.ns-item[aria-disabled=\"true\"] {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.ns-viewport {\n position: relative;\n overflow: auto;\n -webkit-overflow-scrolling: touch;\n}\n\n.ns-spacer {\n position: absolute;\n top: 0;\n left: 0;\n width: 1px;\n pointer-events: none;\n}\n\n/* Screen reader only */\n.ns-sr-only {\n position: absolute;\n left: -9999px;\n width: 1px;\n height: 1px;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n white-space: nowrap;\n}\n\n/* Portal mode (teleported outside shadow DOM) */\n.ns-portal {\n position: fixed;\n z-index: var(--ns-portal-z-index, 9999);\n}\n\n/* CSP warning banner (only shown in development) */\n.ns-csp-warning {\n padding: 8px;\n background: #fff3cd;\n border: 1px solid #ffc107;\n border-radius: 4px;\n color: #856404;\n font-size: 12px;\n margin-bottom: 8px;\n}\n";
62
+ /**
63
+ * Inject static styles into shadow root (CSP-safe).
64
+ * Only called once during component initialization.
65
+ */
66
+ export declare function injectShadowStyles(shadowRoot: ShadowRoot): void;
67
+ /**
68
+ * Check if element has overflow:hidden ancestors (portal fallback detection).
69
+ */
70
+ export declare function hasOverflowHiddenAncestor(element: HTMLElement): boolean;
71
+ /**
72
+ * Runtime warning for CSP violations (development only).
73
+ */
74
+ export declare function warnCSPViolation(feature: string, fallback: string): void;
@@ -0,0 +1,37 @@
1
+ export type Transformer<T = unknown> = (resp: unknown) => T[] | Promise<T[]>;
2
+ export interface RemoteConfig {
3
+ endpoint: string;
4
+ pageSize?: number;
5
+ headers?: Record<string, string>;
6
+ transformer?: Transformer;
7
+ cacheTTL?: number;
8
+ }
9
+ export interface FetchResult<T> {
10
+ items: T[];
11
+ fromCache: boolean;
12
+ }
13
+ export declare class TTLCache<T> {
14
+ private defaultTTL;
15
+ private store;
16
+ constructor(defaultTTL?: number);
17
+ get(key: string): T[] | null;
18
+ set(key: string, items: T[], ttl?: number): void;
19
+ }
20
+ export declare class LocalSource<T = unknown> {
21
+ private items;
22
+ constructor(items: T[]);
23
+ search(query: string): T[];
24
+ fetchPage(query: string, page: number, pageSize?: number): Promise<FetchResult<T>>;
25
+ }
26
+ export declare class RemoteSource<T = unknown> {
27
+ private cfg;
28
+ private cache;
29
+ private controller;
30
+ private pageMap;
31
+ constructor(cfg: RemoteConfig);
32
+ private key;
33
+ fetchPage(query: string, page: number): Promise<FetchResult<T>>;
34
+ refresh(query: string, page: number): Promise<void>;
35
+ getPage(page: number): T[] | null;
36
+ }
37
+ export declare function debounce<T extends (...args: any[]) => void>(fn: T, ms: number): (...args: Parameters<T>) => void;