@hyvor/design 2.0.6 → 2.0.8-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.
@@ -1,13 +1,22 @@
1
1
  <script lang="ts">
2
- import { getCloudContext } from '../../CloudContext/cloudContextState.svelte.js';
2
+ import { getCloudContext, type ResolvedLicense } from '../../CloudContext/cloudContextState.svelte.js';
3
3
  import Tag from '../../../components/Tag/Tag.svelte';
4
+ import type { TagSize } from '../../../components/Tag/tag.types.js';
4
5
  import Tooltip from '../../../components/Tooltip/Tooltip.svelte';
5
6
  import IconBuilding from '@hyvor/icons/IconBuilding';
6
7
  import type { Component } from 'svelte';
7
8
 
8
- let { name } = $props();
9
+ interface Props {
10
+ name: string; // product name like Hyvor Talk
11
+ customLicense?: ResolvedLicense;
12
+ size?: TagSize;
13
+ tooltip?: boolean;
14
+ href?: string | null;
15
+ }
16
+
17
+ let { name, customLicense, size = 'medium', tooltip: showTooltip = true, href = "/console/billing" }: Props = $props();
9
18
 
10
- const { license } = $derived(getCloudContext());
19
+ const license = $derived(customLicense || getCloudContext().license);
11
20
 
12
21
  function daysDiff(unix: number) {
13
22
  const date = new Date(unix * 1000);
@@ -72,7 +81,7 @@
72
81
  const s = trialDays === 1 ? '' : 's';
73
82
 
74
83
  return {
75
- name: `Trial License (${trialDays}d)`,
84
+ name: `Trial (${trialDays}d)`,
76
85
  tooltip: `You organization is currently using a trial license for ${name}. It will expire in ${trialDays} day${s}.`,
77
86
  tagColor: 'orange'
78
87
  };
@@ -91,12 +100,12 @@
91
100
  </script>
92
101
 
93
102
  {#if config}
94
- <a class="wrap" href="/console/billing">
95
- <Tooltip position="bottom">
103
+ <a class="wrap" href={href}>
104
+ <Tooltip position="bottom" disabled={showTooltip === false}>
96
105
  {#snippet tooltip()}
97
106
  {config.tooltip}
98
107
  {/snippet}
99
- <Tag color={config.tagColor}>
108
+ <Tag color={config.tagColor} {size}>
100
109
  {#snippet start()}
101
110
  {#if config.tagIcon}
102
111
  <config.tagIcon size={10} />
@@ -1,6 +1,13 @@
1
+ import { type ResolvedLicense } from '../../CloudContext/cloudContextState.svelte.js';
2
+ import type { TagSize } from '../../../components/Tag/tag.types.js';
1
3
  import type { Component } from 'svelte';
2
- declare const BarLicense: Component<{
3
- name: any;
4
- }, {}, "">;
4
+ interface Props {
5
+ name: string;
6
+ customLicense?: ResolvedLicense;
7
+ size?: TagSize;
8
+ tooltip?: boolean;
9
+ href?: string | null;
10
+ }
11
+ declare const BarLicense: Component<Props, {}, "">;
5
12
  type BarLicense = ReturnType<typeof BarLicense>;
6
13
  export default BarLicense;
@@ -2,6 +2,7 @@ export { default as CloudContext } from './CloudContext/CloudContext.svelte';
2
2
  export { getCloudContext, setCloudContext, type CloudContext as CloudContextType, type CloudContextUser, type CloudContextOrganization, type OrganizationRole, type OrganizationMember, type ResolvedLicense } from './CloudContext/cloudContextState.svelte.js';
3
3
  export { default as HyvorBar } from './HyvorBar/HyvorBar.svelte';
4
4
  export { bar as hyvorBar } from './HyvorBar/bar.js';
5
+ export { default as BarLicense } from './HyvorBar/BarNotice/BarLicense.svelte';
5
6
  export { default as ResourceCreator } from './ResourceCreator/ResourceCreator.svelte';
6
7
  export { default as OrganizationMemberSearch } from './OrganizationMembers/OrganizationMembersSearch.svelte';
7
8
  export { default as OrganizationCreator } from './OrganizationCreator/OrganizationCreator.svelte';
@@ -2,6 +2,7 @@ export { default as CloudContext } from './CloudContext/CloudContext.svelte';
2
2
  export { getCloudContext, setCloudContext } from './CloudContext/cloudContextState.svelte.js';
3
3
  export { default as HyvorBar } from './HyvorBar/HyvorBar.svelte';
4
4
  export { bar as hyvorBar } from './HyvorBar/bar.js';
5
+ export { default as BarLicense } from './HyvorBar/BarNotice/BarLicense.svelte';
5
6
  export { default as ResourceCreator } from './ResourceCreator/ResourceCreator.svelte';
6
7
  export { default as OrganizationMemberSearch } from './OrganizationMembers/OrganizationMembersSearch.svelte';
7
8
  export { default as OrganizationCreator } from './OrganizationCreator/OrganizationCreator.svelte';
@@ -20,7 +20,7 @@
20
20
  }
21
21
 
22
22
  let {
23
- selected = $bindable(false),
23
+ selected = $bindable(),
24
24
  disabled = false,
25
25
  type = 'default',
26
26
  start,
@@ -30,8 +30,6 @@
30
30
  ...rest
31
31
  }: Props = $props();
32
32
 
33
- selected = selection() !== 'none' && selected;
34
-
35
33
  const dispatch = createEventDispatcher();
36
34
 
37
35
  function handleClick() {
@@ -4,13 +4,13 @@
4
4
 
5
5
  interface Props {
6
6
  selection: 'none' | 'single' | 'multi';
7
- selected: boolean;
7
+ selected?: boolean | undefined;
8
8
  }
9
9
 
10
- let { selection, selected = $bindable(false) }: Props = $props();
10
+ let { selection, selected = $bindable() }: Props = $props();
11
11
  </script>
12
12
 
13
- {#if selection !== 'none'}
13
+ {#if selection !== 'none' && selected !== undefined}
14
14
  <span class="selected">
15
15
  {#if selection === 'multi'}
16
16
  <span style="transform:scale(0.9);transform-origin:top">
@@ -1,6 +1,6 @@
1
1
  interface Props {
2
2
  selection: 'none' | 'single' | 'multi';
3
- selected: boolean;
3
+ selected?: boolean | undefined;
4
4
  }
5
5
  declare const Selected: import("svelte").Component<Props, {}, "selected">;
6
6
  type Selected = ReturnType<typeof Selected>;
@@ -121,6 +121,7 @@
121
121
  font-weight: 600;
122
122
  font-size: 14px;
123
123
  border-radius: 20px;
124
+ line-height: 1;
124
125
  cursor: pointer;
125
126
  --local-hover-shadow-size: 2.5px;
126
127
  --local-hover-shadow-color: var(--accent-light);
@@ -160,8 +161,7 @@
160
161
 
161
162
  /* Sizes */
162
163
  .button.x-small {
163
- height: 20px;
164
- padding: 0 8px;
164
+ padding: 4px 8px;
165
165
  font-size: 12px;
166
166
  --local-hover-shadow-size: 1px;
167
167
  }
@@ -170,8 +170,7 @@
170
170
  }
171
171
 
172
172
  .button.small {
173
- height: 26px;
174
- padding: 0 12px;
173
+ padding: 6px 12px;
175
174
  --local-hover-shadow-size: 2px;
176
175
  }
177
176
  .button.small:active {
@@ -185,13 +184,11 @@
185
184
  }
186
185
 
187
186
  .button.medium {
188
- height: 30px;
189
- padding: 0 14px;
187
+ padding: 8px 14px;
190
188
  }
191
189
 
192
190
  .button.large {
193
- height: 36px;
194
- padding: 0 20px;
191
+ padding: 11px 20px;
195
192
  --local-hover-shadow-size: 3px;
196
193
  }
197
194
  .button.large:active {
@@ -199,8 +196,7 @@
199
196
  }
200
197
 
201
198
  .button.x-large {
202
- height: 40px;
203
- padding: 0 26px;
199
+ padding: 12px 26px;
204
200
  font-size: 16px;
205
201
  }
206
202
 
@@ -0,0 +1,73 @@
1
+ <script lang="ts">
2
+ interface Props {
3
+ logo: string;
4
+ size?: number;
5
+ }
6
+
7
+ let { logo, size = 100 }: Props = $props();
8
+ </script>
9
+
10
+ <div class="loader">
11
+ <div class="hyvor-icon">
12
+ <img src={logo} alt="Logo" width={size} height={size} />
13
+ </div>
14
+ <div class="shadow-wrap">
15
+ <div class="shadow" style="width: calc({size}px * 0.95); height: calc({size}px * 0.12);"></div>
16
+ </div>
17
+ </div>
18
+
19
+ <style>
20
+ @keyframes bounce {
21
+ 0% {
22
+ transform: translateY(0);
23
+ }
24
+ 50% {
25
+ transform: translateY(-24px);
26
+ }
27
+ 100% {
28
+ transform: translateY(0);
29
+ }
30
+ }
31
+
32
+ @keyframes shadowPulse {
33
+ 0%,
34
+ 100% {
35
+ transform: scale(1.2);
36
+ opacity: 1;
37
+ }
38
+ 50% {
39
+ transform: scale(0.8);
40
+ opacity: 0.4;
41
+ }
42
+ }
43
+
44
+ .loader {
45
+ position: fixed;
46
+ display: flex;
47
+ flex-direction: column;
48
+ align-items: center;
49
+ justify-content: center;
50
+ inset: 0;
51
+ }
52
+
53
+ .hyvor-icon {
54
+ animation: bounce 1.2s infinite;
55
+ animation-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
56
+ }
57
+
58
+ .shadow-wrap {
59
+ height: 20px;
60
+ display: flex;
61
+ justify-content: center;
62
+ align-items: flex-start;
63
+ }
64
+
65
+ .shadow {
66
+ background: rgba(0, 0, 0, 0.2);
67
+ border-radius: 50%;
68
+ filter: blur(8px);
69
+ will-change: transform, opacity;
70
+ animation: shadowPulse 1.2s infinite;
71
+ animation-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
72
+ }
73
+ </style>
@@ -0,0 +1,7 @@
1
+ interface Props {
2
+ logo: string;
3
+ size?: number;
4
+ }
5
+ declare const ConsoleLoader: import("svelte").Component<Props, {}, "">;
6
+ type ConsoleLoader = ReturnType<typeof ConsoleLoader>;
7
+ export default ConsoleLoader;
@@ -1,5 +1,4 @@
1
1
  <script lang="ts">
2
- import IconCardImage from '@hyvor/icons/IconCardImage';
3
2
  import IconCaretLeft from '@hyvor/icons/IconCaretLeft';
4
3
  import IconCloudUpload from '@hyvor/icons/IconCloudUpload';
5
4
  import Button from '../Button/Button.svelte';
@@ -46,8 +45,8 @@
46
45
  Back
47
46
  </Button>
48
47
  {:else}
49
- <TabNav bind:active={tab}>
50
- <TabNavItem name="upload">
48
+ <TabNav>
49
+ <TabNavItem name="upload" active>
51
50
  {#snippet start()}
52
51
  <IconCloudUpload />
53
52
  {/snippet}
@@ -8,10 +8,12 @@ export interface Footer {
8
8
  */
9
9
  cancel?: false | {
10
10
  text?: string;
11
+ disabled?: boolean;
11
12
  props?: ComponentProps<typeof Button>;
12
13
  };
13
14
  confirm?: false | {
14
15
  danger?: boolean;
16
+ disabled?: boolean;
15
17
  text?: string;
16
18
  props?: ComponentProps<typeof Button>;
17
19
  };
@@ -1,31 +1,23 @@
1
1
  <script lang="ts">
2
- import { onMount, setContext } from 'svelte';
3
- import { writable } from 'svelte/store';
2
+ import { setContext } from 'svelte';
4
3
 
5
4
  interface Props {
6
- active: string;
5
+ basePath?: string;
6
+ replaceState?: boolean;
7
7
  children?: import('svelte').Snippet;
8
- [key: string]: any;
9
8
  }
10
9
 
11
- let { active = $bindable(), children, ...rest }: Props = $props();
10
+ let { children, basePath, replaceState = false }: Props = $props();
12
11
 
13
- const activeStore = writable(active);
14
- setContext('tab-nav-active', activeStore);
12
+ const tabNavState = {
13
+ basePath,
14
+ replaceState
15
+ };
15
16
 
16
- $effect(() => {
17
- activeStore.set(active);
18
- });
19
-
20
- onMount(() => {
21
- const unsubscribe = activeStore.subscribe((value) => {
22
- active = value;
23
- });
24
- return unsubscribe;
25
- });
17
+ setContext('tab-nav-state', tabNavState);
26
18
  </script>
27
19
 
28
- <div class="tab-nav" {...rest}>
20
+ <div class="tab-nav">
29
21
  {@render children?.()}
30
22
  </div>
31
23
 
@@ -1,8 +1,8 @@
1
1
  interface Props {
2
- active: string;
2
+ basePath?: string;
3
+ replaceState?: boolean;
3
4
  children?: import('svelte').Snippet;
4
- [key: string]: any;
5
5
  }
6
- declare const TabNav: import("svelte").Component<Props, {}, "active">;
6
+ declare const TabNav: import("svelte").Component<Props, {}, "">;
7
7
  type TabNav = ReturnType<typeof TabNav>;
8
8
  export default TabNav;
@@ -1,9 +1,8 @@
1
1
  <script lang="ts">
2
- import { createBubbler, handlers } from 'svelte/legacy';
3
-
4
- const bubble = createBubbler();
5
2
  import { getContext } from 'svelte';
6
- import type { Writable } from 'svelte/store';
3
+ import { page } from '$app/state';
4
+ import { goto } from '$app/navigation';
5
+ import type { TabNavState } from './tabnav.js';
7
6
 
8
7
  interface Props {
9
8
  active?: boolean;
@@ -11,26 +10,40 @@
11
10
  start?: import('svelte').Snippet;
12
11
  children?: import('svelte').Snippet;
13
12
  end?: import('svelte').Snippet;
14
- [key: string]: any;
13
+ index?: boolean; // index for path-based activation
14
+
15
+ onclick?: (event: MouseEvent) => void;
16
+ }
17
+
18
+ let { active = false, name, start, children, end, index, onclick }: Props = $props();
19
+
20
+ const tabNavState = getContext('tab-nav-state') as TabNavState;
21
+
22
+ function getTabPath() {
23
+ if (!tabNavState.basePath) return '';
24
+ return index ? `${tabNavState.basePath}` : `${tabNavState.basePath}/${name}`;
15
25
  }
16
26
 
17
- let { active = false, name, start, children, end, ...rest }: Props = $props();
27
+ let isActive = $derived.by(() => {
28
+ if (active) return true;
18
29
 
19
- const activeStore = getContext('tab-nav-active') as Writable<string>;
30
+ if (tabNavState.basePath) {
31
+ const currentUrl = page.url.pathname;
32
+ return currentUrl === getTabPath();
33
+ }
20
34
 
21
- let isActive = $derived($activeStore === name || active);
35
+ return false;
36
+ });
22
37
 
23
- function handleClick() {
24
- activeStore.set(name);
38
+ function handleClick(event: MouseEvent) {
39
+ if (tabNavState.basePath) {
40
+ goto(getTabPath());
41
+ }
42
+ onclick?.(event);
25
43
  }
26
44
  </script>
27
45
 
28
- <button
29
- class="tab"
30
- class:active={isActive}
31
- onclick={handlers(handleClick, bubble('click'))}
32
- {...rest}
33
- >
46
+ <button class="tab" class:active={isActive} onclick={handleClick}>
34
47
  {#if start}
35
48
  <span class="start">
36
49
  {@render start?.()}
@@ -4,7 +4,8 @@ interface Props {
4
4
  start?: import('svelte').Snippet;
5
5
  children?: import('svelte').Snippet;
6
6
  end?: import('svelte').Snippet;
7
- [key: string]: any;
7
+ index?: boolean;
8
+ onclick?: (event: MouseEvent) => void;
8
9
  }
9
10
  declare const TabNavItem: import("svelte").Component<Props, {}, "">;
10
11
  type TabNavItem = ReturnType<typeof TabNavItem>;
@@ -0,0 +1,4 @@
1
+ export interface TabNavState {
2
+ basePath: string | undefined;
3
+ replaceState: boolean;
4
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -1,11 +1,12 @@
1
1
  <script lang="ts">
2
2
  import { createBubbler } from 'svelte/legacy';
3
+ import type { TagSize } from './tag.types.js';
3
4
 
4
5
  const bubble = createBubbler();
5
6
 
6
7
  interface Props {
7
8
  as?: 'button' | 'a' | 'span';
8
- size?: 'x-small' | 'small' | 'medium' | 'large';
9
+ size?: TagSize;
9
10
  color?:
10
11
  | 'default' // default tag (categories)
11
12
  | 'accent'
@@ -1,6 +1,7 @@
1
+ import type { TagSize } from './tag.types.js';
1
2
  interface Props {
2
3
  as?: 'button' | 'a' | 'span';
3
- size?: 'x-small' | 'small' | 'medium' | 'large';
4
+ size?: TagSize;
4
5
  color?: 'default' | 'accent' | 'green' | 'red' | 'blue' | 'orange';
5
6
  interactive?: boolean;
6
7
  outline?: boolean;
@@ -0,0 +1 @@
1
+ export type TagSize = 'x-small' | 'small' | 'medium' | 'large';
@@ -0,0 +1 @@
1
+ export {};
@@ -14,6 +14,7 @@ export { default as Checkbox } from './Checkbox/Checkbox.svelte';
14
14
  export { default as CodeBlock } from './CodeBlock/CodeBlock.svelte';
15
15
  export { default as TabbedCodeBlock } from './CodeBlock/TabbedCodeBlock.svelte';
16
16
  export { default as ColorPicker } from './ColorPicker/ColorPicker.svelte';
17
+ export { default as ConsoleLoader } from './ConsoleLoader/ConsoleLoader.svelte';
17
18
  export { default as DarkProvider } from './Dark/DarkProvider.svelte';
18
19
  export { default as DarkToggle } from './Dark/DarkToggle.svelte';
19
20
  export { default as DetailCard } from './DetailCard/DetailCard.svelte';
@@ -14,6 +14,7 @@ export { default as Checkbox } from './Checkbox/Checkbox.svelte';
14
14
  export { default as CodeBlock } from './CodeBlock/CodeBlock.svelte';
15
15
  export { default as TabbedCodeBlock } from './CodeBlock/TabbedCodeBlock.svelte';
16
16
  export { default as ColorPicker } from './ColorPicker/ColorPicker.svelte';
17
+ export { default as ConsoleLoader } from './ConsoleLoader/ConsoleLoader.svelte';
17
18
  export { default as DarkProvider } from './Dark/DarkProvider.svelte';
18
19
  export { default as DarkToggle } from './Dark/DarkToggle.svelte';
19
20
  export { default as DetailCard } from './DetailCard/DetailCard.svelte';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hyvor/design",
3
- "version": "2.0.6",
3
+ "version": "2.0.8-beta.1",
4
4
  "license": "MIT",
5
5
  "private": false,
6
6
  "repository": {