sprintify-ui 0.10.80 → 0.10.83

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.
@@ -23,6 +23,10 @@ export default defineComponent({
23
23
  default: '',
24
24
  type: [String, Array, Object],
25
25
  },
26
+ headerClass: {
27
+ default: '',
28
+ type: [String, Array, Object],
29
+ },
26
30
  field: {
27
31
  default: '',
28
32
  type: String,
@@ -109,6 +113,9 @@ export default defineComponent({
109
113
  computed: {
110
114
  style() {
111
115
  return {
116
+ overflow: this.width ? 'hidden' : undefined,
117
+ minWidth: this.width ? this.width + 'px' : undefined,
118
+ maxWidth: this.width ? this.width + 'px' : undefined,
112
119
  width: this.width ? this.width + 'px' : undefined,
113
120
  padding: this.padding ? this.padding : undefined,
114
121
  };
@@ -0,0 +1,259 @@
1
+ <template>
2
+ <div
3
+ class="border rounded-md overflow-hidden bg-white || tiptap"
4
+ :class="[
5
+ hasError ? 'border-red-500' : 'border-slate-300',
6
+ ]"
7
+ >
8
+ <div class="divide-x px-1 py-1 border-b flex">
9
+ <button
10
+ v-for="action in filteredActions"
11
+ :key="action.name"
12
+ :class="[buttonClass, editor.isActive(action.name) ? 'bg-slate-200' : '']"
13
+ type="button"
14
+ :disabled="disabled"
15
+ @click="action.command()"
16
+ >
17
+ <BaseIcon
18
+ class="h-5 w-5"
19
+ :icon="action.icon"
20
+ />
21
+ </button>
22
+ </div>
23
+
24
+ <div
25
+ class="bg-white p-5"
26
+ :class="[disabled ? 'cursor-not-allowed' : '']"
27
+ >
28
+ <editor-content
29
+ v-if="editor"
30
+ :editor="editor"
31
+ />
32
+ </div>
33
+ </div>
34
+ </template>
35
+
36
+ <script setup lang="ts">
37
+ import { Editor, EditorContent } from '@tiptap/vue-3';
38
+ import Document from '@tiptap/extension-document';
39
+ import Link from '@tiptap/extension-link';
40
+ import { Placeholder } from '@tiptap/extensions'
41
+ import { Footnotes, FootnoteReference, Footnote } from "tiptap-footnotes";
42
+ import StarterKit from '@tiptap/starter-kit';
43
+
44
+ const emit = defineEmits(['update:modelValue']);
45
+
46
+ const props = defineProps<{
47
+ modelValue: string | null | undefined;
48
+ size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl';
49
+ hasError?: boolean;
50
+ disabled?: boolean;
51
+ placeholder?: string;
52
+ toolbar?: string[];
53
+ }>();
54
+
55
+ const editor = new Editor({
56
+ editable: !props.disabled,
57
+ extensions: [
58
+ StarterKit.configure({
59
+ document: false,
60
+ link: false,
61
+ }),
62
+ Document.extend({
63
+ content: "block+ footnotes?",
64
+ }),
65
+ Link.configure({
66
+ openOnClick: false,
67
+ defaultProtocol: 'https',
68
+ enableClickSelection: true,
69
+ }),
70
+ Placeholder.configure({
71
+ placeholder: props.placeholder || 'Start typing here...',
72
+ }),
73
+ Footnotes,
74
+ Footnote,
75
+ FootnoteReference,
76
+ ],
77
+ editorProps: {
78
+ attributes: {
79
+ class: 'prose prose-sm mx-auto max-w-full focus:outline-none',
80
+ },
81
+ },
82
+ content: props.modelValue,
83
+ onUpdate: () => {
84
+ emit('update:modelValue', editor?.getHTML() || '');
85
+ },
86
+ });
87
+
88
+ watch(
89
+ () => props.modelValue,
90
+ (newValue) => {
91
+ const isSame = editor?.getHTML() === newValue;
92
+
93
+ if (isSame) {
94
+ return;
95
+ }
96
+
97
+ editor?.commands.setContent(newValue ?? '');
98
+ },
99
+ { immediate: true },
100
+ );
101
+
102
+ watch(
103
+ () => props.disabled,
104
+ (newValue) => {
105
+ editor?.setEditable(!newValue);
106
+ },
107
+ );
108
+
109
+ watch(
110
+ () => props.size,
111
+ (newValue) => {
112
+
113
+ const lookup = {
114
+ 'xs': 'prose-sm',
115
+ 'sm': 'prose-sm',
116
+ 'md': 'prose-sm',
117
+ 'lg': 'prose-md',
118
+ 'xl': 'prose-lg',
119
+ };
120
+
121
+ const sizeClass = lookup[newValue || 'md'] ?? '';
122
+
123
+ editor?.view.setProps({
124
+ attributes: {
125
+ class: `mx-auto max-w-full prose focus:outline-none ${sizeClass}`
126
+ }
127
+ })
128
+ },
129
+ { immediate: true },
130
+ )
131
+
132
+ onBeforeUnmount(() => {
133
+ if (editor) {
134
+ editor.destroy();
135
+ }
136
+ });
137
+
138
+ function setLink() {
139
+ const previousUrl = editor.getAttributes('link').href;
140
+ const url = window.prompt('URL', previousUrl);
141
+
142
+ // cancelled
143
+ if (url === null) {
144
+ return;
145
+ }
146
+
147
+ // empty
148
+ if (url === '') {
149
+ editor.chain().focus().extendMarkRange('link').unsetLink().run();
150
+
151
+ return;
152
+ }
153
+
154
+ // update link
155
+ editor.chain().focus().extendMarkRange('link').setLink({ href: url }).run();
156
+ }
157
+
158
+ const buttonClass = computed(() => {
159
+ const sizeClass = {
160
+ xs: 'p-1',
161
+ sm: 'p-1.5',
162
+ md: 'p-2',
163
+ lg: 'p-2.5',
164
+ xl: 'p-3',
165
+ }
166
+
167
+ return [
168
+ 'hover:bg-slate-100',
169
+ 'disabled:opacity-50 disabled:cursor-not-allowed disabled:hover:bg-white',
170
+ sizeClass[props.size || 'md'] || sizeClass['md'],
171
+ ];
172
+ });
173
+
174
+ interface Action {
175
+ name: string;
176
+ icon: string;
177
+ command: () => void;
178
+ }
179
+
180
+ const actions = computed<Action[]>(() => {
181
+ return [
182
+ {
183
+ name: 'undo',
184
+ icon: 'mdi:undo-variant',
185
+ command: () => editor.chain().focus().undo().run(),
186
+ },
187
+ {
188
+ name: 'redo',
189
+ icon: 'mdi:redo-variant',
190
+ command: () => editor.chain().focus().redo().run(),
191
+ },
192
+ {
193
+ name: 'paragraph',
194
+ icon: 'material-symbols:format-paragraph',
195
+ command: () => editor.chain().focus().setParagraph().run(),
196
+ },
197
+ {
198
+ name: 'heading-2',
199
+ icon: 'material-symbols:format-h2',
200
+ command: () => editor.chain().focus().setHeading({ level: 2 }).run(),
201
+ },
202
+ {
203
+ name: 'heading-3',
204
+ icon: 'material-symbols:format-h3',
205
+ command: () => editor.chain().focus().setHeading({ level: 3 }).run(),
206
+ },
207
+ {
208
+ name: 'bold',
209
+ icon: 'material-symbols:format-bold',
210
+ command: () => editor.chain().focus().toggleBold().run(),
211
+ },
212
+ {
213
+ name: 'italic',
214
+ icon: 'material-symbols:format-italic',
215
+ command: () => editor.chain().focus().toggleItalic().run(),
216
+ },
217
+ {
218
+ name: 'underline',
219
+ icon: 'material-symbols:format-underlined',
220
+ command: () => editor.chain().focus().toggleUnderline().run(),
221
+ },
222
+ {
223
+ name: 'link',
224
+ icon: 'material-symbols:link',
225
+ command: () => setLink(),
226
+ },
227
+ {
228
+ name: 'unlink',
229
+ icon: 'material-symbols:link-off',
230
+ command: () => editor.chain().focus().unsetLink().run(),
231
+ },
232
+ {
233
+ name: 'bulletList',
234
+ icon: 'material-symbols:format-list-bulleted',
235
+ command: () => editor.chain().focus().toggleBulletList().run(),
236
+ },
237
+ {
238
+ name: 'orderedList',
239
+ icon: 'material-symbols:format-list-numbered',
240
+ command: () => editor.chain().focus().toggleOrderedList().run(),
241
+ },
242
+ {
243
+ name: 'footnote',
244
+ icon: 'material-symbols:edit-note-outline',
245
+ command: () => editor?.commands.addFootnote(),
246
+ },
247
+
248
+ ];
249
+ });
250
+
251
+ const filteredActions = computed(() => {
252
+ if (!props.toolbar || props.toolbar.length === 0) {
253
+ return actions.value;
254
+ }
255
+
256
+ return actions.value.filter(action => props.toolbar?.includes(action.name));
257
+ });
258
+
259
+ </script>
@@ -117,12 +117,17 @@ export interface BaseTableColumnData {
117
117
  toggleDefault: boolean;
118
118
  width: number;
119
119
  class?: string | string[];
120
+ headerClass?: string | string[];
120
121
  to?: (row: Row) => RouteLocationRaw;
121
122
  href?: (row: Row) => string;
122
123
  target?: '_blank' | '_self' | '_parent' | '_top';
123
124
  onClick?: (row: Row, index: number, column: BaseTableColumnData, colIndex: number, event: MouseEvent) => void;
124
125
  style: {
125
126
  width: undefined | number;
127
+ maxWidth: undefined | number;
128
+ minWidth: undefined | number;
129
+ overflow: undefined | string;
130
+ padding: undefined | string;
126
131
  };
127
132
  }
128
133