@santi020k/lumen-core 3.0.1 → 4.1.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 (153) hide show
  1. package/PHONE_FLAG_LICENSE.txt +21 -0
  2. package/README.md +384 -3
  3. package/THIRD_PARTY_NOTICES.md +16 -2
  4. package/dist/ai-surfaces.d.ts +25 -0
  5. package/dist/ai-surfaces.d.ts.map +1 -0
  6. package/dist/ai-surfaces.js +162 -0
  7. package/dist/amount-field.d.ts +22 -0
  8. package/dist/amount-field.d.ts.map +1 -0
  9. package/dist/amount-field.js +207 -0
  10. package/dist/attachments.d.ts +15 -0
  11. package/dist/attachments.d.ts.map +1 -0
  12. package/dist/attachments.js +123 -0
  13. package/dist/bullet-chart.d.ts +33 -0
  14. package/dist/bullet-chart.d.ts.map +1 -0
  15. package/dist/bullet-chart.js +80 -0
  16. package/dist/chart-activation.d.ts +32 -0
  17. package/dist/chart-activation.d.ts.map +1 -0
  18. package/dist/chart-activation.js +97 -0
  19. package/dist/chart-interaction.d.ts +12 -0
  20. package/dist/chart-interaction.d.ts.map +1 -0
  21. package/dist/chart-interaction.js +274 -0
  22. package/dist/chart-models.d.ts +156 -0
  23. package/dist/chart-models.d.ts.map +1 -0
  24. package/dist/chart-models.js +348 -0
  25. package/dist/chart-motion.d.ts +6 -0
  26. package/dist/chart-motion.d.ts.map +1 -0
  27. package/dist/chart-motion.js +107 -0
  28. package/dist/charts.d.ts +58 -3
  29. package/dist/charts.d.ts.map +1 -1
  30. package/dist/charts.js +247 -18
  31. package/dist/code.js +1 -1
  32. package/dist/combobox.d.ts +7 -0
  33. package/dist/combobox.d.ts.map +1 -0
  34. package/dist/combobox.js +253 -0
  35. package/dist/comparison-chart.d.ts +32 -0
  36. package/dist/comparison-chart.d.ts.map +1 -0
  37. package/dist/comparison-chart.js +64 -0
  38. package/dist/components.d.ts +210 -25
  39. package/dist/components.d.ts.map +1 -1
  40. package/dist/components.js +102 -26
  41. package/dist/dashboard.d.ts +16 -0
  42. package/dist/dashboard.d.ts.map +1 -0
  43. package/dist/dashboard.js +21 -0
  44. package/dist/data.d.ts.map +1 -1
  45. package/dist/data.js +21 -5
  46. package/dist/dates.d.ts +13 -0
  47. package/dist/dates.d.ts.map +1 -0
  48. package/dist/dates.js +37 -0
  49. package/dist/device-frame.d.ts +25 -0
  50. package/dist/device-frame.d.ts.map +1 -0
  51. package/dist/device-frame.js +50 -0
  52. package/dist/direction.d.ts +3 -0
  53. package/dist/direction.d.ts.map +1 -0
  54. package/dist/direction.js +10 -0
  55. package/dist/extended-charts.d.ts +95 -0
  56. package/dist/extended-charts.d.ts.map +1 -0
  57. package/dist/extended-charts.js +175 -0
  58. package/dist/figma.d.ts.map +1 -1
  59. package/dist/figma.js +10 -1
  60. package/dist/floating-panel.d.ts +24 -0
  61. package/dist/floating-panel.d.ts.map +1 -0
  62. package/dist/floating-panel.js +203 -0
  63. package/dist/forms.d.ts.map +1 -1
  64. package/dist/forms.js +18 -4
  65. package/dist/icon-data.generated.d.ts +1 -1
  66. package/dist/icon-data.generated.d.ts.map +1 -1
  67. package/dist/icon-data.generated.js +1 -1
  68. package/dist/icons.js +3 -4
  69. package/dist/illustrations.generated.d.ts +1 -1
  70. package/dist/image-comparison.d.ts +14 -0
  71. package/dist/image-comparison.d.ts.map +1 -0
  72. package/dist/image-comparison.js +48 -0
  73. package/dist/index.d.ts +37 -4
  74. package/dist/index.d.ts.map +1 -1
  75. package/dist/index.js +36 -3
  76. package/dist/loading.d.ts +34 -0
  77. package/dist/loading.d.ts.map +1 -0
  78. package/dist/loading.js +70 -0
  79. package/dist/media-viewport.d.ts +24 -0
  80. package/dist/media-viewport.d.ts.map +1 -0
  81. package/dist/media-viewport.js +119 -0
  82. package/dist/media-workspace.d.ts +27 -0
  83. package/dist/media-workspace.d.ts.map +1 -0
  84. package/dist/media-workspace.js +83 -0
  85. package/dist/message-scroller.d.ts +14 -0
  86. package/dist/message-scroller.d.ts.map +1 -0
  87. package/dist/message-scroller.js +113 -0
  88. package/dist/motion-workflows.d.ts +24 -0
  89. package/dist/motion-workflows.d.ts.map +1 -0
  90. package/dist/motion-workflows.js +220 -0
  91. package/dist/motion.d.ts +12 -0
  92. package/dist/motion.d.ts.map +1 -0
  93. package/dist/motion.js +96 -0
  94. package/dist/native-input.d.ts +25 -0
  95. package/dist/native-input.d.ts.map +1 -0
  96. package/dist/native-input.js +188 -0
  97. package/dist/phone-flags.generated.d.ts +2 -0
  98. package/dist/phone-flags.generated.d.ts.map +1 -0
  99. package/dist/phone-flags.generated.js +263 -0
  100. package/dist/phone.d.ts +4 -0
  101. package/dist/phone.d.ts.map +1 -1
  102. package/dist/phone.js +6 -1
  103. package/dist/rich-text.d.ts +7 -0
  104. package/dist/rich-text.d.ts.map +1 -1
  105. package/dist/rich-text.js +13 -0
  106. package/dist/rive.d.ts +37 -0
  107. package/dist/rive.d.ts.map +1 -0
  108. package/dist/rive.js +129 -0
  109. package/dist/schedule.d.ts.map +1 -1
  110. package/dist/schedule.js +63 -23
  111. package/dist/tab-indicator.d.ts +3 -0
  112. package/dist/tab-indicator.d.ts.map +1 -0
  113. package/dist/tab-indicator.js +57 -0
  114. package/dist/theme-audit.d.ts +16 -0
  115. package/dist/theme-audit.d.ts.map +1 -0
  116. package/dist/theme-audit.js +57 -0
  117. package/dist/theme-builder.d.ts +7 -1
  118. package/dist/theme-builder.d.ts.map +1 -1
  119. package/dist/theme-builder.js +45 -23
  120. package/dist/theme-presets.generated.d.ts +217 -0
  121. package/dist/theme-presets.generated.d.ts.map +1 -0
  122. package/dist/theme-presets.generated.js +231 -0
  123. package/dist/theme.d.ts +11 -3
  124. package/dist/theme.d.ts.map +1 -1
  125. package/dist/theme.js +56 -6
  126. package/dist/virtual-collection.d.ts +14 -0
  127. package/dist/virtual-collection.d.ts.map +1 -0
  128. package/dist/virtual-collection.js +132 -0
  129. package/dist/virtual-list.d.ts +7 -0
  130. package/dist/virtual-list.d.ts.map +1 -0
  131. package/dist/virtual-list.js +135 -0
  132. package/dist/virtual-window.d.ts +19 -0
  133. package/dist/virtual-window.d.ts.map +1 -0
  134. package/dist/virtual-window.js +84 -0
  135. package/dist/visual-effects.d.ts +6 -0
  136. package/dist/visual-effects.d.ts.map +1 -0
  137. package/dist/visual-effects.js +44 -0
  138. package/dist/world-map-data.generated.d.ts +9 -0
  139. package/dist/world-map-data.generated.d.ts.map +1 -0
  140. package/dist/world-map-data.generated.js +240 -0
  141. package/dist/world-map-navigation.d.ts +16 -0
  142. package/dist/world-map-navigation.d.ts.map +1 -0
  143. package/dist/world-map-navigation.js +53 -0
  144. package/dist/world-map-pan.d.ts +3 -0
  145. package/dist/world-map-pan.d.ts.map +1 -0
  146. package/dist/world-map-pan.js +66 -0
  147. package/dist/world-map-zoom.d.ts +13 -0
  148. package/dist/world-map-zoom.d.ts.map +1 -0
  149. package/dist/world-map-zoom.js +61 -0
  150. package/dist/world-map.d.ts +71 -0
  151. package/dist/world-map.d.ts.map +1 -0
  152. package/dist/world-map.js +143 -0
  153. package/package.json +51 -4
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2013 Panayiotis Lipiridis
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
6
+ this software and associated documentation files (the "Software"), to deal in
7
+ the Software without restriction, including without limitation the rights to
8
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
9
+ of the Software, and to permit persons to whom the Software is furnished to do
10
+ so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,4 +1,66 @@
1
- # @santi020k/lumen-core
1
+ <p align="center">
2
+ <a href="https://lumen.santi020k.com">
3
+ <picture>
4
+ <source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/santi020k/lumen/main/docs/assets/readme/package-dark.svg">
5
+ <img src="https://raw.githubusercontent.com/santi020k/lumen/main/docs/assets/readme/package-light.svg" alt="Lumen UI — Web. Native. Thoughtfully connected." width="1200" height="184">
6
+ </picture>
7
+ </a>
8
+ </p>
9
+
10
+ <h1 align="center">Lumen UI · Core</h1>
11
+
12
+ <p align="center">Shared contracts · Metadata · Framework-neutral helpers</p>
13
+
14
+ <p align="center">
15
+ <a href="https://www.npmjs.com/package/@santi020k/lumen-core"><img src="https://img.shields.io/npm/v/@santi020k/lumen-core?style=flat-square&color=0369a0" alt="npm version"></a>
16
+ <a href="https://github.com/santi020k/lumen/blob/main/LICENSE"><img src="https://img.shields.io/badge/license-MIT-13967e?style=flat-square" alt="MIT license"></a>
17
+ </p>
18
+
19
+ <p align="center">
20
+ <a href="https://lumen.santi020k.com/docs/foundations">Documentation</a>
21
+ ·
22
+ <a href="https://www.npmjs.com/package/@santi020k/lumen-core">npm</a>
23
+ ·
24
+ <a href="https://github.com/santi020k/lumen/tree/main/packages/core">Source</a>
25
+ ·
26
+ <a href="https://github.com/santi020k/lumen/issues">Issues</a>
27
+ </p>
28
+
29
+ **Package:** `@santi020k/lumen-core`
30
+
31
+ **On this page:** [Install](#install) · [Quick start](#quick-start) · [Appearance presets](#appearance-presets) · [Resources](#resources)
32
+
33
+ <details>
34
+ <summary>Browse all sections</summary>
35
+
36
+ - [Install](#install)
37
+ - [Quick start](#quick-start)
38
+ - [Data view state](#data-view-state)
39
+ - [Schedule helpers](#schedule-helpers)
40
+ - [Appearance presets](#appearance-presets)
41
+ - [Language Helpers](#language-helpers)
42
+ - [Date Helpers](#date-helpers)
43
+ - [Chart Helpers](#chart-helpers)
44
+ - [Phone Helpers](#phone-helpers)
45
+ - [Icon Credits](#icon-credits)
46
+ - [Theme Builder Helpers](#theme-builder-helpers)
47
+ - [Figma and Design Tokens](#figma-and-design-tokens)
48
+ - [Static interface icon data](#static-interface-icon-data)
49
+ - [Consumer diagnostics and exact amounts](#consumer-diagnostics-and-exact-amounts)
50
+ - [Combobox DOM controller](#combobox-dom-controller)
51
+ - [Virtual collections and direction](#virtual-collections-and-direction)
52
+ - [Exact localized input drafts](#exact-localized-input-drafts)
53
+ - [Attachment preview state](#attachment-preview-state)
54
+ - [Chart datum activation](#chart-datum-activation)
55
+ - [Dashboard contracts](#dashboard-contracts)
56
+ - [Extended chart models](#extended-chart-models)
57
+ - [Optional visual integrations](#optional-visual-integrations)
58
+ - [Presence motion](#presence-motion)
59
+ - [World map](#world-map)
60
+ - [Studio media workspace](#studio-media-workspace)
61
+ - [Resources](#resources)
62
+
63
+ </details>
2
64
 
3
65
  Shared metadata, token constants, and tiny utilities used by the Lumen package family.
4
66
 
@@ -11,11 +73,71 @@ It also publishes shared web behavior contracts such as `LumenTabsChangeDetail`
11
73
  `LumenTabsChangeEvent`. Import them from the root or `@santi020k/lumen-core/tabs` when application
12
74
  code listens for `ui:tabs-change`.
13
75
 
76
+ Loading helpers are available from the root export for custom web adapters:
77
+ `normalizeLumenProgress(max, value)` produces finite, clamped progress values;
78
+ `resolveLumenSkeletonShape`, `resolveLumenSkeletonAnimation`, and `resolveLumenSkeletonSize`
79
+ normalize placeholder options. Numeric sizes become pixels, and bounded CSS size expressions retain
80
+ custom-property casing. `resolveLumenLoadingSemantics` supplies decorative or named status defaults;
81
+ adapters must preserve explicit consumer ARIA attributes when applying those defaults.
82
+
14
83
  Cross-platform foundations originate in `tokens/lumen.tokens.json` and are published as
15
84
  `@santi020k/lumen-tokens`. Core also exports generated hexadecimal light/dark palettes and native
16
85
  numeric spacing, radius, typography, duration, easing, and elevation values. The legacy
17
86
  `lumenColors` export retains CSS-ready HSL values.
18
87
 
88
+ ## Install
89
+
90
+ Install core directly when building framework-neutral tooling or a custom adapter:
91
+
92
+ ```bash
93
+ pnpm add @santi020k/lumen-core
94
+ ```
95
+
96
+ Core provides data and helpers; it does not register elements, render components, or load CSS.
97
+ Use documented subpath exports such as `/charts`, `/phone`, and `/icon-data` for focused imports.
98
+ Image-comparison helpers use `/image-comparison`; DOM windowing uses
99
+ `/virtual-list`, and data-renderer window calculations use `/virtual-window`.
100
+
101
+ ## Quick start
102
+
103
+ Read semantic foundations through the focused token entry:
104
+
105
+ ```ts
106
+ import { lumenColors } from '@santi020k/lumen-core/tokens'
107
+
108
+ const brandChannels = lumenColors.brand
109
+ ```
110
+
111
+ `lumenColors` contains CSS-ready HSL channels. For portable JSON and native generated palettes,
112
+ use the [design tokens package](https://github.com/santi020k/lumen/blob/main/packages/tokens/README.md).
113
+
114
+ ## Data view state
115
+
116
+ `serializeDataViewState` and `parseDataViewState` preserve named filters, including names that
117
+ match built-in object properties, as ordinary own properties. Repeated filter parameters use
118
+ the last value. `createDataViewRequestUrl` and `createDataViewServerRequest` append state to
119
+ an endpoint's query before its fragment, preserving existing query parameters and fragment text.
120
+ Import these helpers from the root or `@santi020k/lumen-core/data`.
121
+
122
+ ## Schedule helpers
123
+
124
+ `canPlaceScheduleEvent` rejects malformed or reversed candidate intervals, including in an empty
125
+ schedule. `scheduleEventsOverlap` conservatively treats an invalid interval as a conflict with
126
+ a different event sharing its resource; distinct resources and identical event IDs retain their
127
+ existing behavior. Adjacent valid intervals remain available.
128
+
129
+ `resizeScheduleEvent` and `expandRecurringScheduleEvent` reject invalid date-times with `TypeError`.
130
+ Recurrence advances UTC calendar days and preserves UTC time-of-day independently of the host time zone. Applications own civil-time recurrence policies and DST conversion.
131
+
132
+ Invalid bounds, non-finite snapping/recurrence options, unsupported resulting date-times, and
133
+ non-integer or negative recurrence counts produce `RangeError`. Applications own validation and
134
+ recovery feedback. `parseScheduleEvents` preserves structurally valid records with malformed
135
+ date-times so applications can repair the original data; these helpers do not rewrite storage.
136
+
137
+ ## Appearance presets
138
+
139
+ Use `createThemePreset('studio', { scheme: 'dark', overrides: { 'ui-radius': '0.75rem' } })` for a named starting point. Default, Studio and Glass share the [appearance contract](https://github.com/santi020k/lumen/blob/main/docs/appearance-presets.md).
140
+
19
141
  ## Language Helpers
20
142
 
21
143
  The root entry exports the shared locale contract used by the Astro, React, and Elements language
@@ -45,12 +167,43 @@ const label = formatLumenLanguageLabel(
45
167
  )
46
168
  ```
47
169
 
170
+ ## Date Helpers
171
+
172
+ Calendar adapters share `parseLumenDate`, `isLumenDateBoundsValid`, and
173
+ `isLumenDateRangeValid` from the core root entry. They accept complete Gregorian
174
+ `YYYY-MM-DD` dates in years 0001–9999, reject overflow dates, and require ordered,
175
+ inclusive bounds. `resolveLumenDateLocale` normalizes an explicit locale or the
176
+ browser locale, falling back to English for invalid locale tags.
177
+ `resolveLumenDateLabels` supplies English and Spanish navigation, picker, and
178
+ invalid-range defaults through the `LumenDateLabels` contract. Components allow
179
+ label overrides for other languages; pass an explicit locale during SSR.
180
+
181
+ `isLumenDateRangeValid` accepts unknown restored data and returns `false` for a missing record
182
+ or non-string range fields instead of dereferencing malformed input.
183
+
48
184
  ## Chart Helpers
49
185
 
186
+ The package root also exports `createLumenLineChartModel`, `createLumenWaterfallGeometry`,
187
+ `createLumenHistogramGeometry`, and `createLumenHeatmapModel`. These pure models share web geometry,
188
+ validation, ticks, and annotations. The optional `createLumenChartInteractionController` owns only
189
+ DOM listeners and cursor/legend state; call `destroy()` when removing its surface.
190
+ Line chart models ignore malformed annotation entries and containers before reading overlay fields.
191
+ When annotation IDs repeat, the first valid entry wins so overlay identities stay unique.
192
+ Destroying a chart controller restores series marks, inspection values, and legend pressed state
193
+ so rebinding starts with all series visible.
194
+ Waterfall and histogram geometry accept arrays of unknown decoded rows, validate their complete
195
+ shape before accumulation or sorting, and return `valid: false` with empty marks when a row is
196
+ malformed. Typed component props continue to use `LumenWaterfallDatum` and `LumenHistogramBin`.
197
+ `normalizeLumenHeatmapData` validates decoded cell arrays before adapters read coordinates or
198
+ format labels. It returns an empty array when any row has malformed coordinates, measurement
199
+ types, labels, identity, or tone. Heatmap geometry and models use it internally. Explicit `null`
200
+ and non-finite numeric measurements retain the existing missing-cell behavior; numeric coordinates
201
+ must be finite.
202
+
50
203
  `@santi020k/lumen-core/charts` exports the shared `LumenChartSeries` contract plus deterministic
51
204
  domain, tick, scaling, line/area, grouped/stacked bar, and pie/donut geometry helpers. They render
52
205
  no DOM and perform no statistical analysis; framework packages use them to keep chart output
53
- aligned.
206
+ aligned. Linear x coordinates ignore blank strings rather than treating them as zero.
54
207
 
55
208
  ```ts
56
209
  import {
@@ -89,6 +242,8 @@ as-you-type formatting, validation, pasted international-number detection, and E
89
242
  web and React Native adapters.
90
243
 
91
244
  ```ts
245
+ import { getLumenPhoneCountry, resolveLumenPhoneNumber } from '@santi020k/lumen-core/phone'
246
+
92
247
  const colombia = getLumenPhoneCountry('CO', { locale: 'en-US' })
93
248
  if (!colombia) throw new Error('Missing Colombia metadata')
94
249
 
@@ -98,6 +253,8 @@ const phone = resolveLumenPhoneNumber(colombia, '6015550123')
98
253
  It also exports the Lucide-backed icon map (`lumenIcons`, `lumenIconNames`) and helpers such as
99
254
  `renderLumenIconSvg` so framework adapters can render icons by name.
100
255
 
256
+ Icon resolution only accepts dictionary-owned names; inherited object properties are rejected.
257
+
101
258
  ## Icon Credits
102
259
 
103
260
  Icons are provided by [Lucide](https://lucide.dev/) and its open-source contributors. Lucide is
@@ -162,4 +319,228 @@ React consumers can import both the renderer and definitions from
162
319
  `@santi020k/lumen-react/icons`. Existing `getLumenIcon`, runtime names, and registered icon packs
163
320
  remain supported through the original API. The interface selection in `icons/lumen.icons.json`
164
321
  controls the generated exports; run `pnpm run generate:platform-icons` after catalog changes.
165
- See [consumer UI recipes](../../docs/consumer-ui-recipes.md#static-react-icons).
322
+ See [consumer UI recipes](https://github.com/santi020k/lumen/blob/main/docs/consumer-ui-recipes.md#static-react-icons).
323
+
324
+ ## Consumer diagnostics and exact amounts
325
+
326
+ `auditLumenTheme` requires every semantic color mapping and checks normal-text contrast for
327
+ resolved opaque HSL channels. `inspectLumenTheme(element)` reads computed mappings in each
328
+ representative light, dark and nested scope. Unsupported color syntax produces a finding rather
329
+ than an assumed pass; these checks supplement rendered accessibility verification.
330
+
331
+ `formatLumenAmountDraft`, `parseLumenAmountDraft` and `getLumenAmountValue` preserve exact ASCII
332
+ decimal strings across localized display and editing. Invalid locale tags fall back to `en-US`
333
+ consistently in server rendering, parsing and browser controllers. Call the amount controller’s
334
+ `refresh()` after moving it to a different document or shadow root; this rebinds native form resets
335
+ without replacing its draft. The shared amount and message-scroller DOM controllers power the web
336
+ adapters. Currency policy and message state remain consumer-owned.
337
+
338
+ ## Combobox DOM controller
339
+
340
+ `createLumenComboboxController(root)` enhances a client-side root containing an
341
+ `input[role="combobox"]` and a `[role="listbox"]` with `[role="option"]` children.
342
+ It preserves editing focus, observes option changes and supports delegated selection. It returns
343
+ `close()` and `destroy()`; call `destroy()` when the owner disconnects. Astro and Elements manage
344
+ that lifecycle automatically. React uses its state-driven component with the same keyboard contract.
345
+ An accepted native form reset closes options, clears the active descendant, and refilters against
346
+ the restored input value without emitting change events. Canceled resets preserve editing state;
347
+ `destroy()` cancels pending reset work. Pointer selection cancels native option-button submission.
348
+ Filtering preserves application-hidden options; cleanup restores options hidden by the filter.
349
+ The controller respects disabled fieldset ancestors and uses the input's current form association
350
+ when handling resets.
351
+
352
+ The mounted VirtualList controller supports roots and rows created in another document, including
353
+ same-origin iframe documents.
354
+ Data-mode collections preserve iframe keyboard focus across distant scrolling and keyed updates,
355
+ and return focus to the list when the focused record is removed.
356
+
357
+ ## Floating panel placement
358
+
359
+ `connectLumenFloatingPanel(panel, trigger, { onDismiss })` shows a panel anchored to its trigger. When the
360
+ Popover API exists the panel enters the top layer, so scrolling or transformed dialogs cannot clip it;
361
+ older browsers keep fixed placement. The panel flips above or below to stay in the visual viewport,
362
+ aligns to the trigger's logical start or end in RTL, and follows scroll, resize, and enclosing transform
363
+ transitions or animations once they settle. `onDismiss` runs when focus moves outside the panel and
364
+ trigger, when the trigger's containing dialog closes, or when the trigger or panel leaves the document.
365
+ Pass `placement`, `offset`, `collisionPadding`, or an `initialFocus` selector when needed. Connecting
366
+ makes the panel visible, and the caller owns hiding it again: on dismissal, set your closed state and hide the
367
+ panel, then call the returned cleanup. Cleanup leaves the top layer, returns owned focus to the trigger
368
+ without stealing focus handed elsewhere, restores the panel's inline styles and popover attributes, and
369
+ removes every listener and observer. React, Astro, and Elements date pickers and React menus share this helper.
370
+
371
+ ## Virtual collections and direction
372
+
373
+ `createLumenVirtualCollectionController(root, { items, getKey, renderItem, itemSize, overscan })`
374
+ owns an empty data-mode VirtualList root. It mounts only visible rows and focused neighbors, retains
375
+ stable keyed wrappers, and returns `update(items)` and `destroy()`. Declare data mode before the
376
+ Astro or Elements runtime initializes. See [data rendering](https://github.com/santi020k/lumen/blob/main/docs/virtual-list-data.md) for
377
+ setup, state ownership and lifecycle examples.
378
+
379
+ `getLumenVirtualWindow` calculates a fixed-height window with optional disjoint focus retention.
380
+ `observeLumenVirtualWindow` observes scroll, resize and focus; its handle provides `update()` and
381
+ `destroy()`. Applications using these lower-level helpers own row rendering and cleanup.
382
+ Data-mode controllers also preserve focus and reusable keyed content in same-origin iframe
383
+ documents, including elements adopted from another document. Range events and resize observation
384
+ use the root's document.
385
+
386
+ `getLumenDirectionalKey(element, key)` resolves the element's current inherited CSS direction and
387
+ swaps horizontal arrows in RTL. Other keys are unchanged. Web adapters use it for visual keyboard
388
+ navigation; native range inputs retain browser-owned behavior.
389
+
390
+ ## Exact localized input drafts
391
+
392
+ `parseLumenDecimalDraft(value, locale)` distinguishes empty, incomplete, invalid and valid decimal
393
+ input. `isLumenDecimalInBounds(value, { locale, min, max, step })` validates complete values;
394
+ `stepLumenDecimalDraft(value, direction, options)` performs exact steps and inclusive clamping without
395
+ floating-point conversion. Bounds and steps use ASCII decimal strings; drafts use localized decimal
396
+ separators, the locale's numbering-system digits, and Unicode decimal digits. This includes Chinese
397
+ decimal numerals (`hanidec`), so formatted steps remain editable on subsequent steps.
398
+ Grouping, exponents, whitespace and inputs exceeding 128
399
+ characters are rejected. Empty drafts stay distinct from zero; unfinished drafts cannot step.
400
+ Malformed locale tags safely use English decimal symbols.
401
+ Applications own units, currency policy, required validation and submission serialization.
402
+
403
+ `normalizeLumenNumericOTP(proposal, length)` normalizes Unicode decimal digits, whitespace and hyphens
404
+ into ASCII, rejects unrelated text and excess digits, and bounds input to 128 characters. Length must
405
+ be 1–12. `LumenTimeSelection`, `isLumenTimeSelection` and `isLumenTimeInBounds` describe wall-clock
406
+ hours/minutes with inclusive same-day bounds, leaving dates and time zones to the application.
407
+ ## Attachment preview state
408
+
409
+ `resolveLumenAttachmentPreviewState` resolves explicit fallback states, unsupported MIME types,
410
+ and image failures. `createLumenAttachmentPreviewController` enhances the documented DOM child
411
+ contract with safe state events and lifecycle cleanup. Use the framework components for product UI;
412
+ see the [attachment recipe](https://github.com/santi020k/lumen/blob/main/docs/consumer-ui-recipes.md#attachment-previews-and-file-lists).
413
+
414
+ Non-string source or MIME metadata resolves to `unavailable`; explicit loading and error states
415
+ still take precedence.
416
+
417
+ ## Chart datum activation
418
+
419
+ `createLumenChartDatumActivation(seriesId, datum)`, `createLumenHeatmapDatumActivation(datum)`,
420
+ and `createLumenRangeDatumActivation(datum)` return a validated `LumenChartDatumActivationDetail`
421
+ or `null` for an unavailable observation. The discriminated payload preserves raw axes and optional
422
+ datum IDs. `parseLumenChartDatumActivation(unknown)` validates event data and removes unrelated
423
+ fields. These helpers are also available from `@santi020k/lumen-core/charts`.
424
+
425
+ For custom browser charts, `createLumenChartActivationController(root)` delegates clicks from
426
+ `[data-ui-chart-datum]` descendants owned by a `[data-ui-chart-activation]` root. Each target's
427
+ attribute contains a JSON payload from the builders. Use native buttons with descriptive labels
428
+ as keyboard equivalents for decorative SVG marks; the controller does not create that UI.
429
+ It emits the bubbling, composed `ui:chart-datum-activate` event and returns `destroy()` for cleanup.
430
+ Applications own navigation, filtering, detail views, and server authorization.
431
+
432
+ ## Dashboard contracts
433
+
434
+ `LumenChangeSummaryItem` carries explicit display values and caller-owned changed state;
435
+ `LumenActiveFilter` identifies an active criterion. `readLumenChangeSummaryItems` and
436
+ `readLumenActiveFilters` validate unknown input, reject duplicate/empty IDs, and copy records.
437
+
438
+ Scatter geometry supports positive logarithmic X coordinates, explicit domains, and shared
439
+ reference projection. `createLumenScatterReferences`, `scaleLumenScatterX`, and
440
+ `getLumenScatterXTicks` use the same coordinate contract as `createLumenScatterGeometry`.
441
+ See [consumer UI recipes](https://github.com/santi020k/lumen/blob/main/docs/consumer-ui-recipes.md) for application ownership boundaries.
442
+
443
+ ## Extended chart models
444
+
445
+ `createLumenCalendarHeatmapGeometry`, `createLumenFunnelGeometry`, and
446
+ `createLumenBoxPlotGeometry` validate complete datasets and provide normalized geometry.
447
+ Sparse datasets and sparse box-plot outlier arrays are invalid, including empty array slots.
448
+ Comparison chart geometry follows the same rule. Use explicit `null` measurements for missing
449
+ observations; invalid datasets return no plotted rows or cells.
450
+ See [data visualization](https://github.com/santi020k/lumen/blob/main/docs/data-visualization.md) for date-only identities, ordered
451
+ stages, precomputed quartiles, missing values, and domain rules.
452
+
453
+ `isLumenTimeSelection` narrows unknown decoded values to valid same-day wall-clock selections.
454
+ `isLumenTimeInBounds` returns false for malformed selections and preserves explicit bounds validation.
455
+
456
+ ## Optional visual integrations
457
+
458
+ Coordinated DOM motion, chart continuity, safe citation URLs, and prompt/approval controllers are
459
+ exported from the main package without an animation SDK. See [visual interactions](https://github.com/santi020k/lumen/blob/main/docs/visual-interactions.md).
460
+ The optional `@santi020k/lumen-core/rive` entry requires the optional peer `@rive-app/canvas@^2.44.0`.
461
+ It owns playback, data bindings, reduced motion, visibility, and cleanup for a consumer-owned asset.
462
+ ## Presence motion
463
+
464
+ `animateLumenPresence(element, options)` animates a mounted DOM reference using the browser's Web
465
+ Animations API. It is also exported from `@santi020k/lumen`. No animation dependency is required.
466
+
467
+ ```ts
468
+ import { animateLumenPresence } from '@santi020k/lumen-core'
469
+
470
+ const controller = new AbortController()
471
+ await animateLumenPresence(element, {
472
+ duration: 'standard',
473
+ preset: 'slide-up',
474
+ signal: controller.signal
475
+ })
476
+
477
+ // Before exiting, move focus out of the item and prevent further interaction.
478
+ element.inert = true
479
+ const result = await animateLumenPresence(element, {
480
+ phase: 'exit',
481
+ preset: 'fade',
482
+ signal: controller.signal
483
+ })
484
+ if (result !== 'cancelled') element.remove()
485
+ else element.inert = false
486
+ ```
487
+
488
+ Presets are `fade`, `slide-up`, and `scale`. Durations are `fast`, `standard`, and `slow`; the helper
489
+ reads the matching `--ui-duration-fast`, `--ui-duration`, or `--ui-duration-slow` and
490
+ `--ui-ease-emphasized` CSS tokens, with shared-token fallbacks. Existing transforms and opacity are
491
+ preserved. Use a wrapper when another animation already owns those properties.
492
+
493
+ The promise resolves to `finished`, `cancelled`, or `skipped`. Reduced motion, zero duration,
494
+ detached elements, and missing browser animation support skip the effect. Abort on unmount or when
495
+ an operation becomes stale. A new presence request cancels the previous one on the same element.
496
+ System reduced-motion changes cancel a running effect and resolve it as `skipped`. DOM removal,
497
+ framework state, focus restoration, inertness, and announcements belong to the consumer; an exit
498
+ animation does not hide or remove the element itself. Unexpected animation failures reject the
499
+ promise and should use the application's error handling.
500
+
501
+ Use `data-ui-motion="reduce"` on a container to skip new presence requests and, with the optional
502
+ stylesheet, disable descendant CSS motion. Abort existing requests when changing this local preference. An application must never
503
+ override the user's system reduced-motion preference to force animations.
504
+
505
+ Import `@santi020k/lumen/styles/motion.css` alongside the base stylesheet to opt into native
506
+ disclosure height transitions and the CSS reduction scope. This small optional stylesheet works
507
+ with Astro, React, and Elements and keeps those effects out of the default stylesheet. The presence
508
+ helper's system and local reduced-motion checks work without this CSS import.
509
+
510
+ When using Tailwind, import Lumen's layer order before either stylesheet:
511
+
512
+ ```css
513
+ @import "@santi020k/lumen/layers.css";
514
+ @import "tailwindcss";
515
+ @import "@santi020k/lumen/styles.css";
516
+ @import "@santi020k/lumen/styles/motion.css";
517
+ ```
518
+
519
+ ## World map
520
+
521
+ WorldMap supports highlighted countries, location markers, dotted or solid styles, country selection,
522
+ and theme customization. Use `initialView="highlighted"` (Elements: `initial-view`) to start with a
523
+ regional view. Zoom toward the cursor with Ctrl/Cmd-scroll, or fit highlighted countries using the
524
+ map controls. Import geography explicitly from
525
+ `@santi020k/lumen-core/world-map-data`; it is excluded from root exports. See the
526
+ [WorldMap usage guide](https://github.com/santi020k/lumen/blob/main/docs/world-map.md) for adapter examples, events, localization,
527
+ accessibility, and customization.
528
+
529
+ ## Studio media workspace
530
+
531
+ Compose MediaViewport, MediaThumbnail, MediaFilmstrip and ImageComparison modes with the
532
+ [Studio media workspace recipes](https://github.com/santi020k/lumen/blob/main/docs/studio-media-workspaces.md). Applications retain
533
+ media loading, selection, adjustment algorithms, processing, export and persistence.
534
+
535
+ ## Resources
536
+
537
+ | Guide | What you will find |
538
+ | --- | --- |
539
+ | [Cross-platform architecture](https://github.com/santi020k/lumen/blob/main/docs/cross-platform.md) | Shared foundations, adapter boundaries, and support tiers. |
540
+ | [Data visualization](https://github.com/santi020k/lumen/blob/main/docs/data-visualization.md) | Data visualization guidance and examples. |
541
+ | [Figma token export](https://github.com/santi020k/lumen/blob/main/docs/figma.md) | Variables, token export, and Code Connect workflows. |
542
+ | [Contributing](https://github.com/santi020k/lumen/blob/main/CONTRIBUTING.md) | Setup, checks, and contribution workflow. |
543
+ | [Release history](https://github.com/santi020k/lumen/releases) | Published releases and version notes. |
544
+
545
+ Part of [Lumen UI](https://lumen.santi020k.com), created by [Santiago Molina](https://santi020k.com).
546
+ Licensed under [MIT](https://github.com/santi020k/lumen/blob/main/LICENSE); third-party artwork retains its own notices.
@@ -1,7 +1,21 @@
1
1
  # Third-Party Notices
2
2
 
3
- `@santi020k/lumen-core` uses libphonenumber-js and the Lucide icon library. The following notices
4
- are reproduced from their licenses.
3
+ `@santi020k/lumen-core` uses libphonenumber-js, the Lucide icon library, and Natural Earth map data.
4
+ The following notices are reproduced from their licenses.
5
+
6
+ ## Natural Earth
7
+
8
+ The `@santi020k/lumen-core/world-map-data` country geometry is generated from
9
+ [Natural Earth](https://www.naturalearthdata.com/) 1:50m Cultural Vectors, Admin 0 Countries.
10
+
11
+ Per Natural Earth's [terms of use](https://www.naturalearthdata.com/about/terms-of-use/):
12
+
13
+ Natural Earth map data is public domain and may be modified and redistributed without permission
14
+ or required attribution.
15
+
16
+ See [`maps/README.md`](../../maps/README.md) for the exact source release, checksum, retrieval
17
+ date, projection, and precision notes, and `scripts/import-natural-earth-world-map.mjs` for the
18
+ reproducible import step.
5
19
 
6
20
  ## libphonenumber-js
7
21
 
@@ -0,0 +1,25 @@
1
+ export type LumenStreamStatus = 'idle' | 'streaming' | 'complete' | 'error' | 'canceled';
2
+ export type LumenToolStatus = 'queued' | 'running' | 'success' | 'error' | 'canceled';
3
+ export type LumenApprovalStatus = 'pending' | 'approved' | 'rejected';
4
+ export interface LumenPromptSubmitDetail {
5
+ text: string;
6
+ }
7
+ export interface LumenApprovalResponseDetail {
8
+ requestId: string;
9
+ response: 'approve' | 'reject';
10
+ }
11
+ export declare const readLumenPromptSubmitDetail: (value: unknown) => LumenPromptSubmitDetail | undefined;
12
+ export declare const readLumenApprovalResponseDetail: (value: unknown) => LumenApprovalResponseDetail | undefined;
13
+ export declare const normalizeLumenPromptLimit: (value: unknown) => number;
14
+ export declare const canSubmitLumenPrompt: (text: string, limit?: number) => boolean;
15
+ /** Citations accept safe web destinations and local absolute paths, never executable schemes. */
16
+ export declare const resolveLumenCitationHref: (value: unknown) => string | undefined;
17
+ export interface LumenPromptComposerController {
18
+ destroy(): void;
19
+ sync(): void;
20
+ }
21
+ /** Bind an event bridge. A supplied native action keeps its normal POST behavior. */
22
+ export declare const createLumenPromptComposerController: (root: HTMLElement) => LumenPromptComposerController;
23
+ /** This event requests a decision; the application must still authorize the actual operation. */
24
+ export declare const bindLumenApprovalCard: (root: HTMLElement) => (() => void);
25
+ //# sourceMappingURL=ai-surfaces.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ai-surfaces.d.ts","sourceRoot":"","sources":["../src/ai-surfaces.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,iBAAiB,GAAG,MAAM,GAAG,WAAW,GAAG,UAAU,GAAG,OAAO,GAAG,UAAU,CAAA;AACxF,MAAM,MAAM,eAAe,GAAG,QAAQ,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,GAAG,UAAU,CAAA;AACrF,MAAM,MAAM,mBAAmB,GAAG,SAAS,GAAG,UAAU,GAAG,UAAU,CAAA;AAErE,MAAM,WAAW,uBAAuB;IAAG,IAAI,EAAE,MAAM,CAAA;CAAE;AACzD,MAAM,WAAW,2BAA2B;IAAG,SAAS,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,SAAS,GAAG,QAAQ,CAAA;CAAE;AAElG,eAAO,MAAM,2BAA2B,GAAI,OAAO,OAAO,KAAG,uBAAuB,GAAG,SAItF,CAAA;AAED,eAAO,MAAM,+BAA+B,GAAI,OAAO,OAAO,KAAG,2BAA2B,GAAG,SAM9F,CAAA;AAED,eAAO,MAAM,yBAAyB,GAAI,OAAO,OAAO,KAAG,MAI1D,CAAA;AAED,eAAO,MAAM,oBAAoB,GAAI,MAAM,MAAM,EAAE,cAAY,KAAG,OAEjE,CAAA;AAwBD,iGAAiG;AACjG,eAAO,MAAM,wBAAwB,GAAI,OAAO,OAAO,KAAG,MAAM,GAAG,SAQlE,CAAA;AAKD,MAAM,WAAW,6BAA6B;IAC5C,OAAO,IAAI,IAAI,CAAA;IAEf,IAAI,IAAI,IAAI,CAAA;CACb;AAED,qFAAqF;AACrF,eAAO,MAAM,mCAAmC,GAAI,MAAM,WAAW,KAAG,6BA2GvE,CAAA;AAED,iGAAiG;AACjG,eAAO,MAAM,qBAAqB,GAAI,MAAM,WAAW,KAAG,CAAC,MAAM,IAAI,CA2CpE,CAAA"}