@webstudio-is/sdk-components-react 0.268.0 → 0.269.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.
@@ -213,15 +213,22 @@ const e = {
213
213
  defaultValue: "medium",
214
214
  options: ["full", "long", "medium", "short", "none"]
215
215
  },
216
+ datetime: {
217
+ required: !1,
218
+ control: "text",
219
+ type: "string",
220
+ defaultValue: "dateTime attribute is not set",
221
+ description: "Machine-readable value"
222
+ },
216
223
  format: {
217
224
  description: `Custom format template. Overrides Date Style and Time Style.
218
225
 
219
226
  Tokens: YYYY/YY (year), MMMM/MMM/MM/M (month), DDDD/DDD/DD/D (day), HH/H (hours), mm/m (minutes), ss/s (seconds)
220
227
 
221
228
  Examples:
222
- "YYYY-MM-DD" → 2025-11-03
223
- "DDDD, MMMM D" → Monday, November 3
224
- "DDD, D. MMM YYYY" → Mon, 3. Nov 2025
229
+ - "YYYY-MM-DD" → 2025-11-03
230
+ - "DDDD, MMMM D" → Monday, November 3
231
+ - "DDD, D. MMM YYYY" → Mon, 3. Nov 2025
225
232
 
226
233
  Day and month names use the selected language.`,
227
234
  required: !1,
@@ -313,6 +320,16 @@ Day and month names use the selected language.`,
313
320
  type: "string",
314
321
  defaultValue: "none",
315
322
  options: ["full", "long", "medium", "short", "none"]
323
+ },
324
+ timeZone: {
325
+ description: `Time zone used to format the date.
326
+
327
+ Use "UTC" for deterministic UTC output, "visitor" to use the browser time
328
+ zone after hydration, or an IANA time zone like "Europe/Berlin".`,
329
+ required: !1,
330
+ control: "text",
331
+ type: "string",
332
+ defaultValue: "UTC"
316
333
  }
317
334
  };
318
335
  export {
package/lib/components.js CHANGED
@@ -5,9 +5,9 @@ import { MarkdownEmbed as a } from "./markdown-embed.js";
5
5
  import { Body as n } from "./body.js";
6
6
  import { Box as l } from "./box.js";
7
7
  import { Text as k } from "./text.js";
8
- import { Heading as T } from "./heading.js";
9
- import { Paragraph as c } from "./paragraph.js";
10
- import { Link as B, Link as L } from "./link.js";
8
+ import { Heading as B } from "./heading.js";
9
+ import { Paragraph as S } from "./paragraph.js";
10
+ import { BaseLink as b, BaseLink as c } from "./link.js";
11
11
  import { Span as g } from "./span.js";
12
12
  import { Bold as I } from "./bold.js";
13
13
  import { Italic as h } from "./italic.js";
@@ -31,9 +31,9 @@ import { Vimeo as fo } from "./vimeo.js";
31
31
  import { YouTube as io } from "./youtube.js";
32
32
  import { VimeoPreviewImage as lo } from "./vimeo-preview-image.js";
33
33
  import { VimeoPlayButton as ko } from "./vimeo-play-button.js";
34
- import { VimeoSpinner as To } from "./vimeo-spinner.js";
35
- import { XmlNode as co } from "./xml-node.js";
36
- import { XmlTime as Bo } from "./xml-time.js";
34
+ import { VimeoSpinner as Bo } from "./vimeo-spinner.js";
35
+ import { XmlNode as So } from "./xml-node.js";
36
+ import { XmlTime as bo } from "./xml-time.js";
37
37
  import { Time as Ho } from "./time.js";
38
38
  import { Select as Fo } from "./select.js";
39
39
  import { Option as Vo } from "./option.js";
@@ -56,21 +56,21 @@ export {
56
56
  Co as HeadMeta,
57
57
  Po as HeadSlot,
58
58
  Mo as HeadTitle,
59
- T as Heading,
59
+ B as Heading,
60
60
  x as HtmlEmbed,
61
61
  Y as Image,
62
62
  X as Input,
63
63
  h as Italic,
64
64
  $ as Label,
65
- B as Link,
65
+ b as Link,
66
66
  D as List,
67
67
  J as ListItem,
68
68
  a as MarkdownEmbed,
69
69
  Vo as Option,
70
- c as Paragraph,
70
+ S as Paragraph,
71
71
  to as RadioButton,
72
72
  O as RemixForm,
73
- L as RichTextLink,
73
+ c as RichTextLink,
74
74
  Fo as Select,
75
75
  Q as Separator,
76
76
  e as Slot,
@@ -84,8 +84,8 @@ export {
84
84
  fo as Vimeo,
85
85
  ko as VimeoPlayButton,
86
86
  lo as VimeoPreviewImage,
87
- To as VimeoSpinner,
88
- co as XmlNode,
89
- Bo as XmlTime,
87
+ Bo as VimeoSpinner,
88
+ So as XmlNode,
89
+ bo as XmlTime,
90
90
  io as YouTube
91
91
  };
@@ -0,0 +1,48 @@
1
+ import { jsx as e } from "react/jsx-runtime";
2
+ import { forwardRef as f, useContext as L } from "react";
3
+ import { ReactSdkContext as P } from "@webstudio-is/react-sdk/runtime";
4
+ import { BaseLink as a } from "./link.js";
5
+ import { LinkCurrentUrlContext as x } from "./link-current-url.js";
6
+ import { isInternalHref as R } from "@webstudio-is/sdk/link-utils";
7
+ import { getCurrentLinkProps as $, stripRouterOnlyProps as c } from "./link-utils.js";
8
+ const g = (t, o) => t === "" ? `${o.pathname}${o.search}` : t, v = (t) => `https://webstudio.local${t.pathname}${t.search}${t.hash}`, m = ({
9
+ children: t,
10
+ location: o
11
+ }) => /* @__PURE__ */ e(x.Provider, { value: v(o), children: t }), S = ({
12
+ Link: t,
13
+ useLocation: o,
14
+ useResolvedPath: u
15
+ }) => {
16
+ const l = f((r, n) => {
17
+ const i = o(), s = g(r.href, i), { linkProps: d, currentLinkProps: C } = $(
18
+ r,
19
+ i,
20
+ u(r.href)
21
+ );
22
+ return /* @__PURE__ */ e(m, { location: i, children: /* @__PURE__ */ e(t, { ...d, ...C, to: s, ref: n }) });
23
+ }), k = f(
24
+ (r, n) => {
25
+ const i = o();
26
+ return /* @__PURE__ */ e(m, { location: i, children: /* @__PURE__ */ e(
27
+ a,
28
+ {
29
+ ...c(r),
30
+ href: r.href,
31
+ ref: n
32
+ }
33
+ ) });
34
+ }
35
+ ), h = f(
36
+ (r, n) => {
37
+ const { assetBaseUrl: i } = L(P);
38
+ if (r.href === void 0)
39
+ return /* @__PURE__ */ e(a, { ...c(r), ref: n });
40
+ const s = String(r.href);
41
+ return s.startsWith("#") === !1 && R(s, i) ? /* @__PURE__ */ e(l, { ...r, href: s, ref: n }) : s.startsWith("#") ? /* @__PURE__ */ e(k, { ...r, href: s, ref: n }) : /* @__PURE__ */ e(a, { ...c(r), ref: n });
42
+ }
43
+ );
44
+ return h.displayName = a.displayName, h;
45
+ };
46
+ export {
47
+ S as createLink
48
+ };
package/lib/html-embed.js CHANGED
@@ -1,15 +1,13 @@
1
1
  import { jsx as s } from "react/jsx-runtime";
2
2
  import { forwardRef as b, useContext as x, useState as E, useSyncExternalStore as k, useRef as f, useMemo as T, useEffect as g } from "react";
3
3
  import { mergeRefs as L } from "@react-aria/utils";
4
- import { ReactSdkContext as _ } from "@webstudio-is/react-sdk/runtime";
5
- import { patchDomEvents as C, executeDomEvents as w } from "./html-embed-patchers.js";
6
- const M = {
7
- scriptTestIdPrefix: "client-"
8
- }, O = (e) => new Promise((t, n) => {
4
+ import { ReactSdkContext as C } from "@webstudio-is/react-sdk/runtime";
5
+ import { patchDomEvents as w, executeDomEvents as M } from "./html-embed-patchers.js";
6
+ const O = "client-", H = (e) => new Promise((t, n) => {
9
7
  const r = document.createElement("script"), i = e.hasAttribute("src"), a = e.type === "module";
10
8
  for (const { name: c, value: o } of e.attributes)
11
9
  r.setAttribute(c, o);
12
- if (r.dataset.testid !== void 0 && (r.dataset.testid = `${M.scriptTestIdPrefix}${r.dataset.testid}`), i)
10
+ if (r.dataset.testid !== void 0 && (r.dataset.testid = `${O}${r.dataset.testid}`), i)
13
11
  r.addEventListener("load", () => {
14
12
  t();
15
13
  }), r.addEventListener("error", n);
@@ -31,20 +29,20 @@ const M = {
31
29
  e.replaceWith(r), i === !1 && t();
32
30
  }), d = [];
33
31
  let u = !1;
34
- const H = async (e) => {
32
+ const A = async (e) => {
35
33
  if (d.push(...e), await Promise.resolve(), !u) {
36
- for (C(), u = !0; d.length > 0; )
34
+ for (w(), u = !0; d.length > 0; )
37
35
  await d.shift()();
38
- w(), u = !1;
36
+ M(), u = !1;
39
37
  }
40
38
  }, I = (e) => {
41
39
  const t = e.querySelectorAll("script"), n = [], r = [];
42
40
  t.forEach((i) => {
43
- (i.hasAttribute("async") ? r : n).push(() => O(i));
41
+ (i.hasAttribute("async") ? r : n).push(() => H(i));
44
42
  });
45
43
  for (const i of r)
46
44
  i();
47
- H(n);
45
+ A(n);
48
46
  }, P = (e) => {
49
47
  const { code: t, innerRef: n, ...r } = e;
50
48
  return /* @__PURE__ */ s("div", { ref: n, ...r, style: { display: "block", padding: 20 }, children: 'Open the "Settings" panel to insert HTML code.' });
@@ -84,9 +82,9 @@ const H = async (e) => {
84
82
  dangerouslySetInnerHTML: { __html: t ?? "" }
85
83
  }
86
84
  );
87
- }, h = v, A = b(
85
+ }, h = v, U = b(
88
86
  (e, t) => {
89
- const { code: n, executeScriptOnCanvas: r, clientOnly: i, children: a, ...c } = e, { renderer: o, isSafeMode: y } = x(_), R = p(), [S] = E(R);
87
+ const { code: n, executeScriptOnCanvas: r, clientOnly: i, children: a, ...c } = e, { renderer: o, isSafeMode: y } = x(C), R = p(), [S] = E(R);
90
88
  return n === void 0 || String(n).trim().length === 0 ? /* @__PURE__ */ s(P, { innerRef: t, ...c }) : S ? i !== !0 ? /* @__PURE__ */ s(v, { innerRef: t, code: n, ...c }) : /* @__PURE__ */ s(l, { children: /* @__PURE__ */ s(m, { innerRef: t, code: n, ...c }) }) : y ? /* @__PURE__ */ s(l, { children: /* @__PURE__ */ s(
91
89
  h,
92
90
  {
@@ -112,8 +110,7 @@ const H = async (e) => {
112
110
  ) });
113
111
  }
114
112
  );
115
- A.displayName = "HtmlEmbed";
113
+ U.displayName = "HtmlEmbed";
116
114
  export {
117
- A as HtmlEmbed,
118
- M as __testing__
115
+ U as HtmlEmbed
119
116
  };
package/lib/index.js ADDED
@@ -0,0 +1,6 @@
1
+ import { createLink as t } from "./create-link.js";
2
+ import { LinkCurrentUrlContext as n } from "./link-current-url.js";
3
+ export {
4
+ n as LinkCurrentUrlContext,
5
+ t as createLink
6
+ };
@@ -0,0 +1,7 @@
1
+ import { createContext as t } from "react";
2
+ const r = t(
3
+ void 0
4
+ );
5
+ export {
6
+ r as LinkCurrentUrlContext
7
+ };
@@ -0,0 +1,25 @@
1
+ import { resolveLocalLinkUrl as p, isLocalLinkActive as u } from "@webstudio-is/sdk/link-utils";
2
+ const m = (t, r, o) => {
3
+ const { href: s, "aria-current": a, className: n, ...i } = t, c = p(s, r, o), e = u(r, c), l = [n, e ? "active" : void 0].filter(Boolean).join(" ");
4
+ return {
5
+ linkProps: i,
6
+ currentLinkProps: {
7
+ ...e ? { "aria-current": a ?? "page" } : {},
8
+ ...l === "" ? {} : { className: l }
9
+ }
10
+ };
11
+ }, L = ({
12
+ prefetch: t,
13
+ discover: r,
14
+ reloadDocument: o,
15
+ replace: s,
16
+ preventScrollReset: a,
17
+ relative: n,
18
+ state: i,
19
+ viewTransition: c,
20
+ ...e
21
+ }) => e;
22
+ export {
23
+ m as getCurrentLinkProps,
24
+ L as stripRouterOnlyProps
25
+ };
package/lib/link.js CHANGED
@@ -1,15 +1,49 @@
1
- import { jsx as t } from "react/jsx-runtime";
2
- import { forwardRef as n } from "react";
3
- const a = n((e, o) => {
4
- const {
5
- children: s,
1
+ import { jsx as w } from "react/jsx-runtime";
2
+ import { forwardRef as L, useContext as f } from "react";
3
+ import { ReactSdkContext as C } from "@webstudio-is/react-sdk/runtime";
4
+ import { isInternalHref as U } from "@webstudio-is/sdk/link-utils";
5
+ import { stripRouterOnlyProps as p, getCurrentLinkProps as P } from "./link-utils.js";
6
+ import { LinkCurrentUrlContext as x } from "./link-current-url.js";
7
+ const R = () => {
8
+ if (!(typeof window > "u"))
9
+ return window.location.href;
10
+ }, $ = (e) => {
11
+ if (e !== void 0)
12
+ return new URL(e, "https://webstudio.local");
13
+ }, g = L((e, l) => {
14
+ const d = f(x), { assetBaseUrl: m } = f(C), {
15
+ children: h,
6
16
  // @todo: it's a hack made for Image component for the builder and should't be in the runtime at all.
7
- $webstudio$canvasOnly$assetId: i,
8
- ...r
9
- } = e;
10
- return /* @__PURE__ */ t("a", { ...r, href: r.href ?? "#", ref: o, children: s });
17
+ $webstudio$canvasOnly$assetId: v,
18
+ "aria-current": o,
19
+ className: s,
20
+ ...n
21
+ } = e, i = n.href !== void 0, t = i ? String(n.href) : "#", k = d ?? R(), r = $(k);
22
+ let a = p(n), c = {
23
+ ...o === void 0 ? {} : { "aria-current": o },
24
+ ...s === void 0 ? {} : { className: s }
25
+ };
26
+ if (r && i && U(t, m)) {
27
+ const u = P(
28
+ { ...n, href: t, "aria-current": o, className: s },
29
+ r,
30
+ new URL(t, r)
31
+ );
32
+ a = p(u.linkProps), c = u.currentLinkProps;
33
+ }
34
+ return /* @__PURE__ */ w(
35
+ "a",
36
+ {
37
+ ...a,
38
+ ...c,
39
+ href: t === "" && r ? `${r.pathname}${r.search}` : t,
40
+ ref: l,
41
+ children: h
42
+ }
43
+ );
11
44
  });
12
- a.displayName = "Link";
45
+ g.displayName = "Link";
13
46
  export {
14
- a as Link
47
+ g as BaseLink,
48
+ g as Link
15
49
  };
package/lib/time.js CHANGED
@@ -1,6 +1,6 @@
1
- import { jsx as A } from "react/jsx-runtime";
2
- import { forwardRef as N } from "react";
3
- const U = [
1
+ import { jsx as B } from "react/jsx-runtime";
2
+ import { forwardRef as C, useState as g, useEffect as O } from "react";
3
+ const F = [
4
4
  "af",
5
5
  "am",
6
6
  "ar",
@@ -72,7 +72,7 @@ const U = [
72
72
  "uz",
73
73
  "vi",
74
74
  "zh"
75
- ], E = [
75
+ ], p = [
76
76
  "AF",
77
77
  "AL",
78
78
  "DZ",
@@ -272,13 +272,24 @@ const U = [
272
272
  "YE",
273
273
  "ZM",
274
274
  "ZW"
275
- ], C = "dateTime attribute is not set", g = "", u = "en", S = "GB", f = "medium", I = "none", i = "UTC", L = (t) => U.includes(t) ? t : u, G = (t) => E.includes(t) ? t : S, h = (t) => {
275
+ ], Y = "dateTime attribute is not set", b = "", h = "en", L = "GB", Z = "medium", k = "none", D = "UTC", G = "visitor", K = (t) => F.includes(t) ? t : h, w = (t) => p.includes(t) ? t : L, H = (t) => {
276
276
  if (["full", "long", "medium", "short"].includes(t))
277
277
  return t;
278
- }, B = (t) => {
278
+ }, V = (t) => {
279
279
  if (["full", "long", "medium", "short"].includes(t))
280
280
  return t;
281
- }, R = (t) => {
281
+ }, d = (t) => {
282
+ if (typeof t != "string")
283
+ return D;
284
+ const e = t.trim();
285
+ if (e === "" || e === G)
286
+ return D;
287
+ try {
288
+ return new Intl.DateTimeFormat(void 0, { timeZone: e }), e;
289
+ } catch {
290
+ return D;
291
+ }
292
+ }, _ = (t) => {
282
293
  if (t === "")
283
294
  return;
284
295
  let e = new Date(t);
@@ -290,70 +301,87 @@ const U = [
290
301
  }
291
302
  if (Number.isNaN(e.getTime()) === !1)
292
303
  return e;
293
- }, Y = (t, e, n = "en-US") => {
294
- const s = (o, r = 2) => String(o).padStart(r, "0"), D = new Intl.DateTimeFormat(n, {
295
- timeZone: i,
304
+ }, P = (t, e, n = "en-US", s = D) => {
305
+ const r = (m, c = 2) => String(m).padStart(c, "0"), M = new Intl.DateTimeFormat("en-US", {
306
+ timeZone: s,
307
+ year: "numeric",
308
+ month: "numeric",
309
+ day: "numeric",
310
+ hour: "numeric",
311
+ minute: "numeric",
312
+ second: "numeric",
313
+ hourCycle: "h23"
314
+ }).formatToParts(t), o = (m) => {
315
+ var c;
316
+ return ((c = M.find((U) => U.type === m)) == null ? void 0 : c.value) ?? "";
317
+ }, N = o("year"), f = Number(o("month")), S = Number(o("day")), A = Number(o("hour")), T = Number(o("minute")), i = Number(o("second")), E = new Intl.DateTimeFormat(n, {
318
+ timeZone: s,
296
319
  weekday: "long"
297
- }).format(t), M = new Intl.DateTimeFormat(n, {
298
- timeZone: i,
320
+ }).format(t), I = new Intl.DateTimeFormat(n, {
321
+ timeZone: s,
299
322
  weekday: "short"
300
- }).format(t), l = new Intl.DateTimeFormat(n, {
301
- timeZone: i,
323
+ }).format(t), u = new Intl.DateTimeFormat(n, {
324
+ timeZone: s,
302
325
  month: "long"
303
- }).format(t), a = new Intl.DateTimeFormat(n, {
304
- timeZone: i,
326
+ }).format(t), l = new Intl.DateTimeFormat(n, {
327
+ timeZone: s,
305
328
  month: "short"
306
- }).format(t), T = {
307
- YYYY: t.getUTCFullYear(),
308
- YY: String(t.getUTCFullYear()).slice(-2),
309
- MMMM: l,
310
- MMM: a,
311
- MM: s(t.getUTCMonth() + 1),
312
- M: t.getUTCMonth() + 1,
313
- DDDD: D,
314
- DDD: M,
315
- DD: s(t.getUTCDate()),
316
- D: t.getUTCDate(),
317
- HH: s(t.getUTCHours()),
318
- H: t.getUTCHours(),
319
- mm: s(t.getUTCMinutes()),
320
- m: t.getUTCMinutes(),
321
- ss: s(t.getUTCSeconds()),
322
- s: t.getUTCSeconds()
323
- }, c = Object.keys(T).sort((o, r) => r.length - o.length), m = new RegExp(`\\b(${c.join("|")})\\b`, "g");
324
- return e.replace(m, (o) => String(T[o]));
325
- }, O = N(
329
+ }).format(t), a = {
330
+ YYYY: N,
331
+ YY: N.slice(-2),
332
+ MMMM: u,
333
+ MMM: l,
334
+ MM: r(f),
335
+ M: f,
336
+ DDDD: E,
337
+ DDD: I,
338
+ DD: r(S),
339
+ D: S,
340
+ HH: r(A),
341
+ H: A,
342
+ mm: r(T),
343
+ m: T,
344
+ ss: r(i),
345
+ s: i
346
+ }, y = Object.keys(a).sort((m, c) => c.length - m.length), R = new RegExp(`\\b(${y.join("|")})\\b`, "g");
347
+ return e.replace(R, (m) => String(a[m]));
348
+ }, J = C(
326
349
  ({
327
- language: t = u,
328
- country: e = S,
329
- dateStyle: n = f,
330
- timeStyle: s = I,
331
- format: D,
332
- datetime: M = C,
333
- ...l
334
- }, a) => {
335
- const T = `${L(t)}-${G(
350
+ language: t = h,
351
+ country: e = L,
352
+ dateStyle: n = Z,
353
+ timeStyle: s = k,
354
+ timeZone: r = D,
355
+ format: M,
356
+ datetime: o = Y,
357
+ ...N
358
+ }, f) => {
359
+ const [S, A] = g(), T = `${K(t)}-${w(
336
360
  e
337
- )}`, c = {
338
- dateStyle: h(n),
339
- timeStyle: B(s),
340
- timeZone: i
341
- }, m = M === null ? g : M.toString(), o = R(m);
342
- let r = m;
343
- if (o)
344
- if (D)
361
+ )}`, i = typeof r == "string" && r.trim() === G, E = d(i ? S : r), I = {
362
+ dateStyle: H(n),
363
+ timeStyle: V(s),
364
+ timeZone: E
365
+ };
366
+ O(() => {
367
+ i && A(Intl.DateTimeFormat().resolvedOptions().timeZone);
368
+ }, [i]);
369
+ const u = o === null ? b : o.toString(), l = _(u);
370
+ let a = u;
371
+ if (l)
372
+ if (M)
345
373
  try {
346
- r = Y(o, D, T);
374
+ a = P(l, M, T, E);
347
375
  } catch {
348
376
  }
349
377
  else
350
378
  try {
351
- r = new Intl.DateTimeFormat(T, c).format(o);
379
+ a = new Intl.DateTimeFormat(T, I).format(l);
352
380
  } catch {
353
381
  }
354
- return /* @__PURE__ */ A("time", { ref: a, dateTime: m, ...l, children: r });
382
+ return /* @__PURE__ */ B("time", { ref: f, dateTime: u, ...N, children: a });
355
383
  }
356
384
  );
357
385
  export {
358
- O as Time
386
+ J as Time
359
387
  };
package/lib/time.ws.js CHANGED
@@ -1,6 +1,6 @@
1
- import { time as e } from "@webstudio-is/sdk/normalize.css";
2
- import { props as t } from "./__generated__/time.props.js";
3
- const r = {
1
+ import { time as t } from "@webstudio-is/sdk/normalize.css";
2
+ import { props as e } from "./__generated__/time.props.js";
3
+ const n = {
4
4
  category: "localization",
5
5
  description: "Converts machine-readable date and time to a human-readable format.",
6
6
  contentModel: {
@@ -8,7 +8,7 @@ const r = {
8
8
  children: []
9
9
  },
10
10
  presetStyle: {
11
- time: e
11
+ time: t
12
12
  },
13
13
  initialProps: [
14
14
  "datetime",
@@ -16,10 +16,11 @@ const r = {
16
16
  "country",
17
17
  "dateStyle",
18
18
  "timeStyle",
19
+ "timeZone",
19
20
  "format"
20
21
  ],
21
22
  props: {
22
- ...t,
23
+ ...e,
23
24
  datetime: {
24
25
  type: "string",
25
26
  control: "text",
@@ -27,27 +28,36 @@ const r = {
27
28
  contentMode: !0
28
29
  },
29
30
  language: {
30
- ...t.language,
31
+ ...e.language,
31
32
  contentMode: !0
32
33
  },
33
34
  country: {
34
- ...t.country,
35
+ ...e.country,
35
36
  contentMode: !0
36
37
  },
37
38
  dateStyle: {
38
- ...t.dateStyle,
39
+ ...e.dateStyle,
39
40
  contentMode: !0
40
41
  },
41
42
  timeStyle: {
42
- ...t.timeStyle,
43
+ ...e.timeStyle,
44
+ contentMode: !0
45
+ },
46
+ timeZone: {
47
+ required: !1,
48
+ control: "timeZone",
49
+ type: "string",
50
+ defaultValue: "UTC",
51
+ options: ["UTC", "visitor"],
52
+ description: 'Timezone used to display the date. Use "visitor" to display each visitor’s browser timezone after the page loads, or select/type an IANA timezone like "Europe/Berlin".',
43
53
  contentMode: !0
44
54
  },
45
55
  format: {
46
- ...t.format,
56
+ ...e.format,
47
57
  contentMode: !0
48
58
  }
49
59
  }
50
60
  };
51
61
  export {
52
- r as meta
62
+ n as meta
53
63
  };
@@ -1,4 +1,4 @@
1
1
  export declare const defaultTag = "input";
2
- export declare const Checkbox: import("react").ForwardRefExoticComponent<Omit<Omit<import("react").DetailedHTMLProps<import("react").InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>, "type" | "value"> & {
2
+ export declare const Checkbox: import("react").ForwardRefExoticComponent<Omit<Omit<import("react").DetailedHTMLProps<import("react").InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>, "value" | "type"> & {
3
3
  value?: string;
4
4
  }, "ref"> & import("react").RefAttributes<HTMLInputElement>>;
@@ -0,0 +1,36 @@
1
+ import { type ComponentPropsWithoutRef, type ComponentType, type ForwardRefExoticComponent, type LegacyRef, type RefAttributes } from "react";
2
+ import { BaseLink } from "./link";
3
+ import { type UrlParts } from "@webstudio-is/sdk/link-utils";
4
+ export type LinkProps = Omit<ComponentPropsWithoutRef<typeof BaseLink>, "target"> & {
5
+ target?: "_self" | "_blank" | "_parent" | "_top";
6
+ prefetch?: "none" | "intent" | "render" | "viewport";
7
+ discover?: "render" | "none";
8
+ reloadDocument?: boolean;
9
+ replace?: boolean;
10
+ preventScrollReset?: boolean;
11
+ relative?: "route" | "path";
12
+ state?: unknown;
13
+ viewTransition?: boolean;
14
+ };
15
+ type LinkComponent = ForwardRefExoticComponent<LinkProps & RefAttributes<HTMLAnchorElement>>;
16
+ type RouterTo = string | Partial<UrlParts>;
17
+ type RouterLinkComponentProps = Omit<LinkProps, "href" | "target"> & {
18
+ target?: ComponentPropsWithoutRef<"a">["target"];
19
+ to: RouterTo;
20
+ ref?: LegacyRef<HTMLAnchorElement>;
21
+ };
22
+ /**
23
+ * Creates a framework-aware Link.
24
+ *
25
+ * Internal route links render the framework Link component so Remix/React
26
+ * Router keep their own navigation, discovery, prefetch, and transition
27
+ * behavior. Hash-only, external, and asset links fall back to BaseLink because
28
+ * they should behave like native anchors while still supporting current-link
29
+ * styling.
30
+ */
31
+ export declare const createLink: ({ Link, useLocation, useResolvedPath, }: {
32
+ Link: ComponentType<RouterLinkComponentProps>;
33
+ useLocation: () => UrlParts;
34
+ useResolvedPath: (href: string) => UrlParts;
35
+ }) => LinkComponent;
36
+ export {};
@@ -0,0 +1,3 @@
1
+ import { createLink, type LinkProps } from "./create-link";
2
+ import { LinkCurrentUrlContext } from "./link-current-url";
3
+ export { createLink, LinkCurrentUrlContext, type LinkProps };
@@ -0,0 +1 @@
1
+ export declare const LinkCurrentUrlContext: import("react").Context<string | URL | undefined>;
@@ -0,0 +1,25 @@
1
+ import type { ComponentPropsWithoutRef } from "react";
2
+ import { type UrlParts } from "@webstudio-is/sdk/link-utils";
3
+ type AnchorProps = ComponentPropsWithoutRef<"a">;
4
+ export declare const getCurrentLinkProps: <Props extends {
5
+ href: string;
6
+ "aria-current"?: AnchorProps["aria-current"];
7
+ className?: string;
8
+ }>(props: Props, location: UrlParts, resolvedPath: UrlParts) => {
9
+ linkProps: Omit<Props, "className" | "aria-current" | "href">;
10
+ currentLinkProps: {
11
+ className?: string | undefined;
12
+ "aria-current"?: boolean | "time" | "true" | "false" | "page" | "step" | "location" | "date" | undefined;
13
+ };
14
+ };
15
+ export declare const stripRouterOnlyProps: <Props extends {
16
+ prefetch?: unknown;
17
+ discover?: unknown;
18
+ reloadDocument?: unknown;
19
+ replace?: unknown;
20
+ preventScrollReset?: unknown;
21
+ relative?: unknown;
22
+ state?: unknown;
23
+ viewTransition?: unknown;
24
+ }>({ prefetch, discover, reloadDocument, replace, preventScrollReset, relative, state, viewTransition, ...props }: Props) => Omit<Props, "replace" | "state" | "relative" | "prefetch" | "discover" | "reloadDocument" | "preventScrollReset" | "viewTransition">;
25
+ export {};
@@ -1,11 +1,23 @@
1
1
  export declare const defaultTag = "a";
2
- export declare const Link: import("react").ForwardRefExoticComponent<Omit<Omit<import("react").DetailedHTMLProps<import("react").AnchorHTMLAttributes<HTMLAnchorElement>, HTMLAnchorElement>, "target" | "download"> & {
2
+ /**
3
+ * Plain Webstudio anchor implementation.
4
+ *
5
+ * Used by base components, SSG, builder preview, and framework-link fallbacks.
6
+ * It owns current-link styling for native anchors, while framework packages
7
+ * keep their own Link components for route navigation and prefetch behavior.
8
+ */
9
+ export declare const BaseLink: import("react").ForwardRefExoticComponent<Omit<Omit<import("react").DetailedHTMLProps<import("react").AnchorHTMLAttributes<HTMLAnchorElement>, HTMLAnchorElement>, "download" | "target"> & {
3
10
  target?: "_self" | "_blank" | "_parent" | "_top";
4
11
  download?: boolean;
5
12
  prefetch?: "none" | "intent" | "render" | "viewport";
13
+ discover?: "render" | "none";
6
14
  preventScrollReset?: boolean;
7
15
  reloadDocument?: boolean;
8
16
  replace?: boolean;
17
+ relative?: "route" | "path";
18
+ state?: unknown;
19
+ viewTransition?: boolean;
9
20
  } & {
10
21
  $webstudio$canvasOnly$assetId?: string | undefined;
11
22
  }, "ref"> & import("react").RefAttributes<HTMLAnchorElement>>;
23
+ export { BaseLink as Link };
@@ -1,4 +1,4 @@
1
1
  export declare const defaultTag = "input";
2
- export declare const RadioButton: import("react").ForwardRefExoticComponent<Omit<Omit<import("react").DetailedHTMLProps<import("react").InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>, "type" | "value"> & {
2
+ export declare const RadioButton: import("react").ForwardRefExoticComponent<Omit<Omit<import("react").DetailedHTMLProps<import("react").InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>, "value" | "type"> & {
3
3
  value?: string;
4
4
  }, "ref"> & import("react").RefAttributes<HTMLInputElement>>;
@@ -12,6 +12,13 @@ type TimeProps = {
12
12
  country?: Country;
13
13
  dateStyle?: DateStyle;
14
14
  timeStyle?: TimeStyle;
15
+ /**
16
+ * Time zone used to format the date.
17
+ *
18
+ * Use "UTC" for deterministic UTC output, "visitor" to use the browser time
19
+ * zone after hydration, or an IANA time zone like "Europe/Berlin".
20
+ */
21
+ timeZone?: string;
15
22
  /**
16
23
  * Custom format template. Overrides Date Style and Time Style.
17
24
  *
@@ -29,6 +36,7 @@ type TimeProps = {
29
36
  export declare const Time: import("react").ForwardRefExoticComponent<TimeProps & import("react").RefAttributes<HTMLTimeElement>>;
30
37
  export declare const __testing__: {
31
38
  parseDate: (datetimeString: string) => Date | undefined;
32
- formatDate: (date: Date, template: string, locale?: string) => string;
39
+ formatDate: (date: Date, template: string, locale?: string, timeZone?: string) => string;
40
+ timeZoneOrDefault: (timeZone: unknown) => string;
33
41
  };
34
42
  export {};
@@ -1,8 +1,22 @@
1
1
  export declare const VimeoPreviewImage: import("react").ForwardRefExoticComponent<Omit<{
2
+ src?: string | undefined | undefined;
3
+ width?: number | string | undefined | undefined;
4
+ quality?: number | undefined;
5
+ sizes?: string | undefined | undefined;
6
+ height?: number | string | undefined | undefined;
2
7
  slot?: string | undefined | undefined;
3
8
  style?: import("react").CSSProperties | undefined;
4
9
  title?: string | undefined | undefined;
10
+ optimize?: boolean | undefined;
11
+ loading?: "eager" | "lazy" | undefined | undefined;
12
+ decoding?: "async" | "auto" | "sync" | undefined | undefined;
5
13
  key?: import("react").Key | null | undefined;
14
+ alt?: string | undefined | undefined;
15
+ crossOrigin?: "" | "anonymous" | "use-credentials" | undefined;
16
+ fetchPriority?: "high" | "low" | "auto" | undefined;
17
+ referrerPolicy?: import("react").HTMLAttributeReferrerPolicy | undefined;
18
+ srcSet?: string | undefined | undefined;
19
+ useMap?: string | undefined | undefined;
6
20
  defaultChecked?: boolean | undefined | undefined;
7
21
  defaultValue?: string | number | readonly string[] | undefined;
8
22
  suppressContentEditableWarning?: boolean | undefined | undefined;
@@ -10,7 +24,7 @@ export declare const VimeoPreviewImage: import("react").ForwardRefExoticComponen
10
24
  accessKey?: string | undefined | undefined;
11
25
  autoFocus?: boolean | undefined | undefined;
12
26
  className?: string | undefined | undefined;
13
- contentEditable?: "inherit" | (boolean | "true" | "false") | "plaintext-only" | undefined;
27
+ contentEditable?: (boolean | "true" | "false") | "inherit" | "plaintext-only" | undefined;
14
28
  contextMenu?: string | undefined | undefined;
15
29
  dir?: string | undefined | undefined;
16
30
  draggable?: (boolean | "true" | "false") | undefined;
@@ -265,20 +279,6 @@ export declare const VimeoPreviewImage: import("react").ForwardRefExoticComponen
265
279
  onAnimationIterationCapture?: import("react").AnimationEventHandler<HTMLImageElement> | undefined;
266
280
  onTransitionEnd?: import("react").TransitionEventHandler<HTMLImageElement> | undefined;
267
281
  onTransitionEndCapture?: import("react").TransitionEventHandler<HTMLImageElement> | undefined;
268
- height?: number | string | undefined | undefined;
269
- width?: number | string | undefined | undefined;
270
- crossOrigin?: "" | "anonymous" | "use-credentials" | undefined;
271
- useMap?: string | undefined | undefined;
272
- referrerPolicy?: import("react").HTMLAttributeReferrerPolicy | undefined;
273
- alt?: string | undefined | undefined;
274
- src?: string | undefined | undefined;
275
- loading?: "eager" | "lazy" | undefined | undefined;
276
- decoding?: "async" | "auto" | "sync" | undefined | undefined;
277
- fetchPriority?: "high" | "low" | "auto" | undefined;
278
- sizes?: string | undefined | undefined;
279
- srcSet?: string | undefined | undefined;
280
- quality?: number | undefined;
281
- optimize?: boolean | undefined;
282
282
  } & {
283
283
  $webstudio$canvasOnly$assetId?: string | undefined;
284
284
  } & import("react").RefAttributes<HTMLImageElement>, "ref"> & import("react").RefAttributes<HTMLImageElement>>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@webstudio-is/sdk-components-react",
3
- "version": "0.268.0",
3
+ "version": "0.269.0",
4
4
  "description": "Webstudio default library for react",
5
5
  "author": "Webstudio <github@webstudio.is>",
6
6
  "homepage": "https://webstudio.is",
@@ -14,6 +14,11 @@
14
14
  ],
15
15
  "exports": {
16
16
  ".": {
17
+ "webstudio": "./src/index.ts",
18
+ "types": "./lib/types/index.d.ts",
19
+ "import": "./lib/index.js"
20
+ },
21
+ "./components": {
17
22
  "webstudio": "./src/components.ts",
18
23
  "types": "./lib/types/components.d.ts",
19
24
  "import": "./lib/components.js"
@@ -44,10 +49,10 @@
44
49
  "colord": "^2.9.3",
45
50
  "micromark": "^4.0.2",
46
51
  "micromark-extension-gfm-table": "^2.1.1",
47
- "@webstudio-is/icons": "0.268.0",
48
- "@webstudio-is/image": "0.268.0",
49
- "@webstudio-is/sdk": "0.268.0",
50
- "@webstudio-is/react-sdk": "0.268.0"
52
+ "@webstudio-is/icons": "0.269.0",
53
+ "@webstudio-is/react-sdk": "0.269.0",
54
+ "@webstudio-is/image": "0.269.0",
55
+ "@webstudio-is/sdk": "0.269.0"
51
56
  },
52
57
  "devDependencies": {
53
58
  "@testing-library/dom": "^10.4.0",
@@ -59,9 +64,9 @@
59
64
  "react-dom": "18.3.0-canary-14898b6a9-20240318",
60
65
  "vitest": "^3.1.2",
61
66
  "@webstudio-is/design-system": "0.0.0",
62
- "@webstudio-is/sdk-cli": "0.94.0",
63
67
  "@webstudio-is/generate-arg-types": "0.0.0",
64
- "@webstudio-is/template": "0.268.0",
68
+ "@webstudio-is/sdk-cli": "0.94.0",
69
+ "@webstudio-is/template": "0.269.0",
65
70
  "@webstudio-is/tsconfig": "1.0.7"
66
71
  },
67
72
  "scripts": {