@santi020k/lumen-react 3.0.1 → 4.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 (145) hide show
  1. package/README.md +666 -13
  2. package/dist/ai-surfaces.d.ts +49 -0
  3. package/dist/ai-surfaces.d.ts.map +1 -0
  4. package/dist/ai-surfaces.js +88 -0
  5. package/dist/amount-field.d.ts +11 -0
  6. package/dist/amount-field.d.ts.map +1 -0
  7. package/dist/amount-field.js +37 -0
  8. package/dist/attachments.d.ts +17 -0
  9. package/dist/attachments.d.ts.map +1 -0
  10. package/dist/attachments.js +23 -0
  11. package/dist/bullet-chart.d.ts +14 -0
  12. package/dist/bullet-chart.d.ts.map +1 -0
  13. package/dist/bullet-chart.js +22 -0
  14. package/dist/change-summary.d.ts +14 -0
  15. package/dist/change-summary.d.ts.map +1 -0
  16. package/dist/change-summary.js +4 -0
  17. package/dist/chart-inspection.d.ts +10 -0
  18. package/dist/chart-inspection.d.ts.map +1 -0
  19. package/dist/chart-inspection.js +11 -0
  20. package/dist/chart-interaction.d.ts +17 -0
  21. package/dist/chart-interaction.d.ts.map +1 -0
  22. package/dist/chart-interaction.js +50 -0
  23. package/dist/chart-label.d.ts +3 -0
  24. package/dist/chart-label.d.ts.map +1 -0
  25. package/dist/chart-label.js +1 -0
  26. package/dist/chart-recipes.d.ts +8 -0
  27. package/dist/chart-recipes.d.ts.map +1 -1
  28. package/dist/chart-recipes.js +35 -0
  29. package/dist/combobox.d.ts +9 -0
  30. package/dist/combobox.d.ts.map +1 -0
  31. package/dist/combobox.js +137 -0
  32. package/dist/comparison-chart.d.ts +13 -0
  33. package/dist/comparison-chart.d.ts.map +1 -0
  34. package/dist/comparison-chart.js +18 -0
  35. package/dist/components.d.ts +106 -70
  36. package/dist/components.d.ts.map +1 -1
  37. package/dist/components.js +4 -1949
  38. package/dist/dashboard.d.ts +20 -0
  39. package/dist/dashboard.d.ts.map +1 -0
  40. package/dist/dashboard.js +19 -0
  41. package/dist/data-table-range-model.d.ts +8 -0
  42. package/dist/data-table-range-model.d.ts.map +1 -0
  43. package/dist/data-table-range-model.js +31 -0
  44. package/dist/data-table-range.d.ts +17 -0
  45. package/dist/data-table-range.d.ts.map +1 -0
  46. package/dist/data-table-range.js +8 -0
  47. package/dist/data-table-saved-views.d.ts +30 -0
  48. package/dist/data-table-saved-views.d.ts.map +1 -0
  49. package/dist/data-table-saved-views.js +49 -0
  50. package/dist/data-table-selection-model.d.ts +23 -0
  51. package/dist/data-table-selection-model.d.ts.map +1 -0
  52. package/dist/data-table-selection-model.js +36 -0
  53. package/dist/data-table-selection.d.ts +11 -0
  54. package/dist/data-table-selection.d.ts.map +1 -0
  55. package/dist/data-table-selection.js +10 -0
  56. package/dist/data-table-state.d.ts +6 -0
  57. package/dist/data-table-state.d.ts.map +1 -0
  58. package/dist/data-table-state.js +38 -0
  59. package/dist/data-table-view.d.ts +88 -0
  60. package/dist/data-table-view.d.ts.map +1 -0
  61. package/dist/data-table-view.js +1 -0
  62. package/dist/data-table.d.ts +60 -0
  63. package/dist/data-table.d.ts.map +1 -0
  64. package/dist/data-table.js +1 -0
  65. package/dist/date-range-calendar.d.ts +29 -0
  66. package/dist/date-range-calendar.d.ts.map +1 -0
  67. package/dist/date-range-calendar.js +69 -0
  68. package/dist/date-range-input.d.ts +25 -0
  69. package/dist/date-range-input.d.ts.map +1 -0
  70. package/dist/date-range-input.js +195 -0
  71. package/dist/device-frame.d.ts +13 -0
  72. package/dist/device-frame.d.ts.map +1 -0
  73. package/dist/device-frame.js +23 -0
  74. package/dist/dialog-lifecycle.d.ts +3 -0
  75. package/dist/dialog-lifecycle.d.ts.map +1 -0
  76. package/dist/dialog-lifecycle.js +70 -0
  77. package/dist/expanded-charts.d.ts +26 -0
  78. package/dist/expanded-charts.d.ts.map +1 -0
  79. package/dist/expanded-charts.js +46 -0
  80. package/dist/floating-panel.d.ts +11 -0
  81. package/dist/floating-panel.d.ts.map +1 -0
  82. package/dist/floating-panel.js +1 -0
  83. package/dist/form-workflow.d.ts +77 -0
  84. package/dist/form-workflow.d.ts.map +1 -0
  85. package/dist/form-workflow.js +337 -0
  86. package/dist/hooks.d.ts +24 -21
  87. package/dist/hooks.d.ts.map +1 -1
  88. package/dist/hooks.js +1 -2468
  89. package/dist/image-comparison.d.ts +20 -0
  90. package/dist/image-comparison.d.ts.map +1 -0
  91. package/dist/image-comparison.js +55 -0
  92. package/dist/index.d.ts +25 -1
  93. package/dist/index.d.ts.map +1 -1
  94. package/dist/index.js +24 -0
  95. package/dist/interval-charts.d.ts +21 -0
  96. package/dist/interval-charts.d.ts.map +1 -0
  97. package/dist/interval-charts.js +23 -0
  98. package/dist/media-selection.d.ts +18 -0
  99. package/dist/media-selection.d.ts.map +1 -0
  100. package/dist/media-selection.js +12 -0
  101. package/dist/media-viewport.d.ts +16 -0
  102. package/dist/media-viewport.d.ts.map +1 -0
  103. package/dist/media-viewport.js +37 -0
  104. package/dist/motion.d.ts +597 -0
  105. package/dist/motion.d.ts.map +1 -0
  106. package/dist/motion.js +22 -0
  107. package/dist/review-workflow.d.ts +32 -0
  108. package/dist/review-workflow.d.ts.map +1 -0
  109. package/dist/review-workflow.js +76 -0
  110. package/dist/rich-text-editor.d.ts +21 -0
  111. package/dist/rich-text-editor.d.ts.map +1 -0
  112. package/dist/rich-text-editor.js +143 -0
  113. package/dist/select-form.d.ts +3 -0
  114. package/dist/select-form.d.ts.map +1 -0
  115. package/dist/select-form.js +1 -0
  116. package/dist/server-components.d.ts +24 -4
  117. package/dist/server-components.d.ts.map +1 -1
  118. package/dist/server-components.js +11 -3
  119. package/dist/server.d.ts +1 -0
  120. package/dist/server.d.ts.map +1 -1
  121. package/dist/server.js +1 -0
  122. package/dist/toast-context.d.ts +4 -0
  123. package/dist/toast-context.d.ts.map +1 -0
  124. package/dist/toast-context.js +10 -0
  125. package/dist/toast-provider.d.ts +3 -0
  126. package/dist/toast-provider.d.ts.map +1 -0
  127. package/dist/toast-provider.js +3 -0
  128. package/dist/use-copy-feedback.d.ts +17 -0
  129. package/dist/use-copy-feedback.d.ts.map +1 -0
  130. package/dist/use-copy-feedback.js +54 -0
  131. package/dist/virtual-list-data.d.ts +13 -0
  132. package/dist/virtual-list-data.d.ts.map +1 -0
  133. package/dist/virtual-list-data.js +87 -0
  134. package/dist/virtual-list.d.ts +14 -0
  135. package/dist/virtual-list.d.ts.map +1 -0
  136. package/dist/virtual-list.js +24 -0
  137. package/dist/visual-interactions.d.ts +16 -0
  138. package/dist/visual-interactions.d.ts.map +1 -0
  139. package/dist/visual-interactions.js +30 -0
  140. package/dist/world-map.d.ts +26 -0
  141. package/dist/world-map.d.ts.map +1 -0
  142. package/dist/world-map.js +81 -0
  143. package/package.json +99 -11
  144. package/styles/critical.css +634 -61
  145. package/styles/data-table-view.css +36 -0
@@ -0,0 +1,20 @@
1
+ import type { ComponentPropsWithoutRef, ReactNode } from 'react';
2
+ import { type LumenImageComparisonMode } from '@santi020k/lumen-core/image-comparison';
3
+ export interface ImageComparisonProps extends ComponentPropsWithoutRef<'figure'> {
4
+ after: ReactNode;
5
+ afterLabel?: string;
6
+ before: ReactNode;
7
+ beforeLabel?: string;
8
+ defaultValue?: number;
9
+ disabled?: boolean;
10
+ fit?: 'contain' | 'cover';
11
+ label: string;
12
+ locale?: string;
13
+ mode?: LumenImageComparisonMode;
14
+ name?: string;
15
+ onValueChange?: (value: number) => void;
16
+ ratio?: number;
17
+ value?: number;
18
+ }
19
+ export declare const ImageComparison: ({ after, afterLabel, before, beforeLabel, children, className, defaultValue, disabled, fit, label, locale, name, mode: requestedMode, onValueChange, ratio, value, ...props }: ImageComparisonProps) => import("react").JSX.Element;
20
+ //# sourceMappingURL=image-comparison.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"image-comparison.d.ts","sourceRoot":"","sources":["../src/image-comparison.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,wBAAwB,EAAiB,SAAS,EAAE,MAAM,OAAO,CAAA;AAG/E,OAAO,EAEL,KAAK,wBAAwB,EAI9B,MAAM,wCAAwC,CAAA;AAG/C,MAAM,WAAW,oBAAqB,SAAQ,wBAAwB,CAAC,QAAQ,CAAC;IAC9E,KAAK,EAAE,SAAS,CAAA;IAChB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,MAAM,EAAE,SAAS,CAAA;IACjB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,GAAG,CAAC,EAAE,SAAS,GAAG,OAAO,CAAA;IACzB,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,IAAI,CAAC,EAAE,wBAAwB,CAAA;IAC/B,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IACvC,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAOD,eAAO,MAAM,eAAe,GAAI,+KAI7B,oBAAoB,gCA8FtB,CAAA"}
@@ -0,0 +1,55 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { useEffect, useRef, useState } from 'react';
4
+ import { formatLumenImageComparisonValue, normalizeLumenImageComparisonMode, normalizeLumenImageComparisonRatio, normalizeLumenImageComparisonValue } from '@santi020k/lumen-core/image-comparison';
5
+ import { composeClassName } from '@santi020k/lumen-core/tokens';
6
+ export const ImageComparison = ({ after, afterLabel = 'After', before, beforeLabel = 'Before', children, className, defaultValue = 50, disabled = false, fit = 'cover', label, locale, name, mode: requestedMode = 'reveal', onValueChange, ratio = 16 / 9, value, ...props }) => {
7
+ const [internalValue, setInternalValue] = useState(() => normalizeLumenImageComparisonValue(defaultValue));
8
+ const mode = normalizeLumenImageComparisonMode(requestedMode);
9
+ const inputRef = useRef(null);
10
+ const position = normalizeLumenImageComparisonValue(value ?? internalValue);
11
+ useEffect(() => {
12
+ const input = inputRef.current;
13
+ if (!input)
14
+ return;
15
+ const pendingResets = new Set();
16
+ let pendingReset;
17
+ const reset = (event) => {
18
+ if (event.target !== input.form)
19
+ return;
20
+ pendingResets.add(event);
21
+ if (pendingReset !== undefined)
22
+ return;
23
+ pendingReset = window.setTimeout(() => {
24
+ pendingReset = undefined;
25
+ const shouldReset = [...pendingResets].some(resetEvent => !resetEvent.defaultPrevented);
26
+ pendingResets.clear();
27
+ if (!shouldReset || !input.isConnected)
28
+ return;
29
+ const next = normalizeLumenImageComparisonValue(value ?? defaultValue);
30
+ input.value = String(next);
31
+ if (value === undefined)
32
+ setInternalValue(next);
33
+ });
34
+ };
35
+ input.ownerDocument.addEventListener('reset', reset, true);
36
+ return () => {
37
+ if (pendingReset !== undefined)
38
+ window.clearTimeout(pendingReset);
39
+ pendingResets.clear();
40
+ input.ownerDocument.removeEventListener('reset', reset, true);
41
+ };
42
+ }, [defaultValue, value]);
43
+ const frameStyle = {
44
+ '--ui-image-comparison-position': `${position}%`,
45
+ '--ui-image-comparison-ratio': normalizeLumenImageComparisonRatio(ratio)
46
+ };
47
+ return (_jsxs("figure", { ...props, className: composeClassName('ui-image-comparison', className), "data-fit": fit, "data-mode": mode, children: [_jsxs("div", { className: "ui-image-comparison__frame", style: frameStyle, children: [_jsx("div", { className: "ui-image-comparison__before", hidden: mode === 'after', children: before }), _jsx("div", { className: "ui-image-comparison__after", hidden: mode === 'before', children: after }), _jsx("div", { "aria-hidden": "true", className: "ui-image-comparison__divider" })] }), _jsxs("div", { "aria-hidden": "true", className: "ui-image-comparison__labels", children: [_jsx("span", { hidden: mode === 'after', children: beforeLabel }), _jsx("span", { hidden: mode === 'before', children: afterLabel })] }), _jsxs("figcaption", { className: "ui-image-comparison__caption", children: [_jsxs("label", { className: "ui-image-comparison__control", hidden: mode !== 'reveal', children: [_jsx("span", { children: label }), _jsx("input", { ref: inputRef, "aria-valuetext": formatLumenImageComparisonValue(position, afterLabel, locale), className: "ui-slider ui-image-comparison__range", disabled: disabled || mode !== 'reveal', max: 100, min: 0, name: name, onChange: event => {
48
+ if (disabled || mode !== 'reveal')
49
+ return;
50
+ const next = normalizeLumenImageComparisonValue(event.currentTarget.valueAsNumber);
51
+ if (value === undefined)
52
+ setInternalValue(next);
53
+ onValueChange?.(next);
54
+ }, step: 1, type: "range", value: position })] }), children] })] }));
55
+ };
package/dist/index.d.ts CHANGED
@@ -1,4 +1,28 @@
1
+ export * from './ai-surfaces.js';
2
+ export * from './amount-field.js';
3
+ export * from './attachments.js';
4
+ export * from './bullet-chart.js';
5
+ export { ChangeSummary, type ChangeSummaryProps } from './change-summary.js';
6
+ export { type ChartInteractionProps } from './chart-interaction.js';
7
+ export { type ComparisonChartProps, DumbbellChart, LollipopChart } from './comparison-chart.js';
1
8
  export * from './components.js';
9
+ export * from './dashboard.js';
10
+ export * from './data-table.js';
11
+ export * from './data-table-saved-views.js';
12
+ export { parseDataTableViewState } from './data-table-state.js';
13
+ export * from './data-table-view.js';
14
+ export * from './date-range-calendar.js';
15
+ export * from './date-range-input.js';
16
+ export { DeviceFrame, type DeviceFrameProps } from './device-frame.js';
17
+ export * from './expanded-charts.js';
18
+ export * from './form-workflow.js';
2
19
  export * from './hooks.js';
3
- export { type LumenComponentName, lumenComponentNames, type LumenTabsChangeDetail, type LumenTabsChangeEvent } from '@santi020k/lumen-core';
20
+ export * from './image-comparison.js';
21
+ export * from './interval-charts.js';
22
+ export * from './media-selection.js';
23
+ export * from './media-viewport.js';
24
+ export { ToastProvider } from './toast-provider.js';
25
+ export * from './visual-interactions.js';
26
+ export * from './world-map.js';
27
+ export { type LumenChartDatumActivationDetail, type LumenComponentName, lumenComponentNames, type LumenTabsChangeDetail, type LumenTabsChangeEvent } from '@santi020k/lumen-core';
4
28
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,cAAc,iBAAiB,CAAA;AAC/B,cAAc,YAAY,CAAA;AAC1B,OAAO,EACL,KAAK,kBAAkB,EACvB,mBAAmB,EACnB,KAAK,qBAAqB,EAC1B,KAAK,oBAAoB,EAC1B,MAAM,uBAAuB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,cAAc,kBAAkB,CAAA;AAChC,cAAc,mBAAmB,CAAA;AACjC,cAAc,kBAAkB,CAAA;AAChC,cAAc,mBAAmB,CAAA;AACjC,OAAO,EAAE,aAAa,EAAE,KAAK,kBAAkB,EAAE,MAAM,qBAAqB,CAAA;AAC5E,OAAO,EAAE,KAAK,qBAAqB,EAAE,MAAM,wBAAwB,CAAA;AACnE,OAAO,EAAE,KAAK,oBAAoB,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAA;AAC/F,cAAc,iBAAiB,CAAA;AAC/B,cAAc,gBAAgB,CAAA;AAC9B,cAAc,iBAAiB,CAAA;AAC/B,cAAc,6BAA6B,CAAA;AAC3C,OAAO,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAA;AAC/D,cAAc,sBAAsB,CAAA;AACpC,cAAc,0BAA0B,CAAA;AACxC,cAAc,uBAAuB,CAAA;AACrC,OAAO,EAAE,WAAW,EAAE,KAAK,gBAAgB,EAAE,MAAM,mBAAmB,CAAA;AACtE,cAAc,sBAAsB,CAAA;AACpC,cAAc,oBAAoB,CAAA;AAClC,cAAc,YAAY,CAAA;AAC1B,cAAc,uBAAuB,CAAA;AACrC,cAAc,sBAAsB,CAAA;AACpC,cAAc,sBAAsB,CAAA;AACpC,cAAc,qBAAqB,CAAA;AACnC,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AACnD,cAAc,0BAA0B,CAAA;AACxC,cAAc,gBAAgB,CAAA;AAC9B,OAAO,EACL,KAAK,+BAA+B,EACpC,KAAK,kBAAkB,EACvB,mBAAmB,EACnB,KAAK,qBAAqB,EAC1B,KAAK,oBAAoB,EAC1B,MAAM,uBAAuB,CAAA"}
package/dist/index.js CHANGED
@@ -1,4 +1,28 @@
1
1
  'use client';
2
+ export * from './ai-surfaces.js';
3
+ export * from './amount-field.js';
4
+ export * from './attachments.js';
5
+ export * from './bullet-chart.js';
6
+ export { ChangeSummary } from './change-summary.js';
7
+ export {} from './chart-interaction.js';
8
+ export { DumbbellChart, LollipopChart } from './comparison-chart.js';
2
9
  export * from './components.js';
10
+ export * from './dashboard.js';
11
+ export * from './data-table.js';
12
+ export * from './data-table-saved-views.js';
13
+ export { parseDataTableViewState } from './data-table-state.js';
14
+ export * from './data-table-view.js';
15
+ export * from './date-range-calendar.js';
16
+ export * from './date-range-input.js';
17
+ export { DeviceFrame } from './device-frame.js';
18
+ export * from './expanded-charts.js';
19
+ export * from './form-workflow.js';
3
20
  export * from './hooks.js';
21
+ export * from './image-comparison.js';
22
+ export * from './interval-charts.js';
23
+ export * from './media-selection.js';
24
+ export * from './media-viewport.js';
25
+ export { ToastProvider } from './toast-provider.js';
26
+ export * from './visual-interactions.js';
27
+ export * from './world-map.js';
4
28
  export { lumenComponentNames } from '@santi020k/lumen-core';
@@ -0,0 +1,21 @@
1
+ import { type LumenChartLabels, type LumenChartTone, type LumenHistogramBin, type LumenWaterfallDatum } from '@santi020k/lumen-core';
2
+ import { type ChartProps } from './components.js';
3
+ interface IntervalChartProps extends Omit<ChartProps, 'children'> {
4
+ formatValue?: (value: number) => string;
5
+ labels?: Partial<LumenChartLabels>;
6
+ showTable?: boolean;
7
+ valueLabel?: string;
8
+ }
9
+ export interface WaterfallChartProps extends IntervalChartProps {
10
+ data?: readonly LumenWaterfallDatum[];
11
+ }
12
+ export declare const WaterfallChart: ({ className, data, formatValue, ...props }: WaterfallChartProps) => import("react").JSX.Element;
13
+ export interface HistogramProps extends IntervalChartProps {
14
+ bins?: readonly LumenHistogramBin[];
15
+ formatBoundary?: (value: number) => string;
16
+ frequency?: 'count' | 'density';
17
+ tone?: LumenChartTone;
18
+ }
19
+ export declare const Histogram: ({ bins, className, formatBoundary, formatValue, frequency, labels, tone, valueLabel, ...props }: HistogramProps) => import("react").JSX.Element;
20
+ export {};
21
+ //# sourceMappingURL=interval-charts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"interval-charts.d.ts","sourceRoot":"","sources":["../src/interval-charts.tsx"],"names":[],"mappings":"AAIA,OAAO,EAML,KAAK,gBAAgB,EACrB,KAAK,cAAc,EACnB,KAAK,iBAAiB,EACtB,KAAK,mBAAmB,EAEzB,MAAM,uBAAuB,CAAA;AAG9B,OAAO,EAAS,KAAK,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAExD,UAAU,kBAAmB,SAAQ,IAAI,CAAC,UAAU,EAAE,UAAU,CAAC;IAC/D,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAA;IACvC,MAAM,CAAC,EAAE,OAAO,CAAC,gBAAgB,CAAC,CAAA;IAClC,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB;AAqHD,MAAM,WAAW,mBAAoB,SAAQ,kBAAkB;IAC7D,IAAI,CAAC,EAAE,SAAS,mBAAmB,EAAE,CAAA;CACtC;AAED,eAAO,MAAM,cAAc,GAAI,4CAA0E,mBAAmB,gCAAiN,CAAA;AAE7U,MAAM,WAAW,cAAe,SAAQ,kBAAkB;IACxD,IAAI,CAAC,EAAE,SAAS,iBAAiB,EAAE,CAAA;IACnC,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAA;IAC1C,SAAS,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;IAC/B,IAAI,CAAC,EAAE,cAAc,CAAA;CACtB;AAED,eAAO,MAAM,SAAS,GAAI,iGAA+J,cAAc,gCAAyX,CAAA"}
@@ -0,0 +1,23 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
+ import { Fragment } from 'react';
4
+ import { composeClassName, createLumenHistogramGeometry, createLumenWaterfallGeometry, formatLumenChartSummary, getLumenChartToneClassName, resolveLumenChartLabels } from '@santi020k/lumen-core';
5
+ import { getChartPlotLabel } from './chart-label.js';
6
+ import { Chart } from './components.js';
7
+ const isDensityModel = (model) => 'bins' in model && model.frequency === 'density';
8
+ const intervalRows = (model, formatValue, formatBoundary) => model.marks.map((mark, index) => (_jsxs("tr", { children: [_jsx("th", { scope: "row", children: mark.label }), _jsx("td", { children: formatBoundary(mark.start) }), _jsx("td", { children: formatBoundary(mark.end) }), _jsx("td", { children: formatValue(mark.value) }), isDensityModel(model) && _jsx("td", { children: model.bins[index]?.count })] }, mark.key)));
9
+ const intervalSummary = (valid, summary, factual, invalid) => summary ?? (valid ? factual : invalid);
10
+ const intervalValueLabel = (label, fallback) => label ?? fallback;
11
+ const IntervalPlot = ({ formatBoundary, formatValue = String, labels, model, showTable = true, summary, valueLabel, ...props }) => {
12
+ const text = resolveLumenChartLabels(labels);
13
+ const label = intervalValueLabel(valueLabel, text.value);
14
+ const data = model.marks.map(mark => ({ x: mark.key, xLabel: mark.label, y: mark.value }));
15
+ const factualSummary = formatLumenChartSummary([{ id: 'values', label, data }], formatValue, text);
16
+ const hasData = model.marks.length > 0;
17
+ const rows = intervalRows(model, formatValue, formatBoundary);
18
+ return (_jsxs(Chart, { ...props, summary: intervalSummary(model.valid, summary, factualSummary, text.invalidData), children: [!hasData && _jsx("p", { className: "ui-chart__empty", role: "status", children: model.valid ? text.empty : text.invalidData }), hasData && (_jsxs(_Fragment, { children: [_jsx("p", { className: "ui-chart__axis-title", children: label }), _jsx("div", { className: "ui-chart__plot", role: "region", tabIndex: 0, "aria-label": getChartPlotLabel(props['aria-label'], props.heading, text.chartData), children: _jsxs("svg", { "aria-hidden": "true", viewBox: `0 0 ${model.width} ${model.height}`, children: [_jsx("g", { className: "ui-chart__grid", children: model.ticks.map(tick => (_jsxs(Fragment, { children: [_jsx("line", { x1: model.left, x2: model.right, y1: model.y(tick), y2: model.y(tick) }), _jsx("text", { x: model.left - 8, y: model.y(tick), children: formatValue(tick) })] }, tick))) }), _jsx("g", { className: "ui-chart__axis-labels", children: model.categoryTicks.map(tick => _jsx("text", { textAnchor: tick.textAnchor, x: tick.position, y: model.height - 16, children: tick.label }, tick.index)) }), 'connectors' in model && model.connectors.map(connector => (_jsx("line", { className: "ui-waterfall-chart__connector", x1: connector.x1, x2: connector.x2, y1: connector.y, y2: connector.y }, connector.x1))), _jsx("g", { className: "ui-bar-chart__marks", children: model.marks.map(mark => (_jsx("rect", { className: getLumenChartToneClassName(mark.tone), x: mark.x, y: mark.y, width: mark.width, height: mark.height, children: _jsxs("title", { children: [mark.label, ":", ' ', formatValue(mark.value)] }) }, mark.key))) })] }) })] })), showTable && hasData && (_jsxs("details", { className: "ui-chart__data", children: [_jsx("summary", { children: text.viewData }), _jsx("div", { "aria-label": text.chartData, role: "group", tabIndex: 0, children: _jsxs("table", { children: [_jsx("thead", { children: _jsxs("tr", { children: [_jsx("th", { scope: "col", children: text.category }), _jsx("th", { scope: "col", children: text.start }), _jsx("th", { scope: "col", children: text.end }), _jsx("th", { scope: "col", children: label }), isDensityModel(model) && _jsx("th", { scope: "col", children: text.count })] }) }), _jsx("tbody", { children: rows })] }) })] }))] }));
19
+ };
20
+ const emptyWaterfallData = [];
21
+ const emptyHistogramBins = [];
22
+ export const WaterfallChart = ({ className, data = emptyWaterfallData, formatValue = String, ...props }) => _jsx(IntervalPlot, { ...props, className: composeClassName('ui-waterfall-chart', className), model: createLumenWaterfallGeometry(data, { formatValue }), formatValue: formatValue, formatBoundary: formatValue });
23
+ export const Histogram = ({ bins = emptyHistogramBins, className, formatBoundary = String, formatValue = String, frequency = 'count', labels, tone = 'series-1', valueLabel, ...props }) => _jsx(IntervalPlot, { ...props, ...(labels ? { labels } : {}), className: composeClassName('ui-histogram', className), model: createLumenHistogramGeometry(bins, { formatBoundary, formatValue, frequency, tone }), formatBoundary: formatBoundary, formatValue: formatValue, valueLabel: valueLabel ?? resolveLumenChartLabels(labels)[frequency === 'density' ? 'density' : 'count'] });
@@ -0,0 +1,18 @@
1
+ import type { ComponentPropsWithoutRef } from 'react';
2
+ import { type ButtonProps } from './components.js';
3
+ export interface MediaThumbnailProps extends Omit<ButtonProps, 'asChild'> {
4
+ label: string;
5
+ mediaId?: string;
6
+ order?: number;
7
+ selected?: boolean;
8
+ state?: 'ready' | 'loading' | 'error';
9
+ stateLabel?: string;
10
+ }
11
+ export declare const MediaThumbnail: ({ children, className, disabled, label, mediaId, order, selected, state, stateLabel, ...props }: MediaThumbnailProps) => import("react").JSX.Element;
12
+ export interface MediaFilmstripProps extends ComponentPropsWithoutRef<'section'> {
13
+ label: string;
14
+ selectionLabel: string;
15
+ }
16
+ /** Children are native list items containing a thumbnail and optional sibling move actions. */
17
+ export declare const MediaFilmstrip: ({ children, className, label, selectionLabel, ...props }: MediaFilmstripProps) => import("react").JSX.Element;
18
+ //# sourceMappingURL=media-selection.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"media-selection.d.ts","sourceRoot":"","sources":["../src/media-selection.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,OAAO,CAAA;AAKrD,OAAO,EAAU,KAAK,WAAW,EAAE,MAAM,iBAAiB,CAAA;AAE1D,MAAM,WAAW,mBAAoB,SAAQ,IAAI,CAAC,WAAW,EAAE,SAAS,CAAC;IACvE,KAAK,EAAE,MAAM,CAAA;IACb,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,KAAK,CAAC,EAAE,OAAO,GAAG,SAAS,GAAG,OAAO,CAAA;IACrC,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB;AAED,eAAO,MAAM,cAAc,GAAI,iGAE5B,mBAAmB,gCAYrB,CAAA;AAED,MAAM,WAAW,mBAAoB,SAAQ,wBAAwB,CAAC,SAAS,CAAC;IAC9E,KAAK,EAAE,MAAM,CAAA;IACb,cAAc,EAAE,MAAM,CAAA;CACvB;AAED,+FAA+F;AAC/F,eAAO,MAAM,cAAc,GAAI,0DAA0D,mBAAmB,gCAQ3G,CAAA"}
@@ -0,0 +1,12 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { formatLumenMediaThumbnailState, resolveLumenMediaOrder } from '@santi020k/lumen-core/media-workspace';
4
+ import { composeClassName } from '@santi020k/lumen-core/tokens';
5
+ import { Button } from './components.js';
6
+ export const MediaThumbnail = ({ children, className, disabled, label, mediaId, order, selected = false, state = 'ready', stateLabel, ...props }) => {
7
+ const position = resolveLumenMediaOrder(order);
8
+ const status = formatLumenMediaThumbnailState(state, stateLabel);
9
+ return (_jsxs(Button, { ...props, className: composeClassName('ui-media-thumbnail', className), variant: "outline", "aria-busy": state === 'loading' || undefined, "aria-pressed": selected, disabled: disabled === true || state !== 'ready', "data-state": state, "data-media-id": mediaId, children: [_jsx("span", { className: "ui-media-thumbnail__media", "aria-hidden": "true", children: children }), _jsx("span", { className: "ui-media-thumbnail__label", children: label }), position !== undefined && _jsx("span", { className: "ui-media-thumbnail__order", children: position }), state !== 'ready' && _jsx("span", { className: "ui-media-thumbnail__state", children: status })] }));
10
+ };
11
+ /** Children are native list items containing a thumbnail and optional sibling move actions. */
12
+ export const MediaFilmstrip = ({ children, className, label, selectionLabel, ...props }) => (_jsxs("section", { ...props, className: composeClassName('ui-media-filmstrip', className), "aria-label": label, children: [_jsxs("div", { className: "ui-media-filmstrip__heading", children: [_jsx("span", { children: label }), _jsx("span", { role: "status", children: selectionLabel })] }), _jsx("ol", { className: "ui-media-filmstrip__items", children: children })] }));
@@ -0,0 +1,16 @@
1
+ import type { ComponentPropsWithoutRef } from 'react';
2
+ import { type LumenMediaViewportLabels } from '@santi020k/lumen-core/media-viewport';
3
+ import { type LumenMediaViewportValue } from '@santi020k/lumen-core/media-workspace';
4
+ export interface MediaViewportProps extends Omit<ComponentPropsWithoutRef<'figure'>, 'defaultValue'> {
5
+ defaultValue?: Partial<LumenMediaViewportValue>;
6
+ disabled?: boolean;
7
+ label: string;
8
+ labels?: Partial<LumenMediaViewportLabels>;
9
+ locale?: string;
10
+ maxZoom?: number;
11
+ onValueChange?: (value: LumenMediaViewportValue) => void;
12
+ ratio?: number;
13
+ value?: LumenMediaViewportValue;
14
+ }
15
+ export declare const MediaViewport: ({ children, className, defaultValue, disabled, label, labels, locale, maxZoom, onValueChange, ratio, value, ...props }: MediaViewportProps) => import("react").JSX.Element;
16
+ //# sourceMappingURL=media-viewport.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"media-viewport.d.ts","sourceRoot":"","sources":["../src/media-viewport.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,OAAO,CAAA;AAGrD,OAAO,EAIL,KAAK,wBAAwB,EAG9B,MAAM,sCAAsC,CAAA;AAC7C,OAAO,EACL,KAAK,uBAAuB,EAG7B,MAAM,uCAAuC,CAAA;AAK9C,MAAM,WAAW,kBAAmB,SAAQ,IAAI,CAAC,wBAAwB,CAAC,QAAQ,CAAC,EAAE,cAAc,CAAC;IAClG,YAAY,CAAC,EAAE,OAAO,CAAC,uBAAuB,CAAC,CAAA;IAC/C,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,CAAC,EAAE,OAAO,CAAC,wBAAwB,CAAC,CAAA;IAC1C,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,uBAAuB,KAAK,IAAI,CAAA;IACxD,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,KAAK,CAAC,EAAE,uBAAuB,CAAA;CAChC;AAED,eAAO,MAAM,aAAa,GAAI,wHAG3B,kBAAkB,gCAgEpB,CAAA"}
@@ -0,0 +1,37 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { useEffect, useId, useMemo, useRef, useState } from 'react';
4
+ import { bindLumenMediaViewport, formatLumenMediaZoom, lumenMediaViewportActions, lumenMediaViewportLabels, syncLumenMediaViewport } from '@santi020k/lumen-core/media-viewport';
5
+ import { normalizeLumenMediaViewport, resolveLumenMediaMaxZoom } from '@santi020k/lumen-core/media-workspace';
6
+ import { composeClassName } from '@santi020k/lumen-core/tokens';
7
+ import { Button } from './components.js';
8
+ export const MediaViewport = ({ children, className, defaultValue, disabled = false, label, labels, locale, maxZoom = 4, onValueChange, ratio = 16 / 9, value, ...props }) => {
9
+ const [internal, setInternal] = useState(() => normalizeLumenMediaViewport(defaultValue, maxZoom));
10
+ const current = useMemo(() => normalizeLumenMediaViewport(value ?? internal, maxZoom), [value, internal, maxZoom]);
11
+ const rootRef = useRef(null);
12
+ const statusId = useId();
13
+ const optionsRef = useRef({ current, disabled, maxZoom, onValueChange, controlled: value !== undefined });
14
+ useEffect(() => {
15
+ optionsRef.current = { current, disabled, maxZoom, onValueChange, controlled: value !== undefined };
16
+ if (rootRef.current)
17
+ syncLumenMediaViewport(rootRef.current, current, maxZoom, disabled, locale);
18
+ }, [current, disabled, maxZoom, onValueChange, value, locale]);
19
+ useEffect(() => {
20
+ const root = rootRef.current;
21
+ if (!root)
22
+ return;
23
+ return bindLumenMediaViewport(root, {
24
+ disabled: () => optionsRef.current.disabled,
25
+ getValue: () => optionsRef.current.current,
26
+ maxZoom: () => optionsRef.current.maxZoom,
27
+ onValueChange: next => {
28
+ if (!optionsRef.current.controlled)
29
+ setInternal(next);
30
+ optionsRef.current.onValueChange?.(next);
31
+ }
32
+ });
33
+ }, []);
34
+ const copy = { ...lumenMediaViewportLabels, ...labels };
35
+ const safeRatio = Number.isFinite(ratio) && ratio >= 0.1 && ratio <= 10 ? ratio : 16 / 9;
36
+ return (_jsxs("figure", { ...props, ref: rootRef, className: composeClassName('ui-media-viewport', className), children: [_jsx("div", { "aria-describedby": statusId, "aria-disabled": disabled, "aria-label": label, className: "ui-media-viewport__stage", "data-ui-media-viewport-stage": true, role: "group", style: { aspectRatio: safeRatio, touchAction: current.zoom > 1 && !disabled ? 'none' : 'pan-y' }, tabIndex: 0, children: _jsx("div", { className: "ui-media-viewport__content", "data-ui-media-viewport-content": true, style: { transform: `translate(${current.x * (current.zoom - 1) * 50}%, ${current.y * (current.zoom - 1) * 50}%) scale(${current.zoom})` }, children: children }) }), _jsxs("figcaption", { children: [_jsx("span", { children: label }), _jsx("span", { id: statusId, role: "status", "aria-live": "polite", "data-ui-media-viewport-status": true, children: formatLumenMediaZoom(current.zoom, locale) }), _jsx("div", { className: "ui-media-viewport__actions", role: "group", "aria-label": label, children: lumenMediaViewportActions.map(action => (_jsx(Button, { variant: "outline", "data-ui-media-viewport-action": action, disabled: disabled || (action === 'zoom-in' && current.zoom >= resolveLumenMediaMaxZoom(maxZoom)) || (action !== 'zoom-in' && current.zoom === 1), children: copy[action] }, action))) })] })] }));
37
+ };