frappe-ui 0.0.49 → 0.0.52

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "frappe-ui",
3
- "version": "0.0.49",
3
+ "version": "0.0.52",
4
4
  "description": "A set of components and utilities for rapid UI development",
5
5
  "main": "./src/index.js",
6
6
  "scripts": {
@@ -26,6 +26,10 @@
26
26
  "@tiptap/extension-link": "^2.0.0-beta.43",
27
27
  "@tiptap/extension-mention": "^2.0.0-beta.102",
28
28
  "@tiptap/extension-placeholder": "^2.0.0-beta.53",
29
+ "@tiptap/extension-table": "^2.0.0-beta.54",
30
+ "@tiptap/extension-table-cell": "^2.0.0-beta.23",
31
+ "@tiptap/extension-table-header": "^2.0.0-beta.25",
32
+ "@tiptap/extension-table-row": "^2.0.0-beta.22",
29
33
  "@tiptap/extension-text-align": "^2.0.0-beta.31",
30
34
  "@tiptap/starter-kit": "^2.0.0-beta.191",
31
35
  "@tiptap/vue-3": "^2.0.0-beta.96",
@@ -10,7 +10,7 @@
10
10
  @close="open = false"
11
11
  >
12
12
  <div
13
- class="flex items-end justify-center min-h-screen px-4 pt-4 pb-20 text-center sm:block sm:p-0"
13
+ class="flex flex-col items-center justify-center min-h-screen px-4 pt-4 pb-20 text-center"
14
14
  >
15
15
  <TransitionChild
16
16
  as="template"
@@ -26,13 +26,6 @@
26
26
  />
27
27
  </TransitionChild>
28
28
 
29
- <!-- This element is to trick the browser into centering the modal contents. -->
30
- <span
31
- class="hidden sm:inline-block sm:align-middle sm:h-screen"
32
- aria-hidden="true"
33
- >
34
- &#8203;
35
- </span>
36
29
  <TransitionChild
37
30
  as="template"
38
31
  enter="ease-out duration-300"
@@ -43,7 +36,7 @@
43
36
  leave-to="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
44
37
  >
45
38
  <div
46
- class="inline-block overflow-hidden text-left align-bottom transition-all transform bg-white rounded-lg shadow-xl sm:my-8 sm:align-middle sm:max-w-lg sm:w-full"
39
+ class="inline-block w-full max-w-lg my-8 overflow-hidden text-left align-middle transition-all transform bg-white rounded-lg shadow-xl"
47
40
  >
48
41
  <slot name="body">
49
42
  <slot name="body-main">
@@ -71,7 +64,7 @@
71
64
  aria-hidden="true"
72
65
  />
73
66
  </div>
74
- <div class="flex-1 text-center sm:text-left">
67
+ <div class="flex-1">
75
68
  <DialogTitle as="header">
76
69
  <slot name="body-title">
77
70
  <h3
@@ -6,23 +6,36 @@
6
6
  class="border-l w-[2px] h-4"
7
7
  v-if="button.type === 'separator'"
8
8
  ></div>
9
- <div v-else-if="button.map">
9
+ <div class="shrink-0" v-else-if="button.map">
10
10
  <Popover>
11
11
  <template #target="{ togglePopover }">
12
12
  <button
13
13
  class="px-2 py-1 text-base font-medium text-gray-800 transition-colors rounded hover:bg-gray-100"
14
14
  @click="togglePopover"
15
+ :set="
16
+ (activeBtn =
17
+ button.find((b) => b.isActive(editor)) || button[0])
18
+ "
15
19
  >
16
- {{
17
- (button.find((b) => b.isActive(editor)) || button[0]).label
18
- }}
20
+ <component
21
+ v-if="activeBtn.icon"
22
+ :is="activeBtn.icon"
23
+ class="w-4 h-4"
24
+ />
25
+ <span v-else>
26
+ {{ activeBtn.label }}
27
+ </span>
19
28
  </button>
20
29
  </template>
21
30
  <template #body="{ close }">
22
31
  <ul class="p-1 bg-white border rounded shadow-md">
23
- <li class="w-full" v-for="option in button">
32
+ <li
33
+ class="w-full"
34
+ v-for="option in button"
35
+ v-show="option.isDisabled ? !option.isDisabled(editor) : true"
36
+ >
24
37
  <button
25
- class="w-full px-2 py-1 text-base rounded hover:bg-gray-50"
38
+ class="w-full px-2 py-1 text-base text-left rounded hover:bg-gray-50"
26
39
  @click="
27
40
  () => {
28
41
  onClick(option)
@@ -15,7 +15,7 @@
15
15
 
16
16
  <Menu
17
17
  v-if="fixedMenuButtons"
18
- class="w-full border border-gray-200 rounded-t-lg"
18
+ class="w-full overflow-x-auto border border-gray-200 rounded-t-lg"
19
19
  :editor="editor"
20
20
  :buttons="fixedMenuButtons"
21
21
  />
@@ -49,6 +49,10 @@ import { Editor, EditorContent, BubbleMenu, FloatingMenu } from '@tiptap/vue-3'
49
49
  import StarterKit from '@tiptap/starter-kit'
50
50
  import Placeholder from '@tiptap/extension-placeholder'
51
51
  import TextAlign from '@tiptap/extension-text-align'
52
+ import Table from '@tiptap/extension-table'
53
+ import TableCell from '@tiptap/extension-table-cell'
54
+ import TableHeader from '@tiptap/extension-table-header'
55
+ import TableRow from '@tiptap/extension-table-row'
52
56
  import Image from './image-extension'
53
57
  import Link from '@tiptap/extension-link'
54
58
  import configureMention from './mention'
@@ -142,6 +146,12 @@ export default {
142
146
  StarterKit.configure({
143
147
  ...this.starterkitOptions,
144
148
  }),
149
+ Table.configure({
150
+ resizable: true,
151
+ }),
152
+ TableRow,
153
+ TableHeader,
154
+ TableCell,
145
155
  TextAlign.configure({
146
156
  types: ['heading', 'paragraph'],
147
157
  }),
@@ -197,6 +207,21 @@ export default {
197
207
  'Blockquote',
198
208
  'Code',
199
209
  'Horizontal Rule',
210
+ [
211
+ 'InsertTable',
212
+ 'AddColumnBefore',
213
+ 'AddColumnAfter',
214
+ 'DeleteColumn',
215
+ 'AddRowBefore',
216
+ 'AddRowAfter',
217
+ 'DeleteRow',
218
+ 'MergeCells',
219
+ 'SplitCell',
220
+ 'ToggleHeaderColumn',
221
+ 'ToggleHeaderRow',
222
+ 'ToggleHeaderCell',
223
+ 'DeleteTable',
224
+ ],
200
225
  'Separator',
201
226
  'Undo',
202
227
  'Redo',
@@ -251,7 +276,10 @@ export default {
251
276
  editorProps() {
252
277
  return {
253
278
  attributes: {
254
- class: normalizeClass(['prose prose-p:my-1', this.editorClass]),
279
+ class: normalizeClass([
280
+ 'prose prose-p:my-1 prose-table:table-fixed prose-td:p-2 prose-th:p-2 prose-td:border prose-th:border prose-td:border-gray-300 prose-th:border-gray-300 prose-td:relative prose-th:relative prose-th:bg-gray-100',
281
+ this.editorClass,
282
+ ]),
255
283
  },
256
284
  }
257
285
  },
@@ -269,6 +297,7 @@ function createEditorButton(option) {
269
297
  }
270
298
  </script>
271
299
  <style>
300
+ /* Placeholder */
272
301
  .ProseMirror:not(.ProseMirror-focused) p.is-editor-empty:first-child::before {
273
302
  content: attr(data-placeholder);
274
303
  float: left;
@@ -276,8 +305,44 @@ function createEditorButton(option) {
276
305
  pointer-events: none;
277
306
  height: 0;
278
307
  }
308
+
309
+ /* Mentions */
279
310
  .mention {
280
311
  font-weight: 600;
281
312
  box-decoration-break: clone;
282
313
  }
314
+
315
+ /* Table styles */
316
+ .prose table p {
317
+ margin: 0;
318
+ }
319
+
320
+ /* Prosemirror specific table styles */
321
+ .ProseMirror table .selectedCell:after {
322
+ z-index: 2;
323
+ position: absolute;
324
+ content: '';
325
+ left: 0;
326
+ right: 0;
327
+ top: 0;
328
+ bottom: 0;
329
+ pointer-events: none;
330
+ background: theme('colors.blue.200');
331
+ opacity: 0.3;
332
+ }
333
+
334
+ .ProseMirror table .column-resize-handle {
335
+ position: absolute;
336
+ right: -1px;
337
+ top: 0;
338
+ bottom: -2px;
339
+ width: 4px;
340
+ background-color: theme('colors.blue.200');
341
+ pointer-events: none;
342
+ }
343
+
344
+ .resize-cursor {
345
+ cursor: ew-resize;
346
+ cursor: col-resize;
347
+ }
283
348
  </style>
@@ -20,6 +20,7 @@ import Image from './icons/image-add-line.vue'
20
20
  import ArrowGoBack from './icons/arrow-go-back-line.vue'
21
21
  import ArrowGoForward from './icons/arrow-go-forward-line.vue'
22
22
  import Separator from './icons/separator.vue'
23
+ import Table from './icons/table-2.vue'
23
24
 
24
25
  export default {
25
26
  Paragraph: {
@@ -164,6 +165,89 @@ export default {
164
165
  action: (editor) => editor.chain().focus().redo().run(),
165
166
  isActive: (editor) => false,
166
167
  },
168
+ InsertTable: {
169
+ label: 'Insert Table',
170
+ icon: Table,
171
+ action: (editor) =>
172
+ editor
173
+ .chain()
174
+ .focus()
175
+ .insertTable({ rows: 3, cols: 3, withHeaderRow: true })
176
+ .run(),
177
+ isActive: (editor) => false,
178
+ },
179
+ AddColumnBefore: {
180
+ label: 'Add Column Before',
181
+ action: (editor) => editor.chain().focus().addColumnBefore().run(),
182
+ isActive: (editor) => false,
183
+ isDisabled: (editor) => !editor.can().addColumnBefore(),
184
+ },
185
+ AddColumnAfter: {
186
+ label: 'Add Column After',
187
+ action: (editor) => editor.chain().focus().addColumnAfter().run(),
188
+ isActive: (editor) => false,
189
+ isDisabled: (editor) => !editor.can().addColumnAfter(),
190
+ },
191
+ DeleteColumn: {
192
+ label: 'Delete Column',
193
+ action: (editor) => editor.chain().focus().deleteColumn().run(),
194
+ isActive: (editor) => false,
195
+ isDisabled: (editor) => !editor.can().deleteColumn(),
196
+ },
197
+ AddRowBefore: {
198
+ label: 'Add Row Before',
199
+ action: (editor) => editor.chain().focus().addRowBefore().run(),
200
+ isActive: (editor) => false,
201
+ isDisabled: (editor) => !editor.can().addRowBefore(),
202
+ },
203
+ AddRowAfter: {
204
+ label: 'Add Row After',
205
+ action: (editor) => editor.chain().focus().addRowAfter().run(),
206
+ isActive: (editor) => false,
207
+ isDisabled: (editor) => !editor.can().addRowAfter(),
208
+ },
209
+ DeleteRow: {
210
+ label: 'Delete Row',
211
+ action: (editor) => editor.chain().focus().deleteRow().run(),
212
+ isActive: (editor) => false,
213
+ isDisabled: (editor) => !editor.can().deleteRow(),
214
+ },
215
+ DeleteTable: {
216
+ label: 'Delete Table',
217
+ action: (editor) => editor.chain().focus().deleteTable().run(),
218
+ isActive: (editor) => false,
219
+ isDisabled: (editor) => !editor.can().deleteTable(),
220
+ },
221
+ MergeCells: {
222
+ label: 'Merge Cells',
223
+ action: (editor) => editor.chain().focus().mergeCells().run(),
224
+ isActive: (editor) => false,
225
+ isDisabled: (editor) => !editor.can().mergeCells(),
226
+ },
227
+ SplitCell: {
228
+ label: 'Split Cell',
229
+ action: (editor) => editor.chain().focus().splitCell().run(),
230
+ isActive: (editor) => false,
231
+ isDisabled: (editor) => !editor.can().splitCell(),
232
+ },
233
+ ToggleHeaderColumn: {
234
+ label: 'Toggle Header Column',
235
+ action: (editor) => editor.chain().focus().toggleHeaderColumn().run(),
236
+ isActive: (editor) => false,
237
+ isDisabled: (editor) => !editor.can().toggleHeaderColumn(),
238
+ },
239
+ ToggleHeaderRow: {
240
+ label: 'Toggle Header Row',
241
+ action: (editor) => editor.chain().focus().toggleHeaderRow().run(),
242
+ isActive: (editor) => false,
243
+ isDisabled: (editor) => !editor.can().toggleHeaderRow(),
244
+ },
245
+ ToggleHeaderCell: {
246
+ label: 'Toggle Header Cell',
247
+ action: (editor) => editor.chain().focus().toggleHeaderCell().run(),
248
+ isActive: (editor) => false,
249
+ isDisabled: (editor) => !editor.can().toggleHeaderCell(),
250
+ },
167
251
  Separator: {
168
252
  type: 'separator',
169
253
  },