quasar-ui-danx 0.5.2 → 0.5.3

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": "quasar-ui-danx",
3
- "version": "0.5.2",
3
+ "version": "0.5.3",
4
4
  "author": "Dan <dan@flytedesk.com>",
5
5
  "description": "DanX Vue / Quasar component library",
6
6
  "license": "MIT",
@@ -179,7 +179,7 @@
179
179
  <FullScreenCarouselDialog
180
180
  v-if="showPreview && !disabled && previewableFiles"
181
181
  :files="previewableFiles"
182
- :default-slide="previewableFiles[0]?.id || ''"
182
+ :default-slide="computedImage?.id || ''"
183
183
  @close="showPreview = false"
184
184
  />
185
185
  </div>
@@ -264,7 +264,7 @@ const statusMessage = computed(() => isUploading.value ? "Uploading..." : transc
264
264
 
265
265
  const previewableFiles = computed(() => {
266
266
  return props.relatedFiles?.length > 0
267
- ? uniqueBy([computedImage.value, ...props.relatedFiles], filesHaveSameUrl)
267
+ ? uniqueBy([...props.relatedFiles, computedImage.value], filesHaveSameUrl)
268
268
  : [computedImage.value];
269
269
  });
270
270
 
@@ -54,6 +54,13 @@ export function useCodeViewerCollapse(options: UseCodeViewerCollapseOptions): Us
54
54
  const maxLength = 100;
55
55
  let preview = "";
56
56
 
57
+ // For text and markdown formats, just show the first line - no parsing
58
+ if (format.value === "text" || format.value === "markdown") {
59
+ const firstLine = content.split("\n")[0].trim();
60
+ preview = firstLine.length > maxLength ? firstLine.slice(0, maxLength) + "..." : firstLine;
61
+ return preview;
62
+ }
63
+
57
64
  if (format.value === "json") {
58
65
  // For JSON, show compact inline format
59
66
  try {
@@ -10,7 +10,11 @@ export function useFileNavigation(initialFile: Ref<UploadedFile | null>, initial
10
10
  const currentFile = ref<UploadedFile | null>(initialFile.value);
11
11
  const relatedFiles = ref<UploadedFile[]>(initialRelatedFiles.value);
12
12
  const parentStack = ref<FileNavigationParent[]>([]);
13
- const currentIndex = ref(0);
13
+ const currentIndex = ref(
14
+ initialFile.value
15
+ ? Math.max(0, initialRelatedFiles.value.findIndex(f => f.id === initialFile.value!.id))
16
+ : 0
17
+ );
14
18
 
15
19
  // Computed properties
16
20
  const hasParent = computed(() => parentStack.value.length > 0);
@@ -41,6 +41,19 @@ function processInlineContent(element: Element): string {
41
41
  } else if (child.nodeType === Node.ELEMENT_NODE) {
42
42
  const el = child as Element;
43
43
  const tagName = el.tagName.toLowerCase();
44
+
45
+ // Handle color-preview spans - skip the swatch, return only the hex code text
46
+ if (tagName === "span" && el.classList.contains("color-preview")) {
47
+ // Get text content directly, skipping the color-swatch span
48
+ parts.push(el.textContent || "");
49
+ continue;
50
+ }
51
+
52
+ // Skip color-swatch spans entirely (they're purely decorative)
53
+ if (tagName === "span" && el.classList.contains("color-swatch")) {
54
+ continue;
55
+ }
56
+
44
57
  const content = processInlineContent(el);
45
58
 
46
59
  // Skip empty formatting elements
@@ -378,10 +391,22 @@ function processNode(node: Node): string {
378
391
  break;
379
392
  }
380
393
 
381
- // Spans - just process children
382
- case "span":
383
- parts.push(processNode(element));
394
+ // Spans - handle special cases first
395
+ case "span": {
396
+ // Color preview: return only the hex color text
397
+ if (element.classList.contains("color-preview")) {
398
+ parts.push(element.textContent || "");
399
+ }
400
+ // Color swatch: skip entirely (purely decorative)
401
+ else if (element.classList.contains("color-swatch")) {
402
+ // Skip - don't output anything
403
+ }
404
+ // Default: process children
405
+ else {
406
+ parts.push(processNode(element));
407
+ }
384
408
  break;
409
+ }
385
410
 
386
411
  // Tables
387
412
  case "table":
@@ -28,13 +28,26 @@ export function parseInline(text: string, sanitize: boolean = true): string {
28
28
  // 2. HARD LINE BREAKS - Two trailing spaces + newline becomes <br />
29
29
  result = result.replace(/ {2,}\n/g, "<br />\n");
30
30
 
31
- // 3. AUTOLINKS - Must be before regular link parsing
31
+ // 3. HEX COLOR PREVIEW - Display color swatch before hex color codes
32
+ // Match 6-digit hex colors first (more specific), then 3-digit
33
+ // Use word boundary to avoid matching inside URLs or other contexts
34
+ // The pattern must NOT match 4, 5, 7+ digit hex codes
35
+ result = result.replace(
36
+ /(?<![&\w])#([0-9a-fA-F]{6})(?![0-9a-fA-F])/g,
37
+ '<span class="color-preview"><span class="color-swatch" style="background-color: #$1"></span>#$1</span>'
38
+ );
39
+ result = result.replace(
40
+ /(?<![&\w])#([0-9a-fA-F]{3})(?![0-9a-fA-F])/g,
41
+ '<span class="color-preview"><span class="color-swatch" style="background-color: #$1"></span>#$1</span>'
42
+ );
43
+
44
+ // 4. AUTOLINKS - Must be before regular link parsing
32
45
  // URL autolinks: <https://example.com>
33
46
  result = result.replace(/&lt;(https?:\/\/[^&]+)&gt;/g, '<a href="$1">$1</a>');
34
47
  // Email autolinks: <user@example.com>
35
48
  result = result.replace(/&lt;([a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,})&gt;/g, '<a href="mailto:$1">$1</a>');
36
49
 
37
- // 4. FOOTNOTE REFERENCES: [^id]
50
+ // 5. FOOTNOTE REFERENCES: [^id]
38
51
  // Must be before regular link/image parsing to avoid conflicts
39
52
  result = result.replace(/\[\^([^\]]+)\]/g, (match, fnId) => {
40
53
  const fn = currentFootnotes[fnId];
@@ -44,19 +57,19 @@ export function parseInline(text: string, sanitize: boolean = true): string {
44
57
  return match; // Keep original if footnote not defined
45
58
  });
46
59
 
47
- // 5. IMAGES: ![alt](url) - must be before links
60
+ // 6. IMAGES: ![alt](url) - must be before links
48
61
  result = result.replace(
49
62
  /!\[([^\]]*)\]\(([^)]+)\)/g,
50
63
  '<img src="$2" alt="$1" />'
51
64
  );
52
65
 
53
- // 6. INLINE LINKS: [text](url)
66
+ // 7. INLINE LINKS: [text](url)
54
67
  result = result.replace(
55
68
  /\[([^\]]+)\]\(([^)]+)\)/g,
56
69
  '<a href="$2">$1</a>'
57
70
  );
58
71
 
59
- // 7. REFERENCE-STYLE LINKS - Process after regular links
72
+ // 8. REFERENCE-STYLE LINKS - Process after regular links
60
73
  // Full reference: [text][ref-id]
61
74
  result = result.replace(/\[([^\]]+)\]\[([^\]]+)\]/g, (match, text, refId) => {
62
75
  const ref = currentLinkRefs[refId.toLowerCase()];
@@ -88,30 +101,30 @@ export function parseInline(text: string, sanitize: boolean = true): string {
88
101
  return match;
89
102
  });
90
103
 
91
- // 8. INLINE CODE: `code`
104
+ // 9. INLINE CODE: `code`
92
105
  result = result.replace(/`([^`]+)`/g, "<code>$1</code>");
93
106
 
94
- // 9. STRIKETHROUGH: ~~text~~ - Must be before subscript (single tilde)
107
+ // 10. STRIKETHROUGH: ~~text~~ - Must be before subscript (single tilde)
95
108
  result = result.replace(/~~([^~]+)~~/g, "<del>$1</del>");
96
109
 
97
- // 10. HIGHLIGHT: ==text==
110
+ // 11. HIGHLIGHT: ==text==
98
111
  result = result.replace(/==([^=]+)==/g, "<mark>$1</mark>");
99
112
 
100
- // 11. SUPERSCRIPT: X^2^ - Must be before subscript
113
+ // 12. SUPERSCRIPT: X^2^ - Must be before subscript
101
114
  result = result.replace(/\^([^\^]+)\^/g, "<sup>$1</sup>");
102
115
 
103
- // 12. SUBSCRIPT: H~2~O - Single tilde, use negative lookbehind/lookahead to avoid ~~
116
+ // 13. SUBSCRIPT: H~2~O - Single tilde, use negative lookbehind/lookahead to avoid ~~
104
117
  result = result.replace(/(?<!~)~([^~]+)~(?!~)/g, "<sub>$1</sub>");
105
118
 
106
- // 13. BOLD + ITALIC: ***text*** or ___text___
119
+ // 14. BOLD + ITALIC: ***text*** or ___text___
107
120
  result = result.replace(/\*\*\*([^*]+)\*\*\*/g, "<strong><em>$1</em></strong>");
108
121
  result = result.replace(/___([^_]+)___/g, "<strong><em>$1</em></strong>");
109
122
 
110
- // 14. BOLD: **text** or __text__
123
+ // 15. BOLD: **text** or __text__
111
124
  result = result.replace(/\*\*([^*]+)\*\*/g, "<strong>$1</strong>");
112
125
  result = result.replace(/__([^_]+)__/g, "<strong>$1</strong>");
113
126
 
114
- // 15. ITALIC: *text* or _text_ (but not inside words for underscores)
127
+ // 16. ITALIC: *text* or _text_ (but not inside words for underscores)
115
128
  // For asterisks, match any single asterisk pairs
116
129
  result = result.replace(/\*([^*]+)\*/g, "<em>$1</em>");
117
130
  // For underscores, only match at word boundaries
@@ -40,7 +40,9 @@ export function useActionRoutes(baseUrl: string, extend?: object): ListControlsR
40
40
  ...options,
41
41
  ignoreAbort: true
42
42
  };
43
- fields && (options.params = { fields });
43
+ if (fields) {
44
+ options.params = { ...options.params, fields };
45
+ }
44
46
  const item = await request.get(`${baseUrl}/${target.id}/details`, options);
45
47
  return storeObject(item);
46
48
  },
@@ -165,6 +165,23 @@
165
165
  vertical-align: super;
166
166
  }
167
167
 
168
+ // Hex color preview swatch
169
+ .color-preview {
170
+ display: inline-flex;
171
+ align-items: center;
172
+ gap: 0.25em;
173
+
174
+ .color-swatch {
175
+ display: inline-block;
176
+ width: 14px;
177
+ height: 14px;
178
+ border-radius: 3px;
179
+ border: 1px solid rgba(255, 255, 255, 0.3);
180
+ vertical-align: middle;
181
+ flex-shrink: 0;
182
+ }
183
+ }
184
+
168
185
  // Tables
169
186
  table {
170
187
  border-collapse: collapse;
@@ -296,5 +313,10 @@
296
313
  mark {
297
314
  background: rgba(250, 204, 21, 0.5);
298
315
  }
316
+
317
+ // Color swatch - light theme
318
+ .color-preview .color-swatch {
319
+ border-color: rgba(0, 0, 0, 0.2);
320
+ }
299
321
  }
300
322
  }