@santi020k/lumen-react 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.
- package/README.md +692 -13
- package/dist/ai-surfaces.d.ts +49 -0
- package/dist/ai-surfaces.d.ts.map +1 -0
- package/dist/ai-surfaces.js +88 -0
- package/dist/amount-field.d.ts +11 -0
- package/dist/amount-field.d.ts.map +1 -0
- package/dist/amount-field.js +37 -0
- package/dist/attachments.d.ts +17 -0
- package/dist/attachments.d.ts.map +1 -0
- package/dist/attachments.js +23 -0
- package/dist/bullet-chart.d.ts +14 -0
- package/dist/bullet-chart.d.ts.map +1 -0
- package/dist/bullet-chart.js +22 -0
- package/dist/change-summary.d.ts +14 -0
- package/dist/change-summary.d.ts.map +1 -0
- package/dist/change-summary.js +4 -0
- package/dist/chart-inspection.d.ts +10 -0
- package/dist/chart-inspection.d.ts.map +1 -0
- package/dist/chart-inspection.js +11 -0
- package/dist/chart-interaction.d.ts +17 -0
- package/dist/chart-interaction.d.ts.map +1 -0
- package/dist/chart-interaction.js +50 -0
- package/dist/chart-label.d.ts +3 -0
- package/dist/chart-label.d.ts.map +1 -0
- package/dist/chart-label.js +1 -0
- package/dist/chart-recipes.d.ts +8 -0
- package/dist/chart-recipes.d.ts.map +1 -1
- package/dist/chart-recipes.js +35 -0
- package/dist/combobox.d.ts +9 -0
- package/dist/combobox.d.ts.map +1 -0
- package/dist/combobox.js +137 -0
- package/dist/comparison-chart.d.ts +13 -0
- package/dist/comparison-chart.d.ts.map +1 -0
- package/dist/comparison-chart.js +18 -0
- package/dist/components.d.ts +106 -70
- package/dist/components.d.ts.map +1 -1
- package/dist/components.js +4 -1949
- package/dist/dashboard.d.ts +20 -0
- package/dist/dashboard.d.ts.map +1 -0
- package/dist/dashboard.js +19 -0
- package/dist/data-table-range-model.d.ts +8 -0
- package/dist/data-table-range-model.d.ts.map +1 -0
- package/dist/data-table-range-model.js +31 -0
- package/dist/data-table-range.d.ts +17 -0
- package/dist/data-table-range.d.ts.map +1 -0
- package/dist/data-table-range.js +8 -0
- package/dist/data-table-saved-views.d.ts +30 -0
- package/dist/data-table-saved-views.d.ts.map +1 -0
- package/dist/data-table-saved-views.js +49 -0
- package/dist/data-table-selection-model.d.ts +23 -0
- package/dist/data-table-selection-model.d.ts.map +1 -0
- package/dist/data-table-selection-model.js +36 -0
- package/dist/data-table-selection.d.ts +11 -0
- package/dist/data-table-selection.d.ts.map +1 -0
- package/dist/data-table-selection.js +10 -0
- package/dist/data-table-state.d.ts +6 -0
- package/dist/data-table-state.d.ts.map +1 -0
- package/dist/data-table-state.js +38 -0
- package/dist/data-table-view.d.ts +88 -0
- package/dist/data-table-view.d.ts.map +1 -0
- package/dist/data-table-view.js +1 -0
- package/dist/data-table.d.ts +60 -0
- package/dist/data-table.d.ts.map +1 -0
- package/dist/data-table.js +1 -0
- package/dist/date-range-calendar.d.ts +29 -0
- package/dist/date-range-calendar.d.ts.map +1 -0
- package/dist/date-range-calendar.js +69 -0
- package/dist/date-range-input.d.ts +25 -0
- package/dist/date-range-input.d.ts.map +1 -0
- package/dist/date-range-input.js +195 -0
- package/dist/device-frame.d.ts +13 -0
- package/dist/device-frame.d.ts.map +1 -0
- package/dist/device-frame.js +23 -0
- package/dist/dialog-lifecycle.d.ts +3 -0
- package/dist/dialog-lifecycle.d.ts.map +1 -0
- package/dist/dialog-lifecycle.js +70 -0
- package/dist/expanded-charts.d.ts +26 -0
- package/dist/expanded-charts.d.ts.map +1 -0
- package/dist/expanded-charts.js +46 -0
- package/dist/floating-panel.d.ts +12 -0
- package/dist/floating-panel.d.ts.map +1 -0
- package/dist/floating-panel.js +1 -0
- package/dist/form-workflow.d.ts +77 -0
- package/dist/form-workflow.d.ts.map +1 -0
- package/dist/form-workflow.js +337 -0
- package/dist/hooks.d.ts +24 -21
- package/dist/hooks.d.ts.map +1 -1
- package/dist/hooks.js +1 -2468
- package/dist/image-comparison.d.ts +20 -0
- package/dist/image-comparison.d.ts.map +1 -0
- package/dist/image-comparison.js +55 -0
- package/dist/index.d.ts +25 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +24 -0
- package/dist/interval-charts.d.ts +21 -0
- package/dist/interval-charts.d.ts.map +1 -0
- package/dist/interval-charts.js +23 -0
- package/dist/media-selection.d.ts +18 -0
- package/dist/media-selection.d.ts.map +1 -0
- package/dist/media-selection.js +12 -0
- package/dist/media-viewport.d.ts +16 -0
- package/dist/media-viewport.d.ts.map +1 -0
- package/dist/media-viewport.js +37 -0
- package/dist/motion.d.ts +597 -0
- package/dist/motion.d.ts.map +1 -0
- package/dist/motion.js +22 -0
- package/dist/review-workflow.d.ts +32 -0
- package/dist/review-workflow.d.ts.map +1 -0
- package/dist/review-workflow.js +76 -0
- package/dist/rich-text-editor.d.ts +21 -0
- package/dist/rich-text-editor.d.ts.map +1 -0
- package/dist/rich-text-editor.js +143 -0
- package/dist/select-form.d.ts +3 -0
- package/dist/select-form.d.ts.map +1 -0
- package/dist/select-form.js +1 -0
- package/dist/server-components.d.ts +33 -6
- package/dist/server-components.d.ts.map +1 -1
- package/dist/server-components.js +26 -10
- package/dist/server.d.ts +1 -0
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +1 -0
- package/dist/toast-context.d.ts +4 -0
- package/dist/toast-context.d.ts.map +1 -0
- package/dist/toast-context.js +10 -0
- package/dist/toast-provider.d.ts +3 -0
- package/dist/toast-provider.d.ts.map +1 -0
- package/dist/toast-provider.js +3 -0
- package/dist/use-copy-feedback.d.ts +17 -0
- package/dist/use-copy-feedback.d.ts.map +1 -0
- package/dist/use-copy-feedback.js +54 -0
- package/dist/virtual-list-data.d.ts +13 -0
- package/dist/virtual-list-data.d.ts.map +1 -0
- package/dist/virtual-list-data.js +87 -0
- package/dist/virtual-list.d.ts +14 -0
- package/dist/virtual-list.d.ts.map +1 -0
- package/dist/virtual-list.js +24 -0
- package/dist/visual-interactions.d.ts +16 -0
- package/dist/visual-interactions.d.ts.map +1 -0
- package/dist/visual-interactions.js +30 -0
- package/dist/world-map.d.ts +26 -0
- package/dist/world-map.d.ts.map +1 -0
- package/dist/world-map.js +81 -0
- package/package.json +99 -11
- package/styles/critical.css +696 -66
- 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, type LumenSkeletonAnimation, type LumenSkeletonShape, type LumenSkeletonSize } 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?:
|
|
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'>;
|
|
@@ -55,15 +57,22 @@ export interface SeparatorProps extends ComponentPropsWithRef<'hr'> {
|
|
|
55
57
|
orientation?: Orientation;
|
|
56
58
|
}
|
|
57
59
|
export declare const Separator: ({ className, orientation, ...props }: SeparatorProps) => import("react").JSX.Element;
|
|
58
|
-
export
|
|
59
|
-
|
|
60
|
+
export interface SkeletonProps extends ComponentPropsWithRef<'div'> {
|
|
61
|
+
/** `shimmer` (default) keeps the existing sweep; `pulse` fades; `none` is static. */
|
|
62
|
+
animation?: LumenSkeletonAnimation;
|
|
63
|
+
/** Pixels for numbers, or a CSS length such as `0.75rem` or `60%`. */
|
|
64
|
+
height?: LumenSkeletonSize;
|
|
65
|
+
shape?: LumenSkeletonShape;
|
|
66
|
+
width?: LumenSkeletonSize;
|
|
67
|
+
}
|
|
68
|
+
export declare const Skeleton: ({ animation, "aria-hidden": ariaHidden, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledby, className, height, role, shape, style, width, ...props }: SkeletonProps) => import("react").JSX.Element;
|
|
60
69
|
export type SpinnerProps = ComponentPropsWithoutRef<'span'>;
|
|
61
70
|
export declare const Spinner: ({ "aria-hidden": ariaHidden, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledby, className, role, ...props }: SpinnerProps) => import("react").JSX.Element;
|
|
62
71
|
export interface StackProps extends ComponentPropsWithRef<'div'> {
|
|
63
72
|
align?: 'center' | 'end' | 'start' | 'stretch';
|
|
64
73
|
as?: ElementType;
|
|
65
74
|
direction?: Orientation;
|
|
66
|
-
gap?: 'lg' | 'md' | 'none' | 'sm' | 'xl';
|
|
75
|
+
gap?: '2xl' | '3xl' | 'group' | 'lg' | 'md' | 'none' | 'related' | 'section' | 'sm' | 'xl' | 'xs';
|
|
67
76
|
justify?: 'between' | 'center' | 'end' | 'start';
|
|
68
77
|
wrap?: boolean;
|
|
69
78
|
}
|
|
@@ -76,5 +85,23 @@ export interface VisuallyHiddenProps extends ComponentPropsWithRef<'span'> {
|
|
|
76
85
|
focusable?: boolean;
|
|
77
86
|
}
|
|
78
87
|
export declare const VisuallyHidden: ({ className, focusable, ...props }: VisuallyHiddenProps) => import("react").JSX.Element;
|
|
88
|
+
export type DialogHeaderProps = ComponentPropsWithRef<'header'>;
|
|
89
|
+
export declare const DialogHeader: ({ className, ...props }: DialogHeaderProps) => import("react").JSX.Element;
|
|
90
|
+
export type DialogTitleProps = ComponentPropsWithRef<'h2'> & {
|
|
91
|
+
as?: 'h2' | 'h3' | 'h4';
|
|
92
|
+
};
|
|
93
|
+
export declare const DialogTitle: ({ as: Tag, className, ...props }: DialogTitleProps) => import("react").JSX.Element;
|
|
94
|
+
export type DialogBodyProps = ComponentPropsWithRef<'div'>;
|
|
95
|
+
export declare const DialogBody: ({ className, ...props }: DialogBodyProps) => import("react").JSX.Element;
|
|
96
|
+
export type DialogFooterProps = ComponentPropsWithRef<'footer'>;
|
|
97
|
+
export declare const DialogFooter: ({ className, ...props }: DialogFooterProps) => import("react").JSX.Element;
|
|
98
|
+
export type DescriptionItemProps = ComponentPropsWithRef<'div'>;
|
|
99
|
+
export declare const DescriptionItem: ({ className, ...props }: DescriptionItemProps) => import("react").JSX.Element;
|
|
100
|
+
export type DescriptionTermProps = ComponentPropsWithRef<'dt'>;
|
|
101
|
+
export declare const DescriptionTerm: ({ className, ...props }: DescriptionTermProps) => import("react").JSX.Element;
|
|
102
|
+
export type DescriptionDetailProps = ComponentPropsWithRef<'dd'>;
|
|
103
|
+
export declare const DescriptionDetail: ({ className, ...props }: DescriptionDetailProps) => import("react").JSX.Element;
|
|
104
|
+
export type AttachmentListProps = ComponentPropsWithRef<'ul'>;
|
|
105
|
+
export declare const AttachmentList: ({ className, ...props }: AttachmentListProps) => import("react").JSX.Element;
|
|
79
106
|
export {};
|
|
80
107
|
//# sourceMappingURL=server-components.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server-components.d.ts","sourceRoot":"","sources":["../src/server-components.tsx"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,wBAAwB,EAC7B,KAAK,qBAAqB,EAG1B,KAAK,WAAW,EACjB,MAAM,OAAO,CAAA;
|
|
1
|
+
{"version":3,"file":"server-components.d.ts","sourceRoot":"","sources":["../src/server-components.tsx"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,wBAAwB,EAC7B,KAAK,qBAAqB,EAG1B,KAAK,WAAW,EACjB,MAAM,OAAO,CAAA;AAEd,OAAO,EAEL,KAAK,sBAAsB,EAC3B,KAAK,sBAAsB,EAC3B,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,EAMvB,MAAM,uBAAuB,CAAA;AAE9B,MAAM,MAAM,cAAc,GAAG,OAAO,GAAG,QAAQ,GAAG,QAAQ,CAAA;AAE1D,MAAM,MAAM,mBAAmB,CAAC,CAAC,SAAS,WAAW,GAAG,KAAK,IAAI;IAC/D,EAAE,CAAC,EAAE,CAAC,CAAA;CACP,GAAG,IAAI,CAAC,qBAAqB,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAA;AA0BxC,KAAK,YAAY,GACf,SAAS,GAAG,aAAa,GAAG,SAAS,GAAG,WAAW,GAAG,SAAS,GAAG,SAAS,CAAA;AAE7E,MAAM,WAAW,UAAW,SAAQ,qBAAqB,CAAC,MAAM,CAAC;IAC/D,OAAO,CAAC,EAAE,YAAY,CAAA;CACvB;AAED,eAAO,MAAM,KAAK,GAAI,kCAInB,UAAU,gCAMZ,CAAA;AAED,KAAK,WAAW,GAAG,SAAS,GAAG,OAAO,GAAG,aAAa,GAAG,OAAO,GAAG,UAAU,CAAA;AAE7E,MAAM,MAAM,SAAS,CAAC,CAAC,SAAS,WAAW,GAAG,KAAK,IACjD,mBAAmB,CAAC,CAAC,CAAC,GAAG;IACvB,cAAc,CAAC,EAAE,WAAW,CAAA;IAC5B,OAAO,CAAC,EAAE,aAAa,GAAG,SAAS,GAAG,UAAU,CAAA;IAChD,KAAK,CAAC,EAAE,cAAc,CAAA;IACtB,OAAO,CAAC,EAAE,WAAW,CAAA;CACtB,CAAA;AAEH,eAAO,MAAM,IAAI,GAAI,CAAC,SAAS,WAAW,GAAG,KAAK,EAAE,sDAOjD,SAAS,CAAC,CAAC,CAAC,gCAmBd,CAAA;AAED,MAAM,MAAM,eAAe,CAAC,CAAC,SAAS,WAAW,GAAG,KAAK,IAAI,mBAAmB,CAAC,CAAC,CAAC,CAAA;AAEnF,eAAO,MAAM,UAAU,GAAI,CAAC,SAAS,WAAW,GAAG,KAAK,EAAE,kBAGvD,eAAe,CAAC,CAAC,CAAC,gCAOpB,CAAA;AAED,MAAM,MAAM,cAAc,CAAC,CAAC,SAAS,WAAW,GAAG,KAAK,IAAI,mBAAmB,CAAC,CAAC,CAAC,CAAA;AAElF,eAAO,MAAM,SAAS,GAAI,CAAC,SAAS,WAAW,GAAG,KAAK,EAAE,kBAGtD,cAAc,CAAC,CAAC,CAAC,gCAOnB,CAAA;AAED,MAAM,MAAM,oBAAoB,CAAC,CAAC,SAAS,WAAW,GAAG,KAAK,IAAI,mBAAmB,CAAC,CAAC,CAAC,CAAA;AAExF,eAAO,MAAM,eAAe,GAAI,CAAC,SAAS,WAAW,GAAG,KAAK,EAAE,kBAG5D,oBAAoB,CAAC,CAAC,CAAC,gCAOzB,CAAA;AAED,MAAM,MAAM,gBAAgB,CAAC,CAAC,SAAS,WAAW,GAAG,KAAK,IAAI,mBAAmB,CAAC,CAAC,CAAC,CAAA;AAEpF,eAAO,MAAM,WAAW,GAAI,CAAC,SAAS,WAAW,GAAG,KAAK,EAAE,kBAGxD,gBAAgB,CAAC,CAAC,CAAC,gCAOrB,CAAA;AAED,MAAM,MAAM,eAAe,CAAC,CAAC,SAAS,WAAW,GAAG,KAAK,IAAI,mBAAmB,CAAC,CAAC,CAAC,CAAA;AAEnF,eAAO,MAAM,UAAU,GAAI,CAAC,SAAS,WAAW,GAAG,KAAK,EAAE,kBAGvD,eAAe,CAAC,CAAC,CAAC,gCAOpB,CAAA;AAED,MAAM,WAAW,cAAe,SAAQ,qBAAqB,CAAC,KAAK,CAAC;IAClE,EAAE,CAAC,EAAE,WAAW,CAAA;IAChB,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAA;CACnC;AAED,eAAO,MAAM,SAAS,GAAI,mCAKvB,cAAc,2FAKf,CAAA;AAEF,MAAM,MAAM,cAAc,GAAG,wBAAwB,CAAC,KAAK,CAAC,CAAA;AAE5D,eAAO,MAAM,SAAS,GAAI,8BAIvB,cAAc,gCAEhB,CAAA;AAED,MAAM,WAAW,SAAU,SAAQ,qBAAqB,CAAC,KAAK,CAAC;IAC7D,EAAE,CAAC,EAAE,WAAW,CAAA;IAChB,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,MAAM,CAAA;IACzC,GAAG,CAAC,EAAE,KAAK,GAAG,KAAK,GAAG,OAAO,GAAG,IAAI,GAAG,IAAI,GAAG,MAAM,GAAG,SAAS,GAAG,SAAS,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAA;IACjG,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB;AAKD,eAAO,MAAM,IAAI,GAAI,gEAQlB,SAAS,2FAeX,CAAA;AAED,MAAM,WAAW,UAAW,SAAQ,qBAAqB,CAAC,OAAO,CAAC;IAChE,UAAU,CAAC,EAAE,sBAAsB,CAAA;CACpC;AAED,eAAO,MAAM,KAAK,GAAI,gDAMnB,UAAU,gCAYZ,CAAA;AAED,MAAM,MAAM,UAAU,GAAG,qBAAqB,CAAC,OAAO,CAAC,CAAA;AAEvD,eAAO,MAAM,KAAK,GAAI,yBAAyB,UAAU,gCAExD,CAAA;AAED,KAAK,WAAW,GAAG,YAAY,GAAG,UAAU,CAAA;AAE5C,MAAM,WAAW,aAAc,SAAQ,wBAAwB,CAAC,KAAK,CAAC;IACpE,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED,eAAO,MAAM,QAAQ,GAAI,qCAKtB,aAAa,gCAmBf,CAAA;AAED,MAAM,WAAW,cAAe,SAAQ,qBAAqB,CAAC,IAAI,CAAC;IACjE,WAAW,CAAC,EAAE,WAAW,CAAA;CAC1B;AAED,eAAO,MAAM,SAAS,GAAI,sCAIvB,cAAc,gCAShB,CAAA;AAED,MAAM,WAAW,aAAc,SAAQ,qBAAqB,CAAC,KAAK,CAAC;IACjE,qFAAqF;IACrF,SAAS,CAAC,EAAE,sBAAsB,CAAA;IAClC,sEAAsE;IACtE,MAAM,CAAC,EAAE,iBAAiB,CAAA;IAC1B,KAAK,CAAC,EAAE,kBAAkB,CAAA;IAC1B,KAAK,CAAC,EAAE,iBAAiB,CAAA;CAC1B;AAED,eAAO,MAAM,QAAQ,GAAI,8JAYtB,aAAa,gCA4Bf,CAAA;AAED,MAAM,MAAM,YAAY,GAAG,wBAAwB,CAAC,MAAM,CAAC,CAAA;AAE3D,eAAO,MAAM,OAAO,GAAI,sHAOrB,YAAY,gCAad,CAAA;AAED,MAAM,WAAW,UAAW,SAAQ,qBAAqB,CAAC,KAAK,CAAC;IAC9D,KAAK,CAAC,EAAE,QAAQ,GAAG,KAAK,GAAG,OAAO,GAAG,SAAS,CAAA;IAC9C,EAAE,CAAC,EAAE,WAAW,CAAA;IAChB,SAAS,CAAC,EAAE,WAAW,CAAA;IACvB,GAAG,CAAC,EAAE,KAAK,GAAG,KAAK,GAAG,OAAO,GAAG,IAAI,GAAG,IAAI,GAAG,MAAM,GAAG,SAAS,GAAG,SAAS,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAA;IACjG,OAAO,CAAC,EAAE,SAAS,GAAG,QAAQ,GAAG,KAAK,GAAG,OAAO,CAAA;IAChD,IAAI,CAAC,EAAE,OAAO,CAAA;CACf;AAED,eAAO,MAAM,KAAK,GAAI,mEASnB,UAAU,2FAaX,CAAA;AAEF,MAAM,MAAM,aAAa,GAAG,qBAAqB,CAAC,UAAU,CAAC,CAAA;AAE7D,eAAO,MAAM,QAAQ,GAAI,oCAKtB,aAAa,gCAOf,CAAA;AAED,MAAM,MAAM,eAAe,GAAG,wBAAwB,CAAC,KAAK,CAAC,CAAA;AAE7D,eAAO,MAAM,UAAU,GAAI,yBAAyB,eAAe,gCAElE,CAAA;AAED,MAAM,WAAW,mBAAoB,SAAQ,qBAAqB,CAAC,MAAM,CAAC;IACxE,SAAS,CAAC,EAAE,OAAO,CAAA;CACpB;AAED,eAAO,MAAM,cAAc,GAAI,oCAI5B,mBAAmB,gCAUrB,CAAA;AAED,MAAM,MAAM,iBAAiB,GAAG,qBAAqB,CAAC,QAAQ,CAAC,CAAA;AAC/D,eAAO,MAAM,YAAY,GAAI,yBAAyB,iBAAiB,gCAEtE,CAAA;AAED,MAAM,MAAM,gBAAgB,GAAG,qBAAqB,CAAC,IAAI,CAAC,GAAG;IAAE,EAAE,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,CAAA;CAAE,CAAA;AACxF,eAAO,MAAM,WAAW,GAAI,kCAAyC,gBAAgB,gCAEpF,CAAA;AAED,MAAM,MAAM,eAAe,GAAG,qBAAqB,CAAC,KAAK,CAAC,CAAA;AAC1D,eAAO,MAAM,UAAU,GAAI,yBAAyB,eAAe,gCAElE,CAAA;AAED,MAAM,MAAM,iBAAiB,GAAG,qBAAqB,CAAC,QAAQ,CAAC,CAAA;AAC/D,eAAO,MAAM,YAAY,GAAI,yBAAyB,iBAAiB,gCAEtE,CAAA;AAED,MAAM,MAAM,oBAAoB,GAAG,qBAAqB,CAAC,KAAK,CAAC,CAAA;AAC/D,eAAO,MAAM,eAAe,GAAI,yBAAyB,oBAAoB,gCAE5E,CAAA;AAED,MAAM,MAAM,oBAAoB,GAAG,qBAAqB,CAAC,IAAI,CAAC,CAAA;AAC9D,eAAO,MAAM,eAAe,GAAI,yBAAyB,oBAAoB,gCAE5E,CAAA;AAED,MAAM,MAAM,sBAAsB,GAAG,qBAAqB,CAAC,IAAI,CAAC,CAAA;AAChE,eAAO,MAAM,iBAAiB,GAAI,yBAAyB,sBAAsB,gCAEhF,CAAA;AAED,MAAM,MAAM,mBAAmB,GAAG,qBAAqB,CAAC,IAAI,CAAC,CAAA;AAC7D,eAAO,MAAM,cAAc,GAAI,yBAAyB,mBAAmB,gCAE1E,CAAA"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { createElement } from 'react';
|
|
3
|
-
import { composeClassName } from '@santi020k/lumen-core';
|
|
3
|
+
import { composeClassName, normalizeLumenProgress, resolveLumenLoadingSemantics, resolveLumenSkeletonAnimation, resolveLumenSkeletonShape, resolveLumenSkeletonSize } from '@santi020k/lumen-core';
|
|
4
4
|
const Primitive = ({ as, className, uiClassName, ...props }) => {
|
|
5
5
|
const tag = as ?? 'div';
|
|
6
6
|
const safeClassName = typeof className === 'string' ? className : undefined;
|
|
@@ -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 = '
|
|
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
|
|
@@ -42,18 +42,26 @@ export const Grid = ({ as = 'div', className, columns = 'auto', gap = 'md', minI
|
|
|
42
42
|
export const Input = ({ className, ref, type = 'text', visualSize = 'default', ...props }) => (_jsx("input", { className: composeClassName('ui-input', visualSize === 'sm' && 'ui-input--sm', visualSize === 'lg' && 'ui-input--lg', className), ref: ref, type: type, ...props }));
|
|
43
43
|
export const Label = ({ className, ...props }) => (_jsx("label", { className: composeClassName('ui-label', className), ...props }));
|
|
44
44
|
export const Progress = ({ className, max = 100, value = 0, ...props }) => {
|
|
45
|
-
const safeMax
|
|
46
|
-
const safeValue = Math.min(safeMax, Math.max(0, value));
|
|
47
|
-
const percentage = (safeValue / safeMax) * 100;
|
|
45
|
+
const { max: safeMax, percentage, value: safeValue } = normalizeLumenProgress(max, value);
|
|
48
46
|
return (_jsx("div", { "aria-valuemax": safeMax, "aria-valuemin": 0, "aria-valuenow": safeValue, className: composeClassName('ui-progress', className), role: "progressbar", ...props, children: _jsx("span", { className: "ui-progress__bar", "data-slot": "progress-indicator", style: { width: `${percentage}%` } }) }));
|
|
49
47
|
};
|
|
50
48
|
export const Separator = ({ className, orientation = 'horizontal', ...props }) => (_jsx("hr", { "aria-orientation": orientation, className: composeClassName('ui-separator', `ui-separator--${orientation}`, className), "data-orientation": orientation, ...props }));
|
|
51
|
-
export const Skeleton = ({
|
|
49
|
+
export const Skeleton = ({ animation, 'aria-hidden': ariaHidden, 'aria-label': ariaLabel, 'aria-labelledby': ariaLabelledby, className, height, role, shape, style, width, ...props }) => {
|
|
50
|
+
const semantics = resolveLumenLoadingSemantics({ ariaHidden, ariaLabel, ariaLabelledby, role });
|
|
51
|
+
const resolvedShape = resolveLumenSkeletonShape(shape);
|
|
52
|
+
const resolvedAnimation = resolveLumenSkeletonAnimation(animation);
|
|
53
|
+
const skeletonStyle = {
|
|
54
|
+
'--ui-skeleton-height': resolveLumenSkeletonSize(height),
|
|
55
|
+
'--ui-skeleton-width': resolveLumenSkeletonSize(width),
|
|
56
|
+
...style
|
|
57
|
+
};
|
|
58
|
+
return (_jsx("div", { "aria-hidden": ariaHidden ?? (semantics.ariaHidden ? true : undefined), "aria-label": ariaLabel, "aria-labelledby": ariaLabelledby, className: composeClassName('ui-skeleton', resolvedShape !== 'rectangle' && `ui-skeleton--${resolvedShape}`, resolvedAnimation === 'pulse' && 'ui-skeleton--pulse', resolvedAnimation === 'none' && 'ui-skeleton--static', className), role: role ?? semantics.role, style: skeletonStyle, ...props }));
|
|
59
|
+
};
|
|
52
60
|
export const Spinner = ({ 'aria-hidden': ariaHidden, 'aria-label': ariaLabel, 'aria-labelledby': ariaLabelledby, className, role, ...props }) => {
|
|
53
|
-
const
|
|
54
|
-
return (_jsx("span", { "aria-hidden": ariaHidden ?? (
|
|
61
|
+
const semantics = resolveLumenLoadingSemantics({ ariaHidden, ariaLabel, ariaLabelledby, role });
|
|
62
|
+
return (_jsx("span", { "aria-hidden": ariaHidden ?? (semantics.ariaHidden ? true : undefined), "aria-label": ariaLabel, "aria-labelledby": ariaLabelledby, className: composeClassName('ui-spinner', className), role: role ?? semantics.role, ...props }));
|
|
55
63
|
};
|
|
56
|
-
export const Stack = ({ align = 'stretch', as = 'div', className, direction = 'vertical', gap = '
|
|
64
|
+
export const Stack = ({ align = 'stretch', as = 'div', className, direction = 'vertical', gap = 'group', justify = 'start', wrap = false, ...props }) => createElement(as, {
|
|
57
65
|
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
66
|
'data-direction': direction,
|
|
59
67
|
'data-ui-stack': true,
|
|
@@ -62,3 +70,11 @@ export const Stack = ({ align = 'stretch', as = 'div', className, direction = 'v
|
|
|
62
70
|
export const Textarea = ({ className, ref, rows = 4, ...props }) => (_jsx("textarea", { className: composeClassName('ui-textarea', className), ref: ref, rows: rows, ...props }));
|
|
63
71
|
export const Typography = ({ className, ...props }) => (_jsx("div", { className: composeClassName('ui-typography', className), ...props }));
|
|
64
72
|
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 }));
|
|
73
|
+
export const DialogHeader = ({ className, ...props }) => (_jsx("header", { ...props, className: composeClassName('ui-dialog-header', className), "data-slot": "dialog-header" }));
|
|
74
|
+
export const DialogTitle = ({ as: Tag = 'h2', className, ...props }) => (_jsx(Tag, { ...props, className: composeClassName('ui-dialog-title', className), "data-slot": "dialog-title" }));
|
|
75
|
+
export const DialogBody = ({ className, ...props }) => (_jsx("div", { ...props, className: composeClassName('ui-dialog-body', className), "data-slot": "dialog-body" }));
|
|
76
|
+
export const DialogFooter = ({ className, ...props }) => (_jsx("footer", { ...props, className: composeClassName('ui-dialog-footer', className), "data-slot": "dialog-footer" }));
|
|
77
|
+
export const DescriptionItem = ({ className, ...props }) => (_jsx("div", { ...props, className: composeClassName('ui-description-item', 'ui-descriptions__item', className), "data-slot": "description-item" }));
|
|
78
|
+
export const DescriptionTerm = ({ className, ...props }) => (_jsx("dt", { ...props, className: composeClassName('ui-description-term', 'ui-descriptions__term', className), "data-slot": "description-term" }));
|
|
79
|
+
export const DescriptionDetail = ({ className, ...props }) => (_jsx("dd", { ...props, className: composeClassName('ui-description-detail', 'ui-descriptions__detail', className), "data-slot": "description-detail" }));
|
|
80
|
+
export const AttachmentList = ({ className, ...props }) => (_jsx("ul", { ...props, className: composeClassName('ui-attachment-list', className), "data-slot": "attachment-list" }));
|
package/dist/server.d.ts
CHANGED
package/dist/server.d.ts.map
CHANGED
|
@@ -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
|
@@ -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 @@
|
|
|
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"}
|