@hyvor/design 1.1.10 → 1.1.12-beta.1

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.
@@ -0,0 +1,56 @@
1
+ <script lang="ts">
2
+ import type { Snippet } from "svelte";
3
+
4
+ interface Props {
5
+ label: string | Snippet;
6
+ content?: string;
7
+ children?: Snippet;
8
+ }
9
+
10
+ let { label, content, children }: Props = $props();
11
+
12
+ const labelId = `detail-card-${Math.random().toString(36).substring(2, 15)}`;
13
+
14
+ </script>
15
+
16
+ <div class="detail-card" role="region" aria-labelledby={labelId}>
17
+
18
+ <div class="label" id={labelId}>
19
+ {#if typeof label === "string"}
20
+ {label}
21
+ {:else}
22
+ {@render label()}
23
+ {/if}
24
+ </div>
25
+
26
+ <div class="content">
27
+ {#if children}
28
+ {@render children()}
29
+ {:else if content}
30
+ {content}
31
+ {/if}
32
+ </div>
33
+
34
+ </div>
35
+
36
+ <style>
37
+ .detail-card {
38
+ background: var(--hover);
39
+ padding: 15px 20px;
40
+ border-radius: var(--box-radius);
41
+ border: 1px solid var(--border);
42
+ }
43
+ .label {
44
+ display: block;
45
+ font-size: 12px;
46
+ font-weight: 600;
47
+ color: var(--text-light);
48
+ text-transform: uppercase;
49
+ letter-spacing: 0.5px;
50
+ margin-bottom: 6px;
51
+ }
52
+ .content {
53
+ font-size: 14px;
54
+ word-break: break-word;
55
+ }
56
+ </style>
@@ -0,0 +1,9 @@
1
+ import type { Snippet } from "svelte";
2
+ interface Props {
3
+ label: string | Snippet;
4
+ content?: string;
5
+ children?: Snippet;
6
+ }
7
+ declare const DetailCard: import("svelte").Component<Props, {}, "">;
8
+ type DetailCard = ReturnType<typeof DetailCard>;
9
+ export default DetailCard;
@@ -0,0 +1,25 @@
1
+ <script lang="ts">
2
+ import type { Snippet } from "svelte";
3
+
4
+ interface Props {
5
+ children?: Snippet
6
+ min?: number;
7
+ }
8
+
9
+ let {
10
+ children,
11
+ min = 300
12
+ }: Props = $props();
13
+ </script>
14
+
15
+ <div class="cards" style="--min: {min}px">
16
+ {@render children?.()}
17
+ </div>
18
+
19
+ <style>
20
+ .cards {
21
+ display: grid;
22
+ grid-template-columns: repeat(auto-fit, minmax(var(--min), 1fr));
23
+ gap: 10px;
24
+ }
25
+ </style>
@@ -0,0 +1,8 @@
1
+ import type { Snippet } from "svelte";
2
+ interface Props {
3
+ children?: Snippet;
4
+ min?: number;
5
+ }
6
+ declare const DetailCards: import("svelte").Component<Props, {}, "">;
7
+ type DetailCards = ReturnType<typeof DetailCards>;
8
+ export default DetailCards;
@@ -15,6 +15,8 @@ export { default as TabbedCodeBlock } from './CodeBlock/TabbedCodeBlock.svelte';
15
15
  export { default as ColorPicker } from './ColorPicker/ColorPicker.svelte';
16
16
  export { default as DarkProvider } from './Dark/DarkProvider.svelte';
17
17
  export { default as DarkToggle } from './Dark/DarkToggle.svelte';
18
+ export { default as DetailCard } from './DetailCard/DetailCard.svelte';
19
+ export { default as DetailCards } from './DetailCard/DetailCards.svelte';
18
20
  export { default as Dropdown } from './Dropdown/Dropdown.svelte';
19
21
  export { default as Divider } from './Divider/Divider.svelte';
20
22
  export { default as Caption } from './FormControl/Caption.svelte';
@@ -15,6 +15,8 @@ export { default as TabbedCodeBlock } from './CodeBlock/TabbedCodeBlock.svelte';
15
15
  export { default as ColorPicker } from './ColorPicker/ColorPicker.svelte';
16
16
  export { default as DarkProvider } from './Dark/DarkProvider.svelte';
17
17
  export { default as DarkToggle } from './Dark/DarkToggle.svelte';
18
+ export { default as DetailCard } from './DetailCard/DetailCard.svelte';
19
+ export { default as DetailCards } from './DetailCard/DetailCards.svelte';
18
20
  export { default as Dropdown } from './Dropdown/Dropdown.svelte';
19
21
  export { default as Divider } from './Divider/Divider.svelte';
20
22
  export { default as Caption } from './FormControl/Caption.svelte';
@@ -0,0 +1,75 @@
1
+ <script lang="ts">
2
+ import Link from '../../components/Link/Link.svelte';
3
+ import Modal from '../../components/Modal/Modal.svelte';
4
+ import { replaceState } from '$app/navigation';
5
+ import { onMount } from 'svelte';
6
+
7
+ let partner: string | null = $state(null);
8
+ let showModal = $state(false);
9
+
10
+ onMount(() => {
11
+ const params = new URLSearchParams(window.location.search);
12
+ partner = params.get('partner');
13
+
14
+ if (partner) {
15
+ showModal = true;
16
+ }
17
+ });
18
+
19
+ function handleConsent() {
20
+ const coreUrl = `${location.protocol}//${location.hostname.split('.').slice(-2).join('.')}`;
21
+
22
+ fetch(coreUrl + '/api/public/affiliate/placement', {
23
+ method: 'POST',
24
+ headers: {
25
+ 'Content-Type': 'application/json'
26
+ },
27
+ body: JSON.stringify({
28
+ partner: partner,
29
+ url: window.location.href
30
+ }),
31
+ credentials: 'include'
32
+ }).then((response) => {
33
+ if (response.ok) {
34
+ console.info('Affiliate placement recorded for partner:', partner);
35
+ }
36
+ }).finally(() => {
37
+ const url = new URL(window.location.href);
38
+ url.searchParams.delete('partner');
39
+ replaceState(url, {});
40
+ showModal = false;
41
+ });
42
+ }
43
+ </script>
44
+
45
+ <Modal
46
+ title="Referred by {partner}"
47
+ bind:show={showModal}
48
+ closeOnOutsideClick={false}
49
+ footer={
50
+ {
51
+ cancel: {
52
+ text: "Do not track"
53
+ },
54
+ confirm: {
55
+ text: "Ok, Visit Site",
56
+ }
57
+ }
58
+ }
59
+ on:confirm={handleConsent}
60
+ >
61
+ <div class="notice">
62
+ You visited our site through our affiliate partner <strong>{partner}</strong>. To track this referral, we will place a small
63
+ cookie in your browser. This cookie helps us identify which affiliate partner referred you
64
+ if you sign up. It does not collect any personal data.
65
+ </div>
66
+ <p>
67
+ You can read more in our <Link href="https://hyvor.com/privacy" target="_blank">Privacy Policy</Link>.
68
+ </p>
69
+ </Modal>
70
+
71
+ <style>
72
+ .notice {
73
+ line-height: 24px;
74
+ }
75
+ </style>
@@ -0,0 +1,3 @@
1
+ declare const Affiliate: import("svelte").Component<Record<string, never>, {}, "">;
2
+ type Affiliate = ReturnType<typeof Affiliate>;
3
+ export default Affiliate;
@@ -13,6 +13,7 @@
13
13
  import LanguageToggle from '../../components/Internationalization/LanguageToggle.svelte';
14
14
  import IconBluesky from '@hyvor/icons/IconBluesky';
15
15
  import { SOCIAL_LINKS, type Socials } from '../social.js';
16
+ import Affiliate from '../Affiliate/Affiliate.svelte';
16
17
 
17
18
  const year = new Date().getFullYear();
18
19
 
@@ -20,12 +21,14 @@
20
21
  email?: string | null;
21
22
  social?: Partial<Socials>;
22
23
  center?: import('svelte').Snippet;
24
+ affiliate?: boolean;
23
25
  }
24
26
 
25
27
  let {
26
28
  email = null,
27
29
  social = $bindable({} as Record<string, string | null>),
28
- center
30
+ center,
31
+ affiliate = true
29
32
  }: Props = $props();
30
33
 
31
34
  social = {
@@ -109,6 +112,11 @@
109
112
  <div class="footer-bottom-right">From France 🇫🇷</div>
110
113
  </div>
111
114
  </Container>
115
+
116
+ {#if affiliate}
117
+ <Affiliate />
118
+ {/if}
119
+
112
120
  </footer>
113
121
 
114
122
  <style>
@@ -3,6 +3,7 @@ interface Props {
3
3
  email?: string | null;
4
4
  social?: Partial<Socials>;
5
5
  center?: import('svelte').Snippet;
6
+ affiliate?: boolean;
6
7
  }
7
8
  declare const Footer: import("svelte").Component<Props, {}, "social">;
8
9
  type Footer = ReturnType<typeof Footer>;
package/package.json CHANGED
@@ -59,5 +59,5 @@
59
59
  "publishConfig": {
60
60
  "access": "public"
61
61
  },
62
- "version": "1.1.10"
62
+ "version": "1.1.12-beta.1"
63
63
  }