@ephia/dova-sdk 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +89 -0
- package/dist/EphiaBinding-BvRmlqqC.d.ts +36 -0
- package/dist/EphiaFloatingButton-CxiF86VW.d.ts +65 -0
- package/dist/EphiaTextarea-B4_CAVUg.d.ts +183 -0
- package/dist/NativeBinding-ChG0GeSz.d.ts +53 -0
- package/dist/TargetBinding-BKGQwUMc.d.ts +89 -0
- package/dist/TiptapBinding-B-agfV2H.d.ts +45 -0
- package/dist/Transport-zdeA4Pou.d.ts +63 -0
- package/dist/audio-state-kZ3KSvux.d.ts +39 -0
- package/dist/chunk-35AJK2IO.js +1 -0
- package/dist/chunk-35AJK2IO.js.map +1 -0
- package/dist/chunk-3LXZODL4.js +886 -0
- package/dist/chunk-3LXZODL4.js.map +1 -0
- package/dist/chunk-5IK5TLSK.js +67 -0
- package/dist/chunk-5IK5TLSK.js.map +1 -0
- package/dist/chunk-7E43RY75.js +9 -0
- package/dist/chunk-7E43RY75.js.map +1 -0
- package/dist/chunk-A5UEXJ5R.js +183 -0
- package/dist/chunk-A5UEXJ5R.js.map +1 -0
- package/dist/chunk-AEE554FT.js +51 -0
- package/dist/chunk-AEE554FT.js.map +1 -0
- package/dist/chunk-DIEWY3IT.js +1332 -0
- package/dist/chunk-DIEWY3IT.js.map +1 -0
- package/dist/chunk-EGIAN7FH.js +18 -0
- package/dist/chunk-EGIAN7FH.js.map +1 -0
- package/dist/chunk-EMOEAPVU.js +486 -0
- package/dist/chunk-EMOEAPVU.js.map +1 -0
- package/dist/chunk-IDC7FHIZ.js +40 -0
- package/dist/chunk-IDC7FHIZ.js.map +1 -0
- package/dist/chunk-ITJFN3VM.js +601 -0
- package/dist/chunk-ITJFN3VM.js.map +1 -0
- package/dist/chunk-K24GNU27.js +22 -0
- package/dist/chunk-K24GNU27.js.map +1 -0
- package/dist/chunk-LXMCRXXF.js +778 -0
- package/dist/chunk-LXMCRXXF.js.map +1 -0
- package/dist/chunk-MJCEOOLW.js +122 -0
- package/dist/chunk-MJCEOOLW.js.map +1 -0
- package/dist/chunk-N7U5M3VZ.js +33 -0
- package/dist/chunk-N7U5M3VZ.js.map +1 -0
- package/dist/chunk-PSYX674B.js +27 -0
- package/dist/chunk-PSYX674B.js.map +1 -0
- package/dist/chunk-RFQRV7ML.js +33 -0
- package/dist/chunk-RFQRV7ML.js.map +1 -0
- package/dist/chunk-THNHRV2B.js +18 -0
- package/dist/chunk-THNHRV2B.js.map +1 -0
- package/dist/chunk-VSLGR64U.js +62 -0
- package/dist/chunk-VSLGR64U.js.map +1 -0
- package/dist/chunk-W2ZP674X.js +346 -0
- package/dist/chunk-W2ZP674X.js.map +1 -0
- package/dist/chunk-YWZUMUYE.js +695 -0
- package/dist/chunk-YWZUMUYE.js.map +1 -0
- package/dist/client-options-Uo6jXO8k.d.ts +64 -0
- package/dist/connection-state-Bk33YprE.d.ts +32 -0
- package/dist/core/bindings/index.d.ts +24 -0
- package/dist/core/bindings/index.js +1025 -0
- package/dist/core/bindings/index.js.map +1 -0
- package/dist/core/index.d.ts +383 -0
- package/dist/core/index.js +1284 -0
- package/dist/core/index.js.map +1 -0
- package/dist/createEphiaClient-BhdZ183V.d.ts +69 -0
- package/dist/devices/speechmike/index.d.ts +148 -0
- package/dist/devices/speechmike/index.js +40 -0
- package/dist/devices/speechmike/index.js.map +1 -0
- package/dist/headless/index.d.ts +10 -0
- package/dist/headless/index.js +25 -0
- package/dist/headless/index.js.map +1 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.js +119 -0
- package/dist/index.js.map +1 -0
- package/dist/react/index.d.ts +38 -0
- package/dist/react/index.js +70 -0
- package/dist/react/index.js.map +1 -0
- package/dist/rich-editor/index.d.ts +46 -0
- package/dist/rich-editor/index.js +13 -0
- package/dist/rich-editor/index.js.map +1 -0
- package/dist/schema-B2ycPlNB.d.ts +87 -0
- package/dist/session-APaXR48R.d.ts +12 -0
- package/dist/shared/index.d.ts +16 -0
- package/dist/shared/index.js +30 -0
- package/dist/shared/index.js.map +1 -0
- package/dist/style.css +1093 -0
- package/dist/testing/index.d.ts +84 -0
- package/dist/testing/index.js +36 -0
- package/dist/testing/index.js.map +1 -0
- package/dist/types-D5SXPSwR.d.ts +32 -0
- package/dist/ui/index.d.ts +30 -0
- package/dist/ui/index.js +34 -0
- package/dist/ui/index.js.map +1 -0
- package/dist/useEphiaSpeechMike-CjD7DWnh.d.ts +64 -0
- package/package.json +110 -0
- package/src/core/audio/audio-worklet-source.ts +30 -0
- package/src/core/audio/index.ts +3 -0
- package/src/core/audio/voice-level-meter.test.ts +27 -0
- package/src/core/audio/voice-level-meter.ts +270 -0
- package/src/core/bindings/EphiaBinding.ts +41 -0
- package/src/core/bindings/SegmentBindingBridge.test.ts +422 -0
- package/src/core/bindings/SegmentBindingBridge.ts +377 -0
- package/src/core/bindings/TargetBinding.ts +142 -0
- package/src/core/bindings/adapters/NativeAdapter.test.ts +85 -0
- package/src/core/bindings/adapters/NativeAdapter.ts +216 -0
- package/src/core/bindings/adapters/ProseMirrorAdapter.ts +231 -0
- package/src/core/bindings/adapters/index.ts +2 -0
- package/src/core/bindings/binding-factory.ts +78 -0
- package/src/core/bindings/detect-editor-type.ts +87 -0
- package/src/core/bindings/index.ts +13 -0
- package/src/core/bindings/insertion-boundary.test.ts +38 -0
- package/src/core/bindings/insertion-boundary.ts +26 -0
- package/src/core/bindings/native/NativeBinding.test.ts +277 -0
- package/src/core/bindings/native/NativeBinding.ts +239 -0
- package/src/core/bindings/resolver.ts +18 -0
- package/src/core/bindings/targets/codemirror.binding.ts +293 -0
- package/src/core/bindings/targets/contenteditable.binding.ts +452 -0
- package/src/core/bindings/targets/index.ts +10 -0
- package/src/core/bindings/targets/monaco.binding.ts +315 -0
- package/src/core/bindings/targets/tiptap.binding.test.ts +417 -0
- package/src/core/bindings/targets/tiptap.binding.ts +1192 -0
- package/src/core/bindings/tiptap/TiptapBinding.test.ts +63 -0
- package/src/core/bindings/tiptap/TiptapBinding.ts +464 -0
- package/src/core/bindings/types.ts +41 -0
- package/src/core/client/EphiaAudioClient.ts +654 -0
- package/src/core/client/audio-capture.ts +263 -0
- package/src/core/client/client-options.ts +39 -0
- package/src/core/client/client-state.ts +18 -0
- package/src/core/client/constants.ts +23 -0
- package/src/core/client/session-api.ts +415 -0
- package/src/core/connection/connection-state.ts +78 -0
- package/src/core/connection/index.ts +6 -0
- package/src/core/index.ts +47 -0
- package/src/core/operations/textToDocumentOperations.test.ts +69 -0
- package/src/core/operations/textToDocumentOperations.ts +92 -0
- package/src/core/runtime/DictationRuntime.test.ts +578 -0
- package/src/core/runtime/DictationRuntime.ts +434 -0
- package/src/core/runtime/TranscriptApplier.test.ts +355 -0
- package/src/core/runtime/TranscriptApplier.ts +229 -0
- package/src/core/runtime/index.ts +18 -0
- package/src/core/session/index.ts +2 -0
- package/src/core/session/session-machine.test.ts +16 -0
- package/src/core/session/session-machine.ts +59 -0
- package/src/core/targets/EditorContextCollector.ts +71 -0
- package/src/core/targets/TargetManager.test.ts +194 -0
- package/src/core/targets/TargetManager.ts +194 -0
- package/src/core/targets/index.ts +10 -0
- package/src/core/text-processing/index.ts +11 -0
- package/src/core/text-processing/overlap.test.ts +35 -0
- package/src/core/text-processing/overlap.ts +101 -0
- package/src/core/text-processing/voice-formatting.normalizer.test.ts +132 -0
- package/src/core/text-processing/voice-formatting.normalizer.ts +284 -0
- package/src/core/transcript/client-transcript.reducer.ts +366 -0
- package/src/core/transcript/client-transcript.state.ts +25 -0
- package/src/core/transcript/index.ts +19 -0
- package/src/core/transcript/transcript.assembler.test.ts +205 -0
- package/src/core/transcript/transcript.assembler.ts +152 -0
- package/src/core/transcript/transcript.reducer.test.ts +199 -0
- package/src/core/transcript/transcript.reducer.ts +771 -0
- package/src/core/transcript/transcript.state.ts +123 -0
- package/src/core/transport/LiveKitTransport.publish.test.ts +226 -0
- package/src/core/transport/LiveKitTransport.ts +459 -0
- package/src/core/transport/MockTransport.ts +231 -0
- package/src/core/transport/Transport.ts +82 -0
- package/src/debug/sdk-debug-collector.ts +79 -0
- package/src/devices/index.ts +2 -0
- package/src/devices/speechmike/__tests__/EphiaSpeechMikeProvider.test.tsx +99 -0
- package/src/devices/speechmike/__tests__/speechmike-audio-resolver.test.ts +96 -0
- package/src/devices/speechmike/__tests__/speechmike-button-router.test.ts +66 -0
- package/src/devices/speechmike/__tests__/speechmike-device-manager.test.ts +201 -0
- package/src/devices/speechmike/__tests__/speechmike-led-controller.test.ts +68 -0
- package/src/devices/speechmike/browser.ts +80 -0
- package/src/devices/speechmike/constants.ts +74 -0
- package/src/devices/speechmike/dictation-support-loader.ts +81 -0
- package/src/devices/speechmike/index.ts +11 -0
- package/src/devices/speechmike/react/EphiaSpeechMikeContext.ts +34 -0
- package/src/devices/speechmike/react/EphiaSpeechMikeProvider.tsx +287 -0
- package/src/devices/speechmike/react/useEphiaSpeechMike.ts +26 -0
- package/src/devices/speechmike/speechmike-audio-resolver.ts +58 -0
- package/src/devices/speechmike/speechmike-button-router.ts +73 -0
- package/src/devices/speechmike/speechmike-device-manager.ts +461 -0
- package/src/devices/speechmike/speechmike-led-controller.ts +78 -0
- package/src/devices/speechmike/types.ts +96 -0
- package/src/dictation_support.d.ts +31 -0
- package/src/global.d.ts +10 -0
- package/src/headless/createEphiaClient.ts +220 -0
- package/src/headless/index.ts +18 -0
- package/src/index.ts +89 -0
- package/src/react/EphiaAuto.tsx +87 -0
- package/src/react/components/EphiaDictationButton.tsx +88 -0
- package/src/react/components/EphiaStatusBar.tsx +59 -0
- package/src/react/components/EphiaTextarea.tsx +295 -0
- package/src/react/ephia-react.css +318 -0
- package/src/react/hooks/targets/index.ts +3 -0
- package/src/react/hooks/targets/useEphiaCodemirror.ts +35 -0
- package/src/react/hooks/targets/useEphiaMonaco.ts +35 -0
- package/src/react/hooks/targets/useEphiaTiptap.ts +23 -0
- package/src/react/hooks/useEphia.lifecycle.test.tsx +389 -0
- package/src/react/hooks/useEphia.ts +367 -0
- package/src/react/hooks/useEphiaDiscardTarget.ts +53 -0
- package/src/react/hooks/useEphiaServerEvent.ts +33 -0
- package/src/react/hooks/useEphiaTarget.ts +47 -0
- package/src/react/hooks/useEphiaTranscript.ts +22 -0
- package/src/react/index.ts +58 -0
- package/src/react/provider/EphiaContext.ts +63 -0
- package/src/react/provider/EphiaInternalContext.ts +32 -0
- package/src/react/provider/EphiaProvider.tsx +373 -0
- package/src/react/registry/binding-factory.ts +7 -0
- package/src/react/registry/detect-editor-type.ts +2 -0
- package/src/react/registry/events.ts +37 -0
- package/src/react/registry/registries/CodeMirrorInstanceRegistry.ts +24 -0
- package/src/react/registry/registries/MonacoInstanceRegistry.ts +23 -0
- package/src/react/registry/registries/TargetRegistry.ts +327 -0
- package/src/react/registry/registries/TiptapInstanceRegistry.ts +43 -0
- package/src/react/registry/registries/index.ts +5 -0
- package/src/react/store/create-ephia-store.ts +36 -0
- package/src/react/store/types.ts +41 -0
- package/src/react/utils/flash-range.ts +24 -0
- package/src/react/utils/index.ts +1 -0
- package/src/rich-editor/adapters/tiptap.test.ts +86 -0
- package/src/rich-editor/adapters/tiptap.ts +23 -0
- package/src/rich-editor/index.ts +3 -0
- package/src/rich-editor/types.ts +24 -0
- package/src/rich-editor/use-ephia-rich-editor.test.tsx +202 -0
- package/src/rich-editor/use-ephia-rich-editor.ts +47 -0
- package/src/shared/config/endpoint.test.ts +45 -0
- package/src/shared/config/endpoint.ts +39 -0
- package/src/shared/config/schema.ts +32 -0
- package/src/shared/effective-text.ts +13 -0
- package/src/shared/errors/EphiaSdkError.ts +54 -0
- package/src/shared/errors/messages.ts +40 -0
- package/src/shared/index.ts +27 -0
- package/src/shared/state/audio-state.ts +45 -0
- package/src/shared/state/index.ts +2 -0
- package/src/shared/store/document-store.ts +32 -0
- package/src/shared/store/index.ts +2 -0
- package/src/shared/types/editors.ts +28 -0
- package/src/shared/types/session.ts +12 -0
- package/src/style.css +2 -0
- package/src/testing/index.tsx +60 -0
- package/src/ui/assets/ephia-logo.svg +4 -0
- package/src/ui/components/EphiaLogo.tsx +77 -0
- package/src/ui/index.ts +24 -0
- package/src/ui/primitives/Button.tsx +53 -0
- package/src/ui/primitives/Spinner.tsx +21 -0
- package/src/ui/primitives/index.ts +5 -0
- package/src/ui/recorder/EphiaFloatingButton.tsx +489 -0
- package/src/ui/recorder/MinimalProcessingBars.tsx +122 -0
- package/src/ui/recorder/StandardIntensityVisualizer.tsx +148 -0
- package/src/ui/recorder/appearance.ts +9 -0
- package/src/ui/recorder/index.ts +8 -0
- package/src/ui/theme.css +775 -0
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import React, { useMemo } from "react";
|
|
4
|
+
import { EphiaContext, type EphiaContextValue } from "../react/provider/EphiaContext";
|
|
5
|
+
import { createEphiaStore, type EphiaStore } from "../react/store/create-ephia-store";
|
|
6
|
+
|
|
7
|
+
export type { EphiaStore } from "../react/store/create-ephia-store";
|
|
8
|
+
export type { EphiaContextValue, EphiaProviderConfig } from "../react/provider/EphiaContext";
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Crée un store Ephia vierge pour les tests ou le catalogue UI.
|
|
12
|
+
*
|
|
13
|
+
* Le store a le même shape que celui utilisé par <EphiaProvider>, mais il n'est
|
|
14
|
+
* connecté à aucun client audio. C'est utile pour monter des composants qui
|
|
15
|
+
* consomment useEphiaStatus / useEphiaConnection / useEphia en isolation.
|
|
16
|
+
*/
|
|
17
|
+
export function createEphiaTestStore(): EphiaStore {
|
|
18
|
+
return createEphiaStore();
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface EphiaTestProviderProps {
|
|
22
|
+
children: React.ReactNode;
|
|
23
|
+
/**
|
|
24
|
+
* Store injecté. Si absent, un store vierge est créé.
|
|
25
|
+
*/
|
|
26
|
+
store?: EphiaStore;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Provider minimal pour les tests unitaires et le catalogue UI preview.
|
|
31
|
+
*
|
|
32
|
+
* Fournit un contexte Ephia avec un store Zustand réel mais déconnecté
|
|
33
|
+
* (status idle, connexion idle, etc.) afin que les composants utilisant
|
|
34
|
+
* useEphiaStatus / useEphiaConnection / useEphia / useEphiaPartial
|
|
35
|
+
* puissent être montés sans backend.
|
|
36
|
+
*
|
|
37
|
+
* @example
|
|
38
|
+
* ```tsx
|
|
39
|
+
* import { EphiaTestProvider } from "@ephia/dova-sdk/testing";
|
|
40
|
+
*
|
|
41
|
+
* <EphiaTestProvider>
|
|
42
|
+
* <MyComponent />
|
|
43
|
+
* </EphiaTestProvider>
|
|
44
|
+
* ```
|
|
45
|
+
*/
|
|
46
|
+
export function EphiaTestProvider({ children, store: injectedStore }: EphiaTestProviderProps) {
|
|
47
|
+
const store = useMemo(() => injectedStore ?? createEphiaTestStore(), [injectedStore]);
|
|
48
|
+
|
|
49
|
+
const value = useMemo<EphiaContextValue>(
|
|
50
|
+
() => ({
|
|
51
|
+
store,
|
|
52
|
+
registerTarget: () => () => {},
|
|
53
|
+
applyServerEvent: () => {},
|
|
54
|
+
config: {},
|
|
55
|
+
}),
|
|
56
|
+
[store],
|
|
57
|
+
);
|
|
58
|
+
|
|
59
|
+
return <EphiaContext.Provider value={value}>{children}</EphiaContext.Provider>;
|
|
60
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
<svg width="220" height="207" viewBox="0 0 220 207" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<path d="M130.184 22.8784C110.496 11.7584 85.4808 18.5556 74.1504 38.1772C66.8151 50.8807 67.004 65.8635 73.334 77.9663C76.4886 83.9978 77.6606 91.3208 74.2568 97.2153C70.8529 103.109 63.9255 105.756 57.1241 106.04C55.4205 106.111 53.7254 106.287 52.0498 106.566C51.9939 106.576 51.9377 106.586 51.8818 106.596C51.8243 106.606 51.7665 106.615 51.709 106.625C47.369 107.377 43.2604 108.806 39.4981 110.8C34.2218 113.586 29.4987 117.542 25.7589 122.554C25.7424 122.576 25.7254 122.598 25.709 122.62C25.6788 122.661 25.6482 122.701 25.6182 122.742C21.6987 128.032 19.015 134.293 17.9923 141.097C17.9778 141.192 17.964 141.289 17.9502 141.385C17.9421 141.442 17.9337 141.499 17.9258 141.556C17.6653 143.422 17.5345 145.296 17.5312 147.163V147.28C17.5314 157.14 20.9911 166.192 26.7617 173.29C26.796 173.332 26.8307 173.375 26.8652 173.417C26.928 173.494 26.9915 173.57 27.0548 173.646C27.1098 173.713 27.1653 173.779 27.2207 173.845C27.255 173.885 27.2898 173.927 27.3242 173.968C27.6222 174.319 27.9266 174.666 28.2374 175.009C28.2534 175.026 28.2701 175.044 28.2861 175.061C28.3779 175.162 28.4706 175.263 28.5635 175.363C28.5869 175.388 28.6114 175.413 28.6349 175.438C28.7264 175.536 28.8185 175.635 28.9111 175.732C28.9284 175.75 28.9456 175.769 28.9629 175.787C29.1492 175.982 29.3377 176.176 29.5283 176.367L29.6191 176.458C29.6653 176.504 29.7125 176.55 29.7589 176.596C29.8119 176.648 29.8646 176.702 29.918 176.754C36.4444 183.148 45.0865 187.393 54.6963 188.342C54.7093 188.343 54.7223 188.344 54.7354 188.346C55.0558 188.377 55.3777 188.405 55.7002 188.429C55.7229 188.43 55.746 188.432 55.7687 188.434C55.8996 188.443 56.031 188.452 56.1622 188.46C57.0288 188.515 57.8957 188.543 58.7607 188.543C58.774 188.543 58.7875 188.543 58.8008 188.543C58.8551 188.543 58.9096 188.542 58.9639 188.542C59.0597 188.542 59.1561 188.541 59.252 188.54C66.9707 188.457 74.1811 186.256 80.3292 182.49C80.3971 182.449 80.4656 182.407 80.5333 182.365C80.5789 182.337 80.6245 182.308 80.6699 182.279C85.3019 179.393 89.4161 175.551 92.6865 170.84C92.7302 170.777 92.7741 170.714 92.8174 170.651C92.8427 170.614 92.8684 170.577 92.8936 170.54C94.8281 167.711 96.419 164.628 97.6074 161.353C99.3661 156.525 100.166 151.511 100.075 146.558C100.266 130.196 106.911 115.387 117.584 104.555C120.604 101.544 123.936 98.8469 127.529 96.5151C128.082 96.1565 127.539 96.5073 129.953 95.0288C135.565 91.8709 140.505 87.373 144.245 81.6763C144.281 81.623 144.315 81.5686 144.351 81.5151C144.368 81.489 144.385 81.4622 144.402 81.436C144.828 80.7863 145.239 80.1208 145.632 79.4399C155.114 63.0194 152.024 42.7913 139.35 29.896C136.719 27.1793 133.672 24.7768 130.236 22.7886L130.184 22.8784Z" fill="#723ADE"/>
|
|
3
|
+
<path d="M151.646 107.073C154.645 106.38 157.768 106.016 160.977 106.016C183.769 106.016 202.246 124.49 202.246 147.278C202.246 167.41 187.826 184.171 168.751 187.807C167.995 187.951 167.233 188.074 166.463 188.177C166.383 188.187 166.304 188.201 166.224 188.211C164.503 188.43 162.749 188.543 160.969 188.543C138.176 188.543 119.699 170.069 119.699 147.28C119.699 127.697 133.344 111.298 151.646 107.073Z" fill="#00EBD0"/>
|
|
4
|
+
</svg>
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import type { CSSProperties } from "react";
|
|
4
|
+
|
|
5
|
+
/** Source of truth: `src/ui/assets/ephia-logo.svg` (same as apps/ephia-website/public/ephia_logo.svg). */
|
|
6
|
+
export const EPHIA_LOGO_VIEWBOX = "0 0 220 207";
|
|
7
|
+
export const EPHIA_LOGO_ASPECT = 220 / 207;
|
|
8
|
+
|
|
9
|
+
export const EPHIA_BRAND_PURPLE = "#723ADE";
|
|
10
|
+
export const EPHIA_BRAND_TEAL = "#00EBD0";
|
|
11
|
+
|
|
12
|
+
const LOGO_PURPLE_PATH =
|
|
13
|
+
"M130.184 22.8784C110.496 11.7584 85.4808 18.5556 74.1504 38.1772C66.8151 50.8807 67.004 65.8635 73.334 77.9663C76.4886 83.9978 77.6606 91.3208 74.2568 97.2153C70.8529 103.109 63.9255 105.756 57.1241 106.04C55.4205 106.111 53.7254 106.287 52.0498 106.566C51.9939 106.576 51.9377 106.586 51.8818 106.596C51.8243 106.606 51.7665 106.615 51.709 106.625C47.369 107.377 43.2604 108.806 39.4981 110.8C34.2218 113.586 29.4987 117.542 25.7589 122.554C25.7424 122.576 25.7254 122.598 25.709 122.62C25.6788 122.661 25.6482 122.701 25.6182 122.742C21.6987 128.032 19.015 134.293 17.9923 141.097C17.9778 141.192 17.964 141.289 17.9502 141.385C17.9421 141.442 17.9337 141.499 17.9258 141.556C17.6653 143.422 17.5345 145.296 17.5312 147.163V147.28C17.5314 157.14 20.9911 166.192 26.7617 173.29C26.796 173.332 26.8307 173.375 26.8652 173.417C26.928 173.494 26.9915 173.57 27.0548 173.646C27.1098 173.713 27.1653 173.779 27.2207 173.845C27.255 173.885 27.2898 173.927 27.3242 173.968C27.6222 174.319 27.9266 174.666 28.2374 175.009C28.2534 175.026 28.2701 175.044 28.2861 175.061C28.3779 175.162 28.4706 175.263 28.5635 175.363C28.5869 175.388 28.6114 175.413 28.6349 175.438C28.7264 175.536 28.8185 175.635 28.9111 175.732C28.9284 175.75 28.9456 175.769 28.9629 175.787C29.1492 175.982 29.3377 176.176 29.5283 176.367L29.6191 176.458C29.6653 176.504 29.7125 176.55 29.7589 176.596C29.8119 176.648 29.8646 176.702 29.918 176.754C36.4444 183.148 45.0865 187.393 54.6963 188.342C54.7093 188.343 54.7223 188.344 54.7354 188.346C55.0558 188.377 55.3777 188.405 55.7002 188.429C55.7229 188.43 55.746 188.432 55.7687 188.434C55.8996 188.443 56.031 188.452 56.1622 188.46C57.0288 188.515 57.8957 188.543 58.7607 188.543C58.774 188.543 58.7875 188.543 58.8008 188.543C58.8551 188.543 58.9096 188.542 58.9639 188.542C59.0597 188.542 59.1561 188.541 59.252 188.54C66.9707 188.457 74.1811 186.256 80.3292 182.49C80.3971 182.449 80.4656 182.407 80.5333 182.365C80.5789 182.337 80.6245 182.308 80.6699 182.279C85.3019 179.393 89.4161 175.551 92.6865 170.84C92.7302 170.777 92.7741 170.714 92.8174 170.651C92.8427 170.614 92.8684 170.577 92.8936 170.54C94.8281 167.711 96.419 164.628 97.6074 161.353C99.3661 156.525 100.166 151.511 100.075 146.558C100.266 130.196 106.911 115.387 117.584 104.555C120.604 101.544 123.936 98.8469 127.529 96.5151C128.082 96.1565 127.539 96.5073 129.953 95.0288C135.565 91.8709 140.505 87.373 144.245 81.6763C144.281 81.623 144.315 81.5686 144.351 81.5151C144.368 81.489 144.385 81.4622 144.402 81.436C144.828 80.7863 145.239 80.1208 145.632 79.4399C155.114 63.0194 152.024 42.7913 139.35 29.896C136.719 27.1793 133.672 24.7768 130.236 22.7886L130.184 22.8784Z";
|
|
14
|
+
|
|
15
|
+
const LOGO_TEAL_PATH =
|
|
16
|
+
"M151.646 107.073C154.645 106.38 157.768 106.016 160.977 106.016C183.769 106.016 202.246 124.49 202.246 147.278C202.246 167.41 187.826 184.171 168.751 187.807C167.995 187.951 167.233 188.074 166.463 188.177C166.383 188.187 166.304 188.201 166.224 188.211C164.503 188.43 162.749 188.543 160.969 188.543C138.176 188.543 119.699 170.069 119.699 147.28C119.699 127.697 133.344 111.298 151.646 107.073Z";
|
|
17
|
+
|
|
18
|
+
export type EphiaLogoVariant = "color" | "mono";
|
|
19
|
+
|
|
20
|
+
export interface EphiaLogoProps {
|
|
21
|
+
height?: number;
|
|
22
|
+
width?: number;
|
|
23
|
+
className?: string;
|
|
24
|
+
style?: CSSProperties;
|
|
25
|
+
variant?: EphiaLogoVariant;
|
|
26
|
+
/** Mono fill (custom brand colors). Ignored when variant is "color". */
|
|
27
|
+
fill?: string;
|
|
28
|
+
isRecording?: boolean;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export function logoWidthFromHeight(heightPx: number): number {
|
|
32
|
+
return Math.round(heightPx * EPHIA_LOGO_ASPECT);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export function EphiaLogo({
|
|
36
|
+
height,
|
|
37
|
+
width,
|
|
38
|
+
className,
|
|
39
|
+
style,
|
|
40
|
+
variant = "color",
|
|
41
|
+
fill = "currentColor",
|
|
42
|
+
isRecording = false,
|
|
43
|
+
}: EphiaLogoProps) {
|
|
44
|
+
const resolvedHeight = height ?? (width != null ? Math.round(width / EPHIA_LOGO_ASPECT) : 24);
|
|
45
|
+
const resolvedWidth = width ?? logoWidthFromHeight(resolvedHeight);
|
|
46
|
+
|
|
47
|
+
const svgClass = [
|
|
48
|
+
"ephia-transcribe-logo-svg",
|
|
49
|
+
isRecording ? "ephia-transcribe-logo-svg--recording" : "",
|
|
50
|
+
className ?? "",
|
|
51
|
+
]
|
|
52
|
+
.filter(Boolean)
|
|
53
|
+
.join(" ");
|
|
54
|
+
|
|
55
|
+
return (
|
|
56
|
+
<svg
|
|
57
|
+
viewBox={EPHIA_LOGO_VIEWBOX}
|
|
58
|
+
className={svgClass}
|
|
59
|
+
style={{ height: resolvedHeight, width: resolvedWidth, ...style }}
|
|
60
|
+
fill="none"
|
|
61
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
62
|
+
aria-hidden
|
|
63
|
+
>
|
|
64
|
+
{variant === "color" ? (
|
|
65
|
+
<>
|
|
66
|
+
<path d={LOGO_PURPLE_PATH} fill={EPHIA_BRAND_PURPLE} />
|
|
67
|
+
<path d={LOGO_TEAL_PATH} fill={EPHIA_BRAND_TEAL} />
|
|
68
|
+
</>
|
|
69
|
+
) : (
|
|
70
|
+
<>
|
|
71
|
+
<path d={LOGO_PURPLE_PATH} fill={fill} />
|
|
72
|
+
<path d={LOGO_TEAL_PATH} fill={fill} />
|
|
73
|
+
</>
|
|
74
|
+
)}
|
|
75
|
+
</svg>
|
|
76
|
+
);
|
|
77
|
+
}
|
package/src/ui/index.ts
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
// ── Brand ──────────────────────────────────────────────────
|
|
2
|
+
export {
|
|
3
|
+
EphiaLogo,
|
|
4
|
+
EPHIA_BRAND_PURPLE,
|
|
5
|
+
EPHIA_BRAND_TEAL,
|
|
6
|
+
EPHIA_LOGO_VIEWBOX,
|
|
7
|
+
EPHIA_LOGO_ASPECT,
|
|
8
|
+
logoWidthFromHeight,
|
|
9
|
+
} from "./components/EphiaLogo";
|
|
10
|
+
export type { EphiaLogoProps, EphiaLogoVariant } from "./components/EphiaLogo";
|
|
11
|
+
|
|
12
|
+
// ── Primitives ─────────────────────────────────────────────
|
|
13
|
+
export { Button, Spinner } from "./primitives";
|
|
14
|
+
export type { ButtonProps, SpinnerProps } from "./primitives";
|
|
15
|
+
|
|
16
|
+
// ── Recorder ───────────────────────────────────────────────
|
|
17
|
+
export { EphiaFloatingButton } from "./recorder";
|
|
18
|
+
export type {
|
|
19
|
+
EphiaFloatingButtonProps,
|
|
20
|
+
EphiaFloatingButtonPosition,
|
|
21
|
+
EphiaFloatingButtonTheme,
|
|
22
|
+
EphiaFloatingButtonSize,
|
|
23
|
+
EphiaFloatingButtonBorderRadius,
|
|
24
|
+
} from "./recorder";
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import type { ButtonHTMLAttributes, ReactNode } from "react";
|
|
4
|
+
|
|
5
|
+
export type ButtonProps = ButtonHTMLAttributes<HTMLButtonElement> & {
|
|
6
|
+
variant?: "primary" | "danger" | "ghost" | "outline";
|
|
7
|
+
size?: "sm" | "md" | "lg";
|
|
8
|
+
isLoading?: boolean;
|
|
9
|
+
children: ReactNode;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export function Button({
|
|
13
|
+
variant = "primary",
|
|
14
|
+
size = "md",
|
|
15
|
+
isLoading,
|
|
16
|
+
children,
|
|
17
|
+
className = "",
|
|
18
|
+
disabled,
|
|
19
|
+
...rest
|
|
20
|
+
}: ButtonProps) {
|
|
21
|
+
const base =
|
|
22
|
+
"inline-flex items-center justify-center font-medium rounded-full transition focus:outline-none focus:ring-2 focus:ring-offset-1";
|
|
23
|
+
|
|
24
|
+
const variants = {
|
|
25
|
+
primary:
|
|
26
|
+
"bg-[var(--ephia-primary)] text-white hover:opacity-90 focus:ring-[var(--ephia-primary)]",
|
|
27
|
+
danger:
|
|
28
|
+
"bg-[var(--ephia-danger)] text-white hover:opacity-90 focus:ring-[var(--ephia-danger)]",
|
|
29
|
+
ghost:
|
|
30
|
+
"bg-transparent text-neutral-700 hover:bg-neutral-100 focus:ring-neutral-300",
|
|
31
|
+
outline:
|
|
32
|
+
"border border-neutral-200 bg-white text-neutral-700 hover:bg-neutral-50 focus:ring-neutral-300",
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
const sizes = {
|
|
36
|
+
sm: "px-3 py-1.5 text-xs",
|
|
37
|
+
md: "px-4 py-2 text-sm",
|
|
38
|
+
lg: "px-6 py-3 text-base",
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
return (
|
|
42
|
+
<button
|
|
43
|
+
className={`${base} ${variants[variant]} ${sizes[size]} ${className}`}
|
|
44
|
+
disabled={disabled || isLoading}
|
|
45
|
+
{...rest}
|
|
46
|
+
>
|
|
47
|
+
{isLoading ? (
|
|
48
|
+
<span className="mr-2 inline-block h-4 w-4 animate-spin rounded-full border-2 border-white/30 border-t-white" />
|
|
49
|
+
) : null}
|
|
50
|
+
{children}
|
|
51
|
+
</button>
|
|
52
|
+
);
|
|
53
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
export type SpinnerProps = {
|
|
4
|
+
size?: "sm" | "md" | "lg";
|
|
5
|
+
className?: string;
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
export function Spinner({ size = "md", className = "" }: SpinnerProps) {
|
|
9
|
+
const sizes = {
|
|
10
|
+
sm: "h-3 w-3 border-2",
|
|
11
|
+
md: "h-5 w-5 border-2",
|
|
12
|
+
lg: "h-8 w-8 border-[3px]",
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
return (
|
|
16
|
+
<span
|
|
17
|
+
className={`inline-block animate-spin rounded-full border-neutral-300 border-t-[var(--ephia-primary)] ${sizes[size]} ${className}`}
|
|
18
|
+
aria-label="Chargement"
|
|
19
|
+
/>
|
|
20
|
+
);
|
|
21
|
+
}
|