compote-ui 0.19.5 → 0.20.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.
@@ -11,6 +11,9 @@
11
11
  }: CarouselItemProps & { children?: Snippet } = $props();
12
12
  </script>
13
13
 
14
- <Carousel.Item class={cn('min-w-0 flex-[0_0_100%] data-[orientation=vertical]:min-h-0', className)} {...rest}>
14
+ <Carousel.Item
15
+ class={cn('min-w-0 flex-[0_0_100%] data-[orientation=vertical]:min-h-0', className)}
16
+ {...rest}
17
+ >
15
18
  {@render children?.()}
16
19
  </Carousel.Item>
@@ -1,5 +1,5 @@
1
1
  <script lang="ts">
2
- import PhArrowRight from '../../icons/PhArrowRight.svelte';
2
+ import { PhArrowRight } from '../../icons';
3
3
  import { Carousel } from '@ark-ui/svelte/carousel';
4
4
  import type { CarouselNextTriggerProps } from '@ark-ui/svelte/carousel';
5
5
  import { cn } from 'tailwind-variants';
@@ -1,5 +1,5 @@
1
1
  <script lang="ts">
2
- import PhArrowLeft from '../../icons/PhArrowLeft.svelte';
2
+ import { PhArrowLeft } from '../../icons';
3
3
  import { Carousel } from '@ark-ui/svelte/carousel';
4
4
  import type { CarouselPrevTriggerProps } from '@ark-ui/svelte/carousel';
5
5
  import { cn } from 'tailwind-variants';
@@ -1,8 +1,7 @@
1
1
  <script lang="ts">
2
2
  import { Checkbox } from '@ark-ui/svelte/checkbox';
3
3
  import type { CheckboxProps as Props } from './checkbox.types.js';
4
- import PhCheck from '../../icons/PhCheck.svelte';
5
- import PhMinus from '../../icons/PhMinus.svelte';
4
+ import { PhCheck, PhMinus } from '../../icons';
6
5
 
7
6
  let { checked = $bindable(), label, children, ...rest }: Props = $props();
8
7
  </script>
@@ -6,9 +6,7 @@
6
6
  import type { ComboboxProps } from './types';
7
7
  import { createListCollection, type ListItem } from '../../utils/collections';
8
8
  import { cn } from 'tailwind-variants';
9
- import PhCaretDown from '../../icons/PhCaretDown.svelte';
10
- import PhCheck from '../../icons/PhCheck.svelte';
11
- import PhX from '../../icons/PhX.svelte';
9
+ import { PhCaretDown, PhCheck, PhX } from '../../icons';
12
10
 
13
11
  let {
14
12
  value = $bindable(),
@@ -1,5 +1,5 @@
1
1
  <script lang="ts">
2
- import PhX from '../../icons/PhX.svelte';
2
+ import { PhX } from '../../icons';
3
3
  import { Dialog } from '@ark-ui/svelte/dialog';
4
4
  import { Portal } from '@ark-ui/svelte/portal';
5
5
  import type { AlertDialogProps } from './dialog.types';
@@ -2,7 +2,7 @@
2
2
  import { Dialog } from '@ark-ui/svelte/dialog';
3
3
  import { Portal } from '@ark-ui/svelte/portal';
4
4
  import { cn } from 'tailwind-variants';
5
- import PhX from '../../icons/PhX.svelte';
5
+ import { PhX } from '../../icons';
6
6
  import type { DialogProps } from './dialog.types';
7
7
 
8
8
  let {
@@ -2,7 +2,7 @@
2
2
  import { FileUpload } from '@ark-ui/svelte/file-upload';
3
3
  import { getAcceptAttribute } from './utils';
4
4
  import type { FileUploadDropzoneProps } from './types';
5
- import PhUploadSimple from '../../icons/PhUploadSimple.svelte';
5
+ import { PhUploadSimple } from '../../icons';
6
6
 
7
7
  let {
8
8
  fileType,
@@ -1,6 +1,6 @@
1
1
  <script lang="ts">
2
2
  import { FileUpload, type FileUploadFileError } from '@ark-ui/svelte/file-upload';
3
- import PhX from '../../icons/PhX.svelte';
3
+ import { PhX } from '../../icons';
4
4
  import type { FileUploadProps } from './types';
5
5
  import { getAcceptAttribute } from './utils';
6
6
  import { getFileIcon } from './icons';
@@ -1,10 +1,4 @@
1
- import PhFile from '../../icons/PhFile.svelte';
2
- import PhFileArchive from '../../icons/PhFileArchive.svelte';
3
- import PhFileText from '../../icons/PhFileText.svelte';
4
- import PhImage from '../../icons/PhImage.svelte';
5
- import PhMicrosoftExcelLogo from '../../icons/PhMicrosoftExcelLogo.svelte';
6
- import PhVideoCamera from '../../icons/PhVideoCamera.svelte';
7
- import PhHeadphones from '../../icons/PhHeadphones.svelte';
1
+ import { PhFile, PhFileArchive, PhFileText, PhHeadphones, PhImage, PhMicrosoftExcelLogo, PhVideoCamera } from '../../icons';
8
2
  export const getFileIcon = (file) => {
9
3
  const fileType = file.type;
10
4
  const fileName = file.name;
@@ -4,11 +4,14 @@
4
4
  import { Button } from '../..';
5
5
  import { cropImage } from '../../utils/image-processing';
6
6
  import type { ProcessImageOptions } from '../../utils/image-processing';
7
+ import { PhArrowClockwise, PhArrowCounterClockwise } from '../../icons';
7
8
 
8
9
  let {
9
10
  src,
10
11
  alt = 'Image',
11
12
  aspectRatio = $bindable(),
13
+ rotation = $bindable(0),
14
+ onRotationChange,
12
15
  // eslint-disable-next-line no-useless-assignment
13
16
  getCroppedImage = $bindable(),
14
17
  // eslint-disable-next-line no-useless-assignment
@@ -41,7 +44,15 @@
41
44
  };
42
45
  });
43
46
 
44
- const imageCropper = useImageCropper(() => ({ ...cropperProps, aspectRatio }));
47
+ const imageCropper = useImageCropper(() => ({
48
+ ...cropperProps,
49
+ aspectRatio,
50
+ rotation,
51
+ onRotationChange: (e) => {
52
+ rotation = e.rotation;
53
+ onRotationChange?.(e);
54
+ }
55
+ }));
45
56
 
46
57
  // eslint-disable-next-line no-useless-assignment
47
58
  getCroppedImage = (options) => imageCropper().getCroppedImage(options);
@@ -56,25 +67,47 @@
56
67
 
57
68
  <div>
58
69
  <div class="mb-2 flex flex-wrap items-center justify-between gap-1.5">
59
- <div>
60
- {#each ASPECT_RATIO_OPTIONS as option (option.label)}
70
+ <div class="flex flex-wrap items-center gap-1.5">
71
+ <div>
72
+ {#each ASPECT_RATIO_OPTIONS as option (option.label)}
73
+ <Button
74
+ variant={aspectRatio === option.value ? 'default' : 'outline'}
75
+ size="sm"
76
+ onclick={() => {
77
+ aspectRatio = option.value;
78
+ }}
79
+ >
80
+ {option.label}
81
+ </Button>
82
+ {/each}
83
+ </div>
84
+ <div class="flex gap-1">
85
+ <Button
86
+ variant="outline"
87
+ size="sm"
88
+ onclick={() => {
89
+ rotation -= 90;
90
+ }}
91
+ >
92
+ <PhArrowCounterClockwise class="size-4" />
93
+ </Button>
61
94
  <Button
62
- variant={aspectRatio === option.value ? 'default' : 'outline'}
95
+ variant="outline"
63
96
  size="sm"
64
97
  onclick={() => {
65
- aspectRatio = option.value;
98
+ rotation += 90;
66
99
  }}
67
100
  >
68
- {option.label}
101
+ <PhArrowClockwise class="size-4" />
69
102
  </Button>
70
- {/each}
103
+ </div>
71
104
  </div>
72
105
  <p>Width: {cropData.width}px / Height: {cropData.height}px</p>
73
106
  </div>
74
107
 
75
108
  <ImageCropper.RootProvider value={imageCropper}>
76
109
  <ImageCropper.Viewport
77
- class="relative overflow-hidden rounded-lg bg-surface-2 max-h-[60vh]"
110
+ class="relative max-h-[60vh] overflow-hidden rounded-lg bg-surface-2"
78
111
  style={imageAspectRatio ? `aspect-ratio: ${imageAspectRatio}` : 'aspect-ratio: 1'}
79
112
  >
80
113
  <ImageCropper.Image
@@ -87,7 +120,9 @@
87
120
  class="cursor-move border-2 border-white/50 [box-shadow:0_0_0_9999px_rgb(0_0_0/0.5)] outline-none focus-visible:border-primary data-dragging:cursor-grabbing data-dragging:border-white/80"
88
121
  >
89
122
  {#each ImageCropper.handles as position (position)}
90
- {@const isCorner = ['top-left', 'top-right', 'bottom-left', 'bottom-right'].includes(position)}
123
+ {@const isCorner = ['top-left', 'top-right', 'bottom-left', 'bottom-right'].includes(
124
+ position
125
+ )}
91
126
  <ImageCropper.Handle
92
127
  {position}
93
128
  class="group absolute flex size-5 touch-none items-center justify-center
@@ -102,12 +137,12 @@
102
137
  >
103
138
  {#if isCorner}
104
139
  <div
105
- class="size-2 shadow-sm transition-transform group-hover:scale-110
106
- group-data-[position=top-left]:border-l-2 group-data-[position=top-left]:border-t-2
107
- group-data-[position=top-right]:border-r-2 group-data-[position=top-right]:border-t-2
108
- group-data-[position=bottom-right]:border-r-2 group-data-[position=bottom-right]:border-b-2
109
- group-data-[position=bottom-left]:border-l-2 group-data-[position=bottom-left]:border-b-2
110
- border-white"
140
+ class="size-2 border-white shadow-sm transition-transform
141
+ group-hover:scale-110 group-data-[position=bottom-left]:border-b-2
142
+ group-data-[position=bottom-left]:border-l-2 group-data-[position=bottom-right]:border-r-2
143
+ group-data-[position=bottom-right]:border-b-2 group-data-[position=top-left]:border-t-2
144
+ group-data-[position=top-left]:border-l-2 group-data-[position=top-right]:border-t-2
145
+ group-data-[position=top-right]:border-r-2"
111
146
  ></div>
112
147
  {:else}
113
148
  <div
@@ -1,5 +1,5 @@
1
1
  import { ImageCropper } from '@ark-ui/svelte/image-cropper';
2
2
  import type { ImageCropperProps } from './types';
3
- declare const ImageCropper: import("svelte").Component<ImageCropperProps, {}, "getCropData" | "aspectRatio" | "getCroppedImage" | "getProcessedImage">;
3
+ declare const ImageCropper: import("svelte").Component<ImageCropperProps, {}, "getCropData" | "aspectRatio" | "rotation" | "getCroppedImage" | "getProcessedImage">;
4
4
  type ImageCropper = ReturnType<typeof ImageCropper>;
5
5
  export default ImageCropper;
@@ -9,7 +9,7 @@
9
9
  import type { ListboxProps } from './types';
10
10
  import type { ListItem } from '../../utils/collections';
11
11
  import { cn } from 'tailwind-variants';
12
- import PhCheck from '../../icons/PhCheck.svelte';
12
+ import { PhCheck } from '../../icons';
13
13
 
14
14
  type Props = ListboxProps<T>;
15
15
 
@@ -4,7 +4,7 @@
4
4
  import type { Snippet } from 'svelte';
5
5
  import { cn } from 'tailwind-variants';
6
6
  import MenuItemIndicator from './menu-item-indicator.svelte';
7
- import PhCheck from '../../icons/PhCheck.svelte';
7
+ import { PhCheck } from '../../icons';
8
8
 
9
9
  type IndicatorSnippet = { indicator?: Snippet };
10
10
 
@@ -3,7 +3,7 @@
3
3
  import type { MenuIndicatorBaseProps } from '@ark-ui/svelte/menu';
4
4
  import type { Snippet } from 'svelte';
5
5
  import { cn } from 'tailwind-variants';
6
- import PhCaretDown from '../../icons/PhCaretDown.svelte';
6
+ import { PhCaretDown } from '../../icons';
7
7
 
8
8
  type Props = MenuIndicatorBaseProps & { class?: string; children?: Snippet };
9
9
 
@@ -2,8 +2,7 @@
2
2
  import { Field } from '@ark-ui/svelte/field';
3
3
  import { NumberInput } from '@ark-ui/svelte/number-input';
4
4
  import type { NumberInputProps } from './types';
5
- import PhCaretDown from '../../icons/PhCaretDown.svelte';
6
- import PhCaretUp from '../../icons/PhCaretUp.svelte';
5
+ import { PhCaretDown, PhCaretUp } from '../../icons';
7
6
  import { useLocaleContext } from '@ark-ui/svelte/locale';
8
7
 
9
8
  let {
@@ -5,8 +5,7 @@
5
5
  import type { SelectProps } from './types';
6
6
  import { createListCollection, type ListItem } from '../../utils/collections';
7
7
  import { cn } from 'tailwind-variants';
8
- import PhCaretDown from '../../icons/PhCaretDown.svelte';
9
- import PhCheck from '../../icons/PhCheck.svelte';
8
+ import { PhCaretDown, PhCheck } from '../../icons';
10
9
 
11
10
  let {
12
11
  value = $bindable(),
@@ -4,14 +4,17 @@
4
4
  import type { TreeViewProps } from './types';
5
5
  import { createTreeCollection, type TreeItem } from '../../utils/collections';
6
6
  import { Debounced } from 'runed';
7
- import PhX from '../../icons/PhX.svelte';
8
- import PhCaretRight from '../../icons/PhCaretRight.svelte';
9
- import PhMinus from '../../icons/PhMinus.svelte';
10
- import PhCheck from '../../icons/PhCheck.svelte';
11
- import PhArrowsInSimple from '../../icons/PhArrowsInSimple.svelte';
7
+ import {
8
+ PhArrowsInSimple,
9
+ PhCaretRight,
10
+ PhCheck,
11
+ PhMagnifyingGlass,
12
+ PhMinus,
13
+ PhX
14
+ } from '../../icons';
12
15
  import { Button, Field } from '../..';
13
16
  import { SvelteSet } from 'svelte/reactivity';
14
- import PhMagnifyingGlass from '../../icons/PhMagnifyingGlass.svelte';
17
+
15
18
  import Icon from '@iconify/svelte';
16
19
 
17
20
  let {
@@ -165,7 +168,7 @@
165
168
  {#if node.children}
166
169
  <TreeView.Branch class="relative">
167
170
  <TreeView.BranchControl
168
- class="hover:bg-accent data-selected:bg-accent data-selected:text-accent-foreground data-disabled:cursor-not-allowed data-disabled:opacity-50 data-disabled:pointer-events-none flex w-full cursor-pointer items-center gap-2 rounded-md py-1.5 pr-3 text-sm select-none"
171
+ class="hover:bg-accent data-selected:bg-accent data-selected:text-accent-foreground flex w-full cursor-pointer items-center gap-2 rounded-md py-1.5 pr-3 text-sm select-none data-disabled:pointer-events-none data-disabled:cursor-not-allowed data-disabled:opacity-50"
169
172
  style="padding-inline-start: calc(var(--tree-px) + (var(--depth) - 1) * (var(--tree-indent) + var(--tree-icon) * 0.5))"
170
173
  >
171
174
  {#if selectionMode === 'multiple'}
@@ -190,7 +193,7 @@
190
193
  </TreeView.Branch>
191
194
  {:else}
192
195
  <TreeView.Item
193
- class="hover:bg-accent data-selected:bg-accent data-selected:text-accent-foreground data-disabled:cursor-not-allowed data-disabled:opacity-50 data-disabled:pointer-events-none flex w-full cursor-pointer items-center gap-2 rounded-md py-1.5 pr-3 text-sm select-none"
196
+ class="hover:bg-accent data-selected:bg-accent data-selected:text-accent-foreground flex w-full cursor-pointer items-center gap-2 rounded-md py-1.5 pr-3 text-sm select-none data-disabled:pointer-events-none data-disabled:cursor-not-allowed data-disabled:opacity-50"
194
197
  style="padding-inline-start: calc(var(--tree-px) + (var(--depth) - 1) * (var(--tree-indent) + var(--tree-icon) * 0.5) + var(--tree-icon) + var(--tree-gap))"
195
198
  >
196
199
  {#if selectionMode === 'multiple'}
@@ -0,0 +1,18 @@
1
+ <script lang="ts">
2
+ let { class: className = '', ...restProps } = $props();
3
+ </script>
4
+
5
+ <svg
6
+ xmlns="http://www.w3.org/2000/svg"
7
+ width="1em"
8
+ height="1em"
9
+ viewBox="0 0 256 256"
10
+ class={className}
11
+ {...restProps}
12
+ >
13
+ <path
14
+ fill="currentColor"
15
+ d="M240 56v48a8 8 0 0 1-8 8h-48a8 8 0 0 1 0-16h27.4l-26.59-24.36l-.25-.24a80 80 0 1 0-1.67 114.78a8 8 0 0 1 11 11.63A95.44 95.44 0 0 1 128 224h-1.32a96 96 0 1 1 69.07-164L224 85.8V56a8 8 0 1 1 16 0"
16
+ />
17
+ </svg>
18
+ <!-- Icon from Phosphor by Phosphor Icons - https://github.com/phosphor-icons/core/blob/main/LICENSE -->
@@ -0,0 +1,5 @@
1
+ declare const PhArrowClockwise: import("svelte").Component<{
2
+ class?: string;
3
+ } & Record<string, any>, {}, "">;
4
+ type PhArrowClockwise = ReturnType<typeof PhArrowClockwise>;
5
+ export default PhArrowClockwise;
@@ -0,0 +1,18 @@
1
+ <script lang="ts">
2
+ let { class: className = '', ...restProps } = $props();
3
+ </script>
4
+
5
+ <svg
6
+ xmlns="http://www.w3.org/2000/svg"
7
+ width="1em"
8
+ height="1em"
9
+ viewBox="0 0 256 256"
10
+ class={className}
11
+ {...restProps}
12
+ >
13
+ <path
14
+ fill="currentColor"
15
+ d="M224 128a96 96 0 0 1-94.71 96H128a95.38 95.38 0 0 1-65.9-26.2a8 8 0 0 1 11-11.63a80 80 0 1 0-1.67-114.78a3 3 0 0 1-.26.25L44.59 96H72a8 8 0 0 1 0 16H24a8 8 0 0 1-8-8V56a8 8 0 0 1 16 0v29.8L60.25 60A96 96 0 0 1 224 128"
16
+ />
17
+ </svg>
18
+ <!-- Icon from Phosphor by Phosphor Icons - https://github.com/phosphor-icons/core/blob/main/LICENSE -->
@@ -0,0 +1,5 @@
1
+ declare const PhArrowCounterClockwise: import("svelte").Component<{
2
+ class?: string;
3
+ } & Record<string, any>, {}, "">;
4
+ type PhArrowCounterClockwise = ReturnType<typeof PhArrowCounterClockwise>;
5
+ export default PhArrowCounterClockwise;
@@ -0,0 +1,23 @@
1
+ export { default as PhArrowClockwise } from './PhArrowClockwise.svelte';
2
+ export { default as PhArrowCounterClockwise } from './PhArrowCounterClockwise.svelte';
3
+ export { default as PhArrowLeft } from './PhArrowLeft.svelte';
4
+ export { default as PhArrowRight } from './PhArrowRight.svelte';
5
+ export { default as PhArrowsInSimple } from './PhArrowsInSimple.svelte';
6
+ export { default as PhCaretDown } from './PhCaretDown.svelte';
7
+ export { default as PhCaretRight } from './PhCaretRight.svelte';
8
+ export { default as PhCaretUp } from './PhCaretUp.svelte';
9
+ export { default as PhCheck } from './PhCheck.svelte';
10
+ export { default as PhFile } from './PhFile.svelte';
11
+ export { default as PhFileArchive } from './PhFileArchive.svelte';
12
+ export { default as PhFileText } from './PhFileText.svelte';
13
+ export { default as PhHeadphones } from './PhHeadphones.svelte';
14
+ export { default as PhImage } from './PhImage.svelte';
15
+ export { default as PhListMagnifyingGlass } from './PhListMagnifyingGlass.svelte';
16
+ export { default as PhMagnifyingGlass } from './PhMagnifyingGlass.svelte';
17
+ export { default as PhMicrosoftExcelLogo } from './PhMicrosoftExcelLogo.svelte';
18
+ export { default as PhMinus } from './PhMinus.svelte';
19
+ export { default as PhStar } from './PhStar.svelte';
20
+ export { default as PhUploadSimple } from './PhUploadSimple.svelte';
21
+ export { default as PhUser } from './PhUser.svelte';
22
+ export { default as PhVideoCamera } from './PhVideoCamera.svelte';
23
+ export { default as PhX } from './PhX.svelte';
@@ -0,0 +1,23 @@
1
+ export { default as PhArrowClockwise } from './PhArrowClockwise.svelte';
2
+ export { default as PhArrowCounterClockwise } from './PhArrowCounterClockwise.svelte';
3
+ export { default as PhArrowLeft } from './PhArrowLeft.svelte';
4
+ export { default as PhArrowRight } from './PhArrowRight.svelte';
5
+ export { default as PhArrowsInSimple } from './PhArrowsInSimple.svelte';
6
+ export { default as PhCaretDown } from './PhCaretDown.svelte';
7
+ export { default as PhCaretRight } from './PhCaretRight.svelte';
8
+ export { default as PhCaretUp } from './PhCaretUp.svelte';
9
+ export { default as PhCheck } from './PhCheck.svelte';
10
+ export { default as PhFile } from './PhFile.svelte';
11
+ export { default as PhFileArchive } from './PhFileArchive.svelte';
12
+ export { default as PhFileText } from './PhFileText.svelte';
13
+ export { default as PhHeadphones } from './PhHeadphones.svelte';
14
+ export { default as PhImage } from './PhImage.svelte';
15
+ export { default as PhListMagnifyingGlass } from './PhListMagnifyingGlass.svelte';
16
+ export { default as PhMagnifyingGlass } from './PhMagnifyingGlass.svelte';
17
+ export { default as PhMicrosoftExcelLogo } from './PhMicrosoftExcelLogo.svelte';
18
+ export { default as PhMinus } from './PhMinus.svelte';
19
+ export { default as PhStar } from './PhStar.svelte';
20
+ export { default as PhUploadSimple } from './PhUploadSimple.svelte';
21
+ export { default as PhUser } from './PhUser.svelte';
22
+ export { default as PhVideoCamera } from './PhVideoCamera.svelte';
23
+ export { default as PhX } from './PhX.svelte';
@@ -123,7 +123,9 @@ export async function cropImage(src, crop, opts) {
123
123
  let canvas = document.createElement('canvas');
124
124
  canvas.width = crop.width;
125
125
  canvas.height = crop.height;
126
- canvas.getContext('2d').drawImage(img, crop.x, crop.y, crop.width, crop.height, 0, 0, crop.width, crop.height);
126
+ canvas
127
+ .getContext('2d')
128
+ .drawImage(img, crop.x, crop.y, crop.width, crop.height, 0, 0, crop.width, crop.height);
127
129
  if (trim)
128
130
  canvas = applyTrim(canvas, trimThreshold);
129
131
  canvas = scaleCanvas(canvas, maxWidth, maxHeight);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "compote-ui",
3
- "version": "0.19.5",
3
+ "version": "0.20.0",
4
4
  "license": "MIT",
5
5
  "scripts": {
6
6
  "dev": "vite dev",