@revenuecat/purchases-ui-js 2.0.2 → 2.0.4

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 (144) hide show
  1. package/dist/components/button/ButtonNode.stories.svelte +66 -102
  2. package/dist/components/button/ButtonNode.svelte +18 -26
  3. package/dist/components/carousel/Carousel.stories.svelte +1039 -0
  4. package/dist/components/carousel/Carousel.stories.svelte.d.ts +19 -0
  5. package/dist/components/carousel/Carousel.svelte +298 -0
  6. package/dist/components/carousel/Carousel.svelte.d.ts +4 -0
  7. package/dist/components/carousel/CarouselPage.svelte +39 -0
  8. package/dist/components/carousel/CarouselPage.svelte.d.ts +11 -0
  9. package/dist/components/carousel/PageControl.svelte +93 -0
  10. package/dist/components/carousel/PageControl.svelte.d.ts +4 -0
  11. package/dist/components/carousel/carousel-utils.d.ts +4 -0
  12. package/dist/components/carousel/carousel-utils.js +21 -0
  13. package/dist/components/footer/Footer.stories.svelte +112 -102
  14. package/dist/components/footer/Footer.svelte +8 -4
  15. package/dist/components/icon/Icon.stories.svelte +100 -0
  16. package/dist/components/icon/Icon.stories.svelte.d.ts +19 -0
  17. package/dist/components/icon/Icon.svelte +73 -0
  18. package/dist/components/icon/Icon.svelte.d.ts +4 -0
  19. package/dist/components/image/ClipPath.svelte +49 -0
  20. package/dist/components/image/ClipPath.svelte.d.ts +9 -0
  21. package/dist/components/image/Image.stories.svelte +83 -188
  22. package/dist/components/image/Image.svelte +152 -136
  23. package/dist/components/image/Image.svelte.d.ts +1 -1
  24. package/dist/components/image/Overlay.svelte +36 -0
  25. package/dist/components/image/Overlay.svelte.d.ts +8 -0
  26. package/dist/components/package/Package.stories.svelte +10 -21
  27. package/dist/components/package/Package.svelte +8 -35
  28. package/dist/components/paywall/Node.svelte +25 -32
  29. package/dist/components/paywall/Node.svelte.d.ts +4 -6
  30. package/dist/components/paywall/Paywall.stories.svelte +36 -140
  31. package/dist/components/paywall/Paywall.svelte +23 -7
  32. package/dist/components/paywall/Paywall.svelte.d.ts +4 -2
  33. package/dist/components/paywall/fixtures/override-paywall.d.ts +2 -0
  34. package/dist/components/paywall/fixtures/override-paywall.js +1310 -0
  35. package/dist/components/paywall/fixtures/stack-paywall.d.ts +2 -0
  36. package/dist/components/paywall/fixtures/stack-paywall.js +5223 -0
  37. package/dist/components/paywall/fixtures/variables.d.ts +261 -0
  38. package/dist/components/paywall/fixtures/variables.js +262 -0
  39. package/dist/components/paywall/paywall-utils.d.ts +1 -1
  40. package/dist/components/purchase-button/PurchaseButton.stories.svelte +10 -21
  41. package/dist/components/purchase-button/PurchaseButton.svelte +2 -27
  42. package/dist/components/stack/Stack.stories.svelte +2354 -978
  43. package/dist/components/stack/Stack.svelte +116 -134
  44. package/dist/components/stack/Stack.svelte.d.ts +8 -2
  45. package/dist/components/stack/stack-utils.d.ts +10 -30
  46. package/dist/components/stack/stack-utils.js +77 -255
  47. package/dist/components/text/Text.svelte +3 -37
  48. package/dist/components/text/Text.svelte.d.ts +1 -2
  49. package/dist/components/text/TextNode.stories.svelte +10 -36
  50. package/dist/components/text/TextNode.svelte +25 -28
  51. package/dist/components/text/TextNode.svelte.d.ts +1 -1
  52. package/dist/components/text/text-utils.d.ts +4 -9
  53. package/dist/components/text/text-utils.js +32 -117
  54. package/dist/components/timeline/Timeline.stories.svelte +640 -251
  55. package/dist/components/timeline/Timeline.svelte +42 -28
  56. package/dist/components/timeline/Timeline.svelte.d.ts +1 -1
  57. package/dist/components/timeline/TimelineItem.svelte +80 -112
  58. package/dist/components/timeline/TimelineItem.svelte.d.ts +6 -2
  59. package/dist/components/timeline/timeline-utils.d.ts +24 -6
  60. package/dist/components/timeline/timeline-utils.js +21 -113
  61. package/dist/index.d.ts +3 -2
  62. package/dist/index.js +3 -2
  63. package/dist/stores/color-mode.d.ts +1 -1
  64. package/dist/stores/paywall.d.ts +5 -2
  65. package/dist/stores/selected.d.ts +5 -0
  66. package/dist/stores/selected.js +12 -0
  67. package/dist/stores/variables.d.ts +1 -1
  68. package/dist/stores/variables.js +0 -1
  69. package/dist/stories/component-decorator.d.ts +2 -0
  70. package/dist/stories/component-decorator.js +12 -0
  71. package/dist/stories/fixtures.d.ts +6 -3
  72. package/dist/stories/fixtures.js +5214 -4422
  73. package/dist/stories/paywall-decorator.js +6 -0
  74. package/dist/stories/variables-decorator.d.ts +1 -1
  75. package/dist/stories/viewport-decorator.d.ts +2 -0
  76. package/dist/stories/viewport-decorator.js +8 -0
  77. package/dist/stories/viewport-wrapper.svelte +55 -0
  78. package/dist/stories/viewport-wrapper.svelte.d.ts +10 -0
  79. package/dist/stories/with-layout.d.ts +2 -10
  80. package/dist/stories/with-layout.js +3 -5
  81. package/dist/types/alignment.d.ts +5 -3
  82. package/dist/types/background.d.ts +6 -5
  83. package/dist/types/base.d.ts +7 -0
  84. package/dist/types/colors.d.ts +4 -4
  85. package/dist/types/component.d.ts +7 -2
  86. package/dist/types/components/button.d.ts +6 -1
  87. package/dist/types/components/carousel.d.ts +51 -0
  88. package/dist/types/components/carousel.js +1 -0
  89. package/dist/types/components/footer.d.ts +2 -1
  90. package/dist/types/components/icon.d.ts +28 -0
  91. package/dist/types/components/icon.js +1 -0
  92. package/dist/types/components/image.d.ts +20 -0
  93. package/dist/types/components/image.js +1 -0
  94. package/dist/types/components/package.d.ts +2 -1
  95. package/dist/types/components/purchase-button.d.ts +2 -1
  96. package/dist/types/components/stack.d.ts +32 -0
  97. package/dist/types/components/stack.js +1 -0
  98. package/dist/types/components/text.d.ts +20 -0
  99. package/dist/types/components/text.js +1 -0
  100. package/dist/types/components/timeline.d.ts +35 -0
  101. package/dist/types/components/timeline.js +1 -0
  102. package/dist/types/localization.d.ts +2 -1
  103. package/dist/types/media.d.ts +4 -3
  104. package/dist/types/overrides.d.ts +48 -0
  105. package/dist/types/overrides.js +1 -0
  106. package/dist/types/paywall.d.ts +27 -0
  107. package/dist/types/paywall.js +1 -0
  108. package/dist/types/ui-config.d.ts +20 -0
  109. package/dist/types/ui-config.js +1 -0
  110. package/dist/types/variables.d.ts +13 -0
  111. package/dist/types/variables.js +10 -0
  112. package/dist/types.d.ts +17 -9
  113. package/dist/ui/atoms/typography.stories.svelte +1 -27
  114. package/dist/ui/molecules/button.stories.svelte +3 -8
  115. package/dist/ui/theme/colors.d.ts +0 -6
  116. package/dist/ui/theme/colors.js +1 -1
  117. package/dist/ui/theme/text.d.ts +3 -4
  118. package/dist/ui/theme/utils.d.ts +0 -10
  119. package/dist/ui/theme/utils.js +5 -5
  120. package/dist/utils/background-utils.d.ts +4 -0
  121. package/dist/utils/background-utils.js +39 -0
  122. package/dist/utils/base-utils.d.ts +18 -0
  123. package/dist/utils/base-utils.js +124 -0
  124. package/dist/utils/constants.d.ts +2 -2
  125. package/dist/utils/constants.js +6 -1
  126. package/dist/utils/font-utils.d.ts +4 -0
  127. package/dist/utils/font-utils.js +47 -0
  128. package/dist/utils/style-utils.d.ts +7 -120
  129. package/dist/utils/style-utils.js +29 -304
  130. package/dist/utils/variable-utils.d.ts +1 -22
  131. package/dist/utils/variable-utils.js +28 -24
  132. package/dist/web-components/index.css +1 -1
  133. package/dist/web-components/index.js +1435 -980
  134. package/package.json +36 -26
  135. package/dist/components/button/button-utils.d.ts +0 -2
  136. package/dist/components/button/button-utils.js +0 -19
  137. package/dist/components/image/image-utils.d.ts +0 -19
  138. package/dist/components/image/image-utils.js +0 -33
  139. package/dist/components/purchase-button/purchase-button-utils.d.ts +0 -2
  140. package/dist/components/purchase-button/purchase-button-utils.js +0 -20
  141. package/dist/data/entities.d.ts +0 -162
  142. package/dist/stories/meta-templates.d.ts +0 -12
  143. package/dist/stories/meta-templates.js +0 -155
  144. /package/dist/{data/entities.js → types/base.js} +0 -0
@@ -1,86 +1,55 @@
1
1
  <script module lang="ts">
2
2
  import Image from "./Image.svelte";
3
+ import { componentDecorator } from "../../stories/component-decorator";
3
4
  import { defineMeta } from "@storybook/addon-svelte-csf";
4
5
 
5
6
  const { Story } = defineMeta({
6
7
  title: "Components/Image",
7
8
  component: Image,
8
- tags: ["autodocs"],
9
- argTypes: {
10
- id: { control: "text", description: "Unique identifier for the image" },
11
- color_overlay: {
12
- control: "object",
13
- description: "Image overlay",
14
- },
9
+ decorators: [componentDecorator()],
10
+ args: {
11
+ type: "image",
12
+ id: "image",
13
+ name: "Image",
14
+ fit_mode: "fill",
15
15
  size: {
16
- control: "object",
17
- description: "Size configuration for the image",
18
- },
19
- max_height: {
20
- control: "number",
21
- description: "Maximum height of the image",
22
- },
23
- override_source_lid: {
24
- control: "text",
25
- description: "Override source lid",
26
- },
27
- fit_mode: {
28
- control: { type: "select" },
29
- options: ["fit", "fill"],
30
- description: "Fit mode for the image",
16
+ width: { type: "fill" },
17
+ height: { type: "fill" },
18
+ },
19
+ source: {
20
+ dark: null,
21
+ light: {
22
+ width: 600,
23
+ height: 400,
24
+ original: "https://placehold.co/600x400",
25
+ heic: "https://placehold.co/600x400",
26
+ heic_low_res: "https://placehold.co/600x400",
27
+ webp: "https://placehold.co/600x400",
28
+ webp_low_res: "https://placehold.co/600x400",
29
+ },
31
30
  },
32
31
  },
33
32
  });
34
33
  </script>
35
34
 
36
- <!-- Rectangle story -->
37
35
  <Story
38
36
  name="Rectangle"
39
37
  args={{
40
- id: "example-id",
41
- fit_mode: "fit",
42
- size: {
43
- width: { type: "fill" },
44
- height: { type: "fill" },
45
- },
46
- source: {
47
- light: {
48
- width: 600,
49
- height: 400,
50
- original: "https://placehold.co/600x400",
51
- heic: "https://placehold.co/600x400",
52
- heic_low_res: "https://placehold.co/600x400",
53
- webp: "https://placehold.co/600x400",
54
- webp_low_res: "https://placehold.co/600x400",
38
+ mask_shape: {
39
+ type: "rectangle",
40
+ corners: {
41
+ top_leading: 0,
42
+ top_trailing: 0,
43
+ bottom_leading: 0,
44
+ bottom_trailing: 0,
55
45
  },
56
- dark: null,
57
46
  },
58
- mask_shape: { type: "rectangle" },
59
47
  }}
60
48
  />
61
49
 
62
- <!-- Rounded Rectangle story -->
63
50
  <Story
64
51
  name="Rounded Rectangle"
65
52
  args={{
66
- id: "example-id",
67
- fit_mode: "fit",
68
- size: {
69
- width: { type: "fill" },
70
- height: { type: "fill" },
71
- },
72
- source: {
73
- light: {
74
- width: 600,
75
- height: 400,
76
- original: "https://placehold.co/600x400",
77
- heic: "https://placehold.co/600x400",
78
- heic_low_res: "https://placehold.co/600x400",
79
- webp: "https://placehold.co/600x400",
80
- webp_low_res: "https://placehold.co/600x400",
81
- },
82
- dark: null,
83
- },
84
53
  mask_shape: {
85
54
  type: "rectangle",
86
55
  corners: {
@@ -92,161 +61,63 @@
92
61
  },
93
62
  }}
94
63
  />
95
- <!-- Circle story -->
64
+
96
65
  <Story
97
66
  name="Circle"
98
67
  args={{
99
- id: "example-id",
100
- fit_mode: "fit",
101
- size: {
102
- width: { type: "fill" },
103
- height: { type: "fill" },
104
- },
105
- source: {
106
- light: {
107
- width: 600,
108
- height: 400,
109
- original: "https://placehold.co/600x400",
110
- heic: "https://placehold.co/600x400",
111
- heic_low_res: "https://placehold.co/600x400",
112
- webp: "https://placehold.co/600x400",
113
- webp_low_res: "https://placehold.co/600x400",
114
- },
115
- dark: null,
116
- },
117
68
  mask_shape: { type: "circle" },
118
69
  }}
119
70
  />
120
- <!-- Concave story -->
71
+
121
72
  <Story
122
73
  name="Concave"
123
74
  args={{
124
- id: "example-id",
125
- fit_mode: "fit",
126
- size: {
127
- width: { type: "fill" },
128
- height: { type: "fill" },
129
- },
130
- source: {
131
- light: {
132
- width: 600,
133
- height: 400,
134
- original: "https://placehold.co/600x400",
135
- heic: "https://placehold.co/600x400",
136
- heic_low_res: "https://placehold.co/600x400",
137
- webp: "https://placehold.co/600x400",
138
- webp_low_res: "https://placehold.co/600x400",
139
- },
140
- dark: null,
141
- },
142
75
  mask_shape: { type: "concave" },
143
76
  }}
144
77
  />
145
- <!-- Convex story -->
78
+
146
79
  <Story
147
80
  name="Convex"
148
81
  args={{
149
- id: "example-id",
150
- fit_mode: "fit",
151
- size: {
152
- width: { type: "fill" },
153
- height: { type: "fill" },
154
- },
155
- source: {
156
- light: {
157
- width: 600,
158
- height: 400,
159
- original: "https://placehold.co/600x400",
160
- heic: "https://placehold.co/600x400",
161
- heic_low_res: "https://placehold.co/600x400",
162
- webp: "https://placehold.co/600x400",
163
- webp_low_res: "https://placehold.co/600x400",
164
- },
165
- dark: null,
166
- },
167
82
  mask_shape: { type: "convex" },
168
83
  }}
169
84
  />
170
- <!-- Radial Gradient story -->
85
+
171
86
  <Story
172
87
  name="Overlay Radial Gradient"
173
88
  args={{
174
- id: "example-id",
175
- fit_mode: "fit",
176
- size: {
177
- width: { type: "fill" },
178
- height: { type: "fill" },
179
- },
180
- source: {
181
- light: {
182
- width: 600,
183
- height: 400,
184
- original: "https://placehold.co/600x400",
185
- heic: "https://placehold.co/600x400",
186
- heic_low_res: "https://placehold.co/600x400",
187
- webp: "https://placehold.co/600x400",
188
- webp_low_res: "https://placehold.co/600x400",
189
- },
190
- dark: null,
191
- },
192
89
  color_overlay: {
193
- dark: {
194
- type: "hex",
195
- value: "#000000FF",
196
- },
197
90
  light: {
91
+ type: "radial",
198
92
  points: [
199
93
  {
200
- color: "#020024ff",
201
94
  percent: 0,
95
+ color: "#020024ff",
202
96
  },
203
97
  {
204
- color: "#00d4ff00",
205
98
  percent: 100,
99
+ color: "#00d4ff00",
206
100
  },
207
101
  ],
208
- type: "radial",
209
102
  },
210
103
  },
211
104
  }}
212
105
  />
213
- <!-- Linear Gradient story -->
106
+
214
107
  <Story
215
108
  name="Overlay Linear Gradient"
216
109
  args={{
217
- id: "example-id",
218
- fit_mode: "fit",
219
- size: {
220
- width: { type: "fill" },
221
- height: { type: "fill" },
222
- },
223
- source: {
224
- light: {
225
- width: 600,
226
- height: 400,
227
- original: "https://placehold.co/600x400",
228
- heic: "https://placehold.co/600x400",
229
- heic_low_res: "https://placehold.co/600x400",
230
- webp: "https://placehold.co/600x400",
231
- webp_low_res: "https://placehold.co/600x400",
232
- },
233
- dark: null,
234
- },
235
110
  color_overlay: {
236
- dark: {
237
- type: "hex",
238
- value: "#000000FF",
239
- },
240
111
  light: {
241
112
  degrees: 180,
242
113
  points: [
243
114
  {
244
- color: "#020024ff",
245
115
  percent: 0,
116
+ color: "#020024ff",
246
117
  },
247
118
  {
248
- color: "#00d4ff00",
249
119
  percent: 100,
120
+ color: "#00d4ff00",
250
121
  },
251
122
  ],
252
123
  type: "linear",
@@ -254,36 +125,60 @@
254
125
  },
255
126
  }}
256
127
  />
257
- <!-- Solid overlay -->
128
+
258
129
  <Story
259
130
  name="Overlay Solid"
260
131
  args={{
261
- id: "example-id",
262
- fit_mode: "fit",
132
+ color_overlay: {
133
+ light: {
134
+ type: "hex",
135
+ value: "#e7c00069",
136
+ },
137
+ },
138
+ }}
139
+ />
140
+
141
+ <Story
142
+ name="Complex"
143
+ args={{
263
144
  size: {
264
- width: { type: "fill" },
265
- height: { type: "fill" },
145
+ width: { type: "fixed", value: 128 },
146
+ height: { type: "fixed", value: 128 },
266
147
  },
267
- source: {
268
- light: {
269
- width: 600,
270
- height: 400,
271
- original: "https://placehold.co/600x400",
272
- heic: "https://placehold.co/600x400",
273
- heic_low_res: "https://placehold.co/600x400",
274
- webp: "https://placehold.co/600x400",
275
- webp_low_res: "https://placehold.co/600x400",
148
+ mask_shape: {
149
+ type: "rectangle",
150
+ corners: {
151
+ top_leading: 0,
152
+ top_trailing: 16,
153
+ bottom_trailing: 32,
154
+ bottom_leading: 64,
276
155
  },
277
- dark: null,
278
156
  },
157
+ fit_mode: "fill",
158
+ padding: { top: 0, bottom: 0, leading: 0, trailing: 0 },
159
+ margin: { top: 0, bottom: 0, leading: 0, trailing: 0 },
279
160
  color_overlay: {
280
- dark: {
281
- type: "hex",
282
- value: "#000000FF",
283
- },
284
161
  light: {
285
- type: "hex",
286
- value: "#e7c00069",
162
+ type: "linear",
163
+ degrees: 180,
164
+ points: [
165
+ { percent: 0, color: "#ff000080" },
166
+ { percent: 100, color: "#ff00ff00" },
167
+ ],
168
+ },
169
+ },
170
+ border: {
171
+ width: 3,
172
+ color: {
173
+ light: { type: "hex", value: "#00ff0080" },
174
+ },
175
+ },
176
+ shadow: {
177
+ x: 0,
178
+ y: 0,
179
+ radius: 16,
180
+ color: {
181
+ light: { type: "hex", value: "#0000ff80" },
287
182
  },
288
183
  },
289
184
  }}
@@ -1,163 +1,179 @@
1
1
  <script lang="ts">
2
- import { getImageComponentStyles } from "./image-utils";
3
- import type { ImageProps } from "../../data/entities";
4
2
  import { getColorModeContext } from "../../stores/color-mode";
5
- import { DEFAULT_COLOR_MODE } from "../../utils/constants";
3
+ import { getSelectedStateContext } from "../../stores/selected";
4
+ import type { ImageProps } from "../../types/components/image";
5
+ import {
6
+ css,
7
+ mapColor,
8
+ mapColorMode,
9
+ mapFitMode,
10
+ mapSize,
11
+ mapSpacing,
12
+ } from "../../utils/base-utils";
13
+ import { getActiveStateProps } from "../../utils/style-utils";
14
+ import ClipPath from "./ClipPath.svelte";
15
+ import Overlay from "./Overlay.svelte";
6
16
 
7
- const { id, source, ...restProps }: ImageProps = $props();
17
+ const props: ImageProps = $props();
18
+
19
+ const selectedState = getSelectedStateContext();
20
+ const {
21
+ id,
22
+ source,
23
+ size,
24
+ mask_shape,
25
+ fit_mode,
26
+ padding,
27
+ margin,
28
+ color_overlay,
29
+ border,
30
+ shadow,
31
+ } = $derived.by(() => {
32
+ return {
33
+ ...props,
34
+ ...getActiveStateProps($selectedState, props.overrides),
35
+ };
36
+ });
8
37
 
9
38
  const getColorMode = getColorModeContext();
10
39
  const colorMode = $derived(getColorMode());
40
+ const image = $derived(mapColorMode(colorMode, source));
11
41
 
12
- let imageAspectRatio = $state(0);
13
- let imageElement: HTMLImageElement | null;
42
+ let wrapperWidth = $state(0);
43
+ let imageSize = $state({
44
+ height: 0,
45
+ width: 0,
46
+ });
14
47
 
15
- // Calculate aspect ratio once image loads
16
- function onImageLoad() {
17
- if (imageElement) {
18
- imageAspectRatio = imageElement.naturalHeight / imageElement.naturalWidth;
48
+ // TODO: Not needed if width/height are set. Remove once paywall stories are fixed or removed.
49
+ $effect(() => {
50
+ if (image.width || image.height) {
51
+ imageSize = {
52
+ height: image.height,
53
+ width: image.width,
54
+ };
55
+ return;
19
56
  }
20
- }
21
57
 
22
- const { imageStyles, maskPath, linearGradientAngle } = $derived(
23
- getImageComponentStyles(colorMode, {
24
- id,
25
- source,
26
- ...restProps,
27
- imageAspectRatio,
58
+ const img = new window.Image();
59
+ img.src = image.original;
60
+
61
+ const onImageLoad = () => {
62
+ imageSize = {
63
+ height: img.height,
64
+ width: img.width,
65
+ };
66
+ };
67
+
68
+ img.addEventListener("load", onImageLoad);
69
+ return () => {
70
+ img.removeEventListener("load", onImageLoad);
71
+ };
72
+ });
73
+
74
+ const height = $derived.by(() => {
75
+ if (size.height.type === "fixed") {
76
+ return size.height.value;
77
+ }
78
+ return Math.round(wrapperWidth * (imageSize.height / imageSize.width));
79
+ });
80
+
81
+ const style = $derived(
82
+ css({
83
+ width: mapSize(size.width),
84
+ height: `${height}px`,
85
+ margin: mapSpacing(margin),
86
+ padding: mapSpacing(padding),
87
+ "line-height": 0,
88
+ "flex-shrink": size.width.type === "fixed" ? 0 : 1,
28
89
  }),
29
90
  );
30
91
 
31
- const imageSource = $derived.by(() => {
32
- if (source[colorMode]?.original) {
33
- return source[colorMode].original;
34
- } else {
35
- return source[DEFAULT_COLOR_MODE]?.original as string;
92
+ let svgRect = $state<DOMRect | null>(null);
93
+
94
+ const [svgWidth, svgHeight] = $derived.by(() => {
95
+ return [svgRect?.width ?? 0, svgRect?.height ?? 0];
96
+ });
97
+
98
+ const viewBox = $derived.by(() => {
99
+ return `0 0 ${svgWidth} ${svgHeight}`;
100
+ });
101
+
102
+ const svgStyle = $derived.by(() => {
103
+ if (!shadow?.color) {
104
+ return "";
36
105
  }
106
+
107
+ const { x, y, radius, color } = shadow;
108
+ const shadowColor = mapColor(colorMode, color);
109
+ return `filter: drop-shadow(${x}px ${y}px ${radius}px ${shadowColor})`;
37
110
  });
38
111
 
39
- const colorOverlay = $derived(restProps.color_overlay);
40
- const colorInfo = $derived(
41
- colorOverlay?.[colorMode] ?? colorOverlay?.[DEFAULT_COLOR_MODE],
112
+ const overlay = $derived(
113
+ color_overlay && mapColorMode(colorMode, color_overlay),
42
114
  );
43
115
  </script>
44
116
 
45
- <img
46
- src={imageSource}
47
- bind:this={imageElement}
48
- onload={onImageLoad}
49
- style="display: none;"
50
- alt=""
51
- />
52
-
53
- <svg
54
- class="rc-pw-image-container"
55
- id={`rc-pw-image-container-${id}`}
56
- style={imageStyles}
57
- preserveAspectRatio="xMidYMid slice"
58
- viewBox={`0 0 100 ${imageAspectRatio * 100}`}
59
- >
60
- <defs>
61
- <clipPath id={`clip-path-${id}`}>
62
- {#if restProps.mask_shape?.type === "circle"}
63
- <ellipse
64
- cx="50"
65
- cy={imageAspectRatio * 50}
66
- rx="50"
67
- ry={imageAspectRatio * 50}
117
+ <div {style} bind:clientWidth={wrapperWidth}>
118
+ <svg
119
+ bind:contentRect={svgRect}
120
+ width="100%"
121
+ height="100%"
122
+ {viewBox}
123
+ style={svgStyle}
124
+ >
125
+ <defs>
126
+ <clipPath id={`${id}-path`}>
127
+ <ClipPath shape={mask_shape} width={svgWidth} height={svgHeight} />
128
+ </clipPath>
129
+
130
+ <g id={`${id}-border`}>
131
+ <ClipPath shape={mask_shape} width={svgWidth} height={svgHeight} />
132
+ </g>
133
+
134
+ <Overlay id={`${id}-overlay`} {overlay} />
135
+ </defs>
136
+
137
+ {#if border && border.width > 0}
138
+ <use href={`#${id}-border`} fill="transparent" />
139
+ {/if}
140
+
141
+ <g clip-path={`url(#${id}-path)`}>
142
+ <foreignObject x="0" y="0" width="100%" height="100%">
143
+ <img
144
+ src={image.original}
145
+ style="object-fit:{mapFitMode(fit_mode)}"
146
+ alt=""
147
+ />
148
+ </foreignObject>
149
+
150
+ {#if overlay}
151
+ <rect
152
+ x="0"
153
+ y="0"
154
+ height="100%"
155
+ width="100%"
156
+ fill={`url(#${id}-overlay)`}
68
157
  />
69
- {:else}
70
- <path d={maskPath} />
71
158
  {/if}
72
- </clipPath>
73
-
74
- {#if colorInfo?.type === "linear"}
75
- <linearGradient
76
- id={`gradient-${id}`}
77
- x1={linearGradientAngle.x1}
78
- y1={linearGradientAngle.y1}
79
- x2={linearGradientAngle.x2}
80
- y2={linearGradientAngle.y2}
81
- >
82
- {#each colorInfo?.points || [] as stop}
83
- <stop
84
- offset={`${stop.percent}%`}
85
- style={`stop-color: ${stop.color}`}
86
- />
87
- {/each}
88
- </linearGradient>
89
- {:else if colorInfo?.type === "radial"}
90
- <radialGradient
91
- id={`gradient-${id}`}
92
- cx="50%"
93
- cy="50%"
94
- r="50%"
95
- fx="50%"
96
- fy="50%"
97
- >
98
- {#each colorInfo?.points || [] as stop}
99
- <stop
100
- offset={`${stop.percent}%`}
101
- style={`stop-color: ${stop.color}`}
102
- />
103
- {/each}
104
- </radialGradient>
105
- {:else if colorInfo?.type === "hex"}
106
- <linearGradient id={`gradient-${id}`}>
107
- <stop offset="0%" style={`stop-color: ${colorInfo?.value}`} />
108
- </linearGradient>
109
- {/if}
110
- </defs>
111
-
112
- <image
113
- class="rc-pw-image"
114
- href={imageSource}
115
- x="0"
116
- y="0"
117
- width="100"
118
- height={imageAspectRatio * 100}
119
- clip-path={`url(#clip-path-${id})`}
120
- preserveAspectRatio="xMidYMid slice"
121
- {id}
122
- />
123
-
124
- <rect
125
- class="rc-pw-image-overlay"
126
- x="0"
127
- y="0"
128
- width="100"
129
- height={imageAspectRatio * 100}
130
- clip-path={`url(#clip-path-${id})`}
131
- fill={`url(#gradient-${id})`}
132
- />
133
- </svg>
134
159
 
135
- <style>
136
- .rc-pw-image-container {
137
- border-end-start-radius: var(--image-border-end-start-radius, 0px);
138
- border-end-end-radius: var(--image-border-end-end-radius, 0px);
139
- border-start-start-radius: var(--image-border-start-start-radius, 0px);
140
- border-start-end-radius: var(--image-border-start-end-radius, 0px);
141
- position: relative;
142
- overflow: hidden;
143
- display: flex;
144
- flex: var(--image-flex, 1 1 auto);
145
- position: var(--image-position, relative);
146
- inset: var(--image-inset, 0);
147
- transform: var(--image-transform, initial);
148
- height: var(--image-height, initial);
149
- width: var(--image-width, initial);
150
- }
160
+ {#if border && border.width > 0}
161
+ <use
162
+ href={`#${id}-border`}
163
+ fill="none"
164
+ stroke={mapColor(colorMode, border.color)}
165
+ stroke-width={border.width}
166
+ />
167
+ {/if}
168
+ </g>
169
+ </svg>
170
+ </div>
151
171
 
152
- .rc-pw-image {
172
+ <style>
173
+ img {
153
174
  width: 100%;
154
175
  height: 100%;
155
- object-fit: cover;
156
- display: block;
157
- }
158
-
159
- .rc-pw-image-overlay {
160
- position: absolute;
161
- inset: 0;
176
+ object-fit: contain;
177
+ object-position: center;
162
178
  }
163
179
  </style>
@@ -1,4 +1,4 @@
1
- import type { ImageProps } from "../../data/entities";
1
+ import type { ImageProps } from "../../types/components/image";
2
2
  declare const Image: import("svelte").Component<ImageProps, {}, "">;
3
3
  type Image = ReturnType<typeof Image>;
4
4
  export default Image;