@hyvor/design 2.0.0-beta.1 → 2.0.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.
Files changed (61) hide show
  1. package/README.md +9 -0
  2. package/dist/cloud/HyvorBar/BarProducts/BarProducts.svelte +1 -4
  3. package/dist/cloud/HyvorBar/BarUpdatesList.svelte +1 -3
  4. package/dist/cloud/HyvorBar/HyvorBar.svelte +0 -2
  5. package/dist/cloud/HyvorBar/bar.d.ts +1 -1
  6. package/dist/cloud/OrganizationMembers/OrganizationMembersSearch.svelte +1 -4
  7. package/dist/cloud/ResourceCreator/Accordian.svelte +2 -4
  8. package/dist/components/Accordion/Accordion.svelte +134 -134
  9. package/dist/components/ActionList/ActionList.svelte +2 -8
  10. package/dist/components/ActionList/ActionListGroup.svelte +1 -5
  11. package/dist/components/ActionList/ActionListItem.svelte +7 -7
  12. package/dist/components/Button/Button.svelte +2 -12
  13. package/dist/components/CodeBlock/CodeBlock.svelte +45 -28
  14. package/dist/components/CodeBlock/CodeBlock.svelte.d.ts +2 -3
  15. package/dist/components/CodeBlock/TabbedCodeBlock.svelte +60 -64
  16. package/dist/components/CodeBlock/TabbedCodeBlock.svelte.d.ts +1 -1
  17. package/dist/components/CodeBlock/getCode.d.ts +3 -1
  18. package/dist/components/CodeBlock/getCode.js +33 -50
  19. package/dist/components/ColorPicker/ColorPicker.svelte +1 -1
  20. package/dist/components/Dark/DarkProvider.svelte +1 -1
  21. package/dist/components/DetailCard/DetailCard.svelte +43 -46
  22. package/dist/components/DetailCard/DetailCard.svelte.d.ts +1 -1
  23. package/dist/components/DetailCard/DetailCards.svelte +13 -16
  24. package/dist/components/DetailCard/DetailCards.svelte.d.ts +1 -1
  25. package/dist/components/Dropdown/DropdownContent.svelte +1 -2
  26. package/dist/components/EmojiPicker/EmojiSelector.svelte +3 -14
  27. package/dist/components/EmojiPicker/emojidata.js +3 -3
  28. package/dist/components/FileUploader/Preview/Preview.svelte +1 -1
  29. package/dist/components/FileUploader/TabUpload/TabUpload.svelte +2 -4
  30. package/dist/components/FileUploader/file-uploader.js +5 -10
  31. package/dist/components/FileUploader/helpers.js +1 -1
  32. package/dist/components/IconButton/IconButton.svelte +2 -10
  33. package/dist/components/IconMessage/IconMessage.svelte +29 -44
  34. package/dist/components/Internationalization/LanguageToggle.svelte +2 -2
  35. package/dist/components/Internationalization/T.svelte +2 -9
  36. package/dist/components/Internationalization/i18n.js +3 -1
  37. package/dist/components/Loader/Loader.svelte +1 -3
  38. package/dist/components/Modal/ConfirmModalProvider.svelte +1 -3
  39. package/dist/components/Modal/Modal.svelte +16 -12
  40. package/dist/components/TabNav/TabNav.svelte +0 -2
  41. package/dist/components/TextInput/TextInput.svelte +29 -52
  42. package/dist/components/TextInput/TextInput.svelte.d.ts +5 -3
  43. package/dist/components/Textarea/Textarea.svelte +84 -98
  44. package/dist/index.css +4 -4
  45. package/dist/legacy.js +2 -2
  46. package/dist/marketing/Affiliate/Affiliate.svelte +53 -51
  47. package/dist/marketing/Container/Container.svelte +4 -5
  48. package/dist/marketing/Docs/Nav/Nav.svelte +1 -2
  49. package/dist/marketing/Footer/Footer.svelte +2 -2
  50. package/dist/marketing/Header/Header.svelte +131 -140
  51. package/dist/marketing/Header/Header.svelte.d.ts +3 -1
  52. package/dist/marketing/Header/HeaderNotification.svelte +64 -0
  53. package/dist/marketing/Header/HeaderNotification.svelte.d.ts +7 -0
  54. package/dist/marketing/cloud.d.ts +1 -0
  55. package/dist/marketing/cloud.js +15 -0
  56. package/dist/marketing/track/track.d.ts +0 -1
  57. package/dist/marketing/track/track.js +3 -6
  58. package/dist/variables.scss +1 -1
  59. package/package.json +24 -22
  60. package/dist/components/CodeBlock/hljs.scss +0 -228
  61. package/dist/components/CodeBlock/prism.scss +0 -375
@@ -1,23 +1,23 @@
1
1
  <script lang="ts">
2
2
  import Link from '../../components/Link/Link.svelte';
3
3
  import Modal from '../../components/Modal/Modal.svelte';
4
- import { replaceState } from '$app/navigation';
5
- import { onMount } from 'svelte';
4
+ import { replaceState } from '$app/navigation';
5
+ import { onMount } from 'svelte';
6
6
 
7
- let partner: string | null = $state(null);
8
- let showModal = $state(false);
7
+ let partner: string | null = $state(null);
8
+ let showModal = $state(false);
9
9
 
10
- onMount(() => {
11
- const params = new URLSearchParams(window.location.search);
12
- partner = params.get('partner');
10
+ onMount(() => {
11
+ const params = new URLSearchParams(window.location.search);
12
+ partner = params.get('partner');
13
13
 
14
- if (partner) {
15
- showModal = true;
16
- }
17
- });
14
+ if (partner) {
15
+ showModal = true;
16
+ }
17
+ });
18
18
 
19
- function handleConsent() {
20
- const coreUrl = `${location.protocol}//${location.hostname.split('.').slice(-2).join('.')}`;
19
+ function handleConsent() {
20
+ const coreUrl = `${location.protocol}//${location.hostname.split('.').slice(-2).join('.')}`;
21
21
 
22
22
  fetch(coreUrl + '/api/public/affiliate/placement', {
23
23
  method: 'POST',
@@ -29,47 +29,49 @@
29
29
  url: window.location.href
30
30
  }),
31
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
- }
32
+ })
33
+ .then((response) => {
34
+ if (response.ok) {
35
+ console.info('Affiliate placement recorded for partner:', partner);
36
+ }
37
+ })
38
+ .finally(() => {
39
+ const url = new URL(window.location.href);
40
+ url.searchParams.delete('partner');
41
+ replaceState(url, {});
42
+ showModal = false;
43
+ });
44
+ }
43
45
  </script>
44
46
 
45
47
  <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>
48
+ title="Referred by {partner}"
49
+ bind:show={showModal}
50
+ closeOnOutsideClick={false}
51
+ footer={{
52
+ cancel: {
53
+ text: 'Do not track'
54
+ },
55
+ confirm: {
56
+ text: 'Ok, Visit Site'
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
63
+ referral, we will place a small cookie in your browser. This cookie helps us identify which
64
+ affiliate partner referred you 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"
68
+ >Privacy Policy</Link
69
+ >.
70
+ </p>
69
71
  </Modal>
70
72
 
71
73
  <style>
72
- .notice {
73
- line-height: 24px;
74
- }
75
- </style>
74
+ .notice {
75
+ line-height: 24px;
76
+ }
77
+ </style>
@@ -2,16 +2,15 @@
2
2
  interface Props {
3
3
  as?: string;
4
4
  children?: import('svelte').Snippet;
5
- max?: boolean;
5
+ max?: boolean;
6
6
  }
7
7
 
8
- let { as = 'div', children, max = false
9
- }: Props = $props();
8
+ let { as = 'div', children, max = false }: Props = $props();
10
9
 
11
- let width= max ? '1400px' : '1000px';
10
+ let width = max ? '1400px' : '1000px';
12
11
  </script>
13
12
 
14
- <svelte:element this={as} class="container" style:width={width}>
13
+ <svelte:element this={as} class="container" style:width>
15
14
  {@render children?.()}
16
15
  </svelte:element>
17
16
 
@@ -27,8 +27,7 @@
27
27
  }
28
28
 
29
29
  const category =
30
- (activeEl.closest('.nav-category')?.querySelector('.name') as HTMLElement)?.innerText ||
31
- null;
30
+ (activeEl.closest('.nav-category')?.querySelector('.name') as HTMLElement)?.innerText || null;
32
31
 
33
32
  active = {
34
33
  name: activeEl.innerText,
@@ -24,7 +24,7 @@
24
24
  center?: import('svelte').Snippet;
25
25
  affiliate?: boolean;
26
26
  recordVisit?: boolean;
27
- max?: boolean;
27
+ max?: boolean;
28
28
  }
29
29
 
30
30
  let {
@@ -33,7 +33,7 @@
33
33
  center,
34
34
  affiliate = true,
35
35
  recordVisit = true,
36
- max = false,
36
+ max = false
37
37
  }: Props = $props();
38
38
 
39
39
  social = {
@@ -4,35 +4,46 @@
4
4
  import IconButton from '../../components/IconButton/IconButton.svelte';
5
5
  import Dropdown from '../../components/Dropdown/Dropdown.svelte';
6
6
  import IconList from '@hyvor/icons/IconList';
7
+ import HeaderNotification from './HeaderNotification.svelte';
7
8
 
8
9
  interface Props {
9
- logo: string;
10
+ product: string;
11
+ instance?: string;
12
+ logo?: string;
10
13
  name?: string;
11
14
  href?: string;
12
15
  subName?: undefined | string;
13
16
  darkToggle?: boolean;
14
17
  center?: import('svelte').Snippet;
15
18
  end?: import('svelte').Snippet;
16
- max?: boolean;
19
+ max?: boolean;
17
20
  }
18
21
 
19
22
  let {
23
+ product,
20
24
  logo,
25
+ instance = 'https://hyvor.com',
21
26
  name = 'HYVOR',
22
27
  href = '/',
23
28
  subName = undefined,
24
29
  darkToggle = true,
25
30
  center,
26
31
  end,
27
- max = false,
32
+ max = false
28
33
  }: Props = $props();
29
34
  </script>
30
35
 
31
36
  <header>
37
+ <HeaderNotification {instance} {product} />
32
38
  <Container as="nav" {max}>
33
39
  <div class="nav-start">
34
40
  <a class="nav-brand" {href}>
35
- <img src={logo} alt="Hyvor Logo" width="30" height="30" />
41
+ <img
42
+ src={logo || `${instance}/api/public/logo/${product}.svg`}
43
+ alt="{name + (subName ? ' ' + subName : '')} Logo"
44
+ width="30"
45
+ height="30"
46
+ />
36
47
  <span class="brand-product">
37
48
  <span class="brand">{name}</span>
38
49
  {#if subName}
@@ -56,25 +67,6 @@
56
67
  <DarkToggle />
57
68
  </span>
58
69
  {/if}
59
-
60
- <!-- <span class="mobile-nav-wrap">
61
- <Dropdown align="end" width={300}>
62
- <IconButton
63
- color="invisible"
64
- slot="trigger"
65
- >
66
- <IconList size={18} />
67
- </IconButton>
68
- <div slot="content" class="mobile-content">
69
- <div class="mobile-inner center">
70
- <slot name="center" />
71
- </div>
72
- <div class="mobile-inner end">
73
- <slot name="end" />
74
- </div>
75
- </div>
76
- </Dropdown>
77
- </span> -->
78
70
  </div>
79
71
 
80
72
  <span class="mobile-nav-wrap">
@@ -101,120 +93,119 @@
101
93
 
102
94
  <div class="header-space"></div>
103
95
 
104
- <style>.header-space {
105
- height: var(--header-height);
106
- }
107
-
108
- header {
109
- position: fixed;
110
- top: 0;
111
- left: 0;
112
- width: 100%;
113
- z-index: 100;
114
- background-color: var(--background, var(--accent-lightest));
115
- border-bottom: 1px solid var(--border);
116
- height: var(--header-height);
117
- display: flex;
118
- align-items: center;
119
- }
120
-
121
- header :global(nav) {
122
- display: flex;
123
- align-items: center;
124
- }
125
-
126
- .nav-brand {
127
- display: inline-block;
128
- line-height: inherit;
129
- white-space: nowrap;
130
- color: inherit;
131
- text-decoration: none;
132
- font-weight: 600;
133
- }
134
-
135
- .nav-brand img {
136
- vertical-align: middle;
137
- }
138
-
139
- .brand-product {
140
- vertical-align: middle;
141
- display: inline-flex;
142
- flex-direction: column;
143
- justify-content: center;
144
- line-height: 14px;
145
- }
146
-
147
- .brand-product .brand {
148
- font-size: 14px;
149
- }
150
-
151
- .brand-product .product {
152
- font-size: 12px;
153
- font-weight: normal;
154
- color: var(--text-light);
155
- }
156
-
157
- .nav-center {
158
- flex: 1;
159
- display: flex;
160
- align-items: center;
161
- gap: 6px;
162
- justify-content: center;
163
- }
164
-
165
- .nav-end {
166
- display: flex;
167
- align-items: center;
168
- gap: 6px;
169
- }
170
-
171
- .mobile-nav-wrap {
172
- display: none;
173
- }
174
-
175
- .dark-mobile {
176
- display: inline-flex;
177
- align-items: center;
178
- }
179
-
180
- .dark-toggle-wrap {
181
- margin-left: 8px;
182
- }
183
-
184
- @media screen and (max-width: 992px) {
185
- .nav-center {
186
- display: none;
187
- }
188
- .nav-end {
189
- display: none;
190
- }
191
- .mobile-nav-wrap {
192
- display: inline-block;
193
- }
194
- .dark-mobile {
195
- flex: 1;
196
- text-align: right;
197
- display: inline-block;
198
- }
199
- }
200
- .mobile-content,
201
- .mobile-inner {
202
- display: flex;
203
- flex-direction: column;
204
- }
205
-
206
- .mobile-content {
207
- gap: 10px;
208
- }
209
-
210
- .mobile-content :global(.button) {
211
- display: flex;
212
- }
213
-
214
- /*
215
- Scroll padding top is used to prevent the content from being hidden behind the header
216
- https://developer.mozilla.org/en-US/docs/Web/CSS/scroll-padding-top
217
- */
218
- :global(html) {
219
- scroll-padding-top: calc(var(--header-height) + 20px);
220
- }</style>
96
+ <style>
97
+ .header-space {
98
+ height: var(--header-height);
99
+ }
100
+
101
+ header {
102
+ position: fixed;
103
+ top: 0;
104
+ left: 0;
105
+ width: 100%;
106
+ z-index: 100;
107
+ background-color: var(--background, var(--accent-lightest));
108
+ border-bottom: 1px solid var(--border);
109
+ height: var(--header-height);
110
+ display: flex;
111
+ flex-direction: column;
112
+ }
113
+
114
+ header :global(> nav) {
115
+ display: flex;
116
+ align-items: center;
117
+ flex: 1;
118
+ }
119
+ .nav-brand {
120
+ display: inline-block;
121
+ line-height: inherit;
122
+ white-space: nowrap;
123
+ color: inherit;
124
+ text-decoration: none;
125
+ font-weight: 600;
126
+ }
127
+ .nav-brand img {
128
+ vertical-align: middle;
129
+ }
130
+
131
+ .brand-product {
132
+ vertical-align: middle;
133
+ display: inline-flex;
134
+ flex-direction: column;
135
+ justify-content: center;
136
+ line-height: 14px;
137
+ }
138
+ .brand-product .brand {
139
+ font-size: 14px;
140
+ }
141
+ .brand-product .product {
142
+ font-size: 12px;
143
+ font-weight: normal;
144
+ color: var(--text-light);
145
+ }
146
+
147
+ .nav-center {
148
+ flex: 1;
149
+ display: flex;
150
+ align-items: center;
151
+ gap: 6px;
152
+ justify-content: center;
153
+ }
154
+
155
+ .nav-end {
156
+ display: flex;
157
+ align-items: center;
158
+ gap: 6px;
159
+ }
160
+
161
+ .mobile-nav-wrap {
162
+ display: none;
163
+ }
164
+
165
+ .dark-mobile {
166
+ display: inline-flex;
167
+ align-items: center;
168
+ }
169
+
170
+ .dark-toggle-wrap {
171
+ margin-left: 8px;
172
+ }
173
+
174
+ @media screen and (max-width: 992px) {
175
+ .nav-center {
176
+ display: none;
177
+ }
178
+ .nav-end {
179
+ display: none;
180
+ }
181
+ .mobile-nav-wrap {
182
+ display: inline-block;
183
+ }
184
+ .dark-mobile {
185
+ flex: 1;
186
+ text-align: right;
187
+ display: inline-block;
188
+ }
189
+ }
190
+
191
+ .mobile-content,
192
+ .mobile-inner {
193
+ display: flex;
194
+ flex-direction: column;
195
+ }
196
+ .mobile-content {
197
+ gap: 10px;
198
+ }
199
+
200
+ .mobile-content :global(.button) {
201
+ display: flex;
202
+ }
203
+
204
+ /*
205
+ Scroll padding top is used to prevent the content from being hidden behind the header
206
+ https://developer.mozilla.org/en-US/docs/Web/CSS/scroll-padding-top
207
+ */
208
+ :global(html) {
209
+ scroll-padding-top: calc(var(--header-height) + 20px);
210
+ }
211
+ </style>
@@ -1,5 +1,7 @@
1
1
  interface Props {
2
- logo: string;
2
+ product: string;
3
+ instance?: string;
4
+ logo?: string;
3
5
  name?: string;
4
6
  href?: string;
5
7
  subName?: undefined | string;
@@ -0,0 +1,64 @@
1
+ <script lang="ts">
2
+ import { onMount } from 'svelte';
3
+ import { slide } from 'svelte/transition';
4
+ import { isCloud } from '../cloud.js';
5
+ import IconMegaphone from '@hyvor/icons/IconMegaphone';
6
+ import type { BarUpdate } from '../../cloud/HyvorBar/bar.js';
7
+
8
+ let notificationUpdate: BarUpdate | null = $state(null);
9
+
10
+ interface Props {
11
+ instance: string;
12
+ product: string;
13
+ }
14
+
15
+ let { instance, product }: Props = $props();
16
+
17
+ function set(u: BarUpdate) {
18
+ notificationUpdate = u;
19
+ document.documentElement.style.setProperty('--header-height', '85px');
20
+ }
21
+
22
+ onMount(() => {
23
+ if (!isCloud(false)) return;
24
+
25
+ fetch(instance + '/api/public/updates/notification?type=' + product)
26
+ .then((response) => response.json())
27
+ .then((data) => {
28
+ if (data.update) {
29
+ set(data.update);
30
+ }
31
+ });
32
+ });
33
+ </script>
34
+
35
+ {#if notificationUpdate}
36
+ <a
37
+ class="header-notification"
38
+ href={notificationUpdate.url}
39
+ target="_blank"
40
+ transition:slide={{ duration: 300 }}
41
+ >
42
+ <IconMegaphone size={12} />&nbsp;&nbsp;
43
+ {notificationUpdate.title}&nbsp;&nbsp;&rarr;
44
+ </a>
45
+ {/if}
46
+
47
+ <style>
48
+ .header-notification {
49
+ display: block;
50
+ background-color: var(--accent);
51
+ color: var(--accent-text);
52
+ height: 30px;
53
+ display: flex;
54
+ align-items: center;
55
+ justify-content: center;
56
+ font-size: 14px;
57
+ cursor: pointer;
58
+ font-weight: 600;
59
+ transition: opacity 0.2s;
60
+ }
61
+ .header-notification:hover {
62
+ opacity: 0.8;
63
+ }
64
+ </style>
@@ -0,0 +1,7 @@
1
+ interface Props {
2
+ instance: string;
3
+ product: string;
4
+ }
5
+ declare const HeaderNotification: import("svelte").Component<Props, {}, "">;
6
+ type HeaderNotification = ReturnType<typeof HeaderNotification>;
7
+ export default HeaderNotification;
@@ -0,0 +1 @@
1
+ export declare function isCloud(forceProd?: boolean): boolean;
@@ -0,0 +1,15 @@
1
+ export function isCloud(forceProd = true) {
2
+ if (typeof window === 'undefined') {
3
+ return false;
4
+ }
5
+ const hostname = window.location.hostname;
6
+ function isDomain(domain) {
7
+ return hostname === domain || hostname.endsWith(`.${domain}`);
8
+ }
9
+ let domains = ['hyvor.com'];
10
+ if (forceProd === false) {
11
+ domains.push('hyvor.localhost');
12
+ domains.push('hyvorstaging.com');
13
+ }
14
+ return domains.some(isDomain);
15
+ }
@@ -6,7 +6,6 @@ interface InitOptions {
6
6
  }
7
7
  declare class Track {
8
8
  private op;
9
- private isProductionDomain;
10
9
  init({ forceTrack, openPanelApiUrl, openPanelClientId, context }?: InitOptions): void;
11
10
  ready(): boolean;
12
11
  private warnNoOp;
@@ -1,12 +1,9 @@
1
1
  import { OpenPanel } from '@openpanel/web';
2
+ import { isCloud } from '../cloud.js';
2
3
  class Track {
3
4
  op;
4
- isProductionDomain() {
5
- const hostname = window.location.hostname;
6
- return hostname === 'hyvor.com' || hostname.endsWith('.hyvor.com');
7
- }
8
5
  init({ forceTrack = false, openPanelApiUrl = 'https://op.hyvor.com/api', openPanelClientId = 'b11f6143-a6b0-4fa4-a86c-3969c01dbb1d', context = {} } = {}) {
9
- if (!forceTrack && !this.isProductionDomain()) {
6
+ if (!forceTrack && !isCloud()) {
10
7
  console.log('Tracking is disabled in non-production domains.');
11
8
  return;
12
9
  }
@@ -15,7 +12,7 @@ class Track {
15
12
  clientId: openPanelClientId,
16
13
  trackScreenViews: true,
17
14
  trackOutgoingLinks: true,
18
- trackAttributes: true,
15
+ trackAttributes: true
19
16
  });
20
17
  if (Object.keys(context).length > 0) {
21
18
  this.op.setGlobalProperties(context);
@@ -8,7 +8,7 @@
8
8
  --accent: #000;
9
9
  --accent-light: #bdbdbd;
10
10
  --accent-lightest: #fafafa;
11
- --accent-light-mid: #818181;
11
+ --accent-light-mid: #818181;
12
12
  --accent-text: #fff;
13
13
 
14
14
  --border: #e1e1e1;