@expcat/tigercat-vue 2.1.4 → 2.2.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 (46) hide show
  1. package/dist/{chunk-4KFAGTGA.mjs → chunk-3GNK4XIP.mjs} +1 -1
  2. package/dist/{chunk-MWYNO42Z.mjs → chunk-5IVN54XY.mjs} +1 -1
  3. package/dist/{chunk-BFIYTA3E.mjs → chunk-72XR5ZIW.mjs} +6 -2
  4. package/dist/{chunk-XCIQNTJN.mjs → chunk-77L52YWC.mjs} +37 -5
  5. package/dist/chunk-7L5MXXHC.mjs +85 -0
  6. package/dist/{chunk-FZQAYEIU.mjs → chunk-AIONRIMJ.mjs} +1 -1
  7. package/dist/{chunk-ETJ4QD6U.mjs → chunk-AYCK22RG.mjs} +1 -1
  8. package/dist/{chunk-35JLHFUT.mjs → chunk-ETW3MBHS.mjs} +22 -1
  9. package/dist/{chunk-ZHAIO7DA.mjs → chunk-GAIFRCYZ.mjs} +6 -3
  10. package/dist/chunk-GFSZU7EJ.mjs +98 -0
  11. package/dist/{chunk-TQEN6GDE.mjs → chunk-IKM3NBMK.mjs} +5 -6
  12. package/dist/chunk-JUSJUVFQ.mjs +76 -0
  13. package/dist/chunk-OEHI4BZZ.mjs +168 -0
  14. package/dist/{chunk-ZW2VXGO3.mjs → chunk-RBST5GCI.mjs} +6 -3
  15. package/dist/{chunk-HSKBYNCP.mjs → chunk-ZMSGID63.mjs} +7 -5
  16. package/dist/components/ActivityFeed.mjs +2 -2
  17. package/dist/components/Anchor.mjs +1 -1
  18. package/dist/components/BackTop.mjs +1 -1
  19. package/dist/components/Calendar.d.mts +12 -3
  20. package/dist/components/Calendar.mjs +1 -1
  21. package/dist/components/Code.d.mts +19 -1
  22. package/dist/components/Code.mjs +1 -1
  23. package/dist/components/CodeEditor.d.mts +2 -2
  24. package/dist/components/CommentThread.mjs +2 -2
  25. package/dist/components/DataTableWithToolbar.mjs +1 -1
  26. package/dist/components/DatePicker.mjs +2 -2
  27. package/dist/components/Drag.d.mts +62 -0
  28. package/dist/components/Drag.mjs +9 -0
  29. package/dist/components/Footer.d.mts +10 -0
  30. package/dist/components/Footer.mjs +1 -1
  31. package/dist/components/FullscreenButton.d.mts +58 -0
  32. package/dist/components/FullscreenButton.mjs +10 -0
  33. package/dist/components/Icon.d.mts +3 -3
  34. package/dist/components/Loading.d.mts +1 -1
  35. package/dist/components/Menu.d.mts +4 -4
  36. package/dist/components/Menu.mjs +1 -1
  37. package/dist/components/NotificationCenter.mjs +2 -2
  38. package/dist/components/ScrollSpy.mjs +1 -1
  39. package/dist/components/Text.d.mts +23 -73
  40. package/dist/components/Text.mjs +2 -1
  41. package/dist/composables/useFullscreen.d.mts +14 -0
  42. package/dist/composables/useFullscreen.mjs +6 -0
  43. package/dist/index.d.mts +5 -2
  44. package/dist/index.mjs +37 -0
  45. package/package.json +17 -2
  46. package/dist/chunk-I77GUQV4.mjs +0 -93
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  Calendar
3
- } from "./chunk-XCIQNTJN.mjs";
3
+ } from "./chunk-77L52YWC.mjs";
4
4
  import {
5
5
  INPUT_GROUP_INJECTION_KEY
6
6
  } from "./chunk-J4HGCSOE.mjs";
@@ -12,7 +12,7 @@ import {
12
12
  } from "./chunk-7PLYHGMY.mjs";
13
13
  import {
14
14
  Text
15
- } from "./chunk-I77GUQV4.mjs";
15
+ } from "./chunk-OEHI4BZZ.mjs";
16
16
  import {
17
17
  Card
18
18
  } from "./chunk-W4A6L2TC.mjs";
@@ -3,8 +3,8 @@ import { defineComponent, h, computed } from "vue";
3
3
  import {
4
4
  classNames,
5
5
  coerceClassValue,
6
+ getLayoutFooterClasses,
6
7
  injectLayoutGridStyles,
7
- layoutFooterClasses,
8
8
  mergeStyleValues
9
9
  } from "@expcat/tigercat-core";
10
10
  var Footer = defineComponent({
@@ -23,6 +23,10 @@ var Footer = defineComponent({
23
23
  type: String,
24
24
  default: void 0
25
25
  },
26
+ size: {
27
+ type: String,
28
+ default: "default"
29
+ },
26
30
  style: {
27
31
  type: Object,
28
32
  default: void 0
@@ -32,7 +36,7 @@ var Footer = defineComponent({
32
36
  injectLayoutGridStyles();
33
37
  const footerClasses = computed(
34
38
  () => classNames(
35
- layoutFooterClasses,
39
+ getLayoutFooterClasses(props.size),
36
40
  props.className,
37
41
  coerceClassValue(attrs.class)
38
42
  )
@@ -15,6 +15,10 @@ import {
15
15
  } from "vue";
16
16
  import { classNames, coerceClassValue } from "@expcat/tigercat-core";
17
17
  import {
18
+ appendCalendarEventCountLabel,
19
+ buildCalendarDateCellExtra,
20
+ calendarDateCellDotClasses,
21
+ calendarDateCellExtraClasses,
18
22
  calendarGridClasses,
19
23
  calendarHeaderClasses,
20
24
  calendarNavButtonClasses,
@@ -25,6 +29,7 @@ import {
25
29
  followCalendarValue,
26
30
  formatCalendarDayLabel,
27
31
  formatCalendarDayNumber,
32
+ getCalendarEventDotStyle,
28
33
  formatMonthYear,
29
34
  getCalendarContainerClasses,
30
35
  getCalendarDayClasses,
@@ -78,10 +83,11 @@ var Calendar = defineComponent({
78
83
  default: void 0
79
84
  },
80
85
  locale: { type: Object, default: void 0 },
81
- className: { type: String, default: void 0 }
86
+ className: { type: String, default: void 0 },
87
+ events: { type: Array, default: void 0 }
82
88
  },
83
89
  emits: ["update:modelValue", "update:mode", "change", "panel-change"],
84
- setup(props, { emit, attrs, expose }) {
90
+ setup(props, { emit, attrs, expose, slots }) {
85
91
  const config = useTigerConfig();
86
92
  const mergedLocale = computed(() => mergeTigerLocale(config.value.locale, props.locale));
87
93
  const localeCode = computed(() => mergedLocale.value?.locale);
@@ -351,6 +357,27 @@ var Calendar = defineComponent({
351
357
  );
352
358
  const isTodayDate = today.value ? isSameDay(date, today.value) : false;
353
359
  const isDisabled = isCalendarDateDisabled(date, props.disabledDate);
360
+ const extra = buildCalendarDateCellExtra({
361
+ date,
362
+ events: props.events,
363
+ inCurrentMonth: isCurrentMonth,
364
+ today: isTodayDate,
365
+ selected: isSelected,
366
+ disabled: isDisabled
367
+ });
368
+ const customCell = slots.dateCell?.({ date, events: extra.events, extra });
369
+ const hasExtra = Boolean(customCell) || extra.events.length > 0;
370
+ const defaultDots = !customCell && extra.events.length > 0 ? h(
371
+ "span",
372
+ { class: calendarDateCellExtraClasses, "aria-hidden": "true" },
373
+ extra.events.map(
374
+ (event, index) => h("span", {
375
+ key: event.key ?? `${extra.iso}-${index}`,
376
+ class: calendarDateCellDotClasses,
377
+ style: getCalendarEventDotStyle(event.color)
378
+ })
379
+ )
380
+ ) : null;
354
381
  return h(
355
382
  "button",
356
383
  {
@@ -358,7 +385,11 @@ var Calendar = defineComponent({
358
385
  type: "button",
359
386
  role: "gridcell",
360
387
  "data-date": iso,
361
- "aria-label": formatCalendarDayLabel(date, localeCode.value),
388
+ "aria-label": appendCalendarEventCountLabel(
389
+ formatCalendarDayLabel(date, localeCode.value),
390
+ extra.events.length,
391
+ labels.value.eventCountText
392
+ ),
362
393
  "aria-selected": isSelected || isRangeStart || isRangeEnd,
363
394
  "aria-current": isTodayDate ? "date" : void 0,
364
395
  disabled: isDisabled,
@@ -371,12 +402,13 @@ var Calendar = defineComponent({
371
402
  isActive: activeIso.value === iso,
372
403
  isInRange,
373
404
  isRangeStart,
374
- isRangeEnd
405
+ isRangeEnd,
406
+ hasExtra
375
407
  }),
376
408
  onClick: () => selectDay(date),
377
409
  onFocus: () => activeIso.value = iso
378
410
  },
379
- formatCalendarDayNumber(date, localeCode.value)
411
+ [formatCalendarDayNumber(date, localeCode.value), customCell ?? defaultDots]
380
412
  );
381
413
  })
382
414
  )
@@ -0,0 +1,85 @@
1
+ import {
2
+ useDrag
3
+ } from "./chunk-DXL3YHRP.mjs";
4
+
5
+ // src/components/Drag.ts
6
+ import { computed, defineComponent, h } from "vue";
7
+ import {
8
+ classNames,
9
+ coerceClassValue,
10
+ reorderSequence
11
+ } from "@expcat/tigercat-core";
12
+ var Drag = defineComponent({
13
+ name: "TigerDrag",
14
+ inheritAttrs: false,
15
+ props: {
16
+ items: {
17
+ type: Array,
18
+ default: () => []
19
+ },
20
+ config: {
21
+ type: Object,
22
+ default: void 0
23
+ },
24
+ containerId: {
25
+ type: String,
26
+ default: void 0
27
+ },
28
+ className: {
29
+ type: String,
30
+ default: void 0
31
+ }
32
+ },
33
+ emits: ["update:items", "items-change", "drag-start", "drag-over", "drop", "drag-end"],
34
+ setup(props, { emit, slots, attrs }) {
35
+ const drag = useDrag(() => ({
36
+ config: props.config,
37
+ containerId: props.containerId,
38
+ onDragStart: (event) => emit("drag-start", event),
39
+ onDragOver: (event) => emit("drag-over", event),
40
+ onDragEnd: (event) => emit("drag-end", event),
41
+ onDrop: (event) => {
42
+ emit("drop", event);
43
+ if (event.fromIndex === event.toIndex) return;
44
+ const next = reorderSequence(props.items, event.fromIndex, event.toIndex).map(
45
+ (item, index) => ({ ...item, index })
46
+ );
47
+ emit("update:items", next);
48
+ emit("items-change", next);
49
+ }
50
+ }));
51
+ const rootClass = computed(
52
+ () => classNames(
53
+ "m-0 list-none p-0",
54
+ props.className,
55
+ coerceClassValue(attrs.class)
56
+ )
57
+ );
58
+ return () => {
59
+ const zone = drag.getDropZoneAttrs();
60
+ return h(
61
+ "ul",
62
+ {
63
+ ...attrs,
64
+ ...zone,
65
+ class: rootClass.value,
66
+ "data-tiger-drag": "",
67
+ role: "list"
68
+ },
69
+ props.items.map((item) => {
70
+ const itemAttrs = drag.getDragItemAttrs(item);
71
+ const isDragging = drag.draggedItem.value?.id === item.id;
72
+ const custom = slots.item?.({ item, attrs: itemAttrs, isDragging });
73
+ if (custom) return custom;
74
+ return h("li", { ...itemAttrs, key: item.id, role: "listitem" }, String(item.id));
75
+ })
76
+ );
77
+ };
78
+ }
79
+ });
80
+ var Drag_default = Drag;
81
+
82
+ export {
83
+ Drag,
84
+ Drag_default
85
+ };
@@ -10,7 +10,7 @@ import {
10
10
  } from "./chunk-NWPALCKN.mjs";
11
11
  import {
12
12
  Text
13
- } from "./chunk-I77GUQV4.mjs";
13
+ } from "./chunk-OEHI4BZZ.mjs";
14
14
  import {
15
15
  Card
16
16
  } from "./chunk-W4A6L2TC.mjs";
@@ -6,7 +6,7 @@ import {
6
6
  } from "./chunk-7PLYHGMY.mjs";
7
7
  import {
8
8
  Text
9
- } from "./chunk-I77GUQV4.mjs";
9
+ } from "./chunk-OEHI4BZZ.mjs";
10
10
  import {
11
11
  Avatar
12
12
  } from "./chunk-OGXSLKXD.mjs";
@@ -15,6 +15,7 @@ import {
15
15
  getCodeLabels,
16
16
  mergeStyleValues,
17
17
  mergeTigerLocale,
18
+ renderCodeHighlightHtml,
18
19
  resolveLocaleText
19
20
  } from "@expcat/tigercat-core";
20
21
  var Code = defineComponent({
@@ -29,6 +30,14 @@ var Code = defineComponent({
29
30
  type: Boolean,
30
31
  default: true
31
32
  },
33
+ language: {
34
+ type: String,
35
+ default: void 0
36
+ },
37
+ highlighter: {
38
+ type: Object,
39
+ default: void 0
40
+ },
32
41
  copyLabel: {
33
42
  type: String,
34
43
  default: void 0
@@ -110,7 +119,19 @@ var Code = defineComponent({
110
119
  style: mergeStyleValues(attrs.style, props.style)
111
120
  },
112
121
  [
113
- h("pre", { class: codeBlockPreClasses }, [h("code", { class: "block" }, props.code)]),
122
+ h("pre", { class: codeBlockPreClasses }, [
123
+ (() => {
124
+ const highlighted = renderCodeHighlightHtml(
125
+ props.code,
126
+ props.language,
127
+ props.highlighter
128
+ );
129
+ return highlighted == null ? h("code", { class: "block" }, props.code) : h("code", {
130
+ class: "block",
131
+ innerHTML: highlighted
132
+ });
133
+ })()
134
+ ]),
114
135
  props.copyable ? h(
115
136
  "button",
116
137
  {
@@ -60,6 +60,8 @@ import {
60
60
  mergeStyleValues,
61
61
  mergeTigerLocale,
62
62
  moveFocusInMenu,
63
+ resolveMenuSearchQuery,
64
+ shouldShowMenuSearch,
63
65
  nextOpenKeys,
64
66
  nextSelectedKeys,
65
67
  reconcileSearchOpenKeys,
@@ -161,7 +163,7 @@ var Menu = defineComponent({
161
163
  popupPortal: { type: Boolean, default: true },
162
164
  className: { type: String, default: void 0 },
163
165
  style: { type: Object, default: void 0 },
164
- searchable: { type: Boolean, default: false },
166
+ searchable: { type: [Boolean, String], default: false },
165
167
  searchValue: { type: String, default: void 0 },
166
168
  defaultSearchValue: { type: String, default: "" },
167
169
  searchPlaceholder: { type: String, default: void 0 },
@@ -225,10 +227,11 @@ var Menu = defineComponent({
225
227
  emit("update:searchValue", value);
226
228
  emit("search", value);
227
229
  };
230
+ const showSearch = computed(() => shouldShowMenuSearch(props.searchable, collapsed.value));
228
231
  const searchResult = computed(
229
232
  () => resolveSearchFilter({
230
233
  items: props.items,
231
- query: currentSearchValue.value,
234
+ query: resolveMenuSearchQuery(props.searchable, collapsed.value, currentSearchValue.value),
232
235
  filterMode: props.filterMode
233
236
  })
234
237
  );
@@ -348,7 +351,7 @@ var Menu = defineComponent({
348
351
  ...passthroughAttrs.value
349
352
  },
350
353
  [
351
- props.searchable ? h("div", { class: menuSearchFieldClasses }, [
354
+ showSearch.value ? h("div", { class: menuSearchFieldClasses }, [
352
355
  h("input", {
353
356
  type: "search",
354
357
  value: currentSearchValue.value,
@@ -0,0 +1,98 @@
1
+ import {
2
+ useFullscreen
3
+ } from "./chunk-JUSJUVFQ.mjs";
4
+ import {
5
+ useTigerConfig
6
+ } from "./chunk-4GOTWNOO.mjs";
7
+
8
+ // src/components/FullscreenButton.ts
9
+ import { computed, defineComponent, h } from "vue";
10
+ import {
11
+ classNames,
12
+ coerceClassValue,
13
+ fullscreenButtonClasses,
14
+ getFullscreenLabels,
15
+ getIconDefinition,
16
+ mergeTigerLocale
17
+ } from "@expcat/tigercat-core";
18
+ function renderGlyph(name) {
19
+ const definition = getIconDefinition(name);
20
+ if (!definition) return void 0;
21
+ return h(
22
+ "svg",
23
+ {
24
+ xmlns: "http://www.w3.org/2000/svg",
25
+ viewBox: definition.viewBox,
26
+ fill: "none",
27
+ stroke: "currentColor",
28
+ "stroke-width": "1.5",
29
+ "stroke-linecap": "round",
30
+ "stroke-linejoin": "round",
31
+ class: "h-5 w-5",
32
+ "aria-hidden": "true"
33
+ },
34
+ definition.paths.map((d) => h("path", { d }))
35
+ );
36
+ }
37
+ var FullscreenButton = defineComponent({
38
+ name: "TigerFullscreenButton",
39
+ inheritAttrs: false,
40
+ props: {
41
+ target: {
42
+ type: [Object, Function],
43
+ default: void 0
44
+ },
45
+ locale: {
46
+ type: Object,
47
+ default: void 0
48
+ },
49
+ labels: {
50
+ type: Object,
51
+ default: void 0
52
+ },
53
+ className: {
54
+ type: String,
55
+ default: void 0
56
+ }
57
+ },
58
+ emits: ["change", "error"],
59
+ setup(props, { emit, attrs }) {
60
+ const config = useTigerConfig();
61
+ const labelSet = computed(
62
+ () => getFullscreenLabels(mergeTigerLocale(config.value.locale, props.locale), props.labels)
63
+ );
64
+ const fullscreen = useFullscreen(() => ({
65
+ target: props.target,
66
+ onChange: (next) => emit("change", next),
67
+ onError: (error) => emit("error", error)
68
+ }));
69
+ return () => {
70
+ const label = fullscreen.isFullscreen.value ? labelSet.value.exitAriaLabel : labelSet.value.enterAriaLabel;
71
+ return h(
72
+ "button",
73
+ {
74
+ ...attrs,
75
+ type: "button",
76
+ class: classNames(
77
+ fullscreenButtonClasses,
78
+ props.className,
79
+ coerceClassValue(attrs.class)
80
+ ),
81
+ "aria-label": label,
82
+ "aria-pressed": fullscreen.isFullscreen.value,
83
+ disabled: !fullscreen.supported,
84
+ onClick: () => {
85
+ void fullscreen.toggle();
86
+ }
87
+ },
88
+ renderGlyph(fullscreen.isFullscreen.value ? "fullscreen-exit" : "fullscreen")
89
+ );
90
+ };
91
+ }
92
+ });
93
+ var FullscreenButton_default = FullscreenButton;
94
+
95
+ export {
96
+ FullscreenButton,
97
+ FullscreenButton_default
98
+ };
@@ -187,9 +187,8 @@ var Anchor = defineComponent({
187
187
  const config = useTigerConfig();
188
188
  const mergedLocale = computed(() => mergeTigerLocale(config.value.locale, props.locale));
189
189
  const labelSet = computed(() => getAnchorLabels(mergedLocale.value, props.labels));
190
- const scrollLock = createProgrammaticScrollLock(
191
- () => resolveAnchorScrollContainer(props.getContainer)
192
- );
190
+ const resolveContainer = () => resolveAnchorScrollContainer(props.getContainer, anchorRef.value);
191
+ const scrollLock = createProgrammaticScrollLock(() => resolveContainer());
193
192
  const scrollOffset = computed(() => props.targetOffset ?? props.offsetTop);
194
193
  const links = computed(() => sortAnchorHrefsByDocumentOrder(linkEntries.value));
195
194
  const registerLink = (href, node) => {
@@ -217,7 +216,7 @@ var Anchor = defineComponent({
217
216
  let stopObserver = null;
218
217
  const setupObserver = () => {
219
218
  stopObserver?.();
220
- const container = resolveAnchorScrollContainer(props.getContainer);
219
+ const container = resolveContainer();
221
220
  const root = container === window ? null : container;
222
221
  stopObserver = createAnchorObserver(links.value, {
223
222
  offsetTop: scrollOffset.value,
@@ -230,7 +229,7 @@ var Anchor = defineComponent({
230
229
  });
231
230
  };
232
231
  const scrollTo = (href) => {
233
- scrollToAnchor(href, resolveAnchorScrollContainer(props.getContainer), scrollOffset.value);
232
+ scrollToAnchor(href, resolveContainer(), scrollOffset.value);
234
233
  };
235
234
  const handleLinkClick = (href, event, targetAttr) => {
236
235
  const hasTargetElement = Boolean(getAnchorTargetElement(href));
@@ -263,7 +262,7 @@ var Anchor = defineComponent({
263
262
  inkRef.value.style.width = next.width;
264
263
  };
265
264
  const resolvedKey = computed(() => {
266
- const resolved = resolveScrollRoot(props.getContainer);
265
+ const resolved = resolveScrollRoot(props.getContainer, { from: anchorRef.value });
267
266
  return resolved.isWindow ? "window" : resolved.target;
268
267
  });
269
268
  watch(activeLink, () => {
@@ -0,0 +1,76 @@
1
+ // src/composables/useFullscreen.ts
2
+ import {
3
+ getCurrentInstance,
4
+ onBeforeUnmount,
5
+ onMounted,
6
+ ref,
7
+ toValue
8
+ } from "vue";
9
+ import {
10
+ exitElementFullscreen,
11
+ getFullscreenElement,
12
+ isElementFullscreen,
13
+ isFullscreenSupported,
14
+ requestElementFullscreen,
15
+ resolveFullscreenTarget,
16
+ subscribeFullscreenChange
17
+ } from "@expcat/tigercat-core";
18
+ function useFullscreen(options = {}) {
19
+ const getOptions = () => toValue(options);
20
+ const supported = isFullscreenSupported();
21
+ const isFullscreen = ref(false);
22
+ let stop;
23
+ const sync = () => {
24
+ const current = getOptions();
25
+ const target = resolveFullscreenTarget(current.target);
26
+ const next = isElementFullscreen(target);
27
+ isFullscreen.value = next;
28
+ current.onChange?.(next);
29
+ };
30
+ const enter = async () => {
31
+ const current = getOptions();
32
+ const target = resolveFullscreenTarget(current.target);
33
+ if (!target) return;
34
+ if (isElementFullscreen(target)) return;
35
+ try {
36
+ await requestElementFullscreen(target);
37
+ } catch (error) {
38
+ const err = error instanceof Error ? error : new Error("Fullscreen request failed");
39
+ current.onError?.(err);
40
+ }
41
+ };
42
+ const exit = async () => {
43
+ if (!getFullscreenElement()) return;
44
+ const current = getOptions();
45
+ try {
46
+ await exitElementFullscreen();
47
+ } catch (error) {
48
+ const err = error instanceof Error ? error : new Error("Fullscreen exit failed");
49
+ current.onError?.(err);
50
+ }
51
+ };
52
+ const toggle = async () => {
53
+ if (isFullscreen.value) await exit();
54
+ else await enter();
55
+ };
56
+ if (getCurrentInstance()) {
57
+ onMounted(() => {
58
+ sync();
59
+ stop = subscribeFullscreenChange(sync);
60
+ });
61
+ onBeforeUnmount(() => {
62
+ stop?.();
63
+ });
64
+ }
65
+ return {
66
+ isFullscreen,
67
+ supported,
68
+ enter,
69
+ exit,
70
+ toggle
71
+ };
72
+ }
73
+
74
+ export {
75
+ useFullscreen
76
+ };