@grantcodes/ui 2.6.0 → 2.7.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/CHANGELOG.md +35 -0
- package/custom-elements.json +556 -0
- package/package.json +4 -4
- package/src/components/accordion/accordion.component.js +4 -1
- package/src/components/accordion/accordion.css +26 -18
- package/src/components/code-preview/code-preview.css +5 -0
- package/src/components/container/container.css +6 -0
- package/src/components/countdown/countdown.component.js +180 -0
- package/src/components/countdown/countdown.css +62 -0
- package/src/components/countdown/countdown.js +6 -0
- package/src/components/countdown/countdown.react.js +9 -0
- package/src/components/countdown/countdown.stories.js +65 -0
- package/src/components/countdown/index.js +1 -0
- package/src/components/cta/cta.css +6 -0
- package/src/components/dialog/dialog.css +5 -0
- package/src/components/feature-list/feature-list.css +6 -0
- package/src/components/footer/footer.css +3 -1
- package/src/components/form-field/form-field.css +6 -0
- package/src/components/gallery/gallery.css +5 -0
- package/src/components/hero/hero.component.js +7 -0
- package/src/components/hero/hero.css +18 -1
- package/src/components/hero/hero.stories.js +30 -0
- package/src/components/icon/icon.css +6 -0
- package/src/components/loading/loading.css +5 -0
- package/src/components/logo-cloud/logo-cloud.css +6 -0
- package/src/components/map/index.js +1 -0
- package/src/components/map/map.component.js +135 -0
- package/src/components/map/map.css +41 -0
- package/src/components/map/map.js +6 -0
- package/src/components/map/map.react.js +9 -0
- package/src/components/map/map.stories.js +68 -0
- package/src/components/media-text/media-text.css +6 -0
- package/src/components/newsletter/newsletter.css +6 -0
- package/src/components/notice/notice.css +5 -0
- package/src/components/pagination/pagination.css +5 -0
- package/src/components/pricing/pricing.css +6 -0
- package/src/components/stats/stats.css +6 -0
- package/src/components/testimonials/testimonials.css +6 -0
- package/src/components/tooltip/tooltip.css +5 -0
- package/src/lib/styles/all.css +2 -0
- package/src/main.js +2 -0
- package/src/pages/blog-post.stories.js +7 -19
- package/src/react.js +2 -0
- package/src/types.d.ts +18 -0
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import { LitElement, html, nothing } from "lit";
|
|
2
|
+
import mapStyles from "./map.css" with { type: "css" };
|
|
3
|
+
|
|
4
|
+
const DARK_FILTER = "invert(1) hue-rotate(180deg) brightness(0.95) contrast(0.9)";
|
|
5
|
+
|
|
6
|
+
export class GrantCodesMap extends LitElement {
|
|
7
|
+
static styles = [mapStyles];
|
|
8
|
+
|
|
9
|
+
static properties = {
|
|
10
|
+
/**
|
|
11
|
+
* Latitude coordinate.
|
|
12
|
+
* @type {string}
|
|
13
|
+
*/
|
|
14
|
+
lat: { type: String },
|
|
15
|
+
/**
|
|
16
|
+
* Longitude coordinate.
|
|
17
|
+
* @type {string}
|
|
18
|
+
*/
|
|
19
|
+
lng: { type: String },
|
|
20
|
+
/**
|
|
21
|
+
* Map zoom level (1-18).
|
|
22
|
+
* @type {number}
|
|
23
|
+
*/
|
|
24
|
+
zoom: { type: Number },
|
|
25
|
+
/**
|
|
26
|
+
* Accessible label for the map iframe.
|
|
27
|
+
* @type {string}
|
|
28
|
+
*/
|
|
29
|
+
label: { type: String },
|
|
30
|
+
/**
|
|
31
|
+
* URL for a "Get directions" link below the map.
|
|
32
|
+
* @type {string}
|
|
33
|
+
*/
|
|
34
|
+
"directions-url": { type: String, attribute: "directions-url" },
|
|
35
|
+
/**
|
|
36
|
+
* Height of the map. Accepts any CSS length value.
|
|
37
|
+
* @type {string}
|
|
38
|
+
*/
|
|
39
|
+
height: { type: String },
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
constructor() {
|
|
43
|
+
super();
|
|
44
|
+
this.lat = "";
|
|
45
|
+
this.lng = "";
|
|
46
|
+
this.zoom = 14;
|
|
47
|
+
this.label = "Map";
|
|
48
|
+
this["directions-url"] = "";
|
|
49
|
+
this.height = "";
|
|
50
|
+
this._darkQuery = window.matchMedia("(prefers-color-scheme: dark)");
|
|
51
|
+
this._onSchemeChange = () => this._updateFilter();
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
connectedCallback() {
|
|
55
|
+
super.connectedCallback();
|
|
56
|
+
this._observer = new MutationObserver(() => this._updateFilter());
|
|
57
|
+
this._observer.observe(document.documentElement, {
|
|
58
|
+
attributes: true,
|
|
59
|
+
attributeFilter: ["class"],
|
|
60
|
+
});
|
|
61
|
+
this._darkQuery.addEventListener("change", this._onSchemeChange);
|
|
62
|
+
this._updateFilter();
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
disconnectedCallback() {
|
|
66
|
+
super.disconnectedCallback();
|
|
67
|
+
this._observer?.disconnect();
|
|
68
|
+
this._darkQuery.removeEventListener("change", this._onSchemeChange);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
_isDark() {
|
|
72
|
+
if (document.documentElement.classList.contains("dark")) return true;
|
|
73
|
+
if (document.documentElement.classList.contains("light")) return false;
|
|
74
|
+
return this._darkQuery.matches;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
_updateFilter() {
|
|
78
|
+
this.style.setProperty(
|
|
79
|
+
"--g-map-filter",
|
|
80
|
+
this._isDark() ? DARK_FILTER : "none",
|
|
81
|
+
);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
get _embedUrl() {
|
|
85
|
+
if (!this.lat || !this.lng) return "";
|
|
86
|
+
const bbox = this._getBoundingBox(
|
|
87
|
+
Number.parseFloat(this.lat),
|
|
88
|
+
Number.parseFloat(this.lng),
|
|
89
|
+
this.zoom,
|
|
90
|
+
);
|
|
91
|
+
return `https://www.openstreetmap.org/export/embed.html?bbox=${bbox}&marker=${this.lat},${this.lng}&layers=mapnik`;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Calculate a bounding box around a point for the given zoom level.
|
|
96
|
+
*/
|
|
97
|
+
_getBoundingBox(lat, lng, zoom) {
|
|
98
|
+
const spread = 360 / 2 ** zoom;
|
|
99
|
+
return `${lng - spread},${lat - spread},${lng + spread},${lat + spread}`;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
render() {
|
|
103
|
+
if (!this.lat || !this.lng) {
|
|
104
|
+
return nothing;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
const heightStyle = this.height
|
|
108
|
+
? `--map-height: ${this.height}`
|
|
109
|
+
: "";
|
|
110
|
+
|
|
111
|
+
return html`
|
|
112
|
+
<div class="map" style="${heightStyle}">
|
|
113
|
+
<iframe
|
|
114
|
+
class="map__iframe"
|
|
115
|
+
src="${this._embedUrl}"
|
|
116
|
+
title="${this.label}"
|
|
117
|
+
loading="lazy"
|
|
118
|
+
referrerpolicy="no-referrer"
|
|
119
|
+
frameborder="0"
|
|
120
|
+
seamless
|
|
121
|
+
></iframe>
|
|
122
|
+
${
|
|
123
|
+
this["directions-url"]
|
|
124
|
+
? html`<a
|
|
125
|
+
class="map__directions"
|
|
126
|
+
href="${this["directions-url"]}"
|
|
127
|
+
target="_blank"
|
|
128
|
+
rel="noopener noreferrer"
|
|
129
|
+
>Get directions</a>`
|
|
130
|
+
: nothing
|
|
131
|
+
}
|
|
132
|
+
</div>
|
|
133
|
+
`;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
*,
|
|
2
|
+
*::before,
|
|
3
|
+
*::after {
|
|
4
|
+
box-sizing: border-box;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
:host {
|
|
8
|
+
display: block;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
.map {
|
|
12
|
+
position: relative;
|
|
13
|
+
border: 1px solid var(--g-theme-color-border-default);
|
|
14
|
+
border-radius: var(--g-theme-border-radius-md, 0.5rem);
|
|
15
|
+
overflow: hidden;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
.map__iframe {
|
|
19
|
+
display: block;
|
|
20
|
+
vertical-align: top;
|
|
21
|
+
width: 100%;
|
|
22
|
+
height: var(--map-height, 21rem);
|
|
23
|
+
border: 0;
|
|
24
|
+
filter: var(--g-map-filter, none);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
.map__directions {
|
|
28
|
+
display: block;
|
|
29
|
+
padding: var(--g-theme-spacing-sm) var(--g-theme-spacing-md);
|
|
30
|
+
font-size: var(--g-theme-typography-body-sm-font-size);
|
|
31
|
+
color: var(--g-theme-color-content-brand, #7c3aed);
|
|
32
|
+
text-decoration: none;
|
|
33
|
+
border-block-start: 1px solid var(--g-theme-color-border-default);
|
|
34
|
+
background: var(--g-theme-color-background-subtle);
|
|
35
|
+
transition: background-color 0.2s ease;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
.map__directions:hover {
|
|
39
|
+
background: var(--g-theme-color-background-subtle-hover);
|
|
40
|
+
text-decoration: underline;
|
|
41
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { getStorybookHelpers } from "@wc-toolkit/storybook-helpers";
|
|
2
|
+
import "./map.js";
|
|
3
|
+
|
|
4
|
+
const { events, args, argTypes } = getStorybookHelpers("grantcodes-map");
|
|
5
|
+
|
|
6
|
+
const meta = {
|
|
7
|
+
title: "Components/Map",
|
|
8
|
+
component: "grantcodes-map",
|
|
9
|
+
args,
|
|
10
|
+
argTypes,
|
|
11
|
+
parameters: {
|
|
12
|
+
actions: {
|
|
13
|
+
handles: events,
|
|
14
|
+
},
|
|
15
|
+
},
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export default meta;
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Default map showing a location in Granollers, Catalonia.
|
|
22
|
+
*/
|
|
23
|
+
export const Default = {
|
|
24
|
+
args: {
|
|
25
|
+
lat: "41.648747",
|
|
26
|
+
lng: "2.161975",
|
|
27
|
+
zoom: 14,
|
|
28
|
+
label: "Granollers, Catalonia",
|
|
29
|
+
},
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Map with a directions link below.
|
|
34
|
+
*/
|
|
35
|
+
export const WithDirections = {
|
|
36
|
+
args: {
|
|
37
|
+
lat: "41.648747",
|
|
38
|
+
lng: "2.161975",
|
|
39
|
+
zoom: 14,
|
|
40
|
+
label: "Granollers, Catalonia",
|
|
41
|
+
"directions-url": "https://maps.google.com/?q=41.648747,2.161975",
|
|
42
|
+
},
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Map with a custom height.
|
|
47
|
+
*/
|
|
48
|
+
export const CustomHeight = {
|
|
49
|
+
args: {
|
|
50
|
+
lat: "48.8566",
|
|
51
|
+
lng: "2.3522",
|
|
52
|
+
zoom: 12,
|
|
53
|
+
label: "Paris, France",
|
|
54
|
+
height: "600px",
|
|
55
|
+
},
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Zoomed-out world view.
|
|
60
|
+
*/
|
|
61
|
+
export const ZoomedOut = {
|
|
62
|
+
args: {
|
|
63
|
+
lat: "0",
|
|
64
|
+
lng: "0",
|
|
65
|
+
zoom: 2,
|
|
66
|
+
label: "World map",
|
|
67
|
+
},
|
|
68
|
+
};
|
package/src/lib/styles/all.css
CHANGED
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
@import "../../components/card/card.css";
|
|
11
11
|
@import "../../components/code-preview/code-preview.css";
|
|
12
12
|
@import "../../components/container/container.css";
|
|
13
|
+
@import "../../components/countdown/countdown.css";
|
|
13
14
|
@import "../../components/cta/cta.css";
|
|
14
15
|
@import "../../components/dialog/dialog.css";
|
|
15
16
|
@import "../../components/dropdown/dropdown.css";
|
|
@@ -23,6 +24,7 @@
|
|
|
23
24
|
@import "../../components/icon/icon.css";
|
|
24
25
|
@import "../../components/loading/loading.css";
|
|
25
26
|
@import "../../components/logo-cloud/logo-cloud.css";
|
|
27
|
+
@import "../../components/map/map.css";
|
|
26
28
|
@import "../../components/media-text/media-text.css";
|
|
27
29
|
@import "../../components/newsletter/newsletter.css";
|
|
28
30
|
@import "../../components/notice/notice.css";
|
package/src/main.js
CHANGED
|
@@ -5,6 +5,7 @@ export * from "./components/button-group/index.js";
|
|
|
5
5
|
export * from "./components/card/index.js";
|
|
6
6
|
export * from "./components/code-preview/index.js";
|
|
7
7
|
export * from "./components/container/index.js";
|
|
8
|
+
export * from "./components/countdown/index.js";
|
|
8
9
|
export * from "./components/cta/index.js";
|
|
9
10
|
export * from "./components/dialog/index.js";
|
|
10
11
|
export * from "./components/dropzone/index.js";
|
|
@@ -15,6 +16,7 @@ export * from "./components/hero/index.js";
|
|
|
15
16
|
export * from "./components/icon/index.js";
|
|
16
17
|
export * from "./components/loading/index.js";
|
|
17
18
|
export * from "./components/logo-cloud/index.js";
|
|
19
|
+
export * from "./components/map/index.js";
|
|
18
20
|
export * from "./components/media-text/index.js";
|
|
19
21
|
export * from "./components/newsletter/index.js";
|
|
20
22
|
export * from "./components/notice/index.js";
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { html } from "lit";
|
|
2
2
|
import "../components/app-bar/app-bar.js";
|
|
3
|
+
import "../components/app-bar/nav-link.js";
|
|
3
4
|
import "../components/button/button.js";
|
|
4
5
|
import "../components/breadcrumb/breadcrumb.js";
|
|
5
6
|
import "../components/container/container.js";
|
|
@@ -93,10 +94,10 @@ export const Default = {
|
|
|
93
94
|
Flowbase
|
|
94
95
|
</a>
|
|
95
96
|
<div slot="nav" style="display: flex; gap: 0.5rem;">
|
|
96
|
-
<a href="/">Home</a>
|
|
97
|
-
<a href="/features">Features</a>
|
|
98
|
-
<a href="/blog">Blog</a>
|
|
99
|
-
<a href="/pricing">Pricing</a>
|
|
97
|
+
<grantcodes-nav-link><a href="/">Home</a></grantcodes-nav-link>
|
|
98
|
+
<grantcodes-nav-link><a href="/features">Features</a></grantcodes-nav-link>
|
|
99
|
+
<grantcodes-nav-link><a href="/blog">Blog</a></grantcodes-nav-link>
|
|
100
|
+
<grantcodes-nav-link><a href="/pricing">Pricing</a></grantcodes-nav-link>
|
|
100
101
|
</div>
|
|
101
102
|
<div slot="actions" style="display: flex; gap: 0.5rem;">
|
|
102
103
|
<grantcodes-button variant="ghost">Sign in</grantcodes-button>
|
|
@@ -287,7 +288,7 @@ export const Default = {
|
|
|
287
288
|
|
|
288
289
|
<!-- Related posts -->
|
|
289
290
|
<div
|
|
290
|
-
style="
|
|
291
|
+
style="padding-block: var(--g-theme-spacing-2xl);"
|
|
291
292
|
>
|
|
292
293
|
<grantcodes-container>
|
|
293
294
|
<h2
|
|
@@ -352,20 +353,7 @@ export const Default = {
|
|
|
352
353
|
</grantcodes-container>
|
|
353
354
|
</div>
|
|
354
355
|
|
|
355
|
-
|
|
356
|
-
eyebrow="Ready to try it?"
|
|
357
|
-
title="See how Flowbase keeps your team in flow"
|
|
358
|
-
text="Join thousands of teams who've replaced their meeting-heavy workflows with a calmer, more productive way of working."
|
|
359
|
-
primary-action=${JSON.stringify({
|
|
360
|
-
label: "Start for free",
|
|
361
|
-
href: "/signup",
|
|
362
|
-
})}
|
|
363
|
-
secondary-action=${JSON.stringify({
|
|
364
|
-
label: "See all features",
|
|
365
|
-
href: "/features",
|
|
366
|
-
})}
|
|
367
|
-
align="center"
|
|
368
|
-
></grantcodes-cta>
|
|
356
|
+
|
|
369
357
|
|
|
370
358
|
<grantcodes-footer columns="3">
|
|
371
359
|
${footerContent}
|
package/src/react.js
CHANGED
|
@@ -9,6 +9,7 @@ export { ButtonGroup } from "./components/button-group/button-group.react.js"
|
|
|
9
9
|
export { Card } from "./components/card/card.react.js"
|
|
10
10
|
export { CodePreview } from "./components/code-preview/code-preview.react.js"
|
|
11
11
|
export { Container } from "./components/container/container.react.js"
|
|
12
|
+
export { Countdown } from "./components/countdown/countdown.react.js"
|
|
12
13
|
export { Cta } from "./components/cta/cta.react.js"
|
|
13
14
|
export { Dialog } from "./components/dialog/dialog.react.js"
|
|
14
15
|
export { Dropdown, DropdownItem } from "./components/dropdown/dropdown.react.js"
|
|
@@ -22,6 +23,7 @@ export { Hero } from "./components/hero/hero.react.js"
|
|
|
22
23
|
export { Icon } from "./components/icon/icon.react.js"
|
|
23
24
|
export { Loading } from "./components/loading/loading.react.js"
|
|
24
25
|
export { LogoCloud } from "./components/logo-cloud/logo-cloud.react.js"
|
|
26
|
+
export { MapEmbed } from "./components/map/map.react.js"
|
|
25
27
|
export { MediaText } from "./components/media-text/media-text.react.js"
|
|
26
28
|
export { Newsletter } from "./components/newsletter/newsletter.react.js"
|
|
27
29
|
export { Notice } from "./components/notice/notice.react.js"
|
package/src/types.d.ts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ambient module declarations for @grantcodes/ui.
|
|
3
|
+
*
|
|
4
|
+
* Usage: Add to your tsconfig.json:
|
|
5
|
+
* { "compilerOptions": { "types": ["@grantcodes/ui"] } }
|
|
6
|
+
*
|
|
7
|
+
* Or reference directly:
|
|
8
|
+
* /// <reference types="@grantcodes/ui" />
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
// Component deep imports
|
|
12
|
+
declare module "@grantcodes/ui/components/*";
|
|
13
|
+
|
|
14
|
+
// Style imports
|
|
15
|
+
declare module "@grantcodes/ui/styles/*";
|
|
16
|
+
|
|
17
|
+
// Font imports
|
|
18
|
+
declare module "@grantcodes/ui/fonts/*";
|