@santi020k/lumen-react 3.0.0 → 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 -1947
  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,32 @@
1
+ export type LumenReviewResult = {
2
+ status: 'success';
3
+ } | {
4
+ status: 'failure';
5
+ message: string;
6
+ } | {
7
+ status: 'uncertain';
8
+ message: string;
9
+ };
10
+ export type LumenReviewStatus = 'editing' | 'review' | 'pending' | LumenReviewResult['status'];
11
+ export interface LumenReviewWorkflowOptions<T> {
12
+ /** Change after every edit or server revision. Never reuse an earlier revision for a new draft. */
13
+ revision: string;
14
+ submit: (proposal: T) => Promise<LumenReviewResult>;
15
+ /** Safe localized fallback when a thrown error leaves the commit outcome unknown. */
16
+ uncertainMessage: string;
17
+ }
18
+ /** Review immutable application-owned proposals. No requests, persistence or automatic retries. */
19
+ export declare const useLumenReviewWorkflow: <T>({ revision, submit, uncertainMessage }: LumenReviewWorkflowOptions<T>) => {
20
+ status: LumenReviewStatus;
21
+ message: string;
22
+ proposal: T | undefined;
23
+ revision: string | undefined;
24
+ review: (proposal: T) => boolean;
25
+ edit: () => boolean;
26
+ confirm: () => Promise<boolean>;
27
+ /** Call only after the application has checked the durable command outcome. */
28
+ reconcile: (result: Exclude<LumenReviewResult, {
29
+ status: "uncertain";
30
+ }>) => boolean;
31
+ };
32
+ //# sourceMappingURL=review-workflow.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"review-workflow.d.ts","sourceRoot":"","sources":["../src/review-workflow.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,iBAAiB,GAAG;IAAE,MAAM,EAAE,SAAS,CAAA;CAAE,GAAG;IAAE,MAAM,EAAE,SAAS,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,MAAM,EAAE,WAAW,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAA;AACzI,MAAM,MAAM,iBAAiB,GAAG,SAAS,GAAG,QAAQ,GAAG,SAAS,GAAG,iBAAiB,CAAC,QAAQ,CAAC,CAAA;AAE9F,MAAM,WAAW,0BAA0B,CAAC,CAAC;IAC3C,mGAAmG;IACnG,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,KAAK,OAAO,CAAC,iBAAiB,CAAC,CAAA;IACnD,qFAAqF;IACrF,gBAAgB,EAAE,MAAM,CAAA;CACzB;AAED,mGAAmG;AACnG,eAAO,MAAM,sBAAsB,GAAI,CAAC,EAAE,wCAAwC,0BAA0B,CAAC,CAAC,CAAC;;;;;uBAwCxF,CAAC,KAAG,OAAO;gBAWpB,OAAO;mBAWE,OAAO,CAAC,OAAO,CAAC;IAoBnC,+EAA+E;wBAC3D,OAAO,CAAC,iBAAiB,EAAE;QAAE,MAAM,EAAE,WAAW,CAAA;KAAE,CAAC,KAAG,OAAO;CAQpF,CAAA"}
@@ -0,0 +1,76 @@
1
+ 'use client';
2
+ import { useLayoutEffect, useRef, useState } from 'react';
3
+ /** Review immutable application-owned proposals. No requests, persistence or automatic retries. */
4
+ export const useLumenReviewWorkflow = ({ revision, submit, uncertainMessage }) => {
5
+ const latestRef = useRef({ revision, submit, uncertainMessage });
6
+ const snapshotRef = useRef(undefined);
7
+ const phaseRef = useRef('editing');
8
+ const mountedRef = useRef(false);
9
+ const [status, setStatus] = useState('editing');
10
+ const [message, setMessage] = useState('');
11
+ const [reviewedSnapshot, setReviewedSnapshot] = useState(undefined);
12
+ useLayoutEffect(() => {
13
+ latestRef.current = { revision, submit, uncertainMessage };
14
+ });
15
+ useLayoutEffect(() => {
16
+ mountedRef.current = true;
17
+ return () => {
18
+ mountedRef.current = false;
19
+ };
20
+ }, []);
21
+ const changeStatus = (next, text = '') => {
22
+ phaseRef.current = next;
23
+ if (mountedRef.current) {
24
+ setStatus(next);
25
+ setMessage(text);
26
+ }
27
+ };
28
+ const locked = () => phaseRef.current === 'pending' || phaseRef.current === 'uncertain';
29
+ const stale = reviewedSnapshot !== undefined && reviewedSnapshot.revision !== revision;
30
+ const visibleStatus = stale && status !== 'pending' && status !== 'uncertain' ? 'editing' : status;
31
+ return {
32
+ status: visibleStatus,
33
+ message: visibleStatus === 'editing' ? '' : message,
34
+ proposal: visibleStatus === 'editing' ? undefined : reviewedSnapshot?.proposal,
35
+ revision: reviewedSnapshot?.revision,
36
+ review: (proposal) => {
37
+ if (locked())
38
+ return false;
39
+ snapshotRef.current = { revision: latestRef.current.revision, proposal };
40
+ setReviewedSnapshot(snapshotRef.current);
41
+ changeStatus('review');
42
+ return true;
43
+ },
44
+ edit: () => {
45
+ if (locked())
46
+ return false;
47
+ snapshotRef.current = undefined;
48
+ setReviewedSnapshot(undefined);
49
+ changeStatus('editing');
50
+ return true;
51
+ },
52
+ confirm: async () => {
53
+ const reviewed = snapshotRef.current;
54
+ if (!mountedRef.current || locked() || reviewed?.revision !== latestRef.current.revision ||
55
+ (phaseRef.current !== 'review' && phaseRef.current !== 'failure'))
56
+ return false;
57
+ changeStatus('pending');
58
+ let result;
59
+ try {
60
+ result = await latestRef.current.submit(reviewed.proposal);
61
+ }
62
+ catch {
63
+ result = { status: 'uncertain', message: latestRef.current.uncertainMessage };
64
+ }
65
+ changeStatus(result.status, result.status === 'success' ? '' : result.message);
66
+ return result.status === 'success';
67
+ },
68
+ /** Call only after the application has checked the durable command outcome. */
69
+ reconcile: (result) => {
70
+ if (phaseRef.current !== 'uncertain')
71
+ return false;
72
+ changeStatus(result.status, result.status === 'success' ? '' : result.message);
73
+ return true;
74
+ }
75
+ };
76
+ };
@@ -0,0 +1,21 @@
1
+ import type { ComponentPropsWithRef, JSX, RefObject } from 'react';
2
+ import { type LumenRichTextChangeDetail, type LumenRichTextCommandDetail as CoreRichTextCommandDetail, type LumenRichTextCommandRequest } from '@santi020k/lumen-core';
3
+ type ChangeHandler<T> = (value: T) => void;
4
+ type LumenProps<Tag extends keyof JSX.IntrinsicElements> = ComponentPropsWithRef<Tag> & Record<`data-${string}`, unknown>;
5
+ export type RichTextEditorCommandDetail = CoreRichTextCommandDetail;
6
+ export interface RichTextEditorOptions {
7
+ nativeState?: boolean;
8
+ commandHandler?: (request: LumenRichTextCommandRequest) => boolean;
9
+ onChange?: ChangeHandler<LumenRichTextChangeDetail> | undefined;
10
+ onCommand?: ChangeHandler<RichTextEditorCommandDetail> | undefined;
11
+ }
12
+ export interface RichTextEditorController {
13
+ executeCommand: (command: string, root?: HTMLElement | null, value?: string) => boolean;
14
+ getCommandProps: (command: string, props?: LumenProps<'button'>) => LumenProps<'button'>;
15
+ getEditableProps: (props?: ComponentPropsWithRef<'div'>) => LumenProps<'div'>;
16
+ rootProps: LumenProps<'section'>;
17
+ rootRef: RefObject<HTMLElement | null>;
18
+ }
19
+ export declare const useRichTextEditor: ({ commandHandler, nativeState, onChange, onCommand }?: RichTextEditorOptions) => RichTextEditorController;
20
+ export {};
21
+ //# sourceMappingURL=rich-text-editor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rich-text-editor.d.ts","sourceRoot":"","sources":["../src/rich-text-editor.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAGlE,OAAO,EAIL,KAAK,yBAAyB,EAC9B,KAAK,0BAA0B,IAAI,yBAAyB,EAC5D,KAAK,2BAA2B,EACjC,MAAM,uBAAuB,CAAA;AAE9B,KAAK,aAAa,CAAC,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI,CAAA;AAE1C,KAAK,UAAU,CAAC,GAAG,SAAS,MAAM,GAAG,CAAC,iBAAiB,IAAI,qBAAqB,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,QAAQ,MAAM,EAAE,EAAE,OAAO,CAAC,CAAA;AAQzH,MAAM,MAAM,2BAA2B,GAAG,yBAAyB,CAAA;AAEnE,MAAM,WAAW,qBAAqB;IACpC,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,cAAc,CAAC,EAAE,CAAC,OAAO,EAAE,2BAA2B,KAAK,OAAO,CAAA;IAClE,QAAQ,CAAC,EAAE,aAAa,CAAC,yBAAyB,CAAC,GAAG,SAAS,CAAA;IAC/D,SAAS,CAAC,EAAE,aAAa,CAAC,2BAA2B,CAAC,GAAG,SAAS,CAAA;CACnE;AAED,MAAM,WAAW,wBAAwB;IACvC,cAAc,EAAE,CACd,OAAO,EAAE,MAAM,EACf,IAAI,CAAC,EAAE,WAAW,GAAG,IAAI,EACzB,KAAK,CAAC,EAAE,MAAM,KACX,OAAO,CAAA;IACZ,eAAe,EAAE,CACf,OAAO,EAAE,MAAM,EACf,KAAK,CAAC,EAAE,UAAU,CAAC,QAAQ,CAAC,KACzB,UAAU,CAAC,QAAQ,CAAC,CAAA;IACzB,gBAAgB,EAAE,CAAC,KAAK,CAAC,EAAE,qBAAqB,CAAC,KAAK,CAAC,KAAK,UAAU,CAAC,KAAK,CAAC,CAAA;IAC7E,SAAS,EAAE,UAAU,CAAC,SAAS,CAAC,CAAA;IAChC,OAAO,EAAE,SAAS,CAAC,WAAW,GAAG,IAAI,CAAC,CAAA;CACvC;AAmFD,eAAO,MAAM,iBAAiB,GAAI,uDAK/B,qBAA0B,KAAG,wBAiJ/B,CAAA"}
@@ -0,0 +1,143 @@
1
+ import { useCallback, useEffect, useRef } from 'react';
2
+ import { executeLumenRichTextCommand, getLumenRichTextShortcut, isLumenRichTextToggleCommand } from '@santi020k/lumen-core';
3
+ const composeHandlers = (userHandler, lumenHandler) => (event) => {
4
+ userHandler?.(event);
5
+ if (!event.defaultPrevented)
6
+ lumenHandler(event);
7
+ };
8
+ const getCommandState = (control, commandDocument) => {
9
+ const command = control.dataset.uiEditorCommand ?? '';
10
+ const value = control.dataset.uiEditorValue;
11
+ let active = false;
12
+ if (isLumenRichTextToggleCommand(command)) {
13
+ active = commandDocument.queryCommandState?.(command) ?? false;
14
+ control.setAttribute('aria-pressed', String(active));
15
+ }
16
+ else if (command === 'formatBlock' && value) {
17
+ const currentValue = commandDocument
18
+ .queryCommandValue?.(command)
19
+ .replaceAll(/[<>]/g, '')
20
+ .toLowerCase();
21
+ active = currentValue === value.replaceAll(/[<>]/g, '').toLowerCase();
22
+ }
23
+ return active;
24
+ };
25
+ const richTextEditorContentSelector = '[data-ui-rich-text-editable], [contenteditable="true"]';
26
+ const getRichTextChangeDetail = (root) => {
27
+ const editable = root?.querySelector(richTextEditorContentSelector);
28
+ if (!editable)
29
+ return null;
30
+ return {
31
+ html: editable.innerHTML,
32
+ text: editable.textContent
33
+ };
34
+ };
35
+ const executeRichTextDocumentCommand = (commandDocument, command, value) => {
36
+ if (typeof commandDocument?.execCommand !== 'function')
37
+ return false;
38
+ return value === undefined ?
39
+ commandDocument.execCommand(command) :
40
+ commandDocument.execCommand(command, false, value);
41
+ };
42
+ const syncRichTextCommandStates = (root) => {
43
+ if (!root || root.dataset.uiEditorNativeState === 'false')
44
+ return;
45
+ const commandDocument = root.ownerDocument;
46
+ for (const control of root.querySelectorAll('[data-ui-editor-command]')) {
47
+ const active = getCommandState(control, commandDocument);
48
+ control.dataset.state = active ? 'on' : 'off';
49
+ }
50
+ };
51
+ const getRichTextCommandDocument = (root) => {
52
+ if (root)
53
+ return root.ownerDocument;
54
+ return typeof document === 'undefined' ? undefined : document;
55
+ };
56
+ export const useRichTextEditor = ({ commandHandler, nativeState = !commandHandler, onChange, onCommand } = {}) => {
57
+ const rootRef = useRef(null);
58
+ useEffect(() => {
59
+ syncRichTextCommandStates(rootRef.current);
60
+ }, [nativeState]);
61
+ const emitChange = useCallback((root) => {
62
+ const detail = getRichTextChangeDetail(root);
63
+ if (!detail)
64
+ return;
65
+ if (typeof CustomEvent !== 'undefined') {
66
+ root?.dispatchEvent(new CustomEvent('ui:editor-change', {
67
+ bubbles: true,
68
+ detail
69
+ }));
70
+ }
71
+ onChange?.(detail);
72
+ }, [onChange]);
73
+ const executeCommand = useCallback((command, root = rootRef.current, value) => {
74
+ if (!command)
75
+ return false;
76
+ const commandDocument = getRichTextCommandDocument(root);
77
+ const request = { command, ...(value === undefined ? {} : { value }) };
78
+ const fallback = () => executeRichTextDocumentCommand(commandDocument, command, value);
79
+ const executed = executeLumenRichTextCommand(root, request, fallback, commandHandler);
80
+ const detail = {
81
+ command,
82
+ executed,
83
+ ...(value === undefined ? {} : { value })
84
+ };
85
+ if (root && typeof CustomEvent !== 'undefined') {
86
+ root.dispatchEvent(new CustomEvent('ui:editor-command', {
87
+ bubbles: true,
88
+ detail
89
+ }));
90
+ }
91
+ onCommand?.(detail);
92
+ syncRichTextCommandStates(root);
93
+ emitChange(root);
94
+ return executed;
95
+ }, [commandHandler, emitChange, onCommand]);
96
+ const getCommandProps = useCallback((command, props = {}) => ({
97
+ ...props,
98
+ 'data-ui-editor-command': command,
99
+ onClick: composeHandlers(props.onClick, event => {
100
+ const root = event.currentTarget.closest('[data-ui-rich-text-editor]') ?? rootRef.current;
101
+ executeCommand(command, root, event.currentTarget.dataset.uiEditorValue);
102
+ }),
103
+ type: props.type ?? 'button'
104
+ }), [executeCommand]);
105
+ const getEditableProps = useCallback((props = {}) => ({
106
+ ...props,
107
+ 'aria-multiline': props['aria-multiline'] ?? true,
108
+ contentEditable: props.contentEditable ?? true,
109
+ 'data-ui-rich-text-editable': true,
110
+ onInput: composeHandlers(props.onInput, event => {
111
+ const root = event.currentTarget.closest('[data-ui-rich-text-editor]') ?? rootRef.current;
112
+ syncRichTextCommandStates(root);
113
+ emitChange(root);
114
+ }),
115
+ onKeyDown: composeHandlers(props.onKeyDown, event => {
116
+ const command = getLumenRichTextShortcut(event);
117
+ if (!command)
118
+ return;
119
+ event.preventDefault();
120
+ const root = event.currentTarget.closest('[data-ui-rich-text-editor]') ?? rootRef.current;
121
+ executeCommand(command, root);
122
+ }),
123
+ onKeyUp: composeHandlers(props.onKeyUp, event => {
124
+ syncRichTextCommandStates(event.currentTarget.closest('[data-ui-rich-text-editor]') ?? rootRef.current);
125
+ }),
126
+ onMouseUp: composeHandlers(props.onMouseUp, event => {
127
+ syncRichTextCommandStates(event.currentTarget.closest('[data-ui-rich-text-editor]') ?? rootRef.current);
128
+ }),
129
+ role: props.role ?? 'textbox',
130
+ suppressContentEditableWarning: props.suppressContentEditableWarning ?? true
131
+ }), [emitChange, executeCommand]);
132
+ return {
133
+ executeCommand,
134
+ getCommandProps,
135
+ getEditableProps,
136
+ rootProps: {
137
+ 'data-ui-rich-text-editor': true,
138
+ 'data-ui-editor-native-state': String(nativeState),
139
+ ref: rootRef
140
+ },
141
+ rootRef
142
+ };
143
+ };
@@ -0,0 +1,3 @@
1
+ import type { RefObject } from 'react';
2
+ export declare const useSelectFormReset: (rootRef: RefObject<HTMLElement | null>, defaultValue: string, value: string | undefined, restoreValue: (value: string) => void, close: () => void) => void;
3
+ //# sourceMappingURL=select-form.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"select-form.d.ts","sourceRoot":"","sources":["../src/select-form.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAGtC,eAAO,MAAM,kBAAkB,GAC7B,SAAS,SAAS,CAAC,WAAW,GAAG,IAAI,CAAC,EACtC,cAAc,MAAM,EACpB,OAAO,MAAM,GAAG,SAAS,EACzB,cAAc,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,EACrC,OAAO,MAAM,IAAI,KAChB,IAiDF,CAAA"}
@@ -0,0 +1 @@
1
+ import{useEffect}from"react";const useSelectFormReset=(rootRef,defaultValue,value,restoreValue,close)=>{useEffect(()=>{const root=rootRef.current;if(!root)return;const resets=new Set;let timer;const reset=event=>{const native=root.querySelector("[data-ui-select-native]");native&&event.target===native.form&&(resets.add(event),timer===void 0&&(timer=setTimeout(()=>{timer=void 0;const accepted=[...resets].some(resetEvent=>!resetEvent.defaultPrevented);if(resets.clear(),!accepted||!root.isConnected)return;const next=value??defaultValue;restoreValue(next),native.value=next,close()})))};return root.ownerDocument.addEventListener("reset",reset,!0),()=>{clearTimeout(timer),resets.clear(),root.ownerDocument.removeEventListener("reset",reset,!0)}},[close,defaultValue,restoreValue,rootRef,value])};export{useSelectFormReset};
@@ -1,4 +1,5 @@
1
1
  import { type ComponentPropsWithoutRef, type ComponentPropsWithRef, type ElementType } from 'react';
2
+ import { type LumenControlVisualSize } from '@santi020k/lumen-core';
2
3
  export type LumenGlassProp = boolean | 'strong' | 'subtle';
3
4
  export type LumenPrimitiveProps<T extends ElementType = 'div'> = {
4
5
  as?: T;
@@ -11,10 +12,11 @@ export declare const Badge: ({ className, variant, ...props }: BadgeProps) => im
11
12
  type CardVariant = 'default' | 'glass' | 'interactive' | 'muted' | 'unstyled';
12
13
  export type CardProps<T extends ElementType = 'div'> = LumenPrimitiveProps<T> & {
13
14
  'data-variant'?: CardVariant;
15
+ density?: 'comfortable' | 'compact' | 'spacious';
14
16
  glass?: LumenGlassProp;
15
17
  variant?: CardVariant;
16
18
  };
17
- export declare const Card: <T extends ElementType = "div">({ as, className, glass, variant, ...props }: CardProps<T>) => import("react").JSX.Element;
19
+ export declare const Card: <T extends ElementType = "div">({ as, className, density, glass, variant, ...props }: CardProps<T>) => import("react").JSX.Element;
18
20
  export type CardHeaderProps<T extends ElementType = 'div'> = LumenPrimitiveProps<T>;
19
21
  export declare const CardHeader: <T extends ElementType = "div">({ as, ...props }: CardHeaderProps<T>) => import("react").JSX.Element;
20
22
  export type CardTitleProps<T extends ElementType = 'div'> = LumenPrimitiveProps<T>;
@@ -35,12 +37,12 @@ export declare const Direction: ({ className, dir, ...props }: DirectionProps) =
35
37
  export interface GridProps extends ComponentPropsWithRef<'div'> {
36
38
  as?: ElementType;
37
39
  columns?: 1 | 2 | 3 | 4 | 6 | 12 | 'auto';
38
- gap?: 'lg' | 'md' | 'none' | 'sm' | 'xl';
40
+ gap?: '2xl' | '3xl' | 'group' | 'lg' | 'md' | 'none' | 'related' | 'section' | 'sm' | 'xl' | 'xs';
39
41
  minItemWidth?: string;
40
42
  }
41
43
  export declare const Grid: ({ as, className, columns, gap, minItemWidth, style, ...props }: GridProps) => import("react").ReactElement<any, string | import("react").JSXElementConstructor<any>>;
42
44
  export interface InputProps extends ComponentPropsWithRef<'input'> {
43
- visualSize?: 'default' | 'lg' | 'sm';
45
+ visualSize?: LumenControlVisualSize;
44
46
  }
45
47
  export declare const Input: ({ className, ref, type, visualSize, ...props }: InputProps) => import("react").JSX.Element;
46
48
  export type LabelProps = ComponentPropsWithRef<'label'>;
@@ -63,7 +65,7 @@ export interface StackProps extends ComponentPropsWithRef<'div'> {
63
65
  align?: 'center' | 'end' | 'start' | 'stretch';
64
66
  as?: ElementType;
65
67
  direction?: Orientation;
66
- gap?: 'lg' | 'md' | 'none' | 'sm' | 'xl';
68
+ gap?: '2xl' | '3xl' | 'group' | 'lg' | 'md' | 'none' | 'related' | 'section' | 'sm' | 'xl' | 'xs';
67
69
  justify?: 'between' | 'center' | 'end' | 'start';
68
70
  wrap?: boolean;
69
71
  }
@@ -76,5 +78,23 @@ export interface VisuallyHiddenProps extends ComponentPropsWithRef<'span'> {
76
78
  focusable?: boolean;
77
79
  }
78
80
  export declare const VisuallyHidden: ({ className, focusable, ...props }: VisuallyHiddenProps) => import("react").JSX.Element;
81
+ export type DialogHeaderProps = ComponentPropsWithRef<'header'>;
82
+ export declare const DialogHeader: ({ className, ...props }: DialogHeaderProps) => import("react").JSX.Element;
83
+ export type DialogTitleProps = ComponentPropsWithRef<'h2'> & {
84
+ as?: 'h2' | 'h3' | 'h4';
85
+ };
86
+ export declare const DialogTitle: ({ as: Tag, className, ...props }: DialogTitleProps) => import("react").JSX.Element;
87
+ export type DialogBodyProps = ComponentPropsWithRef<'div'>;
88
+ export declare const DialogBody: ({ className, ...props }: DialogBodyProps) => import("react").JSX.Element;
89
+ export type DialogFooterProps = ComponentPropsWithRef<'footer'>;
90
+ export declare const DialogFooter: ({ className, ...props }: DialogFooterProps) => import("react").JSX.Element;
91
+ export type DescriptionItemProps = ComponentPropsWithRef<'div'>;
92
+ export declare const DescriptionItem: ({ className, ...props }: DescriptionItemProps) => import("react").JSX.Element;
93
+ export type DescriptionTermProps = ComponentPropsWithRef<'dt'>;
94
+ export declare const DescriptionTerm: ({ className, ...props }: DescriptionTermProps) => import("react").JSX.Element;
95
+ export type DescriptionDetailProps = ComponentPropsWithRef<'dd'>;
96
+ export declare const DescriptionDetail: ({ className, ...props }: DescriptionDetailProps) => import("react").JSX.Element;
97
+ export type AttachmentListProps = ComponentPropsWithRef<'ul'>;
98
+ export declare const AttachmentList: ({ className, ...props }: AttachmentListProps) => import("react").JSX.Element;
79
99
  export {};
80
100
  //# sourceMappingURL=server-components.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"server-components.d.ts","sourceRoot":"","sources":["../src/server-components.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"server-components.d.ts","sourceRoot":"","sources":["../src/server-components.tsx"],"names":[],"mappings":"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"}
@@ -13,7 +13,7 @@ const glassIntensityClass = (glass) => glass === 'subtle' ?
13
13
  'ui-glass-subtle' :
14
14
  glass === 'strong' && 'ui-glass-strong';
15
15
  export const Badge = ({ className, variant = 'default', ...props }) => (_jsx("span", { className: composeClassName('ui-badge', `ui-badge--${variant}`, className), "data-variant": variant, ...props }));
16
- export const Card = ({ as, className, glass = false, variant = 'default', ...props }) => (_jsx(Primitive, { ...(as ? { as } : {}), className: composeClassName(variant === 'muted' && 'ui-card--muted', variant === 'interactive' && 'ui-card--interactive', variant === 'unstyled' && 'ui-card--unstyled', (glass || variant === 'glass') && composeClassName('ui-card--glass', glassIntensityClass(glass)), className), "data-slot": "card", "data-variant": variant, ...props, uiClassName: "ui-card" }));
16
+ export const Card = ({ as, className, density = 'comfortable', glass = false, variant = 'default', ...props }) => (_jsx(Primitive, { ...(as ? { as } : {}), className: composeClassName(`ui-card--${density}`, variant === 'muted' && 'ui-card--muted', variant === 'interactive' && 'ui-card--interactive', variant === 'unstyled' && 'ui-card--unstyled', (glass || variant === 'glass') && composeClassName('ui-card--glass', glassIntensityClass(glass)), className), "data-density": density, "data-slot": "card", "data-variant": variant, ...props, uiClassName: "ui-card" }));
17
17
  export const CardHeader = ({ as, ...props }) => (_jsx(Primitive, { ...(as ? { as } : {}), "data-slot": "card-header", ...props, uiClassName: "ui-card__header" }));
18
18
  export const CardTitle = ({ as, ...props }) => (_jsx(Primitive, { ...(as ? { as } : {}), "data-slot": "card-title", ...props, uiClassName: "ui-card__title" }));
19
19
  export const CardDescription = ({ as, ...props }) => (_jsx(Primitive, { ...(as ? { as } : {}), "data-slot": "card-description", ...props, uiClassName: "ui-card__description" }));
@@ -26,7 +26,7 @@ export const Container = ({ as = 'div', className, size = 'lg', ...props }) => c
26
26
  ...props
27
27
  });
28
28
  export const Direction = ({ className, dir = 'ltr', ...props }) => (_jsx("div", { className: composeClassName('ui-direction', className), dir: dir, ...props }));
29
- export const Grid = ({ as = 'div', className, columns = 'auto', gap = 'md', minItemWidth, style, ...props }) => {
29
+ export const Grid = ({ as = 'div', className, columns = 'auto', gap = 'group', minItemWidth, style, ...props }) => {
30
30
  const gridStyle = {
31
31
  ...style,
32
32
  '--ui-grid-min': minItemWidth
@@ -53,7 +53,7 @@ export const Spinner = ({ 'aria-hidden': ariaHidden, 'aria-label': ariaLabel, 'a
53
53
  const isAccessible = Boolean(ariaLabel || ariaLabelledby);
54
54
  return (_jsx("span", { "aria-hidden": ariaHidden ?? (isAccessible ? undefined : true), "aria-label": ariaLabel, "aria-labelledby": ariaLabelledby, className: composeClassName('ui-spinner', className), role: role ?? (isAccessible ? 'status' : undefined), ...props }));
55
55
  };
56
- export const Stack = ({ align = 'stretch', as = 'div', className, direction = 'vertical', gap = 'md', justify = 'start', wrap = false, ...props }) => createElement(as, {
56
+ export const Stack = ({ align = 'stretch', as = 'div', className, direction = 'vertical', gap = 'group', justify = 'start', wrap = false, ...props }) => createElement(as, {
57
57
  className: composeClassName('ui-stack', `ui-stack--${direction}`, `ui-stack--gap-${gap}`, `ui-stack--align-${align}`, `ui-stack--justify-${justify}`, wrap && 'ui-stack--wrap', className),
58
58
  'data-direction': direction,
59
59
  'data-ui-stack': true,
@@ -62,3 +62,11 @@ export const Stack = ({ align = 'stretch', as = 'div', className, direction = 'v
62
62
  export const Textarea = ({ className, ref, rows = 4, ...props }) => (_jsx("textarea", { className: composeClassName('ui-textarea', className), ref: ref, rows: rows, ...props }));
63
63
  export const Typography = ({ className, ...props }) => (_jsx("div", { className: composeClassName('ui-typography', className), ...props }));
64
64
  export const VisuallyHidden = ({ className, focusable = false, ...props }) => (_jsx("span", { className: composeClassName('ui-visually-hidden', focusable && 'ui-visually-hidden--focusable', className), "data-ui-visually-hidden": true, ...props }));
65
+ export const DialogHeader = ({ className, ...props }) => (_jsx("header", { ...props, className: composeClassName('ui-dialog-header', className), "data-slot": "dialog-header" }));
66
+ export const DialogTitle = ({ as: Tag = 'h2', className, ...props }) => (_jsx(Tag, { ...props, className: composeClassName('ui-dialog-title', className), "data-slot": "dialog-title" }));
67
+ export const DialogBody = ({ className, ...props }) => (_jsx("div", { ...props, className: composeClassName('ui-dialog-body', className), "data-slot": "dialog-body" }));
68
+ export const DialogFooter = ({ className, ...props }) => (_jsx("footer", { ...props, className: composeClassName('ui-dialog-footer', className), "data-slot": "dialog-footer" }));
69
+ export const DescriptionItem = ({ className, ...props }) => (_jsx("div", { ...props, className: composeClassName('ui-description-item', 'ui-descriptions__item', className), "data-slot": "description-item" }));
70
+ export const DescriptionTerm = ({ className, ...props }) => (_jsx("dt", { ...props, className: composeClassName('ui-description-term', 'ui-descriptions__term', className), "data-slot": "description-term" }));
71
+ export const DescriptionDetail = ({ className, ...props }) => (_jsx("dd", { ...props, className: composeClassName('ui-description-detail', 'ui-descriptions__detail', className), "data-slot": "description-detail" }));
72
+ export const AttachmentList = ({ className, ...props }) => (_jsx("ul", { ...props, className: composeClassName('ui-attachment-list', className), "data-slot": "attachment-list" }));
package/dist/server.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ export { ChangeSummary, type ChangeSummaryProps } from './change-summary.js';
1
2
  export * from './server-components.js';
2
3
  export { type LumenComponentName, lumenComponentNames } from '@santi020k/lumen-core';
3
4
  //# sourceMappingURL=server.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,cAAc,wBAAwB,CAAA;AACtC,OAAO,EACL,KAAK,kBAAkB,EACvB,mBAAmB,EACpB,MAAM,uBAAuB,CAAA"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,KAAK,kBAAkB,EAAE,MAAM,qBAAqB,CAAA;AAC5E,cAAc,wBAAwB,CAAA;AACtC,OAAO,EACL,KAAK,kBAAkB,EACvB,mBAAmB,EACpB,MAAM,uBAAuB,CAAA"}
package/dist/server.js CHANGED
@@ -1,2 +1,3 @@
1
+ export { ChangeSummary } from './change-summary.js';
1
2
  export * from './server-components.js';
2
3
  export { lumenComponentNames } from '@santi020k/lumen-core';
@@ -0,0 +1,4 @@
1
+ import type { ToastApi } from './hooks.js';
2
+ export declare const ToastContext: import("react").Context<ToastApi | null>;
3
+ export declare const useToast: () => ToastApi;
4
+ //# sourceMappingURL=toast-context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"toast-context.d.ts","sourceRoot":"","sources":["../src/toast-context.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAE1C,eAAO,MAAM,YAAY,0CAAuC,CAAA;AAEhE,eAAO,MAAM,QAAQ,QAAO,QAQ3B,CAAA"}
@@ -0,0 +1,10 @@
1
+ 'use client';
2
+ import { createContext, use } from 'react';
3
+ export const ToastContext = createContext(null);
4
+ export const useToast = () => {
5
+ const api = use(ToastContext);
6
+ if (!api) {
7
+ throw new Error('useToast must be used inside a ToastProvider.');
8
+ }
9
+ return api;
10
+ };
@@ -0,0 +1,3 @@
1
+ import type { ToastProviderProps } from './hooks.js';
2
+ export declare const ToastProvider: ({ children, maxCount, placement }: ToastProviderProps) => import("react").JSX.Element;
3
+ //# sourceMappingURL=toast-provider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"toast-provider.d.ts","sourceRoot":"","sources":["../src/toast-provider.tsx"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAyC,kBAAkB,EAAe,MAAM,YAAY,CAAA;AA4NxG,eAAO,MAAM,aAAa,GAAI,mCAI3B,kBAAkB,gCAiFpB,CAAA"}
@@ -0,0 +1,3 @@
1
+ "use client";import{jsx as _jsx,jsxs as _jsxs}from"react/jsx-runtime";import{useCallback,useEffect,useMemo,useRef,useState}from"react";import{composeClassName}from"@santi020k/lumen-core";import{ToastContext,useToast}from"./toast-context.js";const defaultToastDuration=5e3,defaultToastMax=5,closeDelay=240,limitToastPlacement=(toasts,placement,max)=>{const open=toasts.filter(toast=>toast.open&&toast.placement===placement),staleIds=new Set(open.slice(0,Math.max(0,open.length-max)).map(toast=>toast.id));return toasts.map(toast=>staleIds.has(toast.id)?{...toast,open:!1}:toast)},createToastId=()=>typeof crypto<"u"&&typeof crypto.randomUUID=="function"?`ui-toast-${crypto.randomUUID()}`:`ui-toast-${Math.random().toString(36).slice(2)}`,createToastRecord=(detail,placement)=>({...detail,id:detail.id??createToastId(),open:!0,placement:detail.placement??placement,title:detail.title??"Notification",variant:detail.variant??"default"}),ToastItem=({onDismiss,toast})=>{const toastRef=useRef(null),timerRef=useRef(void 0),remainingRef=useRef(toast.duration??defaultToastDuration),startedAtRef=useRef(0),pauseReasonsRef=useRef(new Set),dismiss=useToast().dismiss,clearTimer=useCallback(()=>{clearTimeout(timerRef.current),timerRef.current=void 0},[]),startTimer=useCallback(()=>{const remaining=remainingRef.current;clearTimer(),!(!Number.isFinite(remaining)||remaining<=0||pauseReasonsRef.current.size>0)&&(startedAtRef.current=Date.now(),timerRef.current=setTimeout(()=>{dismiss(toast.id)},remaining))},[clearTimer,dismiss,toast.id]),pauseTimer=useCallback(reason=>{pauseReasonsRef.current.add(reason),timerRef.current!==void 0&&(remainingRef.current=Math.max(0,remainingRef.current-(Date.now()-startedAtRef.current)),clearTimer())},[clearTimer]),resumeTimer=useCallback(reason=>{pauseReasonsRef.current.delete(reason)&&pauseReasonsRef.current.size===0&&remainingRef.current>0&&startTimer()},[startTimer]);useEffect(()=>(remainingRef.current=toast.duration??defaultToastDuration,toast.open&&startTimer(),clearTimer),[clearTimer,startTimer,toast.duration,toast.open]),useEffect(()=>{if(!toast.open){const timer=setTimeout(onDismiss,closeDelay);return()=>{clearTimeout(timer)}}},[onDismiss,toast.open]);const action=toast.action,description=toast.description??"",variantClass=["success","warning","destructive"].includes(toast.variant)&&`ui-toast--${toast.variant}`;return _jsxs("aside",{"aria-live":toast.variant==="destructive"?"assertive":"polite",className:composeClassName("ui-toast",variantClass),"data-description":description,"data-state":toast.open?"open":"closed","data-title":toast.title,"data-ui-toast":!0,"data-variant":toast.variant,id:toast.id,onBlur:event=>{event.currentTarget.contains(event.relatedTarget)||resumeTimer("focus")},onFocus:event=>{event.currentTarget.contains(event.relatedTarget)||pauseTimer("focus")},onKeyDown:event=>{event.defaultPrevented||event.nativeEvent.isComposing||event.key==="Escape"&&(event.preventDefault(),dismiss(toast.id))},onMouseEnter:()=>{pauseTimer("hover")},onMouseLeave:()=>{resumeTimer("hover")},ref:toastRef,role:toast.variant==="destructive"?"alert":"status",children:[_jsxs("div",{className:"ui-toast__body",children:[_jsx("strong",{children:toast.title}),description&&_jsx("p",{children:description})]}),action?.label&&_jsx("button",{className:`
2
+ ui-button ui-button--secondary ui-button--sm ui-toast__action
3
+ `,onClick:event=>{action.onClick?.(event,toastRef.current),toastRef.current?.dispatchEvent(new CustomEvent(action.event??"ui:toast-action",{bubbles:!0,detail:{id:toast.id,value:action.value}})),dismiss(toast.id)},type:"button",children:action.label}),_jsx("button",{"aria-label":"Dismiss notification",className:"ui-toast__dismiss",onClick:()=>{dismiss(toast.id)},type:"button",children:"Dismiss"})]})},ToastViewport=({maxCount,placement,removeToast,toasts})=>_jsx("div",{"aria-atomic":"false","aria-label":"Notifications","aria-live":"polite",className:"ui-tvp","data-placement":placement,"data-ui-toast-viewport":!0,"data-ui-toast-max":maxCount,children:toasts.map(toast=>_jsx(ToastItem,{onDismiss:()=>{removeToast(toast.id)},toast},toast.id))}),ToastProvider=({children,maxCount=defaultToastMax,placement="bottom-right"})=>{const[toasts,setToasts]=useState([]),removeToast=useCallback(id=>{setToasts(current=>current.filter(toast=>toast.id!==id))},[]),dismiss=useCallback(id=>{setToasts(current=>{const targetId=id??current.filter(toast=>toast.open).pop()?.id;return current.map(toast=>toast.id===targetId?{...toast,open:!1}:toast)})},[]),create=useCallback(detail=>{const record=createToastRecord(detail,placement),stackMax=detail.max??maxCount;return setToasts(current=>{const next=[...current.filter(toast=>toast.id!==record.id),record];return limitToastPlacement(next,record.placement,stackMax)}),record.id},[maxCount,placement]),update=useCallback((id,detail)=>{setToasts(current=>{const toast=current.find(item=>item.id===id);if(!toast)return current;const record={...toast,...detail,id,open:!0,placement:detail.placement??toast.placement,title:detail.title??toast.title,variant:detail.variant??toast.variant},next=!toast.open||record.placement!==toast.placement?[...current.filter(item=>item.id!==id),record]:current.map(item=>item.id===id?record:item);return limitToastPlacement(next,record.placement,record.max??maxCount)})},[maxCount]),api=useMemo(()=>({create,dismiss,toasts,update}),[create,dismiss,toasts,update]),placements=[...new Set([placement,...toasts.map(toast=>toast.placement)])];return _jsxs(ToastContext,{value:api,children:[children,placements.map(item=>_jsx(ToastViewport,{maxCount,placement:item,removeToast,toasts:toasts.filter(toast=>toast.placement===item)},item))]})};export{ToastProvider};
@@ -0,0 +1,17 @@
1
+ import type { MouseEvent } from 'react';
2
+ interface CopyFeedbackOptions {
3
+ copiedLabel: string;
4
+ errorLabel: string;
5
+ getValue: (button: HTMLButtonElement) => string | undefined;
6
+ label: string;
7
+ onClick?: ((event: MouseEvent<HTMLButtonElement>) => void) | undefined;
8
+ resetAfter?: number;
9
+ toast?: boolean;
10
+ }
11
+ export declare const useCopyFeedback: ({ copiedLabel, errorLabel, getValue, label, onClick, resetAfter, toast }: CopyFeedbackOptions) => {
12
+ accessibleLabel: string;
13
+ handleClick: (event: MouseEvent<HTMLButtonElement>) => Promise<void>;
14
+ state: "error" | "idle" | "copied";
15
+ };
16
+ export {};
17
+ //# sourceMappingURL=use-copy-feedback.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-copy-feedback.d.ts","sourceRoot":"","sources":["../src/use-copy-feedback.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,OAAO,CAAA;AAMvC,UAAU,mBAAmB;IAC3B,WAAW,EAAE,MAAM,CAAA;IACnB,UAAU,EAAE,MAAM,CAAA;IAClB,QAAQ,EAAE,CAAC,MAAM,EAAE,iBAAiB,KAAK,MAAM,GAAG,SAAS,CAAA;IAC3D,KAAK,EAAE,MAAM,CAAA;IACb,OAAO,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE,UAAU,CAAC,iBAAiB,CAAC,KAAK,IAAI,CAAC,GAAG,SAAS,CAAA;IACtE,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,KAAK,CAAC,EAAE,OAAO,CAAA;CAChB;AAoBD,eAAO,MAAM,eAAe,GAAI,0EAQ7B,mBAAmB;;yBAYc,UAAU,CAAC,iBAAiB,CAAC;;CA0ChE,CAAA"}
@@ -0,0 +1,54 @@
1
+ import { use, useEffect, useRef, useState } from 'react';
2
+ import { ToastContext } from './toast-context.js';
3
+ const normalizedResetAfter = (value) => Number.isFinite(value) ? Math.max(0, value) : 2000;
4
+ const publishCopyToast = (button, api, copied, copiedLabel, errorLabel) => {
5
+ const detail = { title: copied ? copiedLabel : errorLabel, variant: copied ? 'success' : 'destructive' };
6
+ if (api) {
7
+ api.create(detail);
8
+ return;
9
+ }
10
+ const EventConstructor = button.ownerDocument.defaultView?.CustomEvent ?? CustomEvent;
11
+ button.ownerDocument.dispatchEvent(new EventConstructor('ui:toast', { detail }));
12
+ };
13
+ export const useCopyFeedback = ({ copiedLabel, errorLabel, getValue, label, onClick, resetAfter = 2000, toast = false }) => {
14
+ const toastApi = use(ToastContext);
15
+ const [state, setState] = useState('idle');
16
+ const resetTimerRef = useRef(undefined);
17
+ const operationRef = useRef(0);
18
+ useEffect(() => () => {
19
+ operationRef.current += 1;
20
+ globalThis.clearTimeout(resetTimerRef.current);
21
+ }, []);
22
+ const handleClick = async (event) => {
23
+ onClick?.(event);
24
+ if (event.defaultPrevented)
25
+ return;
26
+ const button = event.currentTarget;
27
+ const currentOperation = ++operationRef.current;
28
+ globalThis.clearTimeout(resetTimerRef.current);
29
+ let nextState = 'copied';
30
+ try {
31
+ const value = getValue(button);
32
+ if (value === undefined)
33
+ throw new Error(errorLabel);
34
+ await navigator.clipboard.writeText(value);
35
+ if (operationRef.current !== currentOperation)
36
+ return;
37
+ button.dispatchEvent(new CustomEvent('ui:copy-success', { bubbles: true, detail: { value } }));
38
+ }
39
+ catch (error) {
40
+ if (operationRef.current !== currentOperation)
41
+ return;
42
+ nextState = 'error';
43
+ button.dispatchEvent(new CustomEvent('ui:copy-error', { bubbles: true, detail: { error } }));
44
+ }
45
+ setState(nextState);
46
+ if (toast)
47
+ publishCopyToast(button, toastApi, nextState === 'copied', copiedLabel, errorLabel);
48
+ resetTimerRef.current = globalThis.setTimeout(() => {
49
+ setState('idle');
50
+ }, normalizedResetAfter(resetAfter));
51
+ };
52
+ const accessibleLabel = { copied: copiedLabel, error: errorLabel, idle: label }[state];
53
+ return { accessibleLabel, handleClick, state };
54
+ };
@@ -0,0 +1,13 @@
1
+ import type { ComponentPropsWithRef, ReactNode } from 'react';
2
+ import type { LumenGlassProp } from './components.js';
3
+ export interface VirtualListDataProps<T> extends Omit<ComponentPropsWithRef<'div'>, 'children'> {
4
+ children?: never;
5
+ getKey: (item: T, index: number) => string | number;
6
+ glass?: LumenGlassProp;
7
+ items: readonly T[];
8
+ itemSize?: number;
9
+ overscan?: number;
10
+ renderItem: (item: T, index: number) => ReactNode;
11
+ }
12
+ export declare const VirtualListData: <T>({ className, getKey, glass, items, itemSize, overscan, renderItem, ref, role, style, tabIndex, onFocusCapture, onBlurCapture, ...props }: VirtualListDataProps<T>) => import("react").JSX.Element;
13
+ //# sourceMappingURL=virtual-list-data.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"virtual-list-data.d.ts","sourceRoot":"","sources":["../src/virtual-list-data.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,qBAAqB,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAK7D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAA;AAErD,MAAM,WAAW,oBAAoB,CAAC,CAAC,CAAE,SAAQ,IAAI,CAAC,qBAAqB,CAAC,KAAK,CAAC,EAAE,UAAU,CAAC;IAC7F,QAAQ,CAAC,EAAE,KAAK,CAAA;IAChB,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,MAAM,GAAG,MAAM,CAAA;IACnD,KAAK,CAAC,EAAE,cAAc,CAAA;IACtB,KAAK,EAAE,SAAS,CAAC,EAAE,CAAA;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,UAAU,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,SAAS,CAAA;CAClD;AAiBD,eAAO,MAAM,eAAe,GAAI,CAAC,EAAG,0IAGjC,oBAAoB,CAAC,CAAC,CAAC,gCAwHzB,CAAA"}