@hyvor/design 2.0.16 → 2.0.18

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.
@@ -74,6 +74,12 @@ export interface ResolvedLicense {
74
74
  cancel_at: null | number;
75
75
  };
76
76
  trial_ends_at: null | number;
77
+ complimentary_licenses: ResolvedComplimentaryLicense[];
78
+ }
79
+ export interface ResolvedComplimentaryLicense {
80
+ provider: string;
81
+ type: 'trial' | 'subscription';
82
+ license: Record<string, number | boolean>;
77
83
  }
78
84
  export interface OrganizationMember {
79
85
  id: number;
@@ -4,6 +4,7 @@
4
4
  import Tooltip from '../../../components/Tooltip/Tooltip.svelte';
5
5
  import IconBuilding from '@hyvor/icons/IconBuilding';
6
6
  import type { Component } from 'svelte';
7
+ import { PRODUCTS } from '../BarProducts/products.js';
7
8
 
8
9
  let { name } = $props();
9
10
 
@@ -36,11 +37,11 @@
36
37
  interface Config {
37
38
  name: string;
38
39
  tooltip: string;
39
- tagColor: 'green' | 'blue' | 'red' | 'orange';
40
+ tagColor: 'green' | 'blue' | 'red' | 'orange' | 'default';
40
41
  tagIcon?: Component;
41
42
  }
42
43
 
43
- let config: Config | null = $derived.by(() => {
44
+ let mainConfig: Config | null = $derived.by(() => {
44
45
  if (!license) {
45
46
  return null;
46
47
  }
@@ -79,6 +80,11 @@
79
80
  }
80
81
 
81
82
  if (license.type === 'expired') {
83
+ if (license.complimentary_licenses.length > 0) {
84
+ // if the org has a complimentary license, we do not show the "Expired" tag to prevent confusing the user
85
+ return null;
86
+ }
87
+
82
88
  return {
83
89
  name: `License Expired`,
84
90
  tooltip: `Your organization's license for ${name} has expired. Please renew or upgrade to continue using the service.`,
@@ -88,30 +94,83 @@
88
94
 
89
95
  return null;
90
96
  });
97
+
98
+ let complimentaryConfig: Config | null = $derived.by(() => {
99
+ if (!license) {
100
+ return null;
101
+ }
102
+
103
+ if (!license.complimentary_licenses.length) {
104
+ return null;
105
+ }
106
+
107
+ // for now, we only care about the 1st one
108
+ // we may later add other licenses
109
+ const complimentaryLicense = license.complimentary_licenses[0];
110
+ const providerName = PRODUCTS[complimentaryLicense.provider].name;
111
+
112
+ return {
113
+ name: 'Complimentary',
114
+ tooltip: `Your organization has a complimentary license for ${name} thanks to your ${providerName} ${complimentaryLicense.type}.`,
115
+ tagColor: 'default'
116
+ };
117
+ });
91
118
  </script>
92
119
 
93
- {#if config}
94
- <a class="wrap" href="/console/billing">
95
- <Tooltip position="bottom">
96
- {#snippet tooltip()}
97
- {config.tooltip}
98
- {/snippet}
99
- <Tag color={config.tagColor}>
100
- {#snippet start()}
101
- {#if config.tagIcon}
102
- <config.tagIcon size={10} />
103
- {/if}
120
+ <div class="outer">
121
+ {#if mainConfig}
122
+ <a class="wrap" href="/console/billing">
123
+ <Tooltip position="bottom">
124
+ {#snippet tooltip()}
125
+ {mainConfig.tooltip}
126
+ {/snippet}
127
+ <Tag color={mainConfig.tagColor}>
128
+ {#snippet start()}
129
+ {#if mainConfig.tagIcon}
130
+ <mainConfig.tagIcon size={10} />
131
+ {/if}
132
+ {/snippet}
133
+ {mainConfig.name}
134
+ </Tag>
135
+ </Tooltip>
136
+ </a>
137
+ {/if}
138
+
139
+ {#if mainConfig && complimentaryConfig}
140
+ <span class="pls">+</span>
141
+ {/if}
142
+
143
+ {#if complimentaryConfig}
144
+ <a class="wrap complimentary" href="/console/billing">
145
+ <Tooltip position="bottom">
146
+ {#snippet tooltip()}
147
+ {complimentaryConfig.tooltip}
104
148
  {/snippet}
105
- {config.name}
106
- </Tag>
107
- </Tooltip>
108
- </a>
109
- {/if}
149
+ <Tag color={complimentaryConfig.tagColor}>
150
+ {complimentaryConfig.name}
151
+ </Tag>
152
+ </Tooltip>
153
+ </a>
154
+ {/if}
155
+ </div>
110
156
 
111
157
  <style>
158
+ .outer {
159
+ display: flex;
160
+ align-items: center;
161
+ padding: 0 20px;
162
+ }
163
+
112
164
  .wrap {
113
165
  display: inline-flex;
114
166
  align-items: center;
115
- margin-left: 20px;
167
+ }
168
+
169
+ .pls {
170
+ display: inline-flex;
171
+ margin: 0 6px;
172
+ color: var(--text-light);
173
+ font-size: 12px;
174
+ font-weight: normal;
116
175
  }
117
176
  </style>
@@ -6,7 +6,7 @@
6
6
  type CloudContextOrganization
7
7
  } from '../CloudContext/cloudContextState.svelte.js';
8
8
  import OrganizationSwitcher from '../OrganizationSwitcher/OrganizationSwitcher.svelte';
9
- import Accordian from './Accordian.svelte';
9
+ import Accordion from '../../components/Accordion/Accordion.svelte';
10
10
  import TextInput from '../../components/TextInput/TextInput.svelte';
11
11
  import SplitControl from '../../components/SplitControl/SplitControl.svelte';
12
12
  import IconInfoCircle from '@hyvor/icons/IconInfoCircle';
@@ -129,7 +129,7 @@
129
129
 
130
130
  <div class="content">
131
131
  {#if deployment === 'cloud'}
132
- <Accordian
132
+ <Accordion
133
133
  title="Organization"
134
134
  belowTitle={organization?.name}
135
135
  show={organizationAccordianOpen}
@@ -184,10 +184,10 @@
184
184
  </div>
185
185
  </div>
186
186
  {/if}
187
- </Accordian>
187
+ </Accordion>
188
188
  {/if}
189
189
 
190
- <Accordian
190
+ <Accordion
191
191
  title={resourceTitle}
192
192
  show={contentAccordianOpen}
193
193
  buttonText={cta}
@@ -208,7 +208,7 @@
208
208
  create: handleResourceCreation
209
209
  })}
210
210
  </div>
211
- </Accordian>
211
+ </Accordion>
212
212
  </div>
213
213
  </div>
214
214
  </div>
@@ -1,5 +1,5 @@
1
1
  export { default as CloudContext } from './CloudContext/CloudContext.svelte';
2
- export { getCloudContext, setCloudContext, type CloudContext as CloudContextType, type CloudContextUser, type CloudContextOrganization, type OrganizationRole, type OrganizationMember, type ResolvedLicense } from './CloudContext/cloudContextState.svelte.js';
2
+ export { getCloudContext, setCloudContext, type CloudContext as CloudContextType, type CloudContextUser, type CloudContextOrganization, type OrganizationRole, type OrganizationMember, type ResolvedLicense, type ResolvedComplimentaryLicense } 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
5
  export { default as ResourceCreator } from './ResourceCreator/ResourceCreator.svelte';
@@ -1,143 +1,147 @@
1
1
  <script lang="ts">
2
- import type { Component, Snippet } from 'svelte';
3
- import IconCaretDownFill from '@hyvor/icons/IconCaretDownFill';
2
+ import { Button, Loader } from '../index.js';
3
+ import { type Snippet } from 'svelte';
4
+ import { slide } from 'svelte/transition';
4
5
 
5
- interface Props {
6
+ type Props = {
7
+ show: boolean;
6
8
  title: string;
7
- children?: Snippet;
8
- open?: boolean;
9
- icon?: Component;
10
- headerColor?: string;
11
- textColor?: string;
12
- openedColor?: string;
13
- borderColor?: string;
14
- topBorderColor?: string;
15
- }
9
+ belowTitle?: Snippet | string;
10
+ buttonText: string;
11
+ buttonDisabled?: boolean;
12
+ children: Snippet;
13
+ onButtonClick: () => void;
14
+ onToggle: () => void;
15
+ toggleLocked?: boolean;
16
+ complete?: boolean;
17
+ footer?: boolean;
18
+ loading?: boolean;
19
+ };
16
20
 
17
21
  let {
22
+ show = false,
18
23
  title,
19
24
  children,
20
- open = $bindable(false),
21
- icon,
22
- headerColor,
23
- textColor,
24
- openedColor,
25
- borderColor,
26
- topBorderColor
25
+ buttonText,
26
+ buttonDisabled,
27
+ onButtonClick,
28
+ onToggle,
29
+ toggleLocked = false,
30
+ complete,
31
+ belowTitle,
32
+ footer = true,
33
+ loading = $bindable(false)
27
34
  }: Props = $props();
28
35
 
29
- const Icon = icon;
36
+ let contentEl: HTMLElement;
37
+
38
+ let heightAutoTimeout: ReturnType<typeof setTimeout>;
30
39
 
31
- function handleClick() {
32
- open = !open;
40
+ function setHeight(show: boolean) {
41
+ if (!contentEl) return;
42
+ if (show) {
43
+ contentEl.style.height = contentEl.scrollHeight + 'px';
44
+ } else {
45
+ contentEl.style.height = contentEl.scrollHeight + 'px';
46
+ setTimeout(() => {
47
+ contentEl.style.height = '0px';
48
+ }, 0);
49
+ }
50
+
51
+ clearTimeout(heightAutoTimeout);
52
+ heightAutoTimeout = setTimeout(() => {
53
+ if (show) {
54
+ contentEl.style.height = 'auto';
55
+ }
56
+ }, 300);
33
57
  }
34
- </script>
35
58
 
36
- <div
37
- class="accordion-item"
38
- style:--custom-border={borderColor}
39
- style:--custom-text={textColor}
40
- style:--custom-opened={openedColor}
41
- style:--custom-header={headerColor}
42
- >
43
- <button class="accordion-header" class:open onclick={handleClick}>
44
- {#if icon}
45
- <span class="icon">
46
- <Icon size={20} />
47
- </span>
48
- {/if}
49
- <span class="title">{title}</span>
50
- <span class="chevron" class:rotated={open}>
51
- <IconCaretDownFill />
52
- </span>
53
- </button>
59
+ function toggle() {
60
+ if (toggleLocked) return;
61
+ const showBefore = show;
62
+ onToggle();
63
+ if (showBefore === show) return;
64
+ setHeight(show);
65
+ }
66
+
67
+ $effect(() => {
68
+ setHeight(show);
69
+ });
70
+ </script>
54
71
 
55
- <div class="accordion-content" class:show={open}>
56
- <div
57
- class="content-text"
58
- style:--custom-top-border={topBorderColor}
59
- style:--custom-header={headerColor}
60
- >
61
- {@render children?.()}
72
+ <div class="accordion" class:show class:complete>
73
+ <button class="title-wrap" onclick={toggle}>
74
+ <div class="left">
75
+ <div class="title">
76
+ {title}
77
+ </div>
78
+ {#if belowTitle}
79
+ {#if typeof belowTitle === 'string'}
80
+ {belowTitle}
81
+ {:else}
82
+ {@render belowTitle()}
83
+ {/if}
84
+ {/if}
62
85
  </div>
86
+ <!-- <Dot {complete} /> -->
87
+ </button>
88
+ <div class="content" bind:this={contentEl} transition:slide={{ axis: 'y' }}>
89
+ {@render children()}
90
+
91
+ {#if footer}
92
+ <div class="footer">
93
+ <div class="button-wrap">
94
+ {#if loading}
95
+ <Loader size="small" />
96
+ {/if}
97
+ <Button size="large" onclick={onButtonClick} disabled={loading || buttonDisabled}
98
+ >{buttonText}</Button
99
+ >
100
+ </div>
101
+ </div>
102
+ {/if}
63
103
  </div>
64
104
  </div>
65
105
 
66
106
  <style>
67
- .accordion-item {
68
- overflow: hidden;
107
+ .accordion {
108
+ border: 1px solid #eee;
69
109
  border-radius: 20px;
70
- border: 1px solid var(--custom-border, var(--border));
71
110
  }
72
-
73
- .accordion-header {
74
- width: 100%;
75
- padding: 14px 20px;
76
- background: var(--custom-header, none);
77
- border: none;
111
+ .title-wrap {
78
112
  display: flex;
79
- justify-content: space-between;
113
+ text-align: left;
80
114
  align-items: center;
115
+ padding: 15px 20px;
116
+ border-radius: 20px 20px 0 0;
81
117
  cursor: pointer;
82
- font-size: 16px;
83
- border-radius: 20px;
84
- color: var(--custom-text, var(--text));
118
+ width: 100%;
85
119
  }
86
-
87
- .accordion-header.open {
88
- border-radius: 20px 20px 0 0;
89
- background-color: var(--custom-opened, var(--hover));
120
+ .title-wrap .left {
121
+ flex: 1;
90
122
  }
91
-
92
123
  .title {
93
- font-weight: 500;
94
- text-align: left;
95
- }
96
-
97
- .chevron {
98
- display: flex;
99
- align-items: center;
100
- transition: transform 0.3s ease;
101
- color: var(--custom-text, var(--text));
124
+ font-weight: 600;
102
125
  }
103
-
104
- .chevron.rotated {
105
- transform: rotate(180deg);
126
+ .show .title-wrap {
127
+ background-color: var(--hover);
128
+ border-bottom: 1px solid #eee;
106
129
  }
107
130
 
108
- .accordion-content {
109
- height: 0;
131
+ .content {
110
132
  overflow: hidden;
133
+ height: 0;
134
+ transition: height 0.3s;
111
135
  }
112
-
113
- .accordion-content.show {
114
- height: auto;
115
- overflow: visible;
116
- animation: slideDown 0.3s ease-out;
117
- }
118
-
119
- .content-text {
120
- padding: 20px;
121
- color: var(--custom-text, var(--text));
122
- line-height: 1.6;
123
- border-top: 1px solid var(--custom-top-border, var(--border));
124
- background: var(--custom-header, none);
125
- }
126
-
127
- .icon {
128
- display: inline-block;
129
- margin-right: 10px;
130
- vertical-align: middle;
136
+ .footer {
137
+ padding: 10px 20px;
138
+ border-top: 1px solid #eee;
131
139
  }
132
140
 
133
- @keyframes slideDown {
134
- from {
135
- opacity: 0;
136
- transform: translateY(-10px);
137
- }
138
- to {
139
- opacity: 1;
140
- transform: translateY(0);
141
- }
141
+ .button-wrap {
142
+ display: flex;
143
+ justify-content: flex-end;
144
+ align-items: center;
145
+ gap: 10px;
142
146
  }
143
147
  </style>
@@ -1,15 +1,18 @@
1
- import type { Component, Snippet } from 'svelte';
2
- interface Props {
1
+ import { type Snippet } from 'svelte';
2
+ type Props = {
3
+ show: boolean;
3
4
  title: string;
4
- children?: Snippet;
5
- open?: boolean;
6
- icon?: Component;
7
- headerColor?: string;
8
- textColor?: string;
9
- openedColor?: string;
10
- borderColor?: string;
11
- topBorderColor?: string;
12
- }
13
- declare const Accordion: Component<Props, {}, "open">;
5
+ belowTitle?: Snippet | string;
6
+ buttonText: string;
7
+ buttonDisabled?: boolean;
8
+ children: Snippet;
9
+ onButtonClick: () => void;
10
+ onToggle: () => void;
11
+ toggleLocked?: boolean;
12
+ complete?: boolean;
13
+ footer?: boolean;
14
+ loading?: boolean;
15
+ };
16
+ declare const Accordion: import("svelte").Component<Props, {}, "loading">;
14
17
  type Accordion = ReturnType<typeof Accordion>;
15
18
  export default Accordion;
@@ -63,7 +63,7 @@
63
63
  .callout {
64
64
  padding: 15px 25px;
65
65
  border-radius: var(--box-radius);
66
- /* line-height: var(--line-height-content); */
66
+ line-height: var(--line-height-content);
67
67
  }
68
68
 
69
69
  .callout.soft {
@@ -0,0 +1,143 @@
1
+ <script lang="ts">
2
+ import type { Component, Snippet } from 'svelte';
3
+ import IconCaretDownFill from '@hyvor/icons/IconCaretDownFill';
4
+
5
+ interface Props {
6
+ title: string;
7
+ children?: Snippet;
8
+ open?: boolean;
9
+ icon?: Component;
10
+ headerColor?: string;
11
+ textColor?: string;
12
+ openedColor?: string;
13
+ borderColor?: string;
14
+ topBorderColor?: string;
15
+ }
16
+
17
+ let {
18
+ title,
19
+ children,
20
+ open = $bindable(false),
21
+ icon,
22
+ headerColor,
23
+ textColor,
24
+ openedColor,
25
+ borderColor,
26
+ topBorderColor
27
+ }: Props = $props();
28
+
29
+ const Icon = icon;
30
+
31
+ function handleClick() {
32
+ open = !open;
33
+ }
34
+ </script>
35
+
36
+ <div
37
+ class="accordion-item"
38
+ style:--custom-border={borderColor}
39
+ style:--custom-text={textColor}
40
+ style:--custom-opened={openedColor}
41
+ style:--custom-header={headerColor}
42
+ >
43
+ <button class="accordion-header" class:open onclick={handleClick}>
44
+ {#if icon}
45
+ <span class="icon">
46
+ <Icon size={20} />
47
+ </span>
48
+ {/if}
49
+ <span class="title">{title}</span>
50
+ <span class="chevron" class:rotated={open}>
51
+ <IconCaretDownFill />
52
+ </span>
53
+ </button>
54
+
55
+ <div class="accordion-content" class:show={open}>
56
+ <div
57
+ class="content-text"
58
+ style:--custom-top-border={topBorderColor}
59
+ style:--custom-header={headerColor}
60
+ >
61
+ {@render children?.()}
62
+ </div>
63
+ </div>
64
+ </div>
65
+
66
+ <style>
67
+ .accordion-item {
68
+ overflow: hidden;
69
+ border-radius: 20px;
70
+ border: 1px solid var(--custom-border, var(--border));
71
+ }
72
+
73
+ .accordion-header {
74
+ width: 100%;
75
+ padding: 14px 20px;
76
+ background: var(--custom-header, none);
77
+ border: none;
78
+ display: flex;
79
+ justify-content: space-between;
80
+ align-items: center;
81
+ cursor: pointer;
82
+ font-size: 16px;
83
+ border-radius: 20px;
84
+ color: var(--custom-text, var(--text));
85
+ }
86
+
87
+ .accordion-header.open {
88
+ border-radius: 20px 20px 0 0;
89
+ background-color: var(--custom-opened, var(--hover));
90
+ }
91
+
92
+ .title {
93
+ font-weight: 500;
94
+ text-align: left;
95
+ }
96
+
97
+ .chevron {
98
+ display: flex;
99
+ align-items: center;
100
+ transition: transform 0.3s ease;
101
+ color: var(--custom-text, var(--text));
102
+ }
103
+
104
+ .chevron.rotated {
105
+ transform: rotate(180deg);
106
+ }
107
+
108
+ .accordion-content {
109
+ height: 0;
110
+ overflow: hidden;
111
+ }
112
+
113
+ .accordion-content.show {
114
+ height: auto;
115
+ overflow: visible;
116
+ animation: slideDown 0.3s ease-out;
117
+ }
118
+
119
+ .content-text {
120
+ padding: 20px;
121
+ color: var(--custom-text, var(--text));
122
+ line-height: 1.6;
123
+ border-top: 1px solid var(--custom-top-border, var(--border));
124
+ background: var(--custom-header, none);
125
+ }
126
+
127
+ .icon {
128
+ display: inline-block;
129
+ margin-right: 10px;
130
+ vertical-align: middle;
131
+ }
132
+
133
+ @keyframes slideDown {
134
+ from {
135
+ opacity: 0;
136
+ transform: translateY(-10px);
137
+ }
138
+ to {
139
+ opacity: 1;
140
+ transform: translateY(0);
141
+ }
142
+ }
143
+ </style>
@@ -0,0 +1,15 @@
1
+ import type { Component, Snippet } from 'svelte';
2
+ interface Props {
3
+ title: string;
4
+ children?: Snippet;
5
+ open?: boolean;
6
+ icon?: Component;
7
+ headerColor?: string;
8
+ textColor?: string;
9
+ openedColor?: string;
10
+ borderColor?: string;
11
+ topBorderColor?: string;
12
+ }
13
+ declare const DetailsAccordion: Component<Props, {}, "open">;
14
+ type DetailsAccordion = ReturnType<typeof DetailsAccordion>;
15
+ export default DetailsAccordion;
@@ -94,6 +94,10 @@ content :global(li) {
94
94
  margin-bottom: 8px;
95
95
  }
96
96
 
97
+ content :global(ul) {
98
+ margin-top: 8px;
99
+ }
100
+
97
101
  content :global(.table) {
98
102
  margin: 20px 0;
99
103
  }
@@ -1,3 +1,4 @@
1
+ export { default as Accordion } from './DetailsAccordion/DetailsAccordion.svelte';
1
2
  export { default as Header } from './Header/Header.svelte';
2
3
  export { default as Container } from './Container/Container.svelte';
3
4
  export { default as Docs } from './Docs/Docs.svelte';
@@ -1,3 +1,4 @@
1
+ export { default as Accordion } from './DetailsAccordion/DetailsAccordion.svelte';
1
2
  export { default as Header } from './Header/Header.svelte';
2
3
  export { default as Container } from './Container/Container.svelte';
3
4
  export { default as Docs } from './Docs/Docs.svelte';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hyvor/design",
3
- "version": "2.0.16",
3
+ "version": "2.0.18",
4
4
  "license": "MIT",
5
5
  "private": false,
6
6
  "repository": {
@@ -1,147 +0,0 @@
1
- <script lang="ts">
2
- import { Button, Loader } from '../../components/index.js';
3
- import { type Snippet } from 'svelte';
4
- import { slide } from 'svelte/transition';
5
-
6
- type Props = {
7
- show: boolean;
8
- title: string;
9
- belowTitle?: Snippet | string;
10
- buttonText: string;
11
- buttonDisabled?: boolean;
12
- children: Snippet;
13
- onButtonClick: () => void;
14
- onToggle: () => void;
15
- toggleLocked?: boolean;
16
- complete?: boolean;
17
- footer?: boolean;
18
- loading?: boolean;
19
- };
20
-
21
- let {
22
- show = false,
23
- title,
24
- children,
25
- buttonText,
26
- buttonDisabled,
27
- onButtonClick,
28
- onToggle,
29
- toggleLocked = false,
30
- complete,
31
- belowTitle,
32
- footer = true,
33
- loading = $bindable(false)
34
- }: Props = $props();
35
-
36
- let contentEl: HTMLElement;
37
-
38
- let heightAutoTimeout: ReturnType<typeof setTimeout>;
39
-
40
- function setHeight(show: boolean) {
41
- if (!contentEl) return;
42
- if (show) {
43
- contentEl.style.height = contentEl.scrollHeight + 'px';
44
- } else {
45
- contentEl.style.height = contentEl.scrollHeight + 'px';
46
- setTimeout(() => {
47
- contentEl.style.height = '0px';
48
- }, 0);
49
- }
50
-
51
- clearTimeout(heightAutoTimeout);
52
- heightAutoTimeout = setTimeout(() => {
53
- if (show) {
54
- contentEl.style.height = 'auto';
55
- }
56
- }, 300);
57
- }
58
-
59
- function toggle() {
60
- if (toggleLocked) return;
61
- const showBefore = show;
62
- onToggle();
63
- if (showBefore === show) return;
64
- setHeight(show);
65
- }
66
-
67
- $effect(() => {
68
- setHeight(show);
69
- });
70
- </script>
71
-
72
- <div class="accordian" class:show class:complete>
73
- <button class="title-wrap" onclick={toggle}>
74
- <div class="left">
75
- <div class="title">
76
- {title}
77
- </div>
78
- {#if belowTitle}
79
- {#if typeof belowTitle === 'string'}
80
- {belowTitle}
81
- {:else}
82
- {@render belowTitle()}
83
- {/if}
84
- {/if}
85
- </div>
86
- <!-- <Dot {complete} /> -->
87
- </button>
88
- <div class="content" bind:this={contentEl} transition:slide={{ axis: 'y' }}>
89
- {@render children()}
90
-
91
- {#if footer}
92
- <div class="footer">
93
- <div class="button-wrap">
94
- {#if loading}
95
- <Loader size="small" />
96
- {/if}
97
- <Button size="large" onclick={onButtonClick} disabled={loading || buttonDisabled}
98
- >{buttonText}</Button
99
- >
100
- </div>
101
- </div>
102
- {/if}
103
- </div>
104
- </div>
105
-
106
- <style>
107
- .accordian {
108
- border: 1px solid #eee;
109
- border-radius: 20px;
110
- }
111
- .title-wrap {
112
- display: flex;
113
- text-align: left;
114
- align-items: center;
115
- padding: 15px 20px;
116
- border-radius: 20px 20px 0 0;
117
- cursor: pointer;
118
- width: 100%;
119
- }
120
- .title-wrap .left {
121
- flex: 1;
122
- }
123
- .title {
124
- font-weight: 600;
125
- }
126
- .show .title-wrap {
127
- background-color: var(--hover);
128
- border-bottom: 1px solid #eee;
129
- }
130
-
131
- .content {
132
- overflow: hidden;
133
- height: 0;
134
- transition: height 0.3s;
135
- }
136
- .footer {
137
- padding: 10px 20px;
138
- border-top: 1px solid #eee;
139
- }
140
-
141
- .button-wrap {
142
- display: flex;
143
- justify-content: flex-end;
144
- align-items: center;
145
- gap: 10px;
146
- }
147
- </style>
@@ -1,18 +0,0 @@
1
- import { type Snippet } from 'svelte';
2
- type Props = {
3
- show: boolean;
4
- title: string;
5
- belowTitle?: Snippet | string;
6
- buttonText: string;
7
- buttonDisabled?: boolean;
8
- children: Snippet;
9
- onButtonClick: () => void;
10
- onToggle: () => void;
11
- toggleLocked?: boolean;
12
- complete?: boolean;
13
- footer?: boolean;
14
- loading?: boolean;
15
- };
16
- declare const Accordian: import("svelte").Component<Props, {}, "loading">;
17
- type Accordian = ReturnType<typeof Accordian>;
18
- export default Accordian;