blessing-ui 0.1.0 → 0.3.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 (200) hide show
  1. package/CHANGELOG.md +69 -0
  2. package/README.md +139 -105
  3. package/dist/blessing-ui.css +97 -1
  4. package/dist/components/BlessAnnotator.css +1 -0
  5. package/dist/components/BlessAnnotator.js +6 -0
  6. package/dist/components/BlessAnnotator.vue.d.ts +71 -0
  7. package/dist/components/BlessAnnotator.vue_vue_type_script_setup_true_lang.js +264 -0
  8. package/dist/components/BlessAttachment.vue.d.ts +4 -1
  9. package/dist/components/BlessAttachment.vue_vue_type_script_setup_true_lang.js +3 -2
  10. package/dist/components/BlessCalendar.vue.d.ts +4 -0
  11. package/dist/components/BlessCalendar.vue_vue_type_script_setup_true_lang.js +65 -60
  12. package/dist/components/BlessCarousel.vue.d.ts +3 -0
  13. package/dist/components/BlessCarousel.vue_vue_type_script_setup_true_lang.js +10 -9
  14. package/dist/components/BlessCoachmark.css +1 -0
  15. package/dist/components/BlessCoachmark.js +6 -0
  16. package/dist/components/BlessCoachmark.vue.d.ts +40 -0
  17. package/dist/components/BlessCoachmark.vue_vue_type_script_setup_true_lang.js +74 -0
  18. package/dist/components/BlessCodeBlock.css +1 -0
  19. package/dist/components/BlessCodeBlock.js +6 -0
  20. package/dist/components/BlessCodeBlock.vue.d.ts +72 -0
  21. package/dist/components/BlessCodeBlock.vue_vue_type_script_setup_true_lang.js +140 -0
  22. package/dist/components/BlessCombobox.vue.d.ts +2 -0
  23. package/dist/components/BlessCombobox.vue_vue_type_script_setup_true_lang.js +3 -2
  24. package/dist/components/BlessCommand.css +1 -1
  25. package/dist/components/BlessCommand.vue.d.ts +26 -0
  26. package/dist/components/BlessCommand.vue_vue_type_script_setup_true_lang.js +137 -70
  27. package/dist/components/BlessConfetti.css +1 -0
  28. package/dist/components/BlessConfetti.js +6 -0
  29. package/dist/components/BlessConfetti.vue.d.ts +40 -0
  30. package/dist/components/BlessConfetti.vue_vue_type_script_setup_true_lang.js +77 -0
  31. package/dist/components/BlessCountUp.css +1 -0
  32. package/dist/components/BlessCountUp.js +6 -0
  33. package/dist/components/BlessCountUp.vue.d.ts +18 -0
  34. package/dist/components/BlessCountUp.vue_vue_type_script_setup_true_lang.js +49 -0
  35. package/dist/components/BlessCropper.css +1 -0
  36. package/dist/components/BlessCropper.js +6 -0
  37. package/dist/components/BlessCropper.vue.d.ts +70 -0
  38. package/dist/components/BlessCropper.vue_vue_type_script_setup_true_lang.js +220 -0
  39. package/dist/components/BlessDataTable.vue.d.ts +6 -0
  40. package/dist/components/BlessDataTable.vue_vue_type_script_setup_true_lang.js +56 -42
  41. package/dist/components/BlessDataView.vue.d.ts +7 -0
  42. package/dist/components/BlessDataView.vue_vue_type_script_setup_true_lang.js +38 -31
  43. package/dist/components/BlessDatePicker.vue.d.ts +3 -0
  44. package/dist/components/BlessDatePicker.vue_vue_type_script_setup_true_lang.js +46 -45
  45. package/dist/components/BlessDiff.css +1 -0
  46. package/dist/components/BlessDiff.js +6 -0
  47. package/dist/components/BlessDiff.vue.d.ts +22 -0
  48. package/dist/components/BlessDiff.vue_vue_type_script_setup_true_lang.js +148 -0
  49. package/dist/components/BlessDock.css +1 -0
  50. package/dist/components/BlessDock.js +6 -0
  51. package/dist/components/BlessDock.vue.d.ts +55 -0
  52. package/dist/components/BlessDock.vue_vue_type_script_setup_true_lang.js +100 -0
  53. package/dist/components/BlessEditor.vue.d.ts +2 -0
  54. package/dist/components/BlessEditor.vue_vue_type_script_setup_true_lang.js +23 -22
  55. package/dist/components/BlessFileInput.vue.d.ts +2 -0
  56. package/dist/components/BlessFileInput.vue_vue_type_script_setup_true_lang.js +3 -2
  57. package/dist/components/BlessFormula.css +1 -0
  58. package/dist/components/BlessFormula.js +6 -0
  59. package/dist/components/BlessFormula.vue.d.ts +53 -0
  60. package/dist/components/BlessFormula.vue_vue_type_script_setup_true_lang.js +111 -0
  61. package/dist/components/BlessGantt.css +1 -0
  62. package/dist/components/BlessGantt.js +6 -0
  63. package/dist/components/BlessGantt.vue.d.ts +81 -0
  64. package/dist/components/BlessGantt.vue_vue_type_script_setup_true_lang.js +276 -0
  65. package/dist/components/BlessGauge.css +1 -0
  66. package/dist/components/BlessGauge.js +6 -0
  67. package/dist/components/BlessGauge.vue.d.ts +36 -0
  68. package/dist/components/BlessGauge.vue_vue_type_script_setup_true_lang.js +100 -0
  69. package/dist/components/BlessHeatmapCalendar.css +1 -0
  70. package/dist/components/BlessHeatmapCalendar.js +6 -0
  71. package/dist/components/BlessHeatmapCalendar.vue.d.ts +38 -0
  72. package/dist/components/BlessHeatmapCalendar.vue_vue_type_script_setup_true_lang.js +146 -0
  73. package/dist/components/BlessHotspots.css +1 -0
  74. package/dist/components/BlessHotspots.js +6 -0
  75. package/dist/components/BlessHotspots.vue.d.ts +49 -0
  76. package/dist/components/BlessHotspots.vue_vue_type_script_setup_true_lang.js +127 -0
  77. package/dist/components/BlessInfiniteCanvas.css +1 -0
  78. package/dist/components/BlessInfiniteCanvas.js +6 -0
  79. package/dist/components/BlessInfiniteCanvas.vue.d.ts +91 -0
  80. package/dist/components/BlessInfiniteCanvas.vue_vue_type_script_setup_true_lang.js +232 -0
  81. package/dist/components/BlessInputNumber.vue.d.ts +5 -0
  82. package/dist/components/BlessInputNumber.vue_vue_type_script_setup_true_lang.js +39 -34
  83. package/dist/components/BlessKanban.css +1 -0
  84. package/dist/components/BlessKanban.js +6 -0
  85. package/dist/components/BlessKanban.vue.d.ts +67 -0
  86. package/dist/components/BlessKanban.vue_vue_type_script_setup_true_lang.js +195 -0
  87. package/dist/components/BlessLoadingBar.vue.d.ts +2 -0
  88. package/dist/components/BlessLoadingBar.vue_vue_type_script_setup_true_lang.js +8 -3
  89. package/dist/components/BlessLoupe.css +1 -0
  90. package/dist/components/BlessLoupe.js +6 -0
  91. package/dist/components/BlessLoupe.vue.d.ts +16 -0
  92. package/dist/components/BlessLoupe.vue_vue_type_script_setup_true_lang.js +93 -0
  93. package/dist/components/BlessMarquee.css +1 -0
  94. package/dist/components/BlessMarquee.js +6 -0
  95. package/dist/components/BlessMarquee.vue.d.ts +44 -0
  96. package/dist/components/BlessMarquee.vue_vue_type_script_setup_true_lang.js +69 -0
  97. package/dist/components/BlessMasonry.css +1 -0
  98. package/dist/components/BlessMasonry.js +6 -0
  99. package/dist/components/BlessMasonry.vue.d.ts +33 -0
  100. package/dist/components/BlessMasonry.vue_vue_type_script_setup_true_lang.js +79 -0
  101. package/dist/components/BlessMention.css +1 -0
  102. package/dist/components/BlessMention.js +6 -0
  103. package/dist/components/BlessMention.vue.d.ts +32 -0
  104. package/dist/components/BlessMention.vue_vue_type_script_setup_true_lang.js +116 -0
  105. package/dist/components/BlessNodeGraph.css +1 -0
  106. package/dist/components/BlessNodeGraph.js +6 -0
  107. package/dist/components/BlessNodeGraph.vue.d.ts +110 -0
  108. package/dist/components/BlessNodeGraph.vue_vue_type_script_setup_true_lang.js +321 -0
  109. package/dist/components/BlessOnboardingChecklist.css +1 -0
  110. package/dist/components/BlessOnboardingChecklist.js +6 -0
  111. package/dist/components/BlessOnboardingChecklist.vue.d.ts +72 -0
  112. package/dist/components/BlessOnboardingChecklist.vue_vue_type_script_setup_true_lang.js +157 -0
  113. package/dist/components/BlessOrderList.vue.d.ts +5 -0
  114. package/dist/components/BlessOrderList.vue_vue_type_script_setup_true_lang.js +62 -56
  115. package/dist/components/BlessPagination.vue.d.ts +2 -0
  116. package/dist/components/BlessPagination.vue_vue_type_script_setup_true_lang.js +2 -1
  117. package/dist/components/BlessPickList.vue.d.ts +5 -0
  118. package/dist/components/BlessPickList.vue_vue_type_script_setup_true_lang.js +55 -49
  119. package/dist/components/BlessRadialMenu.css +1 -0
  120. package/dist/components/BlessRadialMenu.js +6 -0
  121. package/dist/components/BlessRadialMenu.vue.d.ts +45 -0
  122. package/dist/components/BlessRadialMenu.vue_vue_type_script_setup_true_lang.js +146 -0
  123. package/dist/components/BlessRangeCalendar.css +1 -0
  124. package/dist/components/BlessRangeCalendar.js +6 -0
  125. package/dist/components/BlessRangeCalendar.vue.d.ts +51 -0
  126. package/dist/components/BlessRangeCalendar.vue_vue_type_script_setup_true_lang.js +217 -0
  127. package/dist/components/BlessScheduler.css +1 -0
  128. package/dist/components/BlessScheduler.js +6 -0
  129. package/dist/components/BlessScheduler.vue.d.ts +95 -0
  130. package/dist/components/BlessScheduler.vue_vue_type_script_setup_true_lang.js +347 -0
  131. package/dist/components/BlessShortcutRecorder.css +1 -0
  132. package/dist/components/BlessShortcutRecorder.js +6 -0
  133. package/dist/components/BlessShortcutRecorder.vue.d.ts +39 -0
  134. package/dist/components/BlessShortcutRecorder.vue_vue_type_script_setup_true_lang.js +126 -0
  135. package/dist/components/BlessSignaturePad.vue.d.ts +1 -1
  136. package/dist/components/BlessSliderCaptcha.css +1 -0
  137. package/dist/components/BlessSliderCaptcha.js +6 -0
  138. package/dist/components/BlessSliderCaptcha.vue.d.ts +38 -0
  139. package/dist/components/BlessSliderCaptcha.vue_vue_type_script_setup_true_lang.js +146 -0
  140. package/dist/components/BlessSortable.css +1 -0
  141. package/dist/components/BlessSortable.js +6 -0
  142. package/dist/components/BlessSortable.vue.d.ts +51 -0
  143. package/dist/components/BlessSortable.vue_vue_type_script_setup_true_lang.js +135 -0
  144. package/dist/components/BlessSparkline.css +1 -0
  145. package/dist/components/BlessSparkline.js +6 -0
  146. package/dist/components/BlessSparkline.vue.d.ts +28 -0
  147. package/dist/components/BlessSparkline.vue_vue_type_script_setup_true_lang.js +107 -0
  148. package/dist/components/BlessSplitView.css +1 -0
  149. package/dist/components/BlessSplitView.js +6 -0
  150. package/dist/components/BlessSplitView.vue.d.ts +61 -0
  151. package/dist/components/BlessSplitView.vue_vue_type_script_setup_true_lang.js +92 -0
  152. package/dist/components/BlessSteps.vue.d.ts +2 -0
  153. package/dist/components/BlessSteps.vue_vue_type_script_setup_true_lang.js +3 -2
  154. package/dist/components/BlessSwipeDeck.css +1 -0
  155. package/dist/components/BlessSwipeDeck.js +6 -0
  156. package/dist/components/BlessSwipeDeck.vue.d.ts +46 -0
  157. package/dist/components/BlessSwipeDeck.vue_vue_type_script_setup_true_lang.js +200 -0
  158. package/dist/components/BlessTimer.css +1 -0
  159. package/dist/components/BlessTimer.js +6 -0
  160. package/dist/components/BlessTimer.vue.d.ts +74 -0
  161. package/dist/components/BlessTimer.vue_vue_type_script_setup_true_lang.js +139 -0
  162. package/dist/components/BlessTour.vue.d.ts +1 -0
  163. package/dist/components/BlessTour.vue_vue_type_script_setup_true_lang.js +48 -42
  164. package/dist/components/BlessTreemap.css +1 -0
  165. package/dist/components/BlessTreemap.js +6 -0
  166. package/dist/components/BlessTreemap.vue.d.ts +46 -0
  167. package/dist/components/BlessTreemap.vue_vue_type_script_setup_true_lang.js +137 -0
  168. package/dist/components/BlessUploader.vue.d.ts +11 -0
  169. package/dist/components/BlessUploader.vue_vue_type_script_setup_true_lang.js +80 -69
  170. package/dist/composables/annotate.d.ts +35 -0
  171. package/dist/composables/annotate.js +33 -0
  172. package/dist/composables/canvasView.d.ts +21 -0
  173. package/dist/composables/canvasView.js +23 -0
  174. package/dist/composables/confetti.d.ts +32 -0
  175. package/dist/composables/confetti.js +23 -0
  176. package/dist/composables/cropBox.d.ts +22 -0
  177. package/dist/composables/cropBox.js +39 -0
  178. package/dist/composables/dayBlocks.d.ts +11 -0
  179. package/dist/composables/dayBlocks.js +26 -0
  180. package/dist/composables/diffLines.d.ts +10 -0
  181. package/dist/composables/diffLines.js +55 -0
  182. package/dist/composables/formula.d.ts +28 -0
  183. package/dist/composables/formula.js +161 -0
  184. package/dist/composables/graph.d.ts +19 -0
  185. package/dist/composables/graph.js +16 -0
  186. package/dist/composables/radial.d.ts +15 -0
  187. package/dist/composables/radial.js +22 -0
  188. package/dist/composables/schedule.d.ts +27 -0
  189. package/dist/composables/schedule.js +54 -0
  190. package/dist/composables/shortcut.d.ts +12 -0
  191. package/dist/composables/shortcut.js +35 -0
  192. package/dist/composables/treemap.d.ts +23 -0
  193. package/dist/composables/treemap.js +77 -0
  194. package/dist/composables/useAutoScroll.d.ts +15 -0
  195. package/dist/composables/useAutoScroll.js +32 -0
  196. package/dist/composables/useSortable.d.ts +58 -0
  197. package/dist/composables/useSortable.js +107 -0
  198. package/dist/index.d.ts +62 -1
  199. package/dist/index.js +93 -53
  200. package/package.json +22 -18
@@ -0,0 +1 @@
1
+ .bless-treemap{gap:var(--bless-space-2);width:100%;font-family:var(--bless-font-sans);font-size:var(--bless-text-sm);color:var(--bless-color-text);flex-direction:column;display:flex}.bless-treemap__path{align-items:center;gap:var(--bless-space-2);display:flex}.bless-treemap__crumb{color:var(--bless-color-accent-text);font:inherit;cursor:pointer;background:0 0;border:0;padding:0;text-decoration:underline}.bless-treemap__here{font-weight:var(--bless-font-weight-bold,700)}.bless-treemap__box{position:relative;overflow:hidden}.bless-treemap__tile{box-sizing:border-box;padding:var(--bless-space-2);border:1px solid var(--bless-color-bg);background:color-mix(in srgb, var(--_c) 24%, var(--bless-color-surface));color:var(--bless-color-text);font:inherit;text-align:start;cursor:default;flex-direction:column;justify-content:flex-start;align-items:flex-start;gap:2px;margin:0;display:flex;position:absolute;overflow:hidden}.bless-treemap__tile--group{cursor:pointer;box-shadow:inset 3px 0 0 var(--_c)}.bless-treemap__tile:hover{background:color-mix(in srgb, var(--_c) 38%, var(--bless-color-surface))}.bless-treemap__tile:focus-visible{outline:2px solid var(--bless-color-accent);outline-offset:-2px;z-index:1}.bless-treemap__name{text-overflow:ellipsis;white-space:nowrap;max-width:100%;font-weight:var(--bless-font-weight-bold,700);overflow:hidden}.bless-treemap__value{font-size:var(--bless-text-xs)}
@@ -0,0 +1,6 @@
1
+ import "./BlessTreemap.css";
2
+ import e from "./BlessTreemap.vue_vue_type_script_setup_true_lang.js";
3
+ //#region src/components/BlessTreemap.vue
4
+ var t = e;
5
+ //#endregion
6
+ export { t as default };
@@ -0,0 +1,46 @@
1
+ import { TreemapNode } from '../composables/treemap';
2
+ export type { TreemapNode as BlessTreemapNode } from '../composables/treemap';
3
+ declare const _default: typeof __VLS_export;
4
+ export default _default;
5
+ declare const __VLS_export: import('vue').DefineComponent<{
6
+ data: TreemapNode[];
7
+ height?: number;
8
+ /** text for a size, e.g. `(v) => v + " MB"` */
9
+ format?: (v: number) => string;
10
+ /** name of the top level in the path, and of the whole chart for screen readers */
11
+ label?: string;
12
+ labels?: Partial<{
13
+ tile: (label: string, value: string, share: string, children: number) => string;
14
+ path: string;
15
+ up: string;
16
+ hint: string;
17
+ }>;
18
+ } & {
19
+ /** ids from the top down to the level being shown */
20
+ path?: string[];
21
+ }, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {
22
+ select: (node: TreemapNode, path: string[]) => any;
23
+ "update:path": (value: string[]) => any;
24
+ }, string, import('vue').PublicProps, Readonly<{
25
+ data: TreemapNode[];
26
+ height?: number;
27
+ /** text for a size, e.g. `(v) => v + " MB"` */
28
+ format?: (v: number) => string;
29
+ /** name of the top level in the path, and of the whole chart for screen readers */
30
+ label?: string;
31
+ labels?: Partial<{
32
+ tile: (label: string, value: string, share: string, children: number) => string;
33
+ path: string;
34
+ up: string;
35
+ hint: string;
36
+ }>;
37
+ } & {
38
+ /** ids from the top down to the level being shown */
39
+ path?: string[];
40
+ }> & Readonly<{
41
+ onSelect?: ((node: TreemapNode, path: string[]) => any) | undefined;
42
+ "onUpdate:path"?: ((value: string[]) => any) | undefined;
43
+ }>, {
44
+ label: string;
45
+ height: number;
46
+ }, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, any>;
@@ -0,0 +1,137 @@
1
+ import { neighbour as e, squarify as t, totalOf as n } from "../composables/treemap.js";
2
+ import { Fragment as r, computed as i, createCommentVNode as a, createElementBlock as o, createElementVNode as s, defineComponent as c, mergeModels as l, nextTick as u, normalizeClass as d, normalizeStyle as f, onBeforeUnmount as p, onMounted as m, openBlock as h, ref as g, renderList as _, toDisplayString as v, useModel as y } from "vue";
3
+ //#region src/components/BlessTreemap.vue?vue&type=script&setup=true&lang.ts
4
+ var b = { class: "bless-treemap" }, x = ["aria-label"], S = ["onClick"], C = {
5
+ key: 1,
6
+ class: "bless-treemap__here",
7
+ "aria-current": "location"
8
+ }, w = ["aria-label"], T = [
9
+ "tabindex",
10
+ "aria-label",
11
+ "title",
12
+ "onClick",
13
+ "onFocus",
14
+ "onKeydown"
15
+ ], E = { class: "bless-treemap__name" }, D = {
16
+ key: 0,
17
+ class: "bless-treemap__value"
18
+ }, O = /*@__PURE__*/ c({
19
+ name: "BlessTreemap",
20
+ __name: "BlessTreemap",
21
+ props: /*@__PURE__*/ l({
22
+ data: {},
23
+ height: { default: 320 },
24
+ format: {},
25
+ label: { default: "All" },
26
+ labels: {}
27
+ }, {
28
+ path: { default: () => [] },
29
+ pathModifiers: {}
30
+ }),
31
+ emits: /*@__PURE__*/ l(["select"], ["update:path"]),
32
+ setup(c, { emit: l }) {
33
+ let O = c, k = y(c, "path"), A = l, j = i(() => ({
34
+ tile: (e, t, n, r) => `${e}, ${t}, ${n}${r ? `, contains ${r} items, Enter opens` : ""}`,
35
+ path: "Path",
36
+ up: "Up one level",
37
+ hint: "Arrow keys move between tiles, Enter opens or selects, Backspace goes up.",
38
+ ...O.labels
39
+ })), M = i(() => O.format ?? ((e) => new Intl.NumberFormat().format(e))), N = (e) => `${e < .01 ? "<1" : Math.round(e * 100)}%`, P = g(), F = g(640), I;
40
+ m(() => {
41
+ let e = () => F.value = P.value?.clientWidth || F.value;
42
+ e(), typeof ResizeObserver == "function" && P.value && (I = new ResizeObserver(e), I.observe(P.value));
43
+ }), p(() => I?.disconnect());
44
+ let L = i(() => {
45
+ let e = [], t = O.data;
46
+ for (let n of k.value) {
47
+ let r = t.find((e) => e.id === n);
48
+ if (!r?.children) break;
49
+ e.push(r), t = r.children;
50
+ }
51
+ return e;
52
+ }), R = i(() => (L.value.at(-1)?.children ?? O.data).filter((e) => n(e) > 0)), z = i(() => R.value.reduce((e, t) => e + n(t), 0)), B = i(() => t(R.value.map(n), F.value, O.height)), V = (e, t) => {
53
+ let n = L.value[0], r = e.color ?? n?.color ?? `chart-${(n ? O.data.indexOf(n) : t) % 5 + 1}`;
54
+ return /^[a-z0-9-]+$/i.test(r) ? `var(--bless-color-${r})` : r;
55
+ }, H = i(() => R.value.map((e, t) => {
56
+ let r = B.value[t], i = n(e);
57
+ return {
58
+ node: e,
59
+ v: i,
60
+ r,
61
+ color: V(e, t),
62
+ big: r.w >= 64 && r.h >= 34,
63
+ tall: r.h >= 54,
64
+ name: j.value.tile(e.label, M.value(i), N(i / (z.value || 1)), e.children?.length ?? 0)
65
+ };
66
+ })), U = g(0), W = i(() => Math.min(U.value, Math.max(0, H.value.length - 1))), G = (e) => {
67
+ U.value = e, u(() => P.value?.querySelectorAll(".bless-treemap__tile")[e]?.focus());
68
+ };
69
+ function K(e) {
70
+ let t = H.value[e], n = [...k.value.slice(0, L.value.length), t.node.id];
71
+ t.node.children?.length && (k.value = n, U.value = 0), A("select", t.node, n);
72
+ }
73
+ function q(e = L.value.length - 1) {
74
+ if (e < 0) return;
75
+ let t = L.value[e]?.id;
76
+ k.value = k.value.slice(0, e), u(() => G(Math.max(0, R.value.findIndex((e) => e.id === t))));
77
+ }
78
+ function J(t, n) {
79
+ let r = {
80
+ ArrowLeft: "left",
81
+ ArrowRight: "right",
82
+ ArrowUp: "up",
83
+ ArrowDown: "down"
84
+ }[n.key];
85
+ r ? (n.preventDefault(), G(e(B.value, t, r))) : n.key === "Home" ? (n.preventDefault(), G(0)) : n.key === "End" ? (n.preventDefault(), G(H.value.length - 1)) : n.key === "Backspace" && L.value.length && (n.preventDefault(), q());
86
+ }
87
+ let Y = "bless-treemap-hint";
88
+ return (e, t) => (h(), o("div", b, [
89
+ L.value.length ? (h(), o("nav", {
90
+ key: 0,
91
+ class: "bless-treemap__path",
92
+ "aria-label": j.value.path
93
+ }, [s("button", {
94
+ type: "button",
95
+ class: "bless-treemap__crumb",
96
+ onClick: t[0] ||= (e) => q(0)
97
+ }, v(c.label), 1), (h(!0), o(r, null, _(L.value, (e, n) => (h(), o(r, { key: e.id }, [t[1] ||= s("span", { "aria-hidden": "true" }, "›", -1), n < L.value.length - 1 ? (h(), o("button", {
98
+ key: 0,
99
+ type: "button",
100
+ class: "bless-treemap__crumb",
101
+ onClick: (e) => q(n + 1)
102
+ }, v(e.label), 9, S)) : (h(), o("span", C, v(e.label), 1))], 64))), 128))], 8, x)) : a("", !0),
103
+ s("div", {
104
+ ref_key: "box",
105
+ ref: P,
106
+ class: "bless-treemap__box",
107
+ role: "group",
108
+ "aria-label": L.value.length ? L.value.at(-1).label : c.label,
109
+ style: f({ height: `${c.height}px` })
110
+ }, [(h(!0), o(r, null, _(H.value, (e, t) => (h(), o("button", {
111
+ key: e.node.id,
112
+ type: "button",
113
+ class: d(["bless-treemap__tile", { "bless-treemap__tile--group": e.node.children?.length }]),
114
+ style: f({
115
+ left: `${e.r.x}px`,
116
+ top: `${e.r.y}px`,
117
+ width: `${e.r.w}px`,
118
+ height: `${e.r.h}px`,
119
+ "--_c": e.color
120
+ }),
121
+ tabindex: W.value === t ? 0 : -1,
122
+ "aria-label": e.name,
123
+ "aria-describedby": Y,
124
+ title: e.big ? void 0 : e.name,
125
+ onClick: (e) => K(t),
126
+ onFocus: (e) => U.value = t,
127
+ onKeydown: (e) => J(t, e)
128
+ }, [e.big ? (h(), o(r, { key: 0 }, [s("span", E, v(e.node.label), 1), e.tall ? (h(), o("span", D, v(M.value(e.v)), 1)) : a("", !0)], 64)) : a("", !0)], 46, T))), 128))], 12, w),
129
+ s("span", {
130
+ id: Y,
131
+ hidden: ""
132
+ }, v(j.value.hint), 1)
133
+ ]));
134
+ }
135
+ });
136
+ //#endregion
137
+ export { O as default };
@@ -19,6 +19,17 @@ type __VLS_Props = {
19
19
  maxSize?: number;
20
20
  label?: string;
21
21
  hint?: string;
22
+ /** button text, item buttons and the messages said as files finish */
23
+ labels?: Partial<{
24
+ clear: string;
25
+ upload: string;
26
+ tooLarge: string;
27
+ failed: string;
28
+ uploaded: (name: string) => string;
29
+ failedFile: (name: string, why: string) => string;
30
+ cancel: (name: string) => string;
31
+ remove: (name: string) => string;
32
+ }>;
22
33
  };
23
34
  declare var __VLS_13: {
24
35
  start: () => void;
@@ -1,15 +1,15 @@
1
1
  import e from "./BlessButton.js";
2
2
  import t from "./BlessProgress.js";
3
3
  import n from "./BlessFileInput.js";
4
- import { Fragment as r, createBlock as i, createCommentVNode as a, createElementBlock as o, createElementVNode as s, createTextVNode as c, createVNode as l, defineComponent as u, nextTick as d, normalizeClass as f, onBeforeUnmount as p, openBlock as m, ref as h, renderList as g, renderSlot as _, toDisplayString as v, withCtx as y } from "vue";
4
+ import { Fragment as r, computed as i, createBlock as a, createCommentVNode as o, createElementBlock as s, createElementVNode as c, createTextVNode as l, createVNode as u, defineComponent as d, nextTick as f, normalizeClass as p, onBeforeUnmount as m, openBlock as h, ref as g, renderList as _, renderSlot as v, toDisplayString as y, withCtx as b } from "vue";
5
5
  //#region src/components/BlessUploader.vue?vue&type=script&setup=true&lang.ts
6
- var b = { class: "bless-uploader__name" }, x = { class: "bless-uploader__meta" }, S = ["aria-label", "onClick"], C = {
6
+ var x = { class: "bless-uploader__name" }, S = { class: "bless-uploader__meta" }, C = ["aria-label", "onClick"], w = {
7
7
  class: "bless-uploader__live",
8
8
  "aria-live": "polite"
9
- }, w = {
9
+ }, T = {
10
10
  key: 1,
11
11
  class: "bless-uploader__actions"
12
- }, T = /*@__PURE__*/ u({
12
+ }, E = /*@__PURE__*/ d({
13
13
  name: "BlessUploader",
14
14
  __name: "BlessUploader",
15
15
  props: {
@@ -27,75 +27,86 @@ var b = { class: "bless-uploader__name" }, x = { class: "bless-uploader__meta" }
27
27
  },
28
28
  maxSize: {},
29
29
  label: { default: "Drop files here or click to browse" },
30
- hint: {}
30
+ hint: {},
31
+ labels: {}
31
32
  },
32
33
  emits: [
33
34
  "upload",
34
35
  "done",
35
36
  "error"
36
37
  ],
37
- setup(u, { expose: T, emit: E }) {
38
- let D = u, O = E, k = h([]), A = h([]), j = 0, M = h("");
39
- function N(e) {
38
+ setup(d, { expose: E, emit: D }) {
39
+ let O = d, k = i(() => ({
40
+ clear: "Clear",
41
+ upload: "Upload",
42
+ tooLarge: "Too large",
43
+ failed: "Upload failed",
44
+ uploaded: (e) => `${e} uploaded`,
45
+ failedFile: (e, t) => `${e}: ${t}`,
46
+ cancel: (e) => `Cancel ${e}`,
47
+ remove: (e) => `Remove ${e}`,
48
+ ...O.labels
49
+ })), A = D, j = g([]), M = g([]), N = 0, P = g("");
50
+ function F(e) {
40
51
  for (let t of e) {
41
- if (D.maxSize && t.size > D.maxSize) {
42
- k.value.push({
43
- id: ++j,
52
+ if (O.maxSize && t.size > O.maxSize) {
53
+ j.value.push({
54
+ id: ++N,
44
55
  file: t,
45
56
  progress: 0,
46
57
  status: "error",
47
- error: "Too large"
58
+ error: k.value.tooLarge
48
59
  });
49
60
  continue;
50
61
  }
51
- k.value.push({
52
- id: ++j,
62
+ j.value.push({
63
+ id: ++N,
53
64
  file: t,
54
65
  progress: 0,
55
66
  status: "queued"
56
67
  });
57
68
  }
58
- A.value = [], D.auto && F();
69
+ M.value = [], O.auto && L();
59
70
  }
60
- function P(e) {
71
+ function I(e) {
61
72
  e.status = "uploading";
62
73
  let t = (t) => e.progress = Math.max(0, Math.min(100, t)), n = () => {
63
- e.status = "done", e.progress = 100, M.value = `${e.file.name} uploaded`, O("done", e);
74
+ e.status = "done", e.progress = 100, P.value = k.value.uploaded(e.file.name), A("done", e);
64
75
  }, r = (t) => {
65
- e.status = "error", e.error = t ?? "Upload failed", M.value = `${e.file.name}: ${e.error}`, O("error", e);
76
+ e.status = "error", e.error = t ?? k.value.failed, P.value = k.value.failedFile(e.file.name, e.error), A("error", e);
66
77
  };
67
- if (!D.url) return void O("upload", e, t, n, r);
78
+ if (!O.url) return void A("upload", e, t, n, r);
68
79
  let i = new XMLHttpRequest();
69
- e.xhr = i, i.open("POST", D.url);
70
- for (let [e, t] of Object.entries(D.headers ?? {})) i.setRequestHeader(e, t);
80
+ e.xhr = i, i.open("POST", O.url);
81
+ for (let [e, t] of Object.entries(O.headers ?? {})) i.setRequestHeader(e, t);
71
82
  i.upload.onprogress = (e) => e.lengthComputable && t(e.loaded / e.total * 100), i.onload = () => i.status < 400 ? n() : r(`HTTP ${i.status}`), i.onerror = () => r(), i.onabort = () => e.status = "cancelled";
72
83
  let a = new FormData();
73
- a.append(D.field, e.file), i.send(a);
84
+ a.append(O.field, e.file), i.send(a);
74
85
  }
75
- let F = () => k.value.filter((e) => e.status === "queued").forEach(P), I = (e) => e.xhr ? e.xhr.abort() : e.status = "cancelled", L = h(), R = h();
76
- async function z(e) {
77
- let t = k.value.indexOf(e);
78
- e.status === "uploading" && I(e), k.value = k.value.filter((t) => t !== e), await d();
79
- let n = R.value?.querySelectorAll(".bless-uploader__x") ?? [];
80
- (n[Math.min(t, n.length - 1)] ?? L.value?.querySelector("input[type=file]"))?.focus();
86
+ let L = () => j.value.filter((e) => e.status === "queued").forEach(I), R = (e) => e.xhr ? e.xhr.abort() : e.status = "cancelled", z = g(), B = g();
87
+ async function V(e) {
88
+ let t = j.value.indexOf(e);
89
+ e.status === "uploading" && R(e), j.value = j.value.filter((t) => t !== e), await f();
90
+ let n = B.value?.querySelectorAll(".bless-uploader__x") ?? [];
91
+ (n[Math.min(t, n.length - 1)] ?? z.value?.querySelector("input[type=file]"))?.focus();
81
92
  }
82
- let B = () => k.value = k.value.filter((e) => e.status === "uploading"), V = (e) => e < 1048576 ? `${(e / 1024).toFixed(0)} KB` : `${(e / 1048576).toFixed(1)} MB`;
83
- return p(() => k.value.forEach((e) => e.status === "uploading" && e.xhr?.abort())), T({
84
- start: F,
85
- clear: B,
86
- queue: k
87
- }), (d, p) => (m(), o("div", {
93
+ let H = () => j.value = j.value.filter((e) => e.status === "uploading"), U = (e) => e < 1048576 ? `${(e / 1024).toFixed(0)} KB` : `${(e / 1048576).toFixed(1)} MB`;
94
+ return m(() => j.value.forEach((e) => e.status === "uploading" && e.xhr?.abort())), E({
95
+ start: L,
96
+ clear: H,
97
+ queue: j
98
+ }), (i, f) => (h(), s("div", {
88
99
  ref_key: "root",
89
- ref: L,
100
+ ref: z,
90
101
  class: "bless-uploader"
91
102
  }, [
92
- l(n, {
93
- modelValue: A.value,
94
- "onUpdate:modelValue": [p[0] ||= (e) => A.value = e, N],
95
- accept: u.accept,
96
- multiple: u.multiple,
97
- label: u.label,
98
- hint: u.hint,
103
+ u(n, {
104
+ modelValue: M.value,
105
+ "onUpdate:modelValue": [f[0] ||= (e) => M.value = e, F],
106
+ accept: d.accept,
107
+ multiple: d.multiple,
108
+ label: d.label,
109
+ hint: d.hint,
99
110
  list: !1
100
111
  }, null, 8, [
101
112
  "modelValue",
@@ -104,54 +115,54 @@ var b = { class: "bless-uploader__name" }, x = { class: "bless-uploader__meta" }
104
115
  "label",
105
116
  "hint"
106
117
  ]),
107
- k.value.length ? (m(), o("ul", {
118
+ j.value.length ? (h(), s("ul", {
108
119
  key: 0,
109
120
  role: "list",
110
121
  ref_key: "list",
111
- ref: R,
122
+ ref: B,
112
123
  class: "bless-uploader__list"
113
- }, [(m(!0), o(r, null, g(k.value, (e) => (m(), o("li", {
124
+ }, [(h(!0), s(r, null, _(j.value, (e) => (h(), s("li", {
114
125
  key: e.id,
115
- class: f(["bless-uploader__item", `bless-uploader__item--${e.status}`])
126
+ class: p(["bless-uploader__item", `bless-uploader__item--${e.status}`])
116
127
  }, [
117
- s("span", b, v(e.file.name), 1),
118
- s("span", x, v(e.error ?? (e.status === "done" ? "done" : e.status === "uploading" ? `${Math.round(e.progress)}%` : V(e.file.size))), 1),
119
- e.status === "uploading" ? (m(), i(t, {
128
+ c("span", x, y(e.file.name), 1),
129
+ c("span", S, y(e.error ?? (e.status === "done" ? "done" : e.status === "uploading" ? `${Math.round(e.progress)}%` : U(e.file.size))), 1),
130
+ e.status === "uploading" ? (h(), a(t, {
120
131
  key: 0,
121
132
  value: e.progress,
122
133
  size: "sm",
123
134
  class: "bless-uploader__bar"
124
- }, null, 8, ["value"])) : a("", !0),
125
- s("button", {
135
+ }, null, 8, ["value"])) : o("", !0),
136
+ c("button", {
126
137
  type: "button",
127
138
  class: "bless-uploader__x",
128
- "aria-label": `${e.status === "uploading" ? "Cancel" : "Remove"} ${e.file.name}`,
129
- onClick: (t) => e.status === "uploading" ? I(e) : z(e)
130
- }, " × ", 8, S)
131
- ], 2))), 128))], 512)) : a("", !0),
132
- s("span", C, v(M.value), 1),
133
- k.value.length ? (m(), o("div", w, [_(d.$slots, "actions", {
134
- start: F,
135
- clear: B,
136
- queue: k.value
137
- }, () => [l(e, {
139
+ "aria-label": (e.status === "uploading" ? k.value.cancel : k.value.remove)(e.file.name),
140
+ onClick: (t) => e.status === "uploading" ? R(e) : V(e)
141
+ }, " × ", 8, C)
142
+ ], 2))), 128))], 512)) : o("", !0),
143
+ c("span", w, y(P.value), 1),
144
+ j.value.length ? (h(), s("div", T, [v(i.$slots, "actions", {
145
+ start: L,
146
+ clear: H,
147
+ queue: j.value
148
+ }, () => [u(e, {
138
149
  size: "sm",
139
150
  variant: "outline",
140
- onClick: B
151
+ onClick: H
141
152
  }, {
142
- default: y(() => [...p[1] ||= [c("Clear", -1)]]),
153
+ default: b(() => [l(y(k.value.clear), 1)]),
143
154
  _: 1
144
- }), u.auto ? a("", !0) : (m(), i(e, {
155
+ }), d.auto ? o("", !0) : (h(), a(e, {
145
156
  key: 0,
146
157
  size: "sm",
147
- disabled: !k.value.some((e) => e.status === "queued"),
148
- onClick: F
158
+ disabled: !j.value.some((e) => e.status === "queued"),
159
+ onClick: L
149
160
  }, {
150
- default: y(() => [...p[2] ||= [c("Upload", -1)]]),
161
+ default: b(() => [l(y(k.value.upload), 1)]),
151
162
  _: 1
152
- }, 8, ["disabled"]))])])) : a("", !0)
163
+ }, 8, ["disabled"]))])])) : o("", !0)
153
164
  ], 512));
154
165
  }
155
166
  });
156
167
  //#endregion
157
- export { T as default };
168
+ export { E as default };
@@ -0,0 +1,35 @@
1
+ /** A mark on an image. All numbers are fractions (0–1) of the image, so they survive any size. */
2
+ export interface Region {
3
+ id: string;
4
+ x: number;
5
+ y: number;
6
+ /** present on a box, absent on a pin */
7
+ w?: number;
8
+ h?: number;
9
+ label: string;
10
+ }
11
+ /** the smallest side of a box, as a fraction of the image */
12
+ export declare const MIN_SIDE = 0.02;
13
+ export declare const isBox: (r: Region) => r is Region & {
14
+ w: number;
15
+ h: number;
16
+ };
17
+ /** The box between two points, kept inside the image. */
18
+ export declare function boxFrom(a: {
19
+ x: number;
20
+ y: number;
21
+ }, b: {
22
+ x: number;
23
+ y: number;
24
+ }): {
25
+ x: number;
26
+ y: number;
27
+ w: number;
28
+ h: number;
29
+ };
30
+ /** `r` moved by (dx, dy), stopping at the image edges. */
31
+ export declare function moveRegion(r: Region, dx: number, dy: number): Region;
32
+ /** A box grown by (dw, dh) from its top-left corner; a pin is returned as it is. */
33
+ export declare function resizeRegion(r: Region, dw: number, dh: number): Region;
34
+ /** The first `r1`, `r2`… not already used. */
35
+ export declare function nextId(regions: readonly Region[]): string;
@@ -0,0 +1,33 @@
1
+ //#region src/composables/annotate.ts
2
+ var e = .02, t = (e) => e.w != null && e.h != null, n = (e, t, n) => Math.min(n, Math.max(t, e)), r = (e) => Math.round(e * 1e4) / 1e4;
3
+ function i(e, t) {
4
+ let i = n(Math.min(e.x, t.x), 0, 1), a = n(Math.min(e.y, t.y), 0, 1), o = n(Math.max(e.x, t.x), 0, 1), s = n(Math.max(e.y, t.y), 0, 1);
5
+ return {
6
+ x: r(i),
7
+ y: r(a),
8
+ w: r(o - i),
9
+ h: r(s - a)
10
+ };
11
+ }
12
+ function a(e, t, i) {
13
+ let a = e.w ?? 0, o = e.h ?? 0;
14
+ return {
15
+ ...e,
16
+ x: r(n(e.x + t, 0, 1 - a)),
17
+ y: r(n(e.y + i, 0, 1 - o))
18
+ };
19
+ }
20
+ function o(i, a, o) {
21
+ return t(i) ? {
22
+ ...i,
23
+ w: r(n(i.w + a, e, 1 - i.x)),
24
+ h: r(n(i.h + o, e, 1 - i.y))
25
+ } : i;
26
+ }
27
+ function s(e) {
28
+ let t = new Set(e.map((e) => e.id)), n = 1;
29
+ for (; t.has(`r${n}`);) n++;
30
+ return `r${n}`;
31
+ }
32
+ //#endregion
33
+ export { e as MIN_SIDE, i as boxFrom, t as isBox, a as moveRegion, s as nextId, o as resizeRegion };
@@ -0,0 +1,21 @@
1
+ export interface CanvasView {
2
+ /** where the world's origin sits inside the viewport, px */
3
+ x: number;
4
+ y: number;
5
+ zoom: number;
6
+ }
7
+ export declare const clampZoom: (z: number, min: number, max: number) => number;
8
+ /** The world point under a viewport point (px relative to the viewport's top-left). */
9
+ export declare const toWorld: (v: CanvasView, px: number, py: number) => {
10
+ x: number;
11
+ y: number;
12
+ };
13
+ /** Zoom by `factor` keeping the world point under (`px`, `py`) where it is. */
14
+ export declare function zoomAt(v: CanvasView, factor: number, px: number, py: number, min: number, max: number): CanvasView;
15
+ /** The view that shows a world rectangle centred in a viewport of `w` × `h`, with `pad` px around. */
16
+ export declare function fitRect(r: {
17
+ x: number;
18
+ y: number;
19
+ width: number;
20
+ height: number;
21
+ }, w: number, h: number, min: number, max: number, pad?: number): CanvasView;
@@ -0,0 +1,23 @@
1
+ //#region src/composables/canvasView.ts
2
+ var e = (e, t, n) => Math.min(n, Math.max(t, e)), t = (e, t, n) => ({
3
+ x: (t - e.x) / e.zoom,
4
+ y: (n - e.y) / e.zoom
5
+ });
6
+ function n(t, n, r, i, a, o) {
7
+ let s = e(t.zoom * n, a, o), c = s / t.zoom;
8
+ return {
9
+ zoom: s,
10
+ x: r - (r - t.x) * c,
11
+ y: i - (i - t.y) * c
12
+ };
13
+ }
14
+ function r(t, n, r, i, a, o = 32) {
15
+ let s = e(Math.min((n - o * 2) / (t.width || 1), (r - o * 2) / (t.height || 1)), i, a);
16
+ return {
17
+ zoom: s,
18
+ x: (n - t.width * s) / 2 - t.x * s,
19
+ y: (r - t.height * s) / 2 - t.y * s
20
+ };
21
+ }
22
+ //#endregion
23
+ export { e as clampZoom, r as fitRect, t as toWorld, n as zoomAt };
@@ -0,0 +1,32 @@
1
+ export interface Particle {
2
+ x: number;
3
+ y: number;
4
+ vx: number;
5
+ vy: number;
6
+ size: number;
7
+ rot: number;
8
+ vr: number;
9
+ color: string;
10
+ round: boolean;
11
+ /** 0..1 of its life left; fades out over the last part */
12
+ life: number;
13
+ }
14
+ export interface BurstOptions {
15
+ count: number;
16
+ /** viewport px */
17
+ origin: {
18
+ x: number;
19
+ y: number;
20
+ };
21
+ /** where the burst points, degrees, 0 = right, 270 = up */
22
+ angle: number;
23
+ /** total width of the cone, degrees */
24
+ spread: number;
25
+ /** px per second at launch (the strongest piece) */
26
+ power: number;
27
+ colors: string[];
28
+ }
29
+ /** The pieces of one burst; `rand` is injected so a test can fix it. */
30
+ export declare function burst(o: BurstOptions, rand?: () => number): Particle[];
31
+ /** Advance a piece by `dt` seconds: gravity pulls down, the air slows it, it fades near the end. */
32
+ export declare function step(p: Particle, dt: number, gravity: number, lifetime: number): void;
@@ -0,0 +1,23 @@
1
+ //#region src/composables/confetti.ts
2
+ function e(e, t = Math.random) {
3
+ return Array.from({ length: e.count }, (n, r) => {
4
+ let i = (e.angle + (t() - .5) * e.spread) * Math.PI / 180, a = e.power * (.45 + t() * .55);
5
+ return {
6
+ x: e.origin.x,
7
+ y: e.origin.y,
8
+ vx: Math.cos(i) * a,
9
+ vy: Math.sin(i) * a,
10
+ size: 5 + t() * 6,
11
+ rot: t() * Math.PI * 2,
12
+ vr: (t() - .5) * 12,
13
+ color: e.colors[r % e.colors.length],
14
+ round: t() < .3,
15
+ life: 1
16
+ };
17
+ });
18
+ }
19
+ function t(e, t, n, r) {
20
+ e.vx *= 1 - 1.6 * t, e.vy = e.vy * (1 - 1.6 * t) + n * t, e.x += e.vx * t, e.y += e.vy * t, e.rot += e.vr * t, e.life -= t / r;
21
+ }
22
+ //#endregion
23
+ export { e as burst, t as step };
@@ -0,0 +1,22 @@
1
+ /** A crop box as fractions (0..1) of the displayed image: left, top, right, bottom. */
2
+ export interface CropBox {
3
+ l: number;
4
+ t: number;
5
+ r: number;
6
+ b: number;
7
+ }
8
+ export declare const MIN = 0.05;
9
+ /**
10
+ * Largest centred box covering `fill` of the image. `ratio` is width / height in fractions
11
+ * (pixel aspect × image height / image width); 0 means free.
12
+ */
13
+ export declare function initialBox(ratio: number, fill?: number): CropBox;
14
+ /** Shift the whole box by (dx, dy) fractions, stopping at the image edge. */
15
+ export declare function moveBox(box: CropBox, dx: number, dy: number): CropBox;
16
+ /**
17
+ * Drag the handle `h` ("n", "se", …) to the point (x, y). The opposite edges stay put; with a
18
+ * `ratio` (corners only) the box keeps its shape by giving up the longer side.
19
+ */
20
+ export declare function resizeBox(box: CropBox, h: string, x: number, y: number, ratio?: number): CropBox;
21
+ /** Grow (+) or shrink (−) around the centre by `d` of the image, keeping shape and staying inside. */
22
+ export declare function scaleBox(box: CropBox, d: number): CropBox;