@dreamtree-org/landing-kit 0.9.0 → 0.10.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.
- package/MIGRATION.md +16 -0
- package/PLATFORM-API.md +17 -13
- package/README.md +41 -1
- package/ai-skills/landing-kit.md +7 -6
- package/auth.css +57 -0
- package/auth.d.ts +2 -2
- package/dist/auth.cjs +143 -38
- package/dist/auth.js +139 -34
- package/dist/index.cjs +605 -540
- package/dist/index.js +573 -508
- package/dist/platform.cjs +1208 -408
- package/dist/platform.js +1209 -409
- package/index.d.ts +25 -0
- package/package.json +3 -2
- package/platform.d.ts +37 -3
- package/styles.css +57 -0
package/dist/auth.js
CHANGED
|
@@ -87,12 +87,115 @@ function DemoAccounts({ load, onSelect, className = "" }) {
|
|
|
87
87
|
] });
|
|
88
88
|
}
|
|
89
89
|
|
|
90
|
+
// src/DreamtreeSso.jsx
|
|
91
|
+
import { useEffect as useEffect2, useRef as useRef2 } from "react";
|
|
92
|
+
|
|
93
|
+
// src/sso.js
|
|
94
|
+
function decodeKey(part) {
|
|
95
|
+
const key = part.split("=")[0];
|
|
96
|
+
try {
|
|
97
|
+
return decodeURIComponent(key.replace(/\+/g, " "));
|
|
98
|
+
} catch {
|
|
99
|
+
return key;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
function buildSsoUrl(startUrl, { returnTo, companySlug } = {}) {
|
|
103
|
+
const raw = String(startUrl != null ? startUrl : "");
|
|
104
|
+
const hashAt = raw.indexOf("#");
|
|
105
|
+
const hash = hashAt === -1 ? "" : raw.slice(hashAt);
|
|
106
|
+
const beforeHash = hashAt === -1 ? raw : raw.slice(0, hashAt);
|
|
107
|
+
const queryAt = beforeHash.indexOf("?");
|
|
108
|
+
const path = queryAt === -1 ? beforeHash : beforeHash.slice(0, queryAt);
|
|
109
|
+
const query = queryAt === -1 ? "" : beforeHash.slice(queryAt + 1);
|
|
110
|
+
const add = [
|
|
111
|
+
["return_to", returnTo],
|
|
112
|
+
["dt_company", companySlug]
|
|
113
|
+
].filter(([, v]) => v != null && v !== "");
|
|
114
|
+
const replaced = new Set(add.map(([k]) => k));
|
|
115
|
+
const params = query.split("&").filter((p) => p && !replaced.has(decodeKey(p))).concat(add.map(([k, v]) => `${k}=${encodeURIComponent(String(v))}`));
|
|
116
|
+
return `${path}${params.length ? `?${params.join("&")}` : ""}${hash}`;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// src/icons.jsx
|
|
120
|
+
import { createElement, isValidElement } from "react";
|
|
121
|
+
import { Fragment as Fragment2, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
122
|
+
var base = {
|
|
123
|
+
viewBox: "0 0 24 24",
|
|
124
|
+
fill: "none",
|
|
125
|
+
stroke: "currentColor",
|
|
126
|
+
strokeWidth: 2,
|
|
127
|
+
strokeLinecap: "round",
|
|
128
|
+
strokeLinejoin: "round",
|
|
129
|
+
"aria-hidden": "true",
|
|
130
|
+
focusable: "false"
|
|
131
|
+
};
|
|
132
|
+
var make = (paths) => function Icon({ size = 16, className = "dt-lp-icon" }) {
|
|
133
|
+
return /* @__PURE__ */ jsx2("svg", { ...base, width: size, height: size, className, children: paths });
|
|
134
|
+
};
|
|
135
|
+
var ArrowRight = make(/* @__PURE__ */ jsx2("path", { d: "M5 12h14M13 6l6 6-6 6" }));
|
|
136
|
+
var ChevronRight = make(/* @__PURE__ */ jsx2("path", { d: "m9 6 6 6-6 6" }));
|
|
137
|
+
var Check = make(/* @__PURE__ */ jsx2("path", { d: "M20 6 9 17l-5-5" }));
|
|
138
|
+
var Help = make(
|
|
139
|
+
/* @__PURE__ */ jsxs2(Fragment2, { children: [
|
|
140
|
+
/* @__PURE__ */ jsx2("circle", { cx: "12", cy: "12", r: "10" }),
|
|
141
|
+
/* @__PURE__ */ jsx2("path", { d: "M9.1 9a3 3 0 0 1 5.8 1c0 2-3 3-3 3M12 17h.01" })
|
|
142
|
+
] })
|
|
143
|
+
);
|
|
144
|
+
var Alert = make(
|
|
145
|
+
/* @__PURE__ */ jsxs2(Fragment2, { children: [
|
|
146
|
+
/* @__PURE__ */ jsx2("path", { d: "M10.3 3.9 1.8 18a2 2 0 0 0 1.7 3h17a2 2 0 0 0 1.7-3L13.7 3.9a2 2 0 0 0-3.4 0Z" }),
|
|
147
|
+
/* @__PURE__ */ jsx2("path", { d: "M12 9v4M12 17h.01" })
|
|
148
|
+
] })
|
|
149
|
+
);
|
|
150
|
+
var MenuIcon = make(/* @__PURE__ */ jsx2("path", { d: "M4 6h16M4 12h16M4 18h16" }));
|
|
151
|
+
var Close = make(/* @__PURE__ */ jsx2("path", { d: "M18 6 6 18M6 6l12 12" }));
|
|
152
|
+
var Calendar = make(
|
|
153
|
+
/* @__PURE__ */ jsxs2(Fragment2, { children: [
|
|
154
|
+
/* @__PURE__ */ jsx2("rect", { x: "3", y: "4", width: "18", height: "18", rx: "2" }),
|
|
155
|
+
/* @__PURE__ */ jsx2("path", { d: "M16 2v4M8 2v4M3 10h18m-12 6 2 2 4-4" })
|
|
156
|
+
] })
|
|
157
|
+
);
|
|
158
|
+
|
|
159
|
+
// src/DreamtreeSso.jsx
|
|
160
|
+
import { Fragment as Fragment3, jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
161
|
+
var DEFAULT_SSO_LABEL = "Continue with Dreamtree";
|
|
162
|
+
function DreamtreeSso({ provider, children }) {
|
|
163
|
+
const { startUrl, mode, label = DEFAULT_SSO_LABEL, companySlug, returnTo } = provider;
|
|
164
|
+
const isSso = mode === "sso";
|
|
165
|
+
const autoRedirect = isSso && provider.autoRedirect !== false;
|
|
166
|
+
const href = buildSsoUrl(startUrl, { returnTo, companySlug });
|
|
167
|
+
const redirected = useRef2(false);
|
|
168
|
+
useEffect2(() => {
|
|
169
|
+
if (!autoRedirect || redirected.current) return;
|
|
170
|
+
redirected.current = true;
|
|
171
|
+
window.location.assign(href);
|
|
172
|
+
}, [autoRedirect, href]);
|
|
173
|
+
const button = /* @__PURE__ */ jsxs3("a", { className: "dt-auth-sso-btn", href, children: [
|
|
174
|
+
/* @__PURE__ */ jsx3("span", { children: label }),
|
|
175
|
+
/* @__PURE__ */ jsx3(ArrowRight, { size: 16, className: "dt-auth-sso-icon" })
|
|
176
|
+
] });
|
|
177
|
+
if (isSso) {
|
|
178
|
+
return /* @__PURE__ */ jsxs3("div", { className: "dt-auth-sso dt-auth-sso--only", children: [
|
|
179
|
+
autoRedirect ? /* @__PURE__ */ jsxs3("p", { className: "dt-auth-sso-status", role: "status", "aria-live": "polite", children: [
|
|
180
|
+
/* @__PURE__ */ jsx3("span", { className: "dt-auth-sso-spinner", "aria-hidden": "true" }),
|
|
181
|
+
"Redirecting to Dreamtree ID\u2026"
|
|
182
|
+
] }) : null,
|
|
183
|
+
button
|
|
184
|
+
] });
|
|
185
|
+
}
|
|
186
|
+
return /* @__PURE__ */ jsxs3(Fragment3, { children: [
|
|
187
|
+
/* @__PURE__ */ jsx3("div", { className: "dt-auth-sso", children: button }),
|
|
188
|
+
/* @__PURE__ */ jsx3("div", { className: "dt-auth-or", children: /* @__PURE__ */ jsx3("span", { children: "or" }) }),
|
|
189
|
+
children
|
|
190
|
+
] });
|
|
191
|
+
}
|
|
192
|
+
|
|
90
193
|
// src/useTapReveal.js
|
|
91
|
-
import { useCallback, useRef as
|
|
194
|
+
import { useCallback, useRef as useRef3, useState as useState2 } from "react";
|
|
92
195
|
function useTapReveal({ taps = 4, windowMs = 1500 } = {}) {
|
|
93
196
|
const [revealed, setRevealed] = useState2(false);
|
|
94
|
-
const count =
|
|
95
|
-
const last =
|
|
197
|
+
const count = useRef3(0);
|
|
198
|
+
const last = useRef3(0);
|
|
96
199
|
const onClick = useCallback(() => {
|
|
97
200
|
if (revealed) return;
|
|
98
201
|
const now = Date.now();
|
|
@@ -104,7 +207,7 @@ function useTapReveal({ taps = 4, windowMs = 1500 } = {}) {
|
|
|
104
207
|
}
|
|
105
208
|
|
|
106
209
|
// src/AuthShell.jsx
|
|
107
|
-
import { jsx as
|
|
210
|
+
import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
108
211
|
var DEFAULT_LEGAL = [
|
|
109
212
|
{ label: "Privacy Policy", href: "/privacy" },
|
|
110
213
|
{ label: "Terms", href: "/terms" },
|
|
@@ -112,10 +215,10 @@ var DEFAULT_LEGAL = [
|
|
|
112
215
|
];
|
|
113
216
|
function BrandMark({ brand, size }) {
|
|
114
217
|
if (brand.logoSrc) {
|
|
115
|
-
return /* @__PURE__ */
|
|
218
|
+
return /* @__PURE__ */ jsx4("img", { className: "dt-auth-mark-img", src: brand.logoSrc, alt: "", width: size, height: size });
|
|
116
219
|
}
|
|
117
|
-
if (brand.mark) return /* @__PURE__ */
|
|
118
|
-
return /* @__PURE__ */
|
|
220
|
+
if (brand.mark) return /* @__PURE__ */ jsx4("span", { className: "dt-auth-mark-node", children: brand.mark });
|
|
221
|
+
return /* @__PURE__ */ jsx4("span", { className: "dt-auth-monogram", style: { width: size, height: size }, "aria-hidden": "true", children: brand.name.charAt(0) });
|
|
119
222
|
}
|
|
120
223
|
function brandStyle(brand) {
|
|
121
224
|
return {
|
|
@@ -134,7 +237,8 @@ function AuthShell({
|
|
|
134
237
|
legalLinks = DEFAULT_LEGAL,
|
|
135
238
|
linkComponent: LinkComponent,
|
|
136
239
|
className = "",
|
|
137
|
-
demoAccounts
|
|
240
|
+
demoAccounts,
|
|
241
|
+
ssoProvider
|
|
138
242
|
}) {
|
|
139
243
|
var _a, _b;
|
|
140
244
|
const headingId = useId();
|
|
@@ -142,44 +246,44 @@ function AuthShell({
|
|
|
142
246
|
const isPlatform = variant === "platform";
|
|
143
247
|
const headline = isPlatform ? brand.platformHeadline || "Platform administration" : brand.headline;
|
|
144
248
|
const pitch = isPlatform ? brand.platformPitch || `Super administrator console for ${brand.name}. Every action here is audited.` : brand.pitch;
|
|
145
|
-
const renderLink = (l) => LinkComponent ? /* @__PURE__ */
|
|
146
|
-
return /* @__PURE__ */
|
|
249
|
+
const renderLink = (l) => LinkComponent ? /* @__PURE__ */ jsx4(LinkComponent, { to: l.href, href: l.href, className: "dt-auth-legal-link", children: l.label }, l.href) : /* @__PURE__ */ jsx4("a", { href: l.href, className: "dt-auth-legal-link", children: l.label }, l.href);
|
|
250
|
+
return /* @__PURE__ */ jsxs4(
|
|
147
251
|
"div",
|
|
148
252
|
{
|
|
149
253
|
className: `dt-auth ${isPlatform ? "dt-auth--platform" : ""} ${className}`,
|
|
150
254
|
style: brandStyle(brand),
|
|
151
255
|
"data-product": brand.id,
|
|
152
256
|
children: [
|
|
153
|
-
/* @__PURE__ */
|
|
154
|
-
/* @__PURE__ */
|
|
155
|
-
/* @__PURE__ */
|
|
156
|
-
/* @__PURE__ */
|
|
157
|
-
isPlatform ? /* @__PURE__ */
|
|
257
|
+
/* @__PURE__ */ jsxs4("aside", { className: "dt-auth-panel", children: [
|
|
258
|
+
/* @__PURE__ */ jsxs4("a", { href: "/", className: "dt-auth-brand", children: [
|
|
259
|
+
/* @__PURE__ */ jsx4(BrandMark, { brand, size: 28 }),
|
|
260
|
+
/* @__PURE__ */ jsx4("span", { className: "dt-auth-brand-name", children: brand.name }),
|
|
261
|
+
isPlatform ? /* @__PURE__ */ jsx4("span", { className: "dt-auth-badge", children: "Platform" }) : null
|
|
158
262
|
] }),
|
|
159
|
-
/* @__PURE__ */
|
|
160
|
-
/* @__PURE__ */
|
|
161
|
-
pitch ? /* @__PURE__ */
|
|
162
|
-
!isPlatform && ((_b = brand.points) == null ? void 0 : _b.length) ? /* @__PURE__ */
|
|
263
|
+
/* @__PURE__ */ jsxs4("div", { className: "dt-auth-pitch", children: [
|
|
264
|
+
/* @__PURE__ */ jsx4("h2", { children: headline }),
|
|
265
|
+
pitch ? /* @__PURE__ */ jsx4("p", { children: pitch }) : null,
|
|
266
|
+
!isPlatform && ((_b = brand.points) == null ? void 0 : _b.length) ? /* @__PURE__ */ jsx4("ul", { children: brand.points.map((p) => /* @__PURE__ */ jsx4("li", { children: p }, p)) }) : null
|
|
163
267
|
] }),
|
|
164
|
-
/* @__PURE__ */
|
|
268
|
+
/* @__PURE__ */ jsx4("p", { className: "dt-auth-panel-foot", children: brand.category || "by Dreamtree-Org" })
|
|
165
269
|
] }),
|
|
166
|
-
/* @__PURE__ */
|
|
167
|
-
/* @__PURE__ */
|
|
168
|
-
/* @__PURE__ */
|
|
169
|
-
/* @__PURE__ */
|
|
170
|
-
isPlatform ? /* @__PURE__ */
|
|
270
|
+
/* @__PURE__ */ jsx4("main", { className: "dt-auth-main", children: /* @__PURE__ */ jsxs4("div", { className: "dt-auth-column", children: [
|
|
271
|
+
/* @__PURE__ */ jsxs4("a", { href: "/", className: "dt-auth-brand dt-auth-brand--mobile", children: [
|
|
272
|
+
/* @__PURE__ */ jsx4(BrandMark, { brand, size: 24 }),
|
|
273
|
+
/* @__PURE__ */ jsx4("span", { className: "dt-auth-brand-name", children: brand.name }),
|
|
274
|
+
isPlatform ? /* @__PURE__ */ jsx4("span", { className: "dt-auth-badge", children: "Platform" }) : null
|
|
171
275
|
] }),
|
|
172
|
-
/* @__PURE__ */
|
|
173
|
-
/* @__PURE__ */
|
|
174
|
-
/* @__PURE__ */
|
|
175
|
-
subtitle ? /* @__PURE__ */
|
|
276
|
+
/* @__PURE__ */ jsxs4("section", { className: "dt-auth-card", "aria-labelledby": headingId, children: [
|
|
277
|
+
/* @__PURE__ */ jsxs4("header", { className: "dt-auth-head", children: [
|
|
278
|
+
/* @__PURE__ */ jsx4("h1", { id: headingId, ...demoAccounts ? tapProps : {}, children: title }),
|
|
279
|
+
subtitle ? /* @__PURE__ */ jsx4("p", { children: subtitle }) : null
|
|
176
280
|
] }),
|
|
177
|
-
children,
|
|
178
|
-
demoAccounts && revealed ? /* @__PURE__ */
|
|
281
|
+
ssoProvider ? /* @__PURE__ */ jsx4(DreamtreeSso, { provider: ssoProvider, children }) : children,
|
|
282
|
+
demoAccounts && revealed && (ssoProvider == null ? void 0 : ssoProvider.mode) !== "sso" ? /* @__PURE__ */ jsx4(DemoAccounts, { load: demoAccounts.load, onSelect: demoAccounts.onSelect }) : null
|
|
179
283
|
] }),
|
|
180
|
-
footer ? /* @__PURE__ */
|
|
181
|
-
(legalLinks == null ? void 0 : legalLinks.length) ? /* @__PURE__ */
|
|
182
|
-
i > 0 ? /* @__PURE__ */
|
|
284
|
+
footer ? /* @__PURE__ */ jsx4("div", { className: "dt-auth-footer", children: footer }) : null,
|
|
285
|
+
(legalLinks == null ? void 0 : legalLinks.length) ? /* @__PURE__ */ jsx4("nav", { className: "dt-auth-legal", "aria-label": "Legal", children: legalLinks.map((l, i) => /* @__PURE__ */ jsxs4("span", { className: "dt-auth-legal-item", children: [
|
|
286
|
+
i > 0 ? /* @__PURE__ */ jsx4("span", { "aria-hidden": "true", children: "\xB7" }) : null,
|
|
183
287
|
renderLink(l)
|
|
184
288
|
] }, l.href)) }) : null
|
|
185
289
|
] }) })
|
|
@@ -345,6 +449,7 @@ export {
|
|
|
345
449
|
DemoAccounts,
|
|
346
450
|
brandStyle,
|
|
347
451
|
brands,
|
|
452
|
+
buildSsoUrl,
|
|
348
453
|
fetchDemoAccounts,
|
|
349
454
|
getBrand,
|
|
350
455
|
normalizeDemoAccounts,
|