@peteai/presentation-editor 0.0.1 → 0.0.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.
Files changed (214) hide show
  1. package/README.md +172 -38
  2. package/dist/components/presentation-editor/active-layers-buttons.svelte +53 -0
  3. package/dist/components/presentation-editor/active-layers-buttons.svelte.d.ts +3 -0
  4. package/dist/components/presentation-editor/active-layers.svelte +181 -0
  5. package/dist/components/presentation-editor/active-layers.svelte.d.ts +3 -0
  6. package/dist/components/presentation-editor/color-indicator/color-indicator-gradient-def.svelte +81 -0
  7. package/dist/components/presentation-editor/color-indicator/color-indicator-gradient-def.svelte.d.ts +9 -0
  8. package/dist/components/presentation-editor/color-indicator/color-indicator-gradient.svelte +21 -0
  9. package/dist/components/presentation-editor/color-indicator/color-indicator-gradient.svelte.d.ts +8 -0
  10. package/dist/components/presentation-editor/color-indicator/color-indicator.svelte +23 -0
  11. package/dist/components/presentation-editor/color-indicator/color-indicator.svelte.d.ts +6 -0
  12. package/dist/components/presentation-editor/color-indicator/index.d.ts +4 -0
  13. package/dist/components/presentation-editor/color-indicator/index.js +6 -0
  14. package/dist/components/presentation-editor/cursor-tooltip.svelte +1 -1
  15. package/dist/components/presentation-editor/dragged.svelte +21 -11
  16. package/dist/components/presentation-editor/fonts.d.ts +3 -0
  17. package/dist/components/presentation-editor/fonts.js +1278 -0
  18. package/dist/components/presentation-editor/header.svelte +21 -33
  19. package/dist/components/presentation-editor/header.svelte.d.ts +16 -6
  20. package/dist/components/presentation-editor/hotkeys.svelte +85 -0
  21. package/dist/components/presentation-editor/{sidebar/layers.svelte.d.ts → hotkeys.svelte.d.ts} +3 -3
  22. package/dist/components/presentation-editor/layers/active-background-border.svelte +3 -7
  23. package/dist/components/presentation-editor/layers/active-layer-border.svelte +2 -5
  24. package/dist/components/presentation-editor/layers/active-layer-border.svelte.d.ts +0 -1
  25. package/dist/components/presentation-editor/layers/buttons/border-button/border-button.svelte +113 -129
  26. package/dist/components/presentation-editor/layers/buttons/border-button/border-button.svelte.d.ts +2 -2
  27. package/dist/components/presentation-editor/layers/buttons/corner-radius-button/corner-radius-button.svelte +51 -32
  28. package/dist/components/presentation-editor/layers/buttons/corner-radius-button/corner-radius-button.svelte.d.ts +2 -2
  29. package/dist/components/presentation-editor/layers/buttons/flip-button/flip-button.svelte +30 -7
  30. package/dist/components/presentation-editor/layers/buttons/flip-button/flip-button.svelte.d.ts +3 -3
  31. package/dist/components/presentation-editor/layers/buttons/opacity-button/opacity-button.svelte +76 -33
  32. package/dist/components/presentation-editor/layers/buttons/opacity-button/opacity-button.svelte.d.ts +3 -3
  33. package/dist/components/presentation-editor/layers/controls/corner-scale-control/corner-scale-control.svelte +89 -59
  34. package/dist/components/presentation-editor/layers/controls/corner-scale-control/corner-scale-control.svelte.d.ts +5 -100
  35. package/dist/components/presentation-editor/layers/controls/group-resize-control/group-resize-control.svelte +337 -0
  36. package/dist/components/presentation-editor/layers/controls/group-resize-control/group-resize-control.svelte.d.ts +104 -0
  37. package/dist/components/presentation-editor/layers/controls/group-resize-control/index.d.ts +2 -0
  38. package/dist/components/presentation-editor/layers/controls/group-resize-control/index.js +4 -0
  39. package/dist/components/presentation-editor/layers/controls/rotate-control/rotate-control.svelte +128 -43
  40. package/dist/components/presentation-editor/layers/controls/rotate-control/rotate-control.svelte.d.ts +1 -5
  41. package/dist/components/presentation-editor/layers/controls/side-resize-control/side-resize-control.svelte +68 -57
  42. package/dist/components/presentation-editor/layers/controls/side-resize-control/side-resize-control.svelte.d.ts +2 -110
  43. package/dist/components/presentation-editor/layers/controls/side-scale-control/side-scale-control.svelte +45 -32
  44. package/dist/components/presentation-editor/layers/controls/side-scale-control/side-scale-control.svelte.d.ts +2 -54
  45. package/dist/components/presentation-editor/layers/index.d.ts +4 -5
  46. package/dist/components/presentation-editor/layers/index.js +7 -8
  47. package/dist/components/presentation-editor/layers/layer-button.svelte +25 -7
  48. package/dist/components/presentation-editor/layers/layer-wrapper.svelte +212 -162
  49. package/dist/components/presentation-editor/layers/layer-wrapper.svelte.d.ts +2 -2
  50. package/dist/components/presentation-editor/layers/types/background/background-content-image.svelte +41 -0
  51. package/dist/components/presentation-editor/layers/types/background/background-content-image.svelte.d.ts +8 -0
  52. package/dist/components/presentation-editor/layers/types/background/background-layer-buttons.svelte +28 -74
  53. package/dist/components/presentation-editor/layers/types/background/background-layer-buttons.svelte.d.ts +2 -17
  54. package/dist/components/presentation-editor/layers/types/background/background-layer-content.svelte +19 -0
  55. package/dist/components/presentation-editor/layers/types/background/background-layer-content.svelte.d.ts +8 -0
  56. package/dist/components/presentation-editor/layers/types/background/background-layer.svelte +69 -61
  57. package/dist/components/presentation-editor/layers/types/background/background-layer.svelte.d.ts +2 -3
  58. package/dist/components/presentation-editor/layers/types/background/index.d.ts +2 -3
  59. package/dist/components/presentation-editor/layers/types/background/index.js +2 -3
  60. package/dist/components/presentation-editor/layers/types/html/buttons/alignment-button/alignment-button.svelte +55 -12
  61. package/dist/components/presentation-editor/layers/types/html/buttons/alignment-button/alignment-button.svelte.d.ts +3 -3
  62. package/dist/components/presentation-editor/layers/types/html/buttons/bold-button/bold-button.svelte +60 -8
  63. package/dist/components/presentation-editor/layers/types/html/buttons/bold-button/bold-button.svelte.d.ts +3 -3
  64. package/dist/components/presentation-editor/layers/types/html/buttons/case-button/case-button.svelte +59 -24
  65. package/dist/components/presentation-editor/layers/types/html/buttons/case-button/case-button.svelte.d.ts +3 -3
  66. package/dist/components/presentation-editor/layers/types/html/buttons/color-button/color-button.svelte +27 -76
  67. package/dist/components/presentation-editor/layers/types/html/buttons/color-button/color-button.svelte.d.ts +3 -3
  68. package/dist/components/presentation-editor/layers/types/html/buttons/font-family-button/font-family-button.svelte +36 -0
  69. package/dist/components/presentation-editor/layers/types/html/buttons/font-family-button/font-family-button.svelte.d.ts +7 -0
  70. package/dist/components/presentation-editor/layers/types/html/buttons/font-family-button/index.d.ts +2 -0
  71. package/dist/components/presentation-editor/layers/types/html/buttons/font-family-button/index.js +2 -0
  72. package/dist/components/presentation-editor/layers/types/html/buttons/font-size-button/font-size-button.svelte +72 -29
  73. package/dist/components/presentation-editor/layers/types/html/buttons/font-size-button/font-size-button.svelte.d.ts +3 -5
  74. package/dist/components/presentation-editor/layers/types/html/buttons/italic-button/italic-button.svelte +60 -8
  75. package/dist/components/presentation-editor/layers/types/html/buttons/italic-button/italic-button.svelte.d.ts +3 -3
  76. package/dist/components/presentation-editor/layers/types/html/buttons/list-button/list-button.svelte +71 -18
  77. package/dist/components/presentation-editor/layers/types/html/buttons/list-button/list-button.svelte.d.ts +3 -3
  78. package/dist/components/presentation-editor/layers/types/html/buttons/strikethrough-button/strikethrough-button.svelte +54 -8
  79. package/dist/components/presentation-editor/layers/types/html/buttons/strikethrough-button/strikethrough-button.svelte.d.ts +3 -3
  80. package/dist/components/presentation-editor/layers/types/html/buttons/underline-button/underline-button.svelte +54 -9
  81. package/dist/components/presentation-editor/layers/types/html/buttons/underline-button/underline-button.svelte.d.ts +3 -3
  82. package/dist/components/presentation-editor/layers/types/html/editor/createEditor.js +2 -2
  83. package/dist/components/presentation-editor/layers/types/html/editor/utils.d.ts +11 -0
  84. package/dist/components/presentation-editor/layers/types/html/editor/utils.js +88 -0
  85. package/dist/components/presentation-editor/layers/types/html/extensions/font-family/font-family.d.ts +27 -0
  86. package/dist/components/presentation-editor/layers/types/html/extensions/font-family/font-family.js +40 -0
  87. package/dist/components/presentation-editor/layers/types/html/extensions/font-family/index.d.ts +3 -0
  88. package/dist/components/presentation-editor/layers/types/html/extensions/font-family/index.js +3 -0
  89. package/dist/components/presentation-editor/layers/types/html/extensions/font-size/font-size.d.ts +5 -1
  90. package/dist/components/presentation-editor/layers/types/html/extensions/font-size/font-size.js +3 -7
  91. package/dist/components/presentation-editor/layers/types/html/extensions.d.ts +1 -0
  92. package/dist/components/presentation-editor/layers/types/html/extensions.js +56 -0
  93. package/dist/components/presentation-editor/layers/types/html/html-content.svelte +26 -5
  94. package/dist/components/presentation-editor/layers/types/html/html-layer-content.svelte +26 -0
  95. package/dist/components/presentation-editor/layers/types/html/html-layer-content.svelte.d.ts +9 -0
  96. package/dist/components/presentation-editor/layers/types/html/html-layer-edit.svelte +103 -0
  97. package/dist/components/presentation-editor/layers/types/html/html-layer-edit.svelte.d.ts +8 -0
  98. package/dist/components/presentation-editor/layers/types/html/html-layer.svelte +61 -53
  99. package/dist/components/presentation-editor/layers/types/html/index.d.ts +3 -5
  100. package/dist/components/presentation-editor/layers/types/html/index.js +3 -56
  101. package/dist/components/presentation-editor/layers/types/image/{image-content.svelte → image-layer-content.svelte} +11 -3
  102. package/dist/components/presentation-editor/layers/types/image/image-layer-content.svelte.d.ts +8 -0
  103. package/dist/components/presentation-editor/layers/types/image/image-layer.svelte +51 -21
  104. package/dist/components/presentation-editor/layers/types/image/index.d.ts +2 -4
  105. package/dist/components/presentation-editor/layers/types/image/index.js +2 -4
  106. package/dist/components/presentation-editor/layers/utils.d.ts +68 -9
  107. package/dist/components/presentation-editor/layers/utils.js +260 -25
  108. package/dist/components/presentation-editor/menu/background-menu-content.svelte +80 -0
  109. package/dist/components/presentation-editor/menu/background-menu-content.svelte.d.ts +9 -0
  110. package/dist/components/presentation-editor/menu/layer-menu-content.svelte +183 -0
  111. package/dist/components/presentation-editor/menu/layer-menu-content.svelte.d.ts +3 -0
  112. package/dist/components/presentation-editor/menu/slide-menu-content.svelte +67 -0
  113. package/dist/components/presentation-editor/menu/slide-menu-content.svelte.d.ts +9 -0
  114. package/dist/components/presentation-editor/presentation-editor.svelte +120 -176
  115. package/dist/components/presentation-editor/presentation-editor.svelte.d.ts +1 -4
  116. package/dist/components/presentation-editor/presentation-editor.svelte.js +597 -136
  117. package/dist/components/presentation-editor/sidebar/color-sidebar/color-sidebar-color.svelte +58 -0
  118. package/dist/components/presentation-editor/sidebar/color-sidebar/color-sidebar-color.svelte.d.ts +10 -0
  119. package/dist/components/presentation-editor/sidebar/color-sidebar/color-sidebar-gradient-picker.svelte +144 -0
  120. package/dist/components/presentation-editor/sidebar/color-sidebar/color-sidebar-gradient-picker.svelte.d.ts +7 -0
  121. package/dist/components/presentation-editor/sidebar/color-sidebar/color-sidebar.svelte +404 -0
  122. package/dist/components/presentation-editor/sidebar/color-sidebar/color-sidebar.svelte.d.ts +3 -0
  123. package/dist/components/presentation-editor/sidebar/color-sidebar/index.d.ts +2 -0
  124. package/dist/components/presentation-editor/sidebar/color-sidebar/index.js +2 -0
  125. package/dist/components/presentation-editor/sidebar/font-sidebar/font-sidebar-button.svelte +26 -0
  126. package/dist/components/presentation-editor/sidebar/font-sidebar/font-sidebar-button.svelte.d.ts +8 -0
  127. package/dist/components/presentation-editor/sidebar/font-sidebar/font-sidebar.svelte +216 -0
  128. package/dist/components/presentation-editor/sidebar/font-sidebar/font-sidebar.svelte.d.ts +3 -0
  129. package/dist/components/presentation-editor/sidebar/font-sidebar/index.d.ts +2 -0
  130. package/dist/components/presentation-editor/sidebar/font-sidebar/index.js +2 -0
  131. package/dist/components/presentation-editor/sidebar/position-slidebar.svelte +130 -0
  132. package/dist/components/presentation-editor/sidebar/position-slidebar.svelte.d.ts +18 -0
  133. package/dist/components/presentation-editor/sidebar/sidebar-text-tab-button.svelte +90 -0
  134. package/dist/components/presentation-editor/sidebar/sidebar-text-tab-button.svelte.d.ts +7 -0
  135. package/dist/components/presentation-editor/sidebar/sidebar-text-tab.svelte +82 -0
  136. package/dist/components/presentation-editor/sidebar/sidebar-text-tab.svelte.d.ts +18 -0
  137. package/dist/components/presentation-editor/sidebar/{images-library.svelte → sidebar-uploads-tab.svelte} +0 -1
  138. package/dist/components/presentation-editor/sidebar/sidebar-uploads-tab.svelte.d.ts +3 -0
  139. package/dist/components/presentation-editor/sidebar/sidebar-wrapper.svelte +25 -0
  140. package/dist/components/presentation-editor/sidebar/sidebar-wrapper.svelte.d.ts +7 -0
  141. package/dist/components/presentation-editor/sidebar/sidebar.svelte +71 -15
  142. package/dist/components/presentation-editor/sidebar/sidebar.svelte.d.ts +16 -5
  143. package/dist/components/presentation-editor/sidebar/uploads-image.svelte +28 -11
  144. package/dist/components/presentation-editor/slide-editor.svelte +20 -22
  145. package/dist/components/presentation-editor/slide-inner.svelte +19 -18
  146. package/dist/components/presentation-editor/slides-navigation/slide-preview.svelte +61 -52
  147. package/dist/components/presentation-editor/slides-navigation/slides-navigation.svelte +6 -8
  148. package/dist/components/presentation-editor/snapping-guides.svelte +3 -3
  149. package/dist/components/presentation-editor/types.d.ts +67 -27
  150. package/dist/components/presentation-editor/utils.d.ts +50 -1
  151. package/dist/components/presentation-editor/utils.js +101 -6
  152. package/dist/components/ui/button/button.svelte +3 -2
  153. package/dist/components/ui/button/button.svelte.d.ts +5 -82
  154. package/dist/components/ui/color-picker/color-picker-alpha-grid.svelte +43 -0
  155. package/dist/components/ui/color-picker/color-picker-alpha-grid.svelte.d.ts +8 -0
  156. package/dist/components/ui/color-picker/color-picker.svelte +344 -0
  157. package/dist/components/ui/color-picker/color-picker.svelte.d.ts +13 -0
  158. package/dist/components/ui/color-picker/index.d.ts +3 -0
  159. package/dist/components/ui/color-picker/index.js +5 -0
  160. package/dist/components/ui/context-menu/context-menu-shortcut.svelte +6 -3
  161. package/dist/components/ui/context-menu/context-menu-sub-trigger.svelte +1 -1
  162. package/dist/components/ui/dropdown-menu/dropdown-menu-item.svelte +1 -1
  163. package/dist/components/ui/dropdown-menu/dropdown-menu-shortcut.svelte +6 -3
  164. package/dist/components/ui/dropdown-menu/dropdown-menu-sub-trigger.svelte +1 -1
  165. package/dist/components/ui/infinite-loader/index.d.ts +4 -0
  166. package/dist/components/ui/infinite-loader/index.js +4 -0
  167. package/dist/components/ui/infinite-loader/infinite-loader-loop-tracker.d.ts +13 -0
  168. package/dist/components/ui/infinite-loader/infinite-loader-loop-tracker.js +44 -0
  169. package/dist/components/ui/infinite-loader/infinite-loader-state.svelte.d.ts +15 -0
  170. package/dist/components/ui/infinite-loader/infinite-loader-state.svelte.js +28 -0
  171. package/dist/components/ui/infinite-loader/infinite-loader.svelte +149 -0
  172. package/dist/components/ui/infinite-loader/infinite-loader.svelte.d.ts +17 -0
  173. package/dist/components/ui/input/input.svelte +1 -1
  174. package/dist/components/ui/slider/slider.svelte +20 -18
  175. package/dist/components/ui/tabs/index.d.ts +6 -0
  176. package/dist/components/ui/tabs/index.js +8 -0
  177. package/dist/components/ui/tabs/tabs-content.svelte +19 -0
  178. package/dist/components/ui/tabs/tabs-content.svelte.d.ts +4 -0
  179. package/dist/components/ui/tabs/tabs-list.svelte +19 -0
  180. package/dist/components/ui/tabs/tabs-list.svelte.d.ts +4 -0
  181. package/dist/components/ui/tabs/tabs-trigger.svelte +19 -0
  182. package/dist/components/ui/tabs/tabs-trigger.svelte.d.ts +4 -0
  183. package/dist/components/ui/toggle/toggle.svelte +3 -2
  184. package/dist/components/ui/toggle/toggle.svelte.d.ts +2 -46
  185. package/dist/index.d.ts +5 -6
  186. package/dist/index.js +1 -4
  187. package/dist/plugin.js +3 -2
  188. package/dist/utils.d.ts +1 -0
  189. package/dist/utils.js +1 -0
  190. package/package.json +28 -25
  191. package/dist/components/presentation-editor/app.css +0 -12
  192. package/dist/components/presentation-editor/layers/hovered-layer.svelte +0 -34
  193. package/dist/components/presentation-editor/layers/hovered-layer.svelte.d.ts +0 -7
  194. package/dist/components/presentation-editor/layers/types/background/background-content.svelte +0 -11
  195. package/dist/components/presentation-editor/layers/types/background/background-content.svelte.d.ts +0 -7
  196. package/dist/components/presentation-editor/layers/types/background/background-layer-thumb.svelte +0 -12
  197. package/dist/components/presentation-editor/layers/types/background/background-layer-thumb.svelte.d.ts +0 -7
  198. package/dist/components/presentation-editor/layers/types/html/html-layer-active.svelte +0 -159
  199. package/dist/components/presentation-editor/layers/types/html/html-layer-active.svelte.d.ts +0 -8
  200. package/dist/components/presentation-editor/layers/types/html/html-layer-buttons.svelte +0 -42
  201. package/dist/components/presentation-editor/layers/types/html/html-layer-buttons.svelte.d.ts +0 -10
  202. package/dist/components/presentation-editor/layers/types/html/html-layer-thumb.svelte +0 -24
  203. package/dist/components/presentation-editor/layers/types/html/html-layer-thumb.svelte.d.ts +0 -8
  204. package/dist/components/presentation-editor/layers/types/image/image-content.svelte.d.ts +0 -8
  205. package/dist/components/presentation-editor/layers/types/image/image-layer-buttons.svelte +0 -21
  206. package/dist/components/presentation-editor/layers/types/image/image-layer-buttons.svelte.d.ts +0 -7
  207. package/dist/components/presentation-editor/layers/types/image/image-layer-thumb.svelte +0 -13
  208. package/dist/components/presentation-editor/layers/types/image/image-layer-thumb.svelte.d.ts +0 -8
  209. package/dist/components/presentation-editor/sidebar/images-library.svelte.d.ts +0 -3
  210. package/dist/components/presentation-editor/sidebar/layers.svelte +0 -94
  211. package/dist/components/presentation-editor/slides-navigation/buttons/slide-delete-button.svelte +0 -32
  212. package/dist/components/presentation-editor/slides-navigation/buttons/slide-delete-button.svelte.d.ts +0 -10
  213. package/dist/components/presentation-editor/slides-navigation/buttons/slide-duplicate-button.svelte +0 -34
  214. package/dist/components/presentation-editor/slides-navigation/buttons/slide-duplicate-button.svelte.d.ts +0 -10
@@ -0,0 +1,344 @@
1
+ <script lang="ts">
2
+ import DeleteIcon from 'lucide-svelte/icons/trash-2';
3
+ import PipetteIcon from 'lucide-svelte/icons/pipette';
4
+ import { untrack } from 'svelte';
5
+ import { Slider } from 'bits-ui';
6
+ import { BROWSER } from 'esm-env';
7
+ import { cn } from '../../../utils.js';
8
+ import type { ChangeEventHandler, FormEventHandler } from 'svelte/elements';
9
+ import { Button } from '../button/index.js';
10
+ import { AlphaGrid } from './index.js';
11
+ import { Input } from '../input/index.js';
12
+
13
+ const defaultColor: string = '#ff0000';
14
+
15
+ interface Props {
16
+ hex?: string;
17
+ alpha?: boolean;
18
+ onChange?: (color: { rgb: number[]; a: number; hex: string }) => void;
19
+ onDelete?: () => void;
20
+ }
21
+
22
+ let {
23
+ hex: startColor = $bindable(defaultColor),
24
+ alpha = false,
25
+ onChange = () => null,
26
+ onDelete,
27
+ }: Props = $props();
28
+
29
+ let pickerRef = $state() as HTMLDivElement;
30
+
31
+ let isMouseDown = false;
32
+
33
+ const parsed = parseHex(startColor);
34
+ let h = $state(parsed?.hsva.h ?? 360);
35
+ let s = $state(parsed?.hsva.s ?? 1);
36
+ let v = $state(parsed?.hsva.v ?? 1);
37
+ let a = $state(parsed?.hsva.a ?? 1);
38
+
39
+ let hexValue = $state(parsed?.hex || defaultColor);
40
+
41
+ const pickedColor = $derived(hsvToRgb(h, 1, 1));
42
+ const rgb = $derived(hsvToRgb(h, s, v));
43
+
44
+ let invalidHex = $state(false);
45
+
46
+ const eyeDropper = BROWSER && 'EyeDropper' in window ? new (window as any).EyeDropper() : null;
47
+
48
+ function openEyedropper() {
49
+ eyeDropper.open().then((result: { sRGBHex: string }) => {
50
+ updateFromHex(result.sRGBHex);
51
+ });
52
+ }
53
+
54
+ function updateFromHex(hex: string) {
55
+ const parsed = parseHex(hex);
56
+ if (!parsed) return;
57
+
58
+ ({ h, s, v, a } = parsed.hsva);
59
+ }
60
+
61
+ $effect(() => {
62
+ if (startColor !== untrack(() => hexValue)) {
63
+ updateFromHex(startColor);
64
+ }
65
+ });
66
+
67
+ function isValidHexColor(hex: string) {
68
+ return new RegExp(`^#([0-9A-F]{${alpha ? 4 : 3}}){2}$`, 'i').test(hex);
69
+ }
70
+
71
+ function hexToRgba(hex: string) {
72
+ const r = parseInt(hex.substring(1, 3), 16);
73
+ const g = parseInt(hex.substring(3, 5), 16);
74
+ const b = parseInt(hex.substring(5, 7), 16);
75
+ const a = hex.length > 7 ? parseInt(hex.substring(7, 9), 16) : 255;
76
+
77
+ return { r, g, b, a };
78
+ }
79
+
80
+ function parseHex(hex: string) {
81
+ if (!isValidHexColor(hex)) {
82
+ console.error('Invalid property value (startColor)', { hex, alpha });
83
+ return;
84
+ }
85
+ const rbga = hexToRgba(hex);
86
+
87
+ return { hex, rbga, hsva: rgbaToHsva(rbga) };
88
+ }
89
+
90
+ function round(val: number) {
91
+ return Math.round(val * 1000) / 1000;
92
+ }
93
+
94
+ function clamp(value: number, min: number, max: number): number {
95
+ return Math.min(Math.max(min, value), max);
96
+ }
97
+
98
+ function onClick(e: { clientX: number; clientY: number }) {
99
+ if (!pickerRef) return;
100
+
101
+ const { width, left, height, top } = pickerRef.getBoundingClientRect();
102
+ const mouse = {
103
+ x: clamp(e.clientX - left, 0, width),
104
+ y: clamp(e.clientY - top, 0, height),
105
+ };
106
+
107
+ s = clamp(mouse.x / width, 0, 1);
108
+ v = clamp((height - mouse.y) / height, 0, 1);
109
+ }
110
+
111
+ function onMouseDown(event: MouseEvent) {
112
+ if (event.button === 0) {
113
+ isMouseDown = true;
114
+ onClick(event);
115
+ }
116
+ }
117
+
118
+ function onMouseUp() {
119
+ isMouseDown = false;
120
+ }
121
+
122
+ function onMouseMove(event: MouseEvent) {
123
+ if (isMouseDown) onClick(event);
124
+ }
125
+
126
+ function onTouch(e: TouchEvent) {
127
+ onClick(e.changedTouches[0]);
128
+ }
129
+
130
+ function toHex(value: number) {
131
+ return value.toString(16).padStart(2, '0');
132
+ }
133
+
134
+ function RGBAToHex(r: number, g: number, b: number) {
135
+ const values = [r, g, b].map(toHex);
136
+
137
+ if (alpha) {
138
+ values.push(toHex(Math.round(a * 255)));
139
+ }
140
+
141
+ return `#${values.join('')}`.toLowerCase();
142
+ }
143
+
144
+ function colorChange() {
145
+ let rgb = hsvToRgb(h, s, v);
146
+ const [r, g, b] = rgb;
147
+ hexValue = RGBAToHex(r, g, b);
148
+ invalidHex = false;
149
+ if (startColor !== hexValue) {
150
+ startColor = hexValue;
151
+ onChange({ rgb, a: a, hex: hexValue });
152
+ }
153
+ }
154
+
155
+ //Math algorithms
156
+ function hsvToRgb(h: number, s: number, v: number) {
157
+ const i = Math.floor(h / 60);
158
+ const f = h / 60 - i;
159
+ const p = v * (1 - s);
160
+ const q = v * (1 - f * s);
161
+ const t = v * (1 - (1 - f) * s);
162
+
163
+ const rgbMap = [
164
+ [v, t, p],
165
+ [q, v, p],
166
+ [p, v, t],
167
+ [p, q, v],
168
+ [t, p, v],
169
+ [v, p, q],
170
+ ];
171
+
172
+ const [r, g, b] = rgbMap[i % 6];
173
+ return [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255)];
174
+ }
175
+
176
+ function rgbaToHsva({ r, g, b, a }: { r: number; g: number; b: number; a: number }) {
177
+ const rperc = r / 255;
178
+ const gperc = g / 255;
179
+ const bperc = b / 255;
180
+ const aperc = a / 255;
181
+
182
+ const max = Math.max(rperc, gperc, bperc);
183
+ const min = Math.min(rperc, gperc, bperc);
184
+ const diff = max - min;
185
+
186
+ let hnew = 0;
187
+ const snew = max === 0 ? 0 : diff / max;
188
+ const vnew = max;
189
+
190
+ if (diff !== 0) {
191
+ if (max === rperc) {
192
+ hnew = (60 * ((gperc - bperc) / diff) + 360) % 360;
193
+ } else if (max === gperc) {
194
+ hnew = (60 * ((bperc - rperc) / diff) + 120) % 360;
195
+ } else if (max === bperc) {
196
+ hnew = (60 * ((rperc - gperc) / diff) + 240) % 360;
197
+ }
198
+ }
199
+
200
+ return { h: round(hnew), s: round(snew), v: round(vnew), a: round(aperc) };
201
+ }
202
+
203
+ $effect(() => {
204
+ if (h || s || v || a) colorChange();
205
+ });
206
+
207
+ const buildHexFromInputVal = (val: string) =>
208
+ '#' + val + (alpha ? toHex(Math.round(a * 255)) : '');
209
+
210
+ const onHexInput: FormEventHandler<HTMLInputElement> = (e) => {
211
+ console.log('onHexInput', e);
212
+ invalidHex = !isValidHexColor(buildHexFromInputVal(e.currentTarget.value));
213
+ };
214
+
215
+ const onHexChange: ChangeEventHandler<HTMLInputElement> = (e) => {
216
+ console.log('onHexChange', e);
217
+ const hex = buildHexFromInputVal(e.currentTarget.value);
218
+ if (isValidHexColor(hex)) {
219
+ updateFromHex(hex);
220
+ }
221
+ };
222
+ </script>
223
+
224
+ <svelte:window onmouseup={onMouseUp} onmousemove={onMouseMove} />
225
+
226
+ <div class="w-full select-none">
227
+ <div
228
+ class="h-28 overflow-hidden rounded-lg"
229
+ style:background={`rgb(${pickedColor[0]},${pickedColor[1]},${pickedColor[2]})`}
230
+ >
231
+ <div
232
+ class="h-full"
233
+ style:background="linear-gradient(to right, rgb(255, 255, 255), rgba(255, 255, 255, 0))"
234
+ >
235
+ <div
236
+ class="h-full overflow-hidden"
237
+ style:background="linear-gradient(to top, rgb(0, 0, 0), rgba(0, 0, 0, 0))"
238
+ >
239
+ <div
240
+ class="border-primary relative m-0 -translate-x-1/2 -translate-y-1/2 rounded-full p-0"
241
+ style:width="16px"
242
+ style:height="16px"
243
+ style:border="2px solid #fffb"
244
+ style:top="{(1 - v) * 100}%"
245
+ style:left="{s * 100}%"
246
+ ></div>
247
+ <!-- svelte-ignore a11y_no_static_element_interactions -->
248
+ <div
249
+ bind:this={pickerRef}
250
+ id="colorsquare-event"
251
+ class="relative h-full w-full touch-none"
252
+ style:translate="0 -16px"
253
+ onmousedown={onMouseDown}
254
+ ontouchstart={onTouch}
255
+ ontouchmove={onTouch}
256
+ ontouchend={onTouch}
257
+ ></div>
258
+ </div>
259
+ </div>
260
+ </div>
261
+
262
+ <div class="mx-1 my-2.5">
263
+ <Slider.Root
264
+ type="single"
265
+ bind:value={h}
266
+ min={0}
267
+ max={360}
268
+ step={0.001}
269
+ class="relative flex w-full touch-none select-none items-center"
270
+ >
271
+ {#snippet children()}
272
+ <span
273
+ class="relative -mx-1 h-3 w-full grow cursor-pointer overflow-hidden rounded-full"
274
+ style:background="linear-gradient(to right, red, yellow, lime, cyan, blue, magenta, red)"
275
+ ></span>
276
+ <Slider.Thumb
277
+ index={0}
278
+ class="border-border-input bg-background hover:border-dark-40 dark:bg-foreground dark:shadow-card block size-2 cursor-pointer rounded-full border shadow transition-colors focus-visible:outline-none active:scale-150"
279
+ />
280
+ {/snippet}
281
+ </Slider.Root>
282
+ </div>
283
+
284
+ {#if alpha}
285
+ <div class="mx-1 my-2.5">
286
+ <Slider.Root
287
+ type="single"
288
+ bind:value={a}
289
+ min={0}
290
+ max={1}
291
+ step={0.001}
292
+ class="relative flex w-full touch-none select-none items-center"
293
+ >
294
+ {#snippet children()}
295
+ <AlphaGrid
296
+ size={8}
297
+ class="shadow-inner-1 relative -mx-1 h-3 w-full grow cursor-pointer overflow-hidden rounded-full"
298
+ >
299
+ <div
300
+ class="h-full w-full rounded-full"
301
+ style:background-image="linear-gradient(to right, transparent, rgb({rgb[0]},{rgb[1]},{rgb[2]}))"
302
+ ></div>
303
+ </AlphaGrid>
304
+ <Slider.Thumb
305
+ index={0}
306
+ class="border-border-input bg-background hover:border-dark-40 dark:bg-foreground dark:shadow-card block size-2 cursor-pointer rounded-full border shadow transition-colors focus-visible:outline-none active:scale-150"
307
+ />
308
+ {/snippet}
309
+ </Slider.Root>
310
+ </div>
311
+ {/if}
312
+
313
+ <div class="flex w-full items-center gap-2">
314
+ {#if onDelete}
315
+ <Button variant="outline" size="icon" class="shrink-0" onclick={onDelete}>
316
+ <DeleteIcon />
317
+ </Button>
318
+ {/if}
319
+ <div class="relative flex flex-1 items-center">
320
+ <div class="pointer-events-none absolute flex w-10 justify-center">
321
+ <div class="size-6 overflow-hidden rounded-full">
322
+ <AlphaGrid size={12}>
323
+ <div
324
+ class="h-full w-full"
325
+ style:background-color="rgba({rgb[0]},{rgb[1]},{rgb[2]},{a})"
326
+ ></div>
327
+ </AlphaGrid>
328
+ </div>
329
+ </div>
330
+ <div class="text-muted-foreground pointer-events-none absolute left-10 text-sm">#</div>
331
+ <Input
332
+ class={cn('pl-12', invalidHex && 'ring-destructive ring-1')}
333
+ value={hexValue.slice(0, 7).replace('#', '')}
334
+ oninput={onHexInput}
335
+ onchange={onHexChange}
336
+ />
337
+ </div>
338
+ {#if eyeDropper}
339
+ <Button variant="outline" size="icon" class="shrink-0" onclick={() => openEyedropper()}>
340
+ <PipetteIcon />
341
+ </Button>
342
+ {/if}
343
+ </div>
344
+ </div>
@@ -0,0 +1,13 @@
1
+ interface Props {
2
+ hex?: string;
3
+ alpha?: boolean;
4
+ onChange?: (color: {
5
+ rgb: number[];
6
+ a: number;
7
+ hex: string;
8
+ }) => void;
9
+ onDelete?: () => void;
10
+ }
11
+ declare const ColorPicker: import("svelte").Component<Props, {}, "hex">;
12
+ type ColorPicker = ReturnType<typeof ColorPicker>;
13
+ export default ColorPicker;
@@ -0,0 +1,3 @@
1
+ import Root from './color-picker.svelte';
2
+ import AlphaGrid from './color-picker-alpha-grid.svelte';
3
+ export { Root, AlphaGrid, Root as ColorPicker, AlphaGrid as ColorPickerAlphaGrid, };
@@ -0,0 +1,5 @@
1
+ import Root from './color-picker.svelte';
2
+ import AlphaGrid from './color-picker-alpha-grid.svelte';
3
+ export { Root, AlphaGrid,
4
+ //
5
+ Root as ColorPicker, AlphaGrid as ColorPickerAlphaGrid, };
@@ -11,10 +11,13 @@
11
11
  }: WithElementRef<HTMLAttributes<HTMLSpanElement>> = $props();
12
12
  </script>
13
13
 
14
- <span
14
+ <kbd
15
15
  bind:this={ref}
16
- class={cn('text-muted-foreground ml-auto text-xs tracking-widest', className)}
16
+ class={cn(
17
+ 'bg-muted text-muted-foreground ml-auto rounded-sm px-2 py-1 font-sans text-xs tracking-widest',
18
+ className,
19
+ )}
17
20
  {...restProps}
18
21
  >
19
22
  {@render children?.()}
20
- </span>
23
+ </kbd>
@@ -17,7 +17,7 @@
17
17
  <ContextMenuPrimitive.SubTrigger
18
18
  bind:ref
19
19
  class={cn(
20
- 'data-[highlighted]:bg-accent data-[state=open]:bg-accent data-[highlighted]:text-accent-foreground data-[state=open]:text-accent-foreground flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none',
20
+ 'data-[highlighted]:bg-accent data-[state=open]:bg-accent data-[highlighted]:text-accent-foreground data-[state=open]:text-accent-foreground flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50',
21
21
  inset && 'pl-8',
22
22
  className,
23
23
  )}
@@ -15,7 +15,7 @@
15
15
  <DropdownMenuPrimitive.Item
16
16
  bind:ref
17
17
  class={cn(
18
- 'relative flex cursor-default select-none items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none transition-colors data-[disabled]:pointer-events-none data-[highlighted]:bg-accent data-[highlighted]:text-accent-foreground data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0',
18
+ 'data-[highlighted]:bg-accent data-[highlighted]:text-accent-foreground relative flex cursor-default select-none items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none transition-colors data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0',
19
19
  inset && 'pl-8',
20
20
  className,
21
21
  )}
@@ -11,10 +11,13 @@
11
11
  }: WithElementRef<HTMLAttributes<HTMLSpanElement>> = $props();
12
12
  </script>
13
13
 
14
- <span
14
+ <kbd
15
15
  bind:this={ref}
16
- class={cn('ml-auto text-xs tracking-widest opacity-60', className)}
16
+ class={cn(
17
+ 'bg-muted text-muted-foreground ml-auto rounded-sm px-2 py-1 font-sans text-xs tracking-widest',
18
+ className,
19
+ )}
17
20
  {...restProps}
18
21
  >
19
22
  {@render children?.()}
20
- </span>
23
+ </kbd>
@@ -17,7 +17,7 @@
17
17
  <DropdownMenuPrimitive.SubTrigger
18
18
  bind:ref
19
19
  class={cn(
20
- 'flex cursor-default select-none items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none data-[highlighted]:bg-accent data-[state=open]:bg-accent [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0',
20
+ 'data-[state=open]:bg-accent data-[highlighted]:bg-accent flex cursor-default select-none items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0',
21
21
  inset && 'pl-8',
22
22
  className,
23
23
  )}
@@ -0,0 +1,4 @@
1
+ import InfiniteLoader from './infinite-loader.svelte';
2
+ import { LoaderState } from './infinite-loader-state.svelte.js';
3
+ import { LoopTracker } from './infinite-loader-loop-tracker.js';
4
+ export { InfiniteLoader, LoaderState, LoopTracker };
@@ -0,0 +1,4 @@
1
+ import InfiniteLoader from './infinite-loader.svelte';
2
+ import { LoaderState } from './infinite-loader-state.svelte.js';
3
+ import { LoopTracker } from './infinite-loader-loop-tracker.js';
4
+ export { InfiniteLoader, LoaderState, LoopTracker };
@@ -0,0 +1,13 @@
1
+ type LoopTrackerOptions = {
2
+ loopTimeout?: number;
3
+ loopDetectionTimeout?: number;
4
+ loopMaxCalls?: number;
5
+ };
6
+ export declare class LoopTracker {
7
+ #private;
8
+ coolingOff: boolean;
9
+ constructor(options: LoopTrackerOptions);
10
+ track(): void;
11
+ destroy(): void;
12
+ }
13
+ export {};
@@ -0,0 +1,44 @@
1
+ // Track load counts to avoid infinite loops
2
+ export class LoopTracker {
3
+ coolingOff = false;
4
+ #coolingOffTimer = null;
5
+ #timer = null;
6
+ #count = 0;
7
+ #options = {
8
+ timeout: 3000,
9
+ detectionTimeout: 2000,
10
+ maxCalls: 5,
11
+ };
12
+ constructor(options) {
13
+ Object.assign(this.#options, options);
14
+ }
15
+ // On each call, increment the count and reset the timer
16
+ track() {
17
+ this.#count += 1;
18
+ if (this.#timer) {
19
+ clearTimeout(this.#timer);
20
+ }
21
+ // Cooldown, after 2s, reset count to 0
22
+ this.#timer = setTimeout(() => {
23
+ this.#count = 0;
24
+ }, this.#options.detectionTimeout);
25
+ // If count > loopMaxCalls, begin cool-down period
26
+ // and start timer to reset loop count tracker
27
+ if (this.#count >= this.#options.maxCalls) {
28
+ console.error(`Attempted to execute load function ${this.#options.maxCalls} or more times within a short period. Please wait before trying again..`);
29
+ this.coolingOff = true;
30
+ this.#coolingOffTimer = setTimeout(() => {
31
+ this.coolingOff = false;
32
+ this.#count = 0;
33
+ }, this.#options.timeout);
34
+ }
35
+ }
36
+ destroy() {
37
+ if (this.#timer) {
38
+ clearTimeout(this.#timer);
39
+ }
40
+ if (this.#coolingOffTimer) {
41
+ clearTimeout(this.#coolingOffTimer);
42
+ }
43
+ }
44
+ }
@@ -0,0 +1,15 @@
1
+ export declare const STATUS: {
2
+ readonly READY: "READY";
3
+ readonly LOADING: "LOADING";
4
+ readonly COMPLETE: "COMPLETE";
5
+ readonly ERROR: "ERROR";
6
+ };
7
+ export declare class LoaderState {
8
+ isFirstLoad: boolean;
9
+ status: "READY" | "LOADING" | "COMPLETE" | "ERROR";
10
+ mounted: boolean;
11
+ loaded: () => void;
12
+ complete: () => void;
13
+ reset: () => void;
14
+ error: () => void;
15
+ }
@@ -0,0 +1,28 @@
1
+ export const STATUS = {
2
+ READY: 'READY',
3
+ LOADING: 'LOADING',
4
+ COMPLETE: 'COMPLETE',
5
+ ERROR: 'ERROR',
6
+ };
7
+ export class LoaderState {
8
+ isFirstLoad = $state(true);
9
+ status = $state(STATUS.READY);
10
+ mounted = $state(false);
11
+ loaded = () => {
12
+ if (this.isFirstLoad)
13
+ this.isFirstLoad = false;
14
+ this.status = STATUS.READY;
15
+ };
16
+ complete = () => {
17
+ if (this.isFirstLoad)
18
+ this.isFirstLoad = false;
19
+ this.status = STATUS.COMPLETE;
20
+ };
21
+ reset = () => {
22
+ this.isFirstLoad = true;
23
+ this.status = STATUS.READY;
24
+ };
25
+ error = () => {
26
+ this.status = STATUS.ERROR;
27
+ };
28
+ }