unipo-ui 1.3.0 → 1.5.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 (166) hide show
  1. package/dist/LembarSurat-CShVDBwp.d.cts +219 -0
  2. package/dist/LembarSurat-CShVDBwp.d.ts +219 -0
  3. package/dist/{admisi-YXCTBECZ.js → admisi-LKPO7LCR.js} +2 -2
  4. package/dist/{admisi-YCOE3DMH.cjs → admisi-U6YYQGBB.cjs} +2 -2
  5. package/dist/{akademik-PJGL6MSP.cjs → akademik-3DFVHKUD.cjs} +2 -2
  6. package/dist/{akademik-TPDFEZGF.js → akademik-IXTTJMVD.js} +2 -2
  7. package/dist/{arsip-2T7IEION.cjs → arsip-23P44PGP.cjs} +2 -2
  8. package/dist/{arsip-LDRV7FYX.js → arsip-NZFZOTY7.js} +2 -2
  9. package/dist/chunk-4YZB47GC.cjs +1026 -0
  10. package/dist/chunk-4YZB47GC.cjs.map +1 -0
  11. package/dist/chunk-5BRCBOYC.cjs +2550 -0
  12. package/dist/chunk-5BRCBOYC.cjs.map +1 -0
  13. package/dist/{chunk-7AJ4LW5H.js → chunk-5T2FWP5A.js} +61 -971
  14. package/dist/chunk-5T2FWP5A.js.map +1 -0
  15. package/dist/{chunk-MKQEH7QS.cjs → chunk-AYBCFK4E.cjs} +51 -50
  16. package/dist/chunk-AYBCFK4E.cjs.map +1 -0
  17. package/dist/{chunk-4BQOABRV.js → chunk-BRARGLUX.js} +32 -32
  18. package/dist/chunk-BRARGLUX.js.map +1 -0
  19. package/dist/{chunk-TYCRRYCQ.js → chunk-CM4EFDV7.js} +367 -34
  20. package/dist/chunk-CM4EFDV7.js.map +1 -0
  21. package/dist/{chunk-TAKLMRU7.cjs → chunk-FK24GBNJ.cjs} +4 -4
  22. package/dist/{chunk-TAKLMRU7.cjs.map → chunk-FK24GBNJ.cjs.map} +1 -1
  23. package/dist/{chunk-LNJTDEQR.cjs → chunk-HGQGB7ET.cjs} +467 -128
  24. package/dist/chunk-HGQGB7ET.cjs.map +1 -0
  25. package/dist/{chunk-34OKV63Q.js → chunk-ITIQ2IHX.js} +3 -3
  26. package/dist/{chunk-34OKV63Q.js.map → chunk-ITIQ2IHX.js.map} +1 -1
  27. package/dist/{chunk-LN6HZMPI.js → chunk-KF7SZPEH.js} +4 -3
  28. package/dist/chunk-KF7SZPEH.js.map +1 -0
  29. package/dist/{chunk-JASW45YF.cjs → chunk-LTADAXBH.cjs} +32 -32
  30. package/dist/chunk-LTADAXBH.cjs.map +1 -0
  31. package/dist/chunk-NA23226U.js +2475 -0
  32. package/dist/chunk-NA23226U.js.map +1 -0
  33. package/dist/chunk-OLQKRLWL.js +922 -0
  34. package/dist/chunk-OLQKRLWL.js.map +1 -0
  35. package/dist/{chunk-5VNCBW4R.cjs → chunk-UC2H3PKQ.cjs} +126 -1119
  36. package/dist/chunk-UC2H3PKQ.cjs.map +1 -0
  37. package/dist/editor.cjs +993 -0
  38. package/dist/editor.cjs.map +1 -0
  39. package/dist/editor.d.cts +468 -0
  40. package/dist/editor.d.ts +468 -0
  41. package/dist/editor.js +738 -0
  42. package/dist/editor.js.map +1 -0
  43. package/dist/{helpdesk-BAOXAU6G.js → helpdesk-LV65LM5V.js} +2 -2
  44. package/dist/{helpdesk-AWVC7BPE.cjs → helpdesk-S7GAHYXG.cjs} +2 -2
  45. package/dist/ikon.cjs +28 -28
  46. package/dist/ikon.js +1 -1
  47. package/dist/{iku-F47ZLMYJ.cjs → iku-CJG75NAT.cjs} +2 -2
  48. package/dist/{iku-7JLF2NIH.js → iku-XFGUJ6CX.js} +2 -2
  49. package/dist/index.cjs +365 -364
  50. package/dist/index.cjs.map +1 -1
  51. package/dist/index.js +7 -5
  52. package/dist/index.js.map +1 -1
  53. package/dist/{kalender-FGGUBYKZ.js → kalender-NZH7F2LO.js} +2 -2
  54. package/dist/{kalender-DGQDGJCL.cjs → kalender-SD7EUASC.cjs} +2 -2
  55. package/dist/karier-BDPZONV6.cjs +20 -0
  56. package/dist/karier-VHUJKKD6.js +11 -0
  57. package/dist/katalog.cjs +236 -139
  58. package/dist/katalog.cjs.map +1 -1
  59. package/dist/katalog.d.cts +10 -5
  60. package/dist/katalog.d.ts +10 -5
  61. package/dist/katalog.js +136 -41
  62. package/dist/katalog.js.map +1 -1
  63. package/dist/{kelulusan-ZR7CM6I5.js → kelulusan-3QCPPC3D.js} +2 -2
  64. package/dist/{kelulusan-BHFQM5N4.cjs → kelulusan-X7DYJN6T.cjs} +2 -2
  65. package/dist/kemahasiswaan-JNCMH3HR.js +11 -0
  66. package/dist/kemahasiswaan-MQYXEVKE.cjs +20 -0
  67. package/dist/kerjasama-KYHEBSLX.cjs +20 -0
  68. package/dist/kerjasama-QSZ5X4OB.js +11 -0
  69. package/dist/keu-6H5WH6A4.js +11 -0
  70. package/dist/keu-MIJRVMGW.cjs +20 -0
  71. package/dist/{layanan-Y6WUCSD2.js → layanan-H25JKJKC.js} +2 -2
  72. package/dist/{layanan-RQ2AWCQ5.cjs → layanan-XR75P7YX.cjs} +2 -2
  73. package/dist/{lms-5JYOSLBI.cjs → lms-2ZCH273D.cjs} +2 -2
  74. package/dist/{lms-NTXMSHG2.js → lms-MFXFO2AZ.js} +2 -2
  75. package/dist/{lppm-UXYGIOIF.js → lppm-B7ECUONV.js} +2 -2
  76. package/dist/{lppm-7DH7PRF3.cjs → lppm-QEQKZXCY.cjs} +2 -2
  77. package/dist/mbkm-737Q4WFQ.js +11 -0
  78. package/dist/mbkm-GMNFIFDS.cjs +20 -0
  79. package/dist/portal-5LCG6IP3.cjs +20 -0
  80. package/dist/portal-NYR3OIU4.js +11 -0
  81. package/dist/profil-FA2WXZR5.js +11 -0
  82. package/dist/profil-J4DRC6LS.cjs +20 -0
  83. package/dist/registry.json +645 -3
  84. package/dist/{repositori-2MJ43NXM.js → repositori-4GHBDDQA.js} +2 -2
  85. package/dist/{repositori-KFXVJB7B.cjs → repositori-JRDIIPDJ.cjs} +2 -2
  86. package/dist/{rpl-2ZXHNSPF.js → rpl-4RGI6RNL.js} +2 -2
  87. package/dist/{rpl-YF5MV2YA.cjs → rpl-NBVCZHQF.cjs} +2 -2
  88. package/dist/sarpras-TAF4M2NQ.js +11 -0
  89. package/dist/sarpras-TXNUAX4Y.cjs +20 -0
  90. package/dist/scss/components/_dokumen.scss +850 -0
  91. package/dist/scss/components/_editor.scss +1093 -0
  92. package/dist/scss/components/_ikon.scss +115 -25
  93. package/dist/scss/components/_konten-blok.scss +413 -0
  94. package/dist/scss/components/_pilih-berkas.scss +156 -0
  95. package/dist/scss/index.scss +4 -0
  96. package/dist/{sdm-QKBXH3JF.js → sdm-5YKAAV3T.js} +2 -2
  97. package/dist/{sdm-N6LE66PP.cjs → sdm-IN64PE3T.cjs} +2 -2
  98. package/dist/siakad.cjs +1399 -909
  99. package/dist/siakad.cjs.map +1 -1
  100. package/dist/siakad.d.cts +205 -2
  101. package/dist/siakad.d.ts +205 -2
  102. package/dist/siakad.js +577 -117
  103. package/dist/siakad.js.map +1 -1
  104. package/dist/{spmi-N6EU7KNC.cjs → spmi-AXZ5B3EJ.cjs} +2 -2
  105. package/dist/{spmi-J37NEYIU.js → spmi-LMUM2XER.js} +2 -2
  106. package/dist/{tracer-M3FTNWBG.js → tracer-UBUAIJEK.js} +2 -2
  107. package/dist/{tracer-G6DDXVXC.cjs → tracer-WWVIA55Q.cjs} +2 -2
  108. package/dist/ui-unipo.css +2867 -24
  109. package/dist/ui-unipo.min.css +1 -1
  110. package/package.json +12 -2
  111. package/src/editor/EditorBerita.tsx +297 -0
  112. package/src/editor/EditorBlok.tsx +369 -0
  113. package/src/editor/Kanvas.tsx +322 -0
  114. package/src/editor/Penyisip.tsx +186 -0
  115. package/src/editor/TeksSebaris.tsx +190 -0
  116. package/src/editor/blok/Media.tsx +132 -0
  117. package/src/editor/blok/Tata.tsx +115 -0
  118. package/src/editor/blok/Teks.tsx +183 -0
  119. package/src/editor/blok/index.tsx +212 -0
  120. package/src/editor/blok/props.ts +24 -0
  121. package/src/editor/dokumen/EditorDokumen.tsx +323 -0
  122. package/src/editor/dokumen/EditorSkripsi.tsx +681 -0
  123. package/src/editor/dokumen/EditorTemplatSurat.tsx +194 -0
  124. package/src/editor/dokumen/LembarSurat.tsx +168 -0
  125. package/src/editor/dokumen/index.ts +8 -0
  126. package/src/editor/dokumen/pustaka.ts +118 -0
  127. package/src/editor/dokumen/saring.ts +92 -0
  128. package/src/editor/dokumen/sisip.ts +42 -0
  129. package/src/editor/dokumen/templat.ts +73 -0
  130. package/src/editor/index.ts +11 -0
  131. package/src/editor/konteks.tsx +61 -0
  132. package/src/editor/render.ts +232 -0
  133. package/src/editor/tipe.ts +295 -0
  134. package/src/ikon/ilustrasi.tsx +30 -30
  135. package/src/katalog/aturan.ts +34 -7
  136. package/src/katalog/isian.tsx +41 -5
  137. package/src/katalog/kelola.tsx +92 -22
  138. package/src/siakad/index.ts +3 -0
  139. package/src/siakad/media-editor.ts +67 -0
  140. package/src/siakad/pilih-berkas.tsx +292 -0
  141. package/src/siakad/status-layanan.tsx +75 -1
  142. package/src/siakad/surat.tsx +759 -0
  143. package/dist/chunk-4BQOABRV.js.map +0 -1
  144. package/dist/chunk-5VNCBW4R.cjs.map +0 -1
  145. package/dist/chunk-7AJ4LW5H.js.map +0 -1
  146. package/dist/chunk-JASW45YF.cjs.map +0 -1
  147. package/dist/chunk-LN6HZMPI.js.map +0 -1
  148. package/dist/chunk-LNJTDEQR.cjs.map +0 -1
  149. package/dist/chunk-MKQEH7QS.cjs.map +0 -1
  150. package/dist/chunk-TYCRRYCQ.js.map +0 -1
  151. package/dist/karier-H3HBFCQQ.js +0 -11
  152. package/dist/karier-QTU2P5YD.cjs +0 -20
  153. package/dist/kemahasiswaan-EINWXAY7.cjs +0 -20
  154. package/dist/kemahasiswaan-NH2LEDH7.js +0 -11
  155. package/dist/kerjasama-FAOHZCML.js +0 -11
  156. package/dist/kerjasama-TXWJOU4Y.cjs +0 -20
  157. package/dist/keu-4TXF4FEP.cjs +0 -20
  158. package/dist/keu-SD7UOCDB.js +0 -11
  159. package/dist/mbkm-OGR72BTB.js +0 -11
  160. package/dist/mbkm-URKJHUIQ.cjs +0 -20
  161. package/dist/portal-EI7TXN7H.cjs +0 -20
  162. package/dist/portal-MMUYX3RA.js +0 -11
  163. package/dist/profil-46FV46VH.cjs +0 -20
  164. package/dist/profil-4BIXIM6D.js +0 -11
  165. package/dist/sarpras-CQ7QKVUN.js +0 -11
  166. package/dist/sarpras-XGPHHFCG.cjs +0 -20
@@ -0,0 +1,219 @@
1
+ import * as React from 'react';
2
+ import { LucideIcon } from 'lucide-react';
3
+
4
+ /**
5
+ * Format blok sama dengan backend (app/Modules/Humas/Support/Blok.php di SIAKAD), jadi isi editor ini bisa
6
+ * langsung dikirim ke /v1/humas/... sebagai `blok`:
7
+ * {"id": "b1", "tipe": "paragraf", "data": {...}, "anak": [[...], [...]]}. `anak` hanya untuk blok kolom.
8
+ */
9
+ type TipeBlok = 'paragraf' | 'judul' | 'daftar' | 'kutipan' | 'gambar' | 'galeri' | 'video' | 'tombol' | 'pemisah' | 'spasi' | 'kolom' | 'tabel' | 'kode' | 'sorotan' | 'berkas' | 'akordion' | 'peta';
10
+ interface Blok {
11
+ id: string;
12
+ tipe: TipeBlok;
13
+ data: Record<string, any>;
14
+ anak?: Blok[][];
15
+ }
16
+ type Grup = 'Teks' | 'Media' | 'Tata letak' | 'Sematan';
17
+ interface DefBlok {
18
+ label: string;
19
+ ikon: LucideIcon;
20
+ grup: Grup;
21
+ deskripsi: string;
22
+ /** Kata kunci pencarian di penyisip (selain label). */
23
+ kunci?: string;
24
+ data: () => Record<string, unknown>;
25
+ anak?: () => Blok[][];
26
+ /** Punya teks utama yang bisa diketik langsung (Enter memecah, Backspace menggabung). */
27
+ teks?: boolean;
28
+ }
29
+ declare const RASIO: Record<string, number>;
30
+ declare const DEF: Record<TipeBlok, DefBlok>;
31
+ declare const URUTAN_GRUP: Grup[];
32
+ declare const idBaru: () => string;
33
+ declare function baru(tipe: TipeBlok, data?: Record<string, unknown>): Blok;
34
+ /** Salin blok dengan id baru (duplikat, sisip pola). */
35
+ declare function salinBaru(b: Blok): Blok;
36
+ /** Pola dari server tidak menyimpan id; beri id dan lengkapi data bawaan. */
37
+ declare function rapikan(daftar: unknown): Blok[];
38
+ /** Teks polos semua blok (hitung kata, ringkasan otomatis). */
39
+ declare function teksBlok(daftar: Blok[]): string;
40
+ declare const hitungKata: (daftar: Blok[]) => number;
41
+ /** Cari blok di semua tingkat (termasuk anak kolom). */
42
+ declare function cariBlok(daftar: Blok[], id: string): Blok | null;
43
+ /** Ganti satu blok (di tingkat mana pun) lewat fungsi. */
44
+ declare function ubahBlok(daftar: Blok[], id: string, f: (b: Blok) => Blok): Blok[];
45
+ /**
46
+ * HTML ke blok. Mengenali kembali HTML `ub-*` hasil blokKeHtml (perataan, paragraf pembuka, kolom, tabel, sorotan,
47
+ * spasi, tombol, galeri, berkas, akordion), jadi isi surat/templat yang disimpan server bisa disunting ulang tanpa
48
+ * kehilangan tata letak. HTML lain (impor lama) diubah sebaik mungkin.
49
+ */
50
+ declare function htmlKeBlok(html?: string | null): Blok[];
51
+ /** Semua blok (termasuk anak kolom) yang memenuhi syarat. */
52
+ declare function cariSemua(daftar: Blok[], syarat: (b: Blok) => boolean): Blok[];
53
+
54
+ interface MintaFokus {
55
+ id: string;
56
+ /** 'awal', 'akhir', atau posisi karakter di teks polos. */
57
+ di: 'awal' | 'akhir' | number;
58
+ }
59
+ /** Berkas media yang dipilih untuk blok gambar, galeri, atau berkas. */
60
+ interface MediaEditor {
61
+ url: string;
62
+ id?: number | string;
63
+ alt?: string;
64
+ judul?: string;
65
+ nama?: string;
66
+ /** Ukuran dalam byte (blok berkas). */
67
+ ukuran?: number | null;
68
+ mime?: string | null;
69
+ /** Gambar kecil untuk kisi pustaka (bawaan `url`). */
70
+ pratinjau?: string | null;
71
+ }
72
+ interface OpsiPilihMedia {
73
+ jenis?: 'gambar' | 'dokumen';
74
+ banyak?: boolean;
75
+ }
76
+ /** Pola: susunan blok siap pakai (mis. "Berita kegiatan", "Pengumuman beasiswa"). */
77
+ interface PolaBlok {
78
+ id: string | number;
79
+ nama: string;
80
+ kategori: string;
81
+ deskripsi?: string;
82
+ blok: unknown;
83
+ }
84
+ interface KonteksEditor {
85
+ pilih: string | null;
86
+ setPilih: (id: string | null) => void;
87
+ fokus: MintaFokus | null;
88
+ setFokus: (f: MintaFokus | null) => void;
89
+ /** Buka pemilih media; hasil null bila dibatalkan. */
90
+ pilihMedia: (opsi?: OpsiPilihMedia) => Promise<MediaEditor[] | null>;
91
+ pola: PolaBlok[] | undefined;
92
+ baca: boolean;
93
+ /** Tipe blok yang boleh disisipkan (bawaan semua). */
94
+ tipe?: TipeBlok[];
95
+ }
96
+ declare const useEditor: () => KonteksEditor;
97
+
98
+ /** Isi blok dengan riwayat urung/ulang. Ketikan beruntun (< 1 detik) digabung jadi satu langkah. */
99
+ declare function useRiwayatBlok(awal: Blok[]): {
100
+ blok: Blok[];
101
+ set: (kini: Blok[]) => void;
102
+ urung: () => void;
103
+ ulang: () => void;
104
+ reset: (b: Blok[]) => void;
105
+ bisaUrung: boolean;
106
+ bisaUlang: boolean;
107
+ };
108
+ type PilihMedia = (opsi?: OpsiPilihMedia) => Promise<MediaEditor[] | null>;
109
+ /**
110
+ * Sumber "pilih dari sistem" untuk pemilih bawaan: berkas yang sudah ada di server, dicari dengan kata kunci.
111
+ * Contoh siap pakai: `useMediaPortal(situs)` di `unipo-ui/siakad` (pustaka media /v1/portal/kelola/media).
112
+ */
113
+ interface SumberMedia {
114
+ /** Label tab, bawaan "Pustaka". */
115
+ nama?: string;
116
+ cari: (q: string, opsi: OpsiPilihMedia & {
117
+ halaman: number;
118
+ }, signal: AbortSignal) => Promise<{
119
+ data: MediaEditor[];
120
+ adaLagi?: boolean;
121
+ }>;
122
+ }
123
+ /**
124
+ * Pemilih media bawaan dengan tiga cara: pilih dari sistem (`sumber`, dengan pencarian), unggah dari perangkat
125
+ * (`unggah`, mis. ke pustaka media portal), dan tempel alamat. Kembalikan `{ pilihMedia, dialog }`; taruh `dialog`
126
+ * di dalam pohon React.
127
+ */
128
+ declare function usePemilihMediaBawaan(unggah?: (file: File, opsi: OpsiPilihMedia) => Promise<MediaEditor>, sumber?: SumberMedia): {
129
+ pilihMedia: PilihMedia;
130
+ dialog: React.JSX.Element;
131
+ };
132
+ interface EditorBlokProps {
133
+ blok: Blok[];
134
+ set: (b: Blok[]) => void;
135
+ urung?: () => void;
136
+ ulang?: () => void;
137
+ /** Blok terpilih (dikendalikan, agar panel samping bisa memakai yang sama). */
138
+ pilih?: string | null;
139
+ setPilih?: (id: string | null) => void;
140
+ /** Pemilih media sendiri (pustaka media). Tanpa ini dipakai dialog URL/unggah bawaan. */
141
+ pilihMedia?: PilihMedia;
142
+ /** Unggah berkas untuk pemilih bawaan. */
143
+ unggah?: (file: File, opsi: OpsiPilihMedia) => Promise<MediaEditor>;
144
+ /** Berkas yang sudah ada di sistem untuk tab Pustaka di pemilih bawaan (cari + pilih). */
145
+ sumberMedia?: SumberMedia;
146
+ /** Pola blok siap pakai di penyisip (tab Pola). */
147
+ pola?: PolaBlok[];
148
+ /** Isi di atas kanvas, mis. isian judul. */
149
+ kepala?: React.ReactNode;
150
+ /** Mode baca: tanpa bilah, tidak bisa diketik. */
151
+ baca?: boolean;
152
+ /** Batasi tipe blok yang bisa disisipkan, mis. untuk surat. */
153
+ tipe?: TipeBlok[];
154
+ className?: string;
155
+ }
156
+ /**
157
+ * Kanvas editor blok gaya Gutenberg: ketik langsung, `/` untuk memilih blok, pintasan Markdown (##, -, 1., >, ---),
158
+ * seret untuk memindah, bilah format (tebal, miring, tautan, sorot, kode), dan Ctrl+Z / Ctrl+Shift+Z.
159
+ * Format blok sama dengan Blok.php di SIAKAD.
160
+ */
161
+ declare function EditorBlok({ blok, set, urung, ulang, pilih: pilihProp, setPilih: setPilihProp, pilihMedia: pilihMediaProp, unggah, sumberMedia, pola, kepala, baca, tipe, className }: EditorBlokProps): React.JSX.Element;
162
+
163
+ type UkuranKertas = 'a4' | 'f4' | 'letter';
164
+ /** Kop surat: logo, nama instansi, unit, dan alamat. */
165
+ interface KopSurat {
166
+ logo?: string;
167
+ instansi: string;
168
+ /** Unit pengirim, mis. "Fakultas Teknik". */
169
+ unit?: string;
170
+ alamat?: string;
171
+ /** Telepon, surel, situs dalam satu baris. */
172
+ kontak?: string;
173
+ }
174
+ interface TujuanSurat {
175
+ nama: string;
176
+ jabatan?: string | null;
177
+ instansi?: string | null;
178
+ alamat?: string | null;
179
+ tembusan?: boolean;
180
+ }
181
+ interface PenandatanganSurat {
182
+ jabatan: string;
183
+ nama: string;
184
+ /** NIP/NIDN/NIK, ditulis apa adanya, mis. "NIDN 0912078501". */
185
+ nomorInduk?: string;
186
+ /** Gambar tanda tangan atau QR tanda tangan elektronik. */
187
+ ttd?: string;
188
+ /** Tautan cek keaslian (GET /v1/arsip/verifikasi/{kode}); tampil di bawah tanda tangan. */
189
+ verifikasi?: string;
190
+ }
191
+ interface LembarSuratProps {
192
+ kop?: KopSurat | React.ReactNode;
193
+ nomor?: string | null;
194
+ lampiran?: string | null;
195
+ perihal?: string | null;
196
+ sifat?: string | null;
197
+ /** Tanggal surat (YYYY-MM-DD) atau teks jadi. */
198
+ tanggal?: string | Date | null;
199
+ /** Tempat di depan tanggal, mis. "Marisa". */
200
+ tempat?: string;
201
+ tujuan?: TujuanSurat[] | React.ReactNode;
202
+ /** Isi surat (HTML). Disaring seperti server sebelum ditampilkan. */
203
+ isi: string;
204
+ penandatangan?: PenandatanganSurat;
205
+ /** Daftar tembusan; tanpa ini diambil dari `tujuan` yang bertanda tembusan. */
206
+ tembusan?: string[];
207
+ kertas?: UkuranKertas;
208
+ /** Tampilkan bayangan kertas di layar (bawaan true). Saat dicetak selalu polos. */
209
+ bayangan?: boolean;
210
+ className?: string;
211
+ }
212
+ /**
213
+ * Satu lembar surat dinas siap cetak: kop, nomor/lampiran/perihal, tanggal, tujuan, isi, tanda tangan, dan
214
+ * tembusan. Ukuran kertas A4/F4/Letter dengan margin surat dinas; `window.print()` mencetak lembarnya saja bila
215
+ * dibungkus `.u-cetak-saja` (lihat dokumentasi).
216
+ */
217
+ declare function LembarSurat({ kop, nomor, lampiran, perihal, sifat, tanggal, tempat, tujuan, isi, penandatangan, tembusan, kertas, bayangan, className }: LembarSuratProps): React.JSX.Element;
218
+
219
+ export { type Blok as B, DEF as D, EditorBlok as E, type Grup as G, type KopSurat as K, LembarSurat as L, type MediaEditor as M, type OpsiPilihMedia as O, type PolaBlok as P, RASIO as R, type SumberMedia as S, type TipeBlok as T, type UkuranKertas as U, type PilihMedia as a, type PenandatanganSurat as b, type DefBlok as c, type EditorBlokProps as d, type LembarSuratProps as e, type MintaFokus as f, type TujuanSurat as g, URUTAN_GRUP as h, baru as i, cariBlok as j, cariSemua as k, hitungKata as l, htmlKeBlok as m, idBaru as n, useEditor as o, usePemilihMediaBawaan as p, useRiwayatBlok as q, rapikan as r, salinBaru as s, teksBlok as t, ubahBlok as u };
@@ -0,0 +1,219 @@
1
+ import * as React from 'react';
2
+ import { LucideIcon } from 'lucide-react';
3
+
4
+ /**
5
+ * Format blok sama dengan backend (app/Modules/Humas/Support/Blok.php di SIAKAD), jadi isi editor ini bisa
6
+ * langsung dikirim ke /v1/humas/... sebagai `blok`:
7
+ * {"id": "b1", "tipe": "paragraf", "data": {...}, "anak": [[...], [...]]}. `anak` hanya untuk blok kolom.
8
+ */
9
+ type TipeBlok = 'paragraf' | 'judul' | 'daftar' | 'kutipan' | 'gambar' | 'galeri' | 'video' | 'tombol' | 'pemisah' | 'spasi' | 'kolom' | 'tabel' | 'kode' | 'sorotan' | 'berkas' | 'akordion' | 'peta';
10
+ interface Blok {
11
+ id: string;
12
+ tipe: TipeBlok;
13
+ data: Record<string, any>;
14
+ anak?: Blok[][];
15
+ }
16
+ type Grup = 'Teks' | 'Media' | 'Tata letak' | 'Sematan';
17
+ interface DefBlok {
18
+ label: string;
19
+ ikon: LucideIcon;
20
+ grup: Grup;
21
+ deskripsi: string;
22
+ /** Kata kunci pencarian di penyisip (selain label). */
23
+ kunci?: string;
24
+ data: () => Record<string, unknown>;
25
+ anak?: () => Blok[][];
26
+ /** Punya teks utama yang bisa diketik langsung (Enter memecah, Backspace menggabung). */
27
+ teks?: boolean;
28
+ }
29
+ declare const RASIO: Record<string, number>;
30
+ declare const DEF: Record<TipeBlok, DefBlok>;
31
+ declare const URUTAN_GRUP: Grup[];
32
+ declare const idBaru: () => string;
33
+ declare function baru(tipe: TipeBlok, data?: Record<string, unknown>): Blok;
34
+ /** Salin blok dengan id baru (duplikat, sisip pola). */
35
+ declare function salinBaru(b: Blok): Blok;
36
+ /** Pola dari server tidak menyimpan id; beri id dan lengkapi data bawaan. */
37
+ declare function rapikan(daftar: unknown): Blok[];
38
+ /** Teks polos semua blok (hitung kata, ringkasan otomatis). */
39
+ declare function teksBlok(daftar: Blok[]): string;
40
+ declare const hitungKata: (daftar: Blok[]) => number;
41
+ /** Cari blok di semua tingkat (termasuk anak kolom). */
42
+ declare function cariBlok(daftar: Blok[], id: string): Blok | null;
43
+ /** Ganti satu blok (di tingkat mana pun) lewat fungsi. */
44
+ declare function ubahBlok(daftar: Blok[], id: string, f: (b: Blok) => Blok): Blok[];
45
+ /**
46
+ * HTML ke blok. Mengenali kembali HTML `ub-*` hasil blokKeHtml (perataan, paragraf pembuka, kolom, tabel, sorotan,
47
+ * spasi, tombol, galeri, berkas, akordion), jadi isi surat/templat yang disimpan server bisa disunting ulang tanpa
48
+ * kehilangan tata letak. HTML lain (impor lama) diubah sebaik mungkin.
49
+ */
50
+ declare function htmlKeBlok(html?: string | null): Blok[];
51
+ /** Semua blok (termasuk anak kolom) yang memenuhi syarat. */
52
+ declare function cariSemua(daftar: Blok[], syarat: (b: Blok) => boolean): Blok[];
53
+
54
+ interface MintaFokus {
55
+ id: string;
56
+ /** 'awal', 'akhir', atau posisi karakter di teks polos. */
57
+ di: 'awal' | 'akhir' | number;
58
+ }
59
+ /** Berkas media yang dipilih untuk blok gambar, galeri, atau berkas. */
60
+ interface MediaEditor {
61
+ url: string;
62
+ id?: number | string;
63
+ alt?: string;
64
+ judul?: string;
65
+ nama?: string;
66
+ /** Ukuran dalam byte (blok berkas). */
67
+ ukuran?: number | null;
68
+ mime?: string | null;
69
+ /** Gambar kecil untuk kisi pustaka (bawaan `url`). */
70
+ pratinjau?: string | null;
71
+ }
72
+ interface OpsiPilihMedia {
73
+ jenis?: 'gambar' | 'dokumen';
74
+ banyak?: boolean;
75
+ }
76
+ /** Pola: susunan blok siap pakai (mis. "Berita kegiatan", "Pengumuman beasiswa"). */
77
+ interface PolaBlok {
78
+ id: string | number;
79
+ nama: string;
80
+ kategori: string;
81
+ deskripsi?: string;
82
+ blok: unknown;
83
+ }
84
+ interface KonteksEditor {
85
+ pilih: string | null;
86
+ setPilih: (id: string | null) => void;
87
+ fokus: MintaFokus | null;
88
+ setFokus: (f: MintaFokus | null) => void;
89
+ /** Buka pemilih media; hasil null bila dibatalkan. */
90
+ pilihMedia: (opsi?: OpsiPilihMedia) => Promise<MediaEditor[] | null>;
91
+ pola: PolaBlok[] | undefined;
92
+ baca: boolean;
93
+ /** Tipe blok yang boleh disisipkan (bawaan semua). */
94
+ tipe?: TipeBlok[];
95
+ }
96
+ declare const useEditor: () => KonteksEditor;
97
+
98
+ /** Isi blok dengan riwayat urung/ulang. Ketikan beruntun (< 1 detik) digabung jadi satu langkah. */
99
+ declare function useRiwayatBlok(awal: Blok[]): {
100
+ blok: Blok[];
101
+ set: (kini: Blok[]) => void;
102
+ urung: () => void;
103
+ ulang: () => void;
104
+ reset: (b: Blok[]) => void;
105
+ bisaUrung: boolean;
106
+ bisaUlang: boolean;
107
+ };
108
+ type PilihMedia = (opsi?: OpsiPilihMedia) => Promise<MediaEditor[] | null>;
109
+ /**
110
+ * Sumber "pilih dari sistem" untuk pemilih bawaan: berkas yang sudah ada di server, dicari dengan kata kunci.
111
+ * Contoh siap pakai: `useMediaPortal(situs)` di `unipo-ui/siakad` (pustaka media /v1/portal/kelola/media).
112
+ */
113
+ interface SumberMedia {
114
+ /** Label tab, bawaan "Pustaka". */
115
+ nama?: string;
116
+ cari: (q: string, opsi: OpsiPilihMedia & {
117
+ halaman: number;
118
+ }, signal: AbortSignal) => Promise<{
119
+ data: MediaEditor[];
120
+ adaLagi?: boolean;
121
+ }>;
122
+ }
123
+ /**
124
+ * Pemilih media bawaan dengan tiga cara: pilih dari sistem (`sumber`, dengan pencarian), unggah dari perangkat
125
+ * (`unggah`, mis. ke pustaka media portal), dan tempel alamat. Kembalikan `{ pilihMedia, dialog }`; taruh `dialog`
126
+ * di dalam pohon React.
127
+ */
128
+ declare function usePemilihMediaBawaan(unggah?: (file: File, opsi: OpsiPilihMedia) => Promise<MediaEditor>, sumber?: SumberMedia): {
129
+ pilihMedia: PilihMedia;
130
+ dialog: React.JSX.Element;
131
+ };
132
+ interface EditorBlokProps {
133
+ blok: Blok[];
134
+ set: (b: Blok[]) => void;
135
+ urung?: () => void;
136
+ ulang?: () => void;
137
+ /** Blok terpilih (dikendalikan, agar panel samping bisa memakai yang sama). */
138
+ pilih?: string | null;
139
+ setPilih?: (id: string | null) => void;
140
+ /** Pemilih media sendiri (pustaka media). Tanpa ini dipakai dialog URL/unggah bawaan. */
141
+ pilihMedia?: PilihMedia;
142
+ /** Unggah berkas untuk pemilih bawaan. */
143
+ unggah?: (file: File, opsi: OpsiPilihMedia) => Promise<MediaEditor>;
144
+ /** Berkas yang sudah ada di sistem untuk tab Pustaka di pemilih bawaan (cari + pilih). */
145
+ sumberMedia?: SumberMedia;
146
+ /** Pola blok siap pakai di penyisip (tab Pola). */
147
+ pola?: PolaBlok[];
148
+ /** Isi di atas kanvas, mis. isian judul. */
149
+ kepala?: React.ReactNode;
150
+ /** Mode baca: tanpa bilah, tidak bisa diketik. */
151
+ baca?: boolean;
152
+ /** Batasi tipe blok yang bisa disisipkan, mis. untuk surat. */
153
+ tipe?: TipeBlok[];
154
+ className?: string;
155
+ }
156
+ /**
157
+ * Kanvas editor blok gaya Gutenberg: ketik langsung, `/` untuk memilih blok, pintasan Markdown (##, -, 1., >, ---),
158
+ * seret untuk memindah, bilah format (tebal, miring, tautan, sorot, kode), dan Ctrl+Z / Ctrl+Shift+Z.
159
+ * Format blok sama dengan Blok.php di SIAKAD.
160
+ */
161
+ declare function EditorBlok({ blok, set, urung, ulang, pilih: pilihProp, setPilih: setPilihProp, pilihMedia: pilihMediaProp, unggah, sumberMedia, pola, kepala, baca, tipe, className }: EditorBlokProps): React.JSX.Element;
162
+
163
+ type UkuranKertas = 'a4' | 'f4' | 'letter';
164
+ /** Kop surat: logo, nama instansi, unit, dan alamat. */
165
+ interface KopSurat {
166
+ logo?: string;
167
+ instansi: string;
168
+ /** Unit pengirim, mis. "Fakultas Teknik". */
169
+ unit?: string;
170
+ alamat?: string;
171
+ /** Telepon, surel, situs dalam satu baris. */
172
+ kontak?: string;
173
+ }
174
+ interface TujuanSurat {
175
+ nama: string;
176
+ jabatan?: string | null;
177
+ instansi?: string | null;
178
+ alamat?: string | null;
179
+ tembusan?: boolean;
180
+ }
181
+ interface PenandatanganSurat {
182
+ jabatan: string;
183
+ nama: string;
184
+ /** NIP/NIDN/NIK, ditulis apa adanya, mis. "NIDN 0912078501". */
185
+ nomorInduk?: string;
186
+ /** Gambar tanda tangan atau QR tanda tangan elektronik. */
187
+ ttd?: string;
188
+ /** Tautan cek keaslian (GET /v1/arsip/verifikasi/{kode}); tampil di bawah tanda tangan. */
189
+ verifikasi?: string;
190
+ }
191
+ interface LembarSuratProps {
192
+ kop?: KopSurat | React.ReactNode;
193
+ nomor?: string | null;
194
+ lampiran?: string | null;
195
+ perihal?: string | null;
196
+ sifat?: string | null;
197
+ /** Tanggal surat (YYYY-MM-DD) atau teks jadi. */
198
+ tanggal?: string | Date | null;
199
+ /** Tempat di depan tanggal, mis. "Marisa". */
200
+ tempat?: string;
201
+ tujuan?: TujuanSurat[] | React.ReactNode;
202
+ /** Isi surat (HTML). Disaring seperti server sebelum ditampilkan. */
203
+ isi: string;
204
+ penandatangan?: PenandatanganSurat;
205
+ /** Daftar tembusan; tanpa ini diambil dari `tujuan` yang bertanda tembusan. */
206
+ tembusan?: string[];
207
+ kertas?: UkuranKertas;
208
+ /** Tampilkan bayangan kertas di layar (bawaan true). Saat dicetak selalu polos. */
209
+ bayangan?: boolean;
210
+ className?: string;
211
+ }
212
+ /**
213
+ * Satu lembar surat dinas siap cetak: kop, nomor/lampiran/perihal, tanggal, tujuan, isi, tanda tangan, dan
214
+ * tembusan. Ukuran kertas A4/F4/Letter dengan margin surat dinas; `window.print()` mencetak lembarnya saja bila
215
+ * dibungkus `.u-cetak-saja` (lihat dokumentasi).
216
+ */
217
+ declare function LembarSurat({ kop, nomor, lampiran, perihal, sifat, tanggal, tempat, tujuan, isi, penandatangan, tembusan, kertas, bayangan, className }: LembarSuratProps): React.JSX.Element;
218
+
219
+ export { type Blok as B, DEF as D, EditorBlok as E, type Grup as G, type KopSurat as K, LembarSurat as L, type MediaEditor as M, type OpsiPilihMedia as O, type PolaBlok as P, RASIO as R, type SumberMedia as S, type TipeBlok as T, type UkuranKertas as U, type PilihMedia as a, type PenandatanganSurat as b, type DefBlok as c, type EditorBlokProps as d, type LembarSuratProps as e, type MintaFokus as f, type TujuanSurat as g, URUTAN_GRUP as h, baru as i, cariBlok as j, cariSemua as k, hitungKata as l, htmlKeBlok as m, idBaru as n, useEditor as o, usePemilihMediaBawaan as p, useRiwayatBlok as q, rapikan as r, salinBaru as s, teksBlok as t, ubahBlok as u };