tecitheme 0.8.1 → 0.9.0
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.
- package/dist/assets/TECi_logo.svelte +177 -0
- package/dist/assets/TECi_logo.svelte.d.ts +23 -0
- package/dist/assets/js/store.d.ts +3 -0
- package/dist/assets/js/store.js +4 -0
- package/dist/components/Accordion.svelte +74 -0
- package/dist/components/Accordion.svelte.d.ts +27 -0
- package/dist/components/Banner.svelte +91 -0
- package/dist/components/Banner.svelte.d.ts +33 -0
- package/dist/components/Button.svelte +21 -0
- package/dist/components/Button.svelte.d.ts +37 -0
- package/dist/components/CTA.svelte +51 -0
- package/dist/components/CTA.svelte.d.ts +23 -0
- package/dist/components/CTASplitImage.svelte +34 -0
- package/dist/components/CTASplitImage.svelte.d.ts +23 -0
- package/dist/components/Card.svelte +91 -0
- package/dist/components/Card.svelte.d.ts +25 -0
- package/dist/components/CognitoForm.svelte +24 -0
- package/dist/components/CognitoForm.svelte.d.ts +27 -0
- package/dist/components/ContentTwoColumns.svelte +54 -0
- package/dist/components/ContentTwoColumns.svelte.d.ts +23 -0
- package/dist/components/CountrySelector.svelte +167 -0
- package/dist/components/CountrySelector.svelte.d.ts +27 -0
- package/dist/components/FeatureGrid.svelte +44 -0
- package/dist/components/FeatureGrid.svelte.d.ts +23 -0
- package/dist/components/Figure.svelte +40 -0
- package/dist/components/Figure.svelte.d.ts +29 -0
- package/dist/components/Footer.svelte +243 -0
- package/dist/components/Footer.svelte.d.ts +23 -0
- package/dist/components/Header.svelte +888 -0
- package/dist/components/Header.svelte.d.ts +30 -0
- package/dist/components/HeadingCentered.svelte +38 -0
- package/dist/components/HeadingCentered.svelte.d.ts +23 -0
- package/dist/components/Hero.svelte +82 -0
- package/dist/components/Hero.svelte.d.ts +23 -0
- package/dist/components/Icon.svelte +162 -0
- package/dist/components/Icon.svelte.d.ts +25 -0
- package/dist/components/LogoCloud.svelte +25 -0
- package/dist/components/LogoCloud.svelte.d.ts +23 -0
- package/dist/components/Math.svelte +24 -0
- package/dist/components/Math.svelte.d.ts +25 -0
- package/dist/components/MediaFeature.svelte +76 -0
- package/dist/components/MediaFeature.svelte.d.ts +23 -0
- package/dist/components/Modal.svelte +69 -0
- package/dist/components/Modal.svelte.d.ts +29 -0
- package/dist/components/NewsGrid.svelte +196 -0
- package/dist/components/NewsGrid.svelte.d.ts +23 -0
- package/dist/components/PageNav.svelte +243 -0
- package/dist/components/PageNav.svelte.d.ts +32 -0
- package/dist/components/PricingTable.svelte +100 -0
- package/dist/components/PricingTable.svelte.d.ts +23 -0
- package/dist/components/SidebarContent.svelte +124 -0
- package/dist/components/SidebarContent.svelte.d.ts +33 -0
- package/dist/components/Stats.svelte +40 -0
- package/dist/components/Stats.svelte.d.ts +23 -0
- package/dist/components/Testimonial.svelte +168 -0
- package/dist/components/Testimonial.svelte.d.ts +23 -0
- package/dist/components/ThreeColumn.svelte +20 -0
- package/dist/components/ThreeColumn.svelte.d.ts +23 -0
- package/dist/components/TrialForm.svelte +296 -0
- package/dist/components/TrialForm.svelte.d.ts +14 -0
- package/dist/components/Video.svelte +125 -0
- package/dist/components/Video.svelte.d.ts +27 -0
- package/dist/components/Wrap.svelte +12 -0
- package/dist/components/Wrap.svelte.d.ts +31 -0
- package/dist/get-content.d.ts +9 -0
- package/dist/get-content.js +98 -0
- package/dist/index.d.ts +31 -0
- package/dist/index.js +31 -0
- package/dist/layouts/blocks.svelte +108 -0
- package/dist/layouts/blocks.svelte.d.ts +47 -0
- package/dist/req_utils.d.ts +3 -0
- package/dist/req_utils.js +63 -0
- package/dist/site_config.json +13 -0
- package/dist/utils.d.ts +5 -0
- package/dist/utils.js +162 -0
- package/dist/variables.d.ts +1 -0
- package/dist/variables.js +2 -0
- package/package.json +1 -1
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/** @typedef {typeof __propDef.props} ModalProps */
|
|
2
|
+
/** @typedef {typeof __propDef.events} ModalEvents */
|
|
3
|
+
/** @typedef {typeof __propDef.slots} ModalSlots */
|
|
4
|
+
export default class Modal extends SvelteComponent<{
|
|
5
|
+
data?: {};
|
|
6
|
+
show?: () => void;
|
|
7
|
+
hide?: () => void;
|
|
8
|
+
}, {
|
|
9
|
+
[evt: string]: CustomEvent<any>;
|
|
10
|
+
}, {}> {
|
|
11
|
+
get show(): () => void;
|
|
12
|
+
get hide(): () => void;
|
|
13
|
+
}
|
|
14
|
+
export type ModalProps = typeof __propDef.props;
|
|
15
|
+
export type ModalEvents = typeof __propDef.events;
|
|
16
|
+
export type ModalSlots = typeof __propDef.slots;
|
|
17
|
+
import { SvelteComponent } from "svelte";
|
|
18
|
+
declare const __propDef: {
|
|
19
|
+
props: {
|
|
20
|
+
data?: {};
|
|
21
|
+
show?: () => void;
|
|
22
|
+
hide?: () => void;
|
|
23
|
+
};
|
|
24
|
+
events: {
|
|
25
|
+
[evt: string]: CustomEvent<any>;
|
|
26
|
+
};
|
|
27
|
+
slots: {};
|
|
28
|
+
};
|
|
29
|
+
export {};
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
import Button from './Button.svelte'
|
|
3
|
+
|
|
4
|
+
import { page } from '$app/stores';
|
|
5
|
+
import { paginate, PaginationNav } from "svelte-paginate";
|
|
6
|
+
import Icon from "./Icon.svelte";
|
|
7
|
+
|
|
8
|
+
export let data = {};
|
|
9
|
+
|
|
10
|
+
let posts = $page.data.newsPosts;
|
|
11
|
+
let filteredPosts = [];
|
|
12
|
+
let items = [];
|
|
13
|
+
let currentPage = 1;
|
|
14
|
+
let pageSize = (data.pageSize?data.pageSize:6);
|
|
15
|
+
let postLimit = data.limit;
|
|
16
|
+
let showArrows = (data.showArrows?data.showArrows:false);
|
|
17
|
+
let rangeLimit = (data.rangeLimit?data.rangeLimit:1)
|
|
18
|
+
let showPagination = (data.showPagination?data.showPagination:false);
|
|
19
|
+
let id
|
|
20
|
+
|
|
21
|
+
if (data.name) {
|
|
22
|
+
id = encodeURIComponent(data.name).toLowerCase()
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
if (postLimit > 0) {
|
|
26
|
+
posts = posts.slice(0, postLimit);
|
|
27
|
+
postLimit <= pageSize ? (showPagination = false) : (showPagination = true);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function termExists(arr, terms) {
|
|
31
|
+
if (arr) {
|
|
32
|
+
return terms.some((term) => {
|
|
33
|
+
return arr.includes(term);
|
|
34
|
+
});
|
|
35
|
+
} else {
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function filterPosts(arr, terms) {
|
|
41
|
+
for (let i = 0; i < arr.length; ) {
|
|
42
|
+
if (termExists(arr[i].categories, terms)) {
|
|
43
|
+
i++;
|
|
44
|
+
continue;
|
|
45
|
+
}
|
|
46
|
+
arr.splice(i, 1);
|
|
47
|
+
}
|
|
48
|
+
return arr;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
if (data.filter) {
|
|
52
|
+
items = filterPosts(posts, data.filter);
|
|
53
|
+
} else {
|
|
54
|
+
items = posts;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
$: paginatedItems = paginate({ items, pageSize, currentPage });
|
|
58
|
+
</script>
|
|
59
|
+
|
|
60
|
+
<section {id} class="relative mx-auto w-full">
|
|
61
|
+
<div
|
|
62
|
+
class="flex flex-col justify-between space-y-4 border-b-2 border-gray-200 pb-4 sm:flex-row sm:items-end sm:space-y-0"
|
|
63
|
+
>
|
|
64
|
+
<div>
|
|
65
|
+
<h1 class="text-3xl font-bold tracking-tight text-gray-900 sm:text-4xl">
|
|
66
|
+
{data.title}
|
|
67
|
+
</h1>
|
|
68
|
+
<p class="text-xl text-gray-500">{data.subtitle}</p>
|
|
69
|
+
</div>
|
|
70
|
+
<div class="w-32">
|
|
71
|
+
<Button
|
|
72
|
+
url="https://www.thunderheadeng.com/subscribe"
|
|
73
|
+
text="Subscribe"
|
|
74
|
+
color="teci"
|
|
75
|
+
justify="right"
|
|
76
|
+
/>
|
|
77
|
+
</div>
|
|
78
|
+
</div>
|
|
79
|
+
{#if items.length > 0}
|
|
80
|
+
{#if showPagination}
|
|
81
|
+
<div class="paginator mx-auto flex justify-center pt-4">
|
|
82
|
+
<PaginationNav
|
|
83
|
+
totalItems={items.length}
|
|
84
|
+
{pageSize}
|
|
85
|
+
{currentPage}
|
|
86
|
+
limit={rangeLimit}
|
|
87
|
+
showStepOptions={showArrows}
|
|
88
|
+
on:setPage={(e) => (currentPage = e.detail.page)}
|
|
89
|
+
/>
|
|
90
|
+
</div>
|
|
91
|
+
{/if}
|
|
92
|
+
<div
|
|
93
|
+
class="grid gap-8 pt-8 md:grid-cols-2 md:gap-16 lg:grid-cols-3 lg:gap-x-5 lg:gap-y-12"
|
|
94
|
+
>
|
|
95
|
+
{#each paginatedItems as post}
|
|
96
|
+
<div class="h-full">
|
|
97
|
+
<div class="flex h-full flex-col items-stretch ">
|
|
98
|
+
<time class="mb-1 block text-sm text-gray-500" datetime={post.date}
|
|
99
|
+
>{new Date(post.date).toLocaleDateString("en-us", {
|
|
100
|
+
weekday: "short",
|
|
101
|
+
year: "numeric",
|
|
102
|
+
month: "short",
|
|
103
|
+
day: "numeric",
|
|
104
|
+
timeZone: "UTC",
|
|
105
|
+
timeZoneName: "short",
|
|
106
|
+
})}</time
|
|
107
|
+
>
|
|
108
|
+
<h2 class="mb-2 text-xl font-semibold text-gray-900">
|
|
109
|
+
<a href={post.slug}>
|
|
110
|
+
{post.title}
|
|
111
|
+
</a>
|
|
112
|
+
</h2>
|
|
113
|
+
{#if post.summary}
|
|
114
|
+
<p class="mb-2 flex-1 text-base text-gray-500">
|
|
115
|
+
<a href={post.slug}>
|
|
116
|
+
{post.summary.length > 190
|
|
117
|
+
? post.summary.substring(0, 190) + " ..."
|
|
118
|
+
: post.summary}
|
|
119
|
+
</a>
|
|
120
|
+
</p>
|
|
121
|
+
{:else}
|
|
122
|
+
<p class="mb-2 flex-1 text-base text-red-500">
|
|
123
|
+
Missing Summary Text
|
|
124
|
+
</p>
|
|
125
|
+
{/if}
|
|
126
|
+
{#if post.categories}
|
|
127
|
+
<div class="flex w-full flex-wrap text-sm">
|
|
128
|
+
{#each post.categories.sort() as term}
|
|
129
|
+
<a
|
|
130
|
+
class="mr-2 mb-2 inline-block"
|
|
131
|
+
href="/news/filter/{term}"
|
|
132
|
+
target="_self"
|
|
133
|
+
>
|
|
134
|
+
<span
|
|
135
|
+
class="inline-flex items-center rounded-full bg-teci-blue-dark px-2.5 py-0.5 text-xs text-white hover:bg-teci-blue-light"
|
|
136
|
+
>{term}</span
|
|
137
|
+
>
|
|
138
|
+
</a>
|
|
139
|
+
{/each}
|
|
140
|
+
</div>
|
|
141
|
+
{/if}
|
|
142
|
+
<p
|
|
143
|
+
class="text-sm font-semibold text-teci-blue-light hover:text-teci-blue-dark"
|
|
144
|
+
>
|
|
145
|
+
<a href={post.slug}>
|
|
146
|
+
Read full article<span aria-hidden="true"> →</span>
|
|
147
|
+
</a>
|
|
148
|
+
</p>
|
|
149
|
+
</div>
|
|
150
|
+
</div>
|
|
151
|
+
{/each}
|
|
152
|
+
</div>
|
|
153
|
+
{#if showPagination}
|
|
154
|
+
<div class="paginator mx-auto flex justify-center pt-8">
|
|
155
|
+
<PaginationNav
|
|
156
|
+
totalItems={items.length}
|
|
157
|
+
{pageSize}
|
|
158
|
+
{currentPage}
|
|
159
|
+
limit={rangeLimit}
|
|
160
|
+
showStepOptions={showArrows}
|
|
161
|
+
on:setPage={(e) => (currentPage = e.detail.page)}
|
|
162
|
+
/>
|
|
163
|
+
</div>
|
|
164
|
+
{/if}
|
|
165
|
+
{#if !showPagination}
|
|
166
|
+
<div class="mt-8 w-full">
|
|
167
|
+
<Button
|
|
168
|
+
url="/news"
|
|
169
|
+
text="All News Posts"
|
|
170
|
+
color="teci"
|
|
171
|
+
justify="right"
|
|
172
|
+
/>
|
|
173
|
+
</div>
|
|
174
|
+
{/if}
|
|
175
|
+
{#if !postLimit}
|
|
176
|
+
<div class="sr-only">
|
|
177
|
+
<p>List of all News links for screen readers and bots.</p>
|
|
178
|
+
<ul>
|
|
179
|
+
{#each posts as post}
|
|
180
|
+
<li>
|
|
181
|
+
<a href={post.slug}>{post.title}</a>
|
|
182
|
+
</li>
|
|
183
|
+
{/each}
|
|
184
|
+
</ul>
|
|
185
|
+
</div>
|
|
186
|
+
{/if}
|
|
187
|
+
{:else}
|
|
188
|
+
<div class="prose">
|
|
189
|
+
<p class="pt-8">
|
|
190
|
+
Sorry, there isn't any news for you to see here.<br />
|
|
191
|
+
Please visit the <a rel="external" href="/news">All News</a> page for an
|
|
192
|
+
updated list.
|
|
193
|
+
</p>
|
|
194
|
+
</div>
|
|
195
|
+
{/if}
|
|
196
|
+
</section>
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/** @typedef {typeof __propDef.props} NewsGridProps */
|
|
2
|
+
/** @typedef {typeof __propDef.events} NewsGridEvents */
|
|
3
|
+
/** @typedef {typeof __propDef.slots} NewsGridSlots */
|
|
4
|
+
export default class NewsGrid extends SvelteComponent<{
|
|
5
|
+
data?: {};
|
|
6
|
+
}, {
|
|
7
|
+
[evt: string]: CustomEvent<any>;
|
|
8
|
+
}, {}> {
|
|
9
|
+
}
|
|
10
|
+
export type NewsGridProps = typeof __propDef.props;
|
|
11
|
+
export type NewsGridEvents = typeof __propDef.events;
|
|
12
|
+
export type NewsGridSlots = typeof __propDef.slots;
|
|
13
|
+
import { SvelteComponent } from "svelte";
|
|
14
|
+
declare const __propDef: {
|
|
15
|
+
props: {
|
|
16
|
+
data?: {};
|
|
17
|
+
};
|
|
18
|
+
events: {
|
|
19
|
+
[evt: string]: CustomEvent<any>;
|
|
20
|
+
};
|
|
21
|
+
slots: {};
|
|
22
|
+
};
|
|
23
|
+
export {};
|
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
import { getColorStyles } from "../utils";
|
|
3
|
+
import { fade, slide } from "svelte/transition";
|
|
4
|
+
import { cubicIn, cubicOut } from "svelte/easing";
|
|
5
|
+
import Icon from "./Icon.svelte";
|
|
6
|
+
|
|
7
|
+
export let data = {};
|
|
8
|
+
let {logo, logo_mobile, logo_link_url, logo_alt_text, color, ctas, dropdowns, links} = data;
|
|
9
|
+
|
|
10
|
+
let id;
|
|
11
|
+
if (data.name) {
|
|
12
|
+
id = encodeURIComponent(data.name).toLowerCase()
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
let openDropdown = "";
|
|
16
|
+
export function clickOutside(node) {
|
|
17
|
+
const handleClick = (event) => {
|
|
18
|
+
if (
|
|
19
|
+
!node.contains(event.target) &&
|
|
20
|
+
event.target.innerText.toLowerCase() != node.parentElement.id
|
|
21
|
+
) {
|
|
22
|
+
node.dispatchEvent(new CustomEvent("outclick"));
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
document.addEventListener("click", handleClick, true);
|
|
26
|
+
return {
|
|
27
|
+
destroy() {
|
|
28
|
+
document.removeEventListener("click", handleClick, true);
|
|
29
|
+
},
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function handleEscape({ key }) {
|
|
34
|
+
if (key === "Escape") {
|
|
35
|
+
openDropdown = "";
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
let mobileOpen = false;
|
|
40
|
+
</script>
|
|
41
|
+
|
|
42
|
+
<svelte:window on:keyup={handleEscape} />
|
|
43
|
+
|
|
44
|
+
<header {id} class="sticky top-0 w-full z-40 bg-white">
|
|
45
|
+
<div
|
|
46
|
+
aria-hidden="true"
|
|
47
|
+
class="pointer-events-none absolute inset-0 z-30 shadow"
|
|
48
|
+
/>
|
|
49
|
+
<div class="relative">
|
|
50
|
+
|
|
51
|
+
<!-- Rail -->
|
|
52
|
+
<div
|
|
53
|
+
class="relative mx-auto w-full flex max-w-7xl items-center justify-between px-2 py-5 sm:px-6 sm:py-4 md:justify-start md:space-x-6 lg:space-x-10 lg:px-8"
|
|
54
|
+
>
|
|
55
|
+
|
|
56
|
+
<!-- Left Icons -->
|
|
57
|
+
<div class="flex-shrink-0">
|
|
58
|
+
<!-- Mobile Nav Icon -->
|
|
59
|
+
<button class="flex-shrink-0 md:hidden flex flex-row items-center"
|
|
60
|
+
|
|
61
|
+
on:click={() => mobileOpen = !mobileOpen}
|
|
62
|
+
>
|
|
63
|
+
<span class="sr-only">{logo_alt_text}</span>
|
|
64
|
+
<Icon classes="h-10 w-auto" icon={logo_mobile} />
|
|
65
|
+
<svg
|
|
66
|
+
class="ml-2 h-10 w-10 group-hover:text-gray-900 {mobileOpen == true
|
|
67
|
+
? 'rotate-180 text-gray-900'
|
|
68
|
+
: 'text-gray-400'}"
|
|
69
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
70
|
+
viewBox="0 0 20 20"
|
|
71
|
+
fill="currentColor"
|
|
72
|
+
aria-hidden="true"
|
|
73
|
+
>
|
|
74
|
+
<path
|
|
75
|
+
fill-rule="evenodd"
|
|
76
|
+
d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z"
|
|
77
|
+
clip-rule="evenodd"
|
|
78
|
+
/>
|
|
79
|
+
</svg>
|
|
80
|
+
</button>
|
|
81
|
+
|
|
82
|
+
<!-- Desktop Nav Icon-->
|
|
83
|
+
<div class="hidden sm:flex sm:flex-shrink-0">
|
|
84
|
+
<a href={logo_link_url} class="flex">
|
|
85
|
+
<span class="sr-only">{logo_alt_text}</span>
|
|
86
|
+
<Icon classes="h-10 w-auto" icon={logo} />
|
|
87
|
+
</a>
|
|
88
|
+
</div>
|
|
89
|
+
</div>
|
|
90
|
+
|
|
91
|
+
<!-- Interactive Elements -->
|
|
92
|
+
<nav class="hidden md:flex md:space-x-4 lg:space-x-10 md:items-center w-full">
|
|
93
|
+
|
|
94
|
+
<!-- Left Links -->
|
|
95
|
+
{#each links as link}
|
|
96
|
+
<a href={link.url} class="text-base font-medium hover:text-gray-900">{link.text}</a>
|
|
97
|
+
{/each}
|
|
98
|
+
|
|
99
|
+
<!-- Spacer -->
|
|
100
|
+
<div class="flex-1" />
|
|
101
|
+
|
|
102
|
+
<!-- Right Dropdowns -->
|
|
103
|
+
{#each dropdowns as drop}
|
|
104
|
+
<div id={drop.key} class="relative">
|
|
105
|
+
|
|
106
|
+
<!-- Rail Buttons-->
|
|
107
|
+
<button
|
|
108
|
+
type="button"
|
|
109
|
+
on:click={() =>
|
|
110
|
+
openDropdown == drop.key
|
|
111
|
+
? (openDropdown = "")
|
|
112
|
+
: (openDropdown = drop.key)}
|
|
113
|
+
class="group inline-flex items-center bg-white text-left text-base font-medium hover:text-gray-900 focus:outline-none focus:ring-2 focus:ring-teci-blue-light focus:ring-offset-2"
|
|
114
|
+
aria-expanded={openDropdown == drop.key}
|
|
115
|
+
>
|
|
116
|
+
<span class:text-gray-900={openDropdown == drop.key}>{drop.text}</span>
|
|
117
|
+
<svg
|
|
118
|
+
class="ml-2 h-5 w-5 group-hover:text-gray-900 {openDropdown == drop.key
|
|
119
|
+
? 'rotate-180 text-gray-900'
|
|
120
|
+
: 'text-gray-400'}"
|
|
121
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
122
|
+
viewBox="0 0 20 20"
|
|
123
|
+
fill="currentColor"
|
|
124
|
+
aria-hidden="true"
|
|
125
|
+
>
|
|
126
|
+
<path
|
|
127
|
+
fill-rule="evenodd"
|
|
128
|
+
d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z"
|
|
129
|
+
clip-rule="evenodd"
|
|
130
|
+
/>
|
|
131
|
+
</svg>
|
|
132
|
+
</button>
|
|
133
|
+
|
|
134
|
+
<!-- Flyout menus -->
|
|
135
|
+
{#if openDropdown == drop.key}
|
|
136
|
+
<div
|
|
137
|
+
class="absolute left-1/2 z-50 mt-3 w-48 max-w-xs -translate-x-1/2 transform overflow-hidden px-2 shadow-lg ring-1 ring-black ring-opacity-5 sm:px-0 bg-white"
|
|
138
|
+
use:clickOutside
|
|
139
|
+
on:outclick={() => (openDropdown = "")}
|
|
140
|
+
in:slide={{ duration: 250, easing: cubicOut }}
|
|
141
|
+
out:slide={{ duration: 150, easing: cubicIn }}
|
|
142
|
+
>
|
|
143
|
+
|
|
144
|
+
<button
|
|
145
|
+
on:click={() => (openDropdown = "")}
|
|
146
|
+
class="relative grid w-full gap-6 bg-white px-2 py-6 text-left"
|
|
147
|
+
>
|
|
148
|
+
{#each drop.links as link}
|
|
149
|
+
<a
|
|
150
|
+
href={link.url}
|
|
151
|
+
class="-m-3 flex items-start py-3 px-4 transition duration-150 ease-in-out hover:bg-gray-50"
|
|
152
|
+
>
|
|
153
|
+
<div class="ml-4">
|
|
154
|
+
<p class="text-base font-medium text-gray-900">{link.text}</p>
|
|
155
|
+
</div>
|
|
156
|
+
</a>
|
|
157
|
+
{/each}
|
|
158
|
+
</button>
|
|
159
|
+
|
|
160
|
+
</div>
|
|
161
|
+
{/if}
|
|
162
|
+
</div>
|
|
163
|
+
{/each}
|
|
164
|
+
|
|
165
|
+
<!-- CTA Buttons -->
|
|
166
|
+
{#each ctas as cta}
|
|
167
|
+
<a href={cta.url} class="inline-block btn {getColorStyles('button', cta.color)}">
|
|
168
|
+
{cta.text}
|
|
169
|
+
<span class="hidden sm:inline" aria-hidden="true">→</span>
|
|
170
|
+
</a>
|
|
171
|
+
{/each}
|
|
172
|
+
</nav>
|
|
173
|
+
|
|
174
|
+
</div>
|
|
175
|
+
|
|
176
|
+
<!-- Mobile Menu -->
|
|
177
|
+
{#if mobileOpen}
|
|
178
|
+
<div
|
|
179
|
+
class="absolute inset-x-0 z-50 divide-y-2 divide-gray-50 bg-white shadow-lg ring-1 ring-black ring-opacity-5 md:hidden px-2 py-4"
|
|
180
|
+
use:clickOutside
|
|
181
|
+
on:outclick={() => mobileOpen = false}
|
|
182
|
+
in:fade={{ duration: 250, easing: cubicOut }}
|
|
183
|
+
out:fade={{ duration: 150, easing: cubicIn }}
|
|
184
|
+
>
|
|
185
|
+
<button
|
|
186
|
+
on:click={() => mobileOpen = false}
|
|
187
|
+
class="relative grid w-full gap-6 bg-white p-2 text-left"
|
|
188
|
+
>
|
|
189
|
+
<!-- Page Home Link -->
|
|
190
|
+
<a
|
|
191
|
+
href={logo_link_url}
|
|
192
|
+
class="-m-3 flex items-start py-3 px-4 transition duration-150 ease-in-out hover:bg-gray-50"
|
|
193
|
+
>
|
|
194
|
+
<div class="ml-4">
|
|
195
|
+
<p class="text-base font-medium text-gray-900">{logo_alt_text}</p>
|
|
196
|
+
</div>
|
|
197
|
+
</a>
|
|
198
|
+
|
|
199
|
+
<!-- Links -->
|
|
200
|
+
{#each links as link}
|
|
201
|
+
<a
|
|
202
|
+
href={link.url}
|
|
203
|
+
class="-m-3 flex items-start py-3 px-4 transition duration-150 ease-in-out hover:bg-gray-50"
|
|
204
|
+
>
|
|
205
|
+
<div class="ml-4">
|
|
206
|
+
<p class="text-base font-medium text-gray-900">{link.text}</p>
|
|
207
|
+
</div>
|
|
208
|
+
</a>
|
|
209
|
+
{/each}
|
|
210
|
+
|
|
211
|
+
<!-- Dropdowns -->
|
|
212
|
+
{#each dropdowns as drop}
|
|
213
|
+
<div id={drop.key} class="-m-3 py-3 px-4">
|
|
214
|
+
<p class="text-base font-medium text-gray-400 px-4">{drop.text}</p>
|
|
215
|
+
{#each drop.links as link}
|
|
216
|
+
<a
|
|
217
|
+
href={drop.url}
|
|
218
|
+
class="flex items-start py-3 px-4 transition duration-150 ease-in-out hover:bg-gray-50"
|
|
219
|
+
>
|
|
220
|
+
<div class="ml-4">
|
|
221
|
+
<p class="text-base font-medium text-gray-900">{link.text}</p>
|
|
222
|
+
</div>
|
|
223
|
+
</a>
|
|
224
|
+
{/each}
|
|
225
|
+
</div>
|
|
226
|
+
{/each}
|
|
227
|
+
|
|
228
|
+
<!-- CTAs -->
|
|
229
|
+
{#each ctas as cta}
|
|
230
|
+
<a
|
|
231
|
+
href={cta.url}
|
|
232
|
+
class="-m-3 flex items-start py-3 px-4 transition duration-150 ease-in-out hover:bg-gray-50"
|
|
233
|
+
>
|
|
234
|
+
<div class="ml-4">
|
|
235
|
+
<p class="text-base font-medium text-gray-900">{cta.text}</p>
|
|
236
|
+
</div>
|
|
237
|
+
</a>
|
|
238
|
+
{/each}
|
|
239
|
+
</button>
|
|
240
|
+
</div>
|
|
241
|
+
{/if}
|
|
242
|
+
</div>
|
|
243
|
+
</header>
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/** @typedef {typeof __propDef.props} PageNavProps */
|
|
2
|
+
/** @typedef {typeof __propDef.events} PageNavEvents */
|
|
3
|
+
/** @typedef {typeof __propDef.slots} PageNavSlots */
|
|
4
|
+
export default class PageNav extends SvelteComponent<{
|
|
5
|
+
data?: {};
|
|
6
|
+
clickOutside?: (node: any) => {
|
|
7
|
+
destroy(): void;
|
|
8
|
+
};
|
|
9
|
+
}, {
|
|
10
|
+
[evt: string]: CustomEvent<any>;
|
|
11
|
+
}, {}> {
|
|
12
|
+
get clickOutside(): (node: any) => {
|
|
13
|
+
destroy(): void;
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
export type PageNavProps = typeof __propDef.props;
|
|
17
|
+
export type PageNavEvents = typeof __propDef.events;
|
|
18
|
+
export type PageNavSlots = typeof __propDef.slots;
|
|
19
|
+
import { SvelteComponent } from "svelte";
|
|
20
|
+
declare const __propDef: {
|
|
21
|
+
props: {
|
|
22
|
+
data?: {};
|
|
23
|
+
clickOutside?: (node: any) => {
|
|
24
|
+
destroy(): void;
|
|
25
|
+
};
|
|
26
|
+
};
|
|
27
|
+
events: {
|
|
28
|
+
[evt: string]: CustomEvent<any>;
|
|
29
|
+
};
|
|
30
|
+
slots: {};
|
|
31
|
+
};
|
|
32
|
+
export {};
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
import { getColorStyles } from '../utils'
|
|
3
|
+
export let data = {};
|
|
4
|
+
let toggleID = data.groups[0].id
|
|
5
|
+
let id
|
|
6
|
+
|
|
7
|
+
if (data.name) {
|
|
8
|
+
id = encodeURIComponent(data.name).toLowerCase()
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
function toggleSelection(group_id) {
|
|
12
|
+
toggleID = group_id
|
|
13
|
+
}
|
|
14
|
+
</script>
|
|
15
|
+
|
|
16
|
+
<section {id} class="overflow-hidden">
|
|
17
|
+
<div class="sm:align-center sm:flex sm:flex-col">
|
|
18
|
+
<h1 class="text-5xl font-bold tracking-tight text-gray-900 sm:text-center">{data.heading}</h1>
|
|
19
|
+
<p class="mt-5 text-xl text-gray-500 sm:text-center">{data.subheading}</p>
|
|
20
|
+
{#if data.groups.length > 1 }
|
|
21
|
+
<div class="relative mt-6 max-w-xs w-full flex flex-row space-x-4 self-center justify-evenly rounded-lg bg-gray-100 p-0.5 sm:mt-8">
|
|
22
|
+
{#each data.groups as group}
|
|
23
|
+
<button type="button"
|
|
24
|
+
on:click={toggleSelection(group.id)}
|
|
25
|
+
id={group.id}
|
|
26
|
+
class="relative w-full whitespace-nowrap rounded-md py-2 text-sm font-medium border focus:z-10 focus:outline-none focus:ring-2 focus:ring-teci-blue-light
|
|
27
|
+
{toggleID == group.id ? "border-gray-200 bg-white text-gray-900 shadow-sm" : "border-transparent text-gray-700"}
|
|
28
|
+
">
|
|
29
|
+
{group.label}
|
|
30
|
+
</button>
|
|
31
|
+
{/each}
|
|
32
|
+
</div>
|
|
33
|
+
{/if}
|
|
34
|
+
<p class="mt-4 text-md max-w-xl mx-auto text-gray-500 sm:text-center">{data.groups.find(x => x.id === toggleID).description}</p>
|
|
35
|
+
</div>
|
|
36
|
+
<div class="mt-8 space-y-4 sm:grid sm:grid-cols-2 sm:gap-6 sm:space-y-0 lg:mx-auto lg:max-w-4xl xl:mx-0 xl:max-w-none xl:grid-cols-4">
|
|
37
|
+
{#each data.groups as group}
|
|
38
|
+
{#if (group.id == toggleID)}
|
|
39
|
+
{#each group.options as option}
|
|
40
|
+
<div class="max-w-xs mx-auto sm:odd:mr-0 sm:even:ml-0 divide-y divide-gray-200 border border-gray-200 {option.highlight ? "shadow-[inset_0_0_6px_0_rgb(0,43,127,1.0)]":"shadow-md"}">
|
|
41
|
+
<div class="p-6">
|
|
42
|
+
<h2 class="text-lg font-medium leading-6 text-gray-900">{option.label}</h2>
|
|
43
|
+
<p class="mt-4 text-sm text-gray-500">{option.text}</p>
|
|
44
|
+
<p class="mt-8">
|
|
45
|
+
{#if option.unit}
|
|
46
|
+
<span class="text-2xl align-super font-medium text-gray-500">{option.unit}</span>
|
|
47
|
+
{/if}
|
|
48
|
+
<span class="text-4xl font-bold tracking-tight text-gray-900">{option.price}</span>
|
|
49
|
+
{#if option.divisor}
|
|
50
|
+
<span class="text-base font-medium text-gray-500">{option.divisor}</span>
|
|
51
|
+
{/if}
|
|
52
|
+
</p>
|
|
53
|
+
{#if option.cta_url}
|
|
54
|
+
<a href={option.cta_url} class="btn mt-8 block w-full border py-2 text-center text-sm font-semibold {getColorStyles('button', data.color)}">{option.cta_label}</a>
|
|
55
|
+
{/if}
|
|
56
|
+
</div>
|
|
57
|
+
<div class="px-6 pt-6 pb-8">
|
|
58
|
+
<h3 class="text-sm font-medium text-gray-900">{option.features_text}</h3>
|
|
59
|
+
<ul class="mt-6 space-y-4">
|
|
60
|
+
{#each option.features as feature}
|
|
61
|
+
<li class="flex space-x-3">
|
|
62
|
+
<!-- Heroicon name: mini/check -->
|
|
63
|
+
<svg class="h-5 w-5 flex-shrink-0 text-green-500" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
|
|
64
|
+
<path fill-rule="evenodd" d="M16.704 4.153a.75.75 0 01.143 1.052l-8 10.5a.75.75 0 01-1.127.075l-4.5-4.5a.75.75 0 011.06-1.06l3.894 3.893 7.48-9.817a.75.75 0 011.05-.143z" clip-rule="evenodd" />
|
|
65
|
+
</svg>
|
|
66
|
+
<span class="text-sm {getColorStyles('text', data.color)}">{feature.text}</span>
|
|
67
|
+
</li>
|
|
68
|
+
{/each}
|
|
69
|
+
</ul>
|
|
70
|
+
</div>
|
|
71
|
+
</div>
|
|
72
|
+
{/each}
|
|
73
|
+
{/if}
|
|
74
|
+
{/each}
|
|
75
|
+
</div>
|
|
76
|
+
{#if data.footer}
|
|
77
|
+
<div class="mt-8">
|
|
78
|
+
{#if data.footer.heading}
|
|
79
|
+
<div class="text-xl mb-4 text-gray-500 sm:text-center">
|
|
80
|
+
<p>{data.footer.heading}</p>
|
|
81
|
+
</div>
|
|
82
|
+
{/if}
|
|
83
|
+
{#if data.footer.text}
|
|
84
|
+
<div class="text-md mb-4 max-w-4xl mx-auto text-gray-500 sm:text-center">
|
|
85
|
+
<p>{@html data.footer.text}</p>
|
|
86
|
+
</div>
|
|
87
|
+
{/if}
|
|
88
|
+
{#if data.footer.ctas}
|
|
89
|
+
<div class="flex gap-x-8 py-2 sm:justify-center">
|
|
90
|
+
{#each data.footer.ctas as cta}
|
|
91
|
+
<a href={cta.url} class="btn {getColorStyles('button', cta.color)}">
|
|
92
|
+
{cta.text}
|
|
93
|
+
<span class="hidden sm:inline" aria-hidden="true">→</span>
|
|
94
|
+
</a>
|
|
95
|
+
{/each}
|
|
96
|
+
</div>
|
|
97
|
+
{/if}
|
|
98
|
+
</div>
|
|
99
|
+
{/if}
|
|
100
|
+
</section>
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/** @typedef {typeof __propDef.props} PricingTableProps */
|
|
2
|
+
/** @typedef {typeof __propDef.events} PricingTableEvents */
|
|
3
|
+
/** @typedef {typeof __propDef.slots} PricingTableSlots */
|
|
4
|
+
export default class PricingTable extends SvelteComponent<{
|
|
5
|
+
data?: {};
|
|
6
|
+
}, {
|
|
7
|
+
[evt: string]: CustomEvent<any>;
|
|
8
|
+
}, {}> {
|
|
9
|
+
}
|
|
10
|
+
export type PricingTableProps = typeof __propDef.props;
|
|
11
|
+
export type PricingTableEvents = typeof __propDef.events;
|
|
12
|
+
export type PricingTableSlots = typeof __propDef.slots;
|
|
13
|
+
import { SvelteComponent } from "svelte";
|
|
14
|
+
declare const __propDef: {
|
|
15
|
+
props: {
|
|
16
|
+
data?: {};
|
|
17
|
+
};
|
|
18
|
+
events: {
|
|
19
|
+
[evt: string]: CustomEvent<any>;
|
|
20
|
+
};
|
|
21
|
+
slots: {};
|
|
22
|
+
};
|
|
23
|
+
export {};
|