@geomak/ui 6.29.2 → 6.31.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/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { colors_default } from './chunk-I2P4JJDB.js';
2
2
  export { colors_default as COLORS, PALETTE as palette, semanticTokens, vars } from './chunk-I2P4JJDB.js';
3
3
  import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
4
- import React28, { createContext, useState, useEffect, useMemo, useId, useCallback, useRef, useLayoutEffect, useContext, useSyncExternalStore } from 'react';
4
+ import React28, { createContext, useState, useEffect, useMemo, useId, useCallback, useRef, useContext, useSyncExternalStore, useLayoutEffect } from 'react';
5
5
  import { createPortal } from 'react-dom';
6
6
  import * as AvatarPrimitive from '@radix-ui/react-avatar';
7
7
  import * as DropdownMenu from '@radix-ui/react-dropdown-menu';
@@ -470,8 +470,8 @@ function Avatar({
470
470
  if (fallback) return fallback;
471
471
  if (alt) {
472
472
  const parts = alt.trim().split(/\s+/).slice(0, 2);
473
- const initials2 = parts.map((p) => p[0]?.toUpperCase() ?? "").join("");
474
- if (initials2) return initials2;
473
+ const initials3 = parts.map((p) => p[0]?.toUpperCase() ?? "").join("");
474
+ if (initials3) return initials3;
475
475
  }
476
476
  return /* @__PURE__ */ jsx(PersonSilhouette, {});
477
477
  })();
@@ -2267,6 +2267,19 @@ var ArrowDown = () => /* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", fill: "
2267
2267
  function TypingDots() {
2268
2268
  return /* @__PURE__ */ jsx("span", { className: "inline-flex items-center gap-1", "aria-hidden": "true", children: [0, 1, 2].map((i) => /* @__PURE__ */ jsx("span", { className: "h-1.5 w-1.5 animate-bounce rounded-full bg-foreground-muted", style: { animationDelay: `${i * 0.15}s` } }, i)) });
2269
2269
  }
2270
+ var SKELETON_ROWS = [
2271
+ { own: false, w: 150 },
2272
+ { own: false, w: 110 },
2273
+ { own: true, w: 180 },
2274
+ { own: false, w: 130 },
2275
+ { own: true, w: 90 }
2276
+ ];
2277
+ function ChatSkeleton() {
2278
+ return /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-2", "aria-hidden": "true", children: SKELETON_ROWS.map((r, i) => /* @__PURE__ */ jsxs("div", { className: ["flex items-end gap-2", r.own ? "flex-row-reverse" : ""].filter(Boolean).join(" "), children: [
2279
+ !r.own && /* @__PURE__ */ jsx("span", { className: "h-6 w-6 flex-shrink-0 animate-pulse rounded-full bg-surface" }),
2280
+ /* @__PURE__ */ jsx("span", { className: "h-8 animate-pulse rounded-2xl bg-surface", style: { width: r.w } })
2281
+ ] }, i)) });
2282
+ }
2270
2283
  function Chat({
2271
2284
  messages,
2272
2285
  currentUserId,
@@ -2279,6 +2292,7 @@ function Chat({
2279
2292
  placeholder = "Write a message\u2026",
2280
2293
  disabled = false,
2281
2294
  hideComposer = false,
2295
+ loading = false,
2282
2296
  emptyState,
2283
2297
  height = 480,
2284
2298
  className = "",
@@ -2288,7 +2302,6 @@ function Chat({
2288
2302
  const atBottomRef = useRef(true);
2289
2303
  const [showJump, setShowJump] = useState(false);
2290
2304
  const [draft, setDraft] = useState("");
2291
- const taRef = useRef(null);
2292
2305
  const hasHeader = title != null || subtitle != null || avatar != null || headerActions != null;
2293
2306
  const isTyping = typingNames.length > 0;
2294
2307
  const scrollToBottom = useCallback((smooth = true) => {
@@ -2310,12 +2323,6 @@ function Chat({
2310
2323
  useEffect(() => {
2311
2324
  scrollToBottom(false);
2312
2325
  }, [scrollToBottom]);
2313
- useLayoutEffect(() => {
2314
- const ta = taRef.current;
2315
- if (!ta) return;
2316
- ta.style.height = "auto";
2317
- ta.style.height = `${Math.min(ta.scrollHeight, 120)}px`;
2318
- }, [draft]);
2319
2326
  const send = () => {
2320
2327
  const text = draft.trim();
2321
2328
  if (!text || disabled) return;
@@ -2344,7 +2351,7 @@ function Chat({
2344
2351
  ] }),
2345
2352
  /* @__PURE__ */ jsxs("div", { className: "relative flex-1 overflow-hidden", children: [
2346
2353
  /* @__PURE__ */ jsxs("div", { ref: listRef, onScroll, className: "flex h-full flex-col gap-1 overflow-y-auto bg-background px-4 py-3", children: [
2347
- messages.length === 0 && !isTyping ? /* @__PURE__ */ jsx("div", { className: "flex flex-1 items-center justify-center text-center text-sm text-foreground-muted", children: emptyState ?? "No messages yet. Say hello \u{1F44B}" }) : messages.map((m, i) => {
2354
+ loading && messages.length === 0 ? /* @__PURE__ */ jsx(ChatSkeleton, {}) : messages.length === 0 && !isTyping ? /* @__PURE__ */ jsx("div", { className: "flex flex-1 items-center justify-center text-center text-sm text-foreground-muted", children: emptyState ?? "No messages yet. Say hello \u{1F44B}" }) : messages.map((m, i) => {
2348
2355
  const own = m.authorId === currentUserId;
2349
2356
  const prev = messages[i - 1];
2350
2357
  const next = messages[i + 1];
@@ -2399,15 +2406,14 @@ function Chat({
2399
2406
  /* @__PURE__ */ jsx(
2400
2407
  "textarea",
2401
2408
  {
2402
- ref: taRef,
2403
- rows: 1,
2409
+ rows: 2,
2404
2410
  value: draft,
2405
2411
  disabled,
2406
2412
  placeholder,
2407
2413
  onChange: (e) => setDraft(e.target.value),
2408
2414
  onKeyDown,
2409
2415
  "aria-label": "Message",
2410
- className: `${fieldShell({ size: "md", hasError: false, disabled, sized: false })} max-h-[120px] flex-1 resize-none px-3 py-2 leading-snug`
2416
+ className: `${fieldShell({ size: "md", hasError: false, disabled, sized: false })} h-[4.5rem] flex-1 resize-none px-3 py-2 leading-snug`
2411
2417
  }
2412
2418
  ),
2413
2419
  /* @__PURE__ */ jsx(
@@ -9283,7 +9289,155 @@ function useJwt(token) {
9283
9289
  const isValid = decoded.payload != null && !isExpired;
9284
9290
  return { payload: decoded.payload, header: decoded.header, expiresAt, isExpired, isValid, raw: token ?? null };
9285
9291
  }
9292
+ var GRADIENT = "radial-gradient(ellipse 80% 60% at 50% 0%, color-mix(in oklab, var(--color-accent) 12%, transparent), transparent 70%)";
9293
+ function Jumbotron({
9294
+ eyebrow,
9295
+ title,
9296
+ description,
9297
+ actions,
9298
+ media,
9299
+ layout = "centered",
9300
+ background = "none",
9301
+ className = "",
9302
+ style
9303
+ }) {
9304
+ const split = layout === "split" && media != null;
9305
+ const bgClass = background === "surface" ? "bg-surface" : "";
9306
+ const copy = /* @__PURE__ */ jsxs("div", { className: ["flex flex-col gap-5", split ? "items-start text-left" : "items-center text-center"].join(" "), children: [
9307
+ eyebrow != null && /* @__PURE__ */ jsx("div", { children: eyebrow }),
9308
+ /* @__PURE__ */ jsx("h1", { className: ["text-4xl font-bold leading-tight tracking-tight text-foreground sm:text-5xl", split ? "" : "max-w-3xl"].join(" "), children: title }),
9309
+ description != null && /* @__PURE__ */ jsx("p", { className: ["text-lg leading-relaxed text-foreground-secondary", split ? "max-w-xl" : "max-w-2xl"].join(" "), children: description }),
9310
+ actions != null && /* @__PURE__ */ jsx("div", { className: ["mt-2 flex flex-wrap gap-3", split ? "justify-start" : "justify-center"].join(" "), children: actions })
9311
+ ] });
9312
+ return /* @__PURE__ */ jsx(
9313
+ "section",
9314
+ {
9315
+ className: ["relative overflow-hidden rounded-2xl px-6 py-16 sm:px-10 sm:py-24", bgClass, className].filter(Boolean).join(" "),
9316
+ style: { ...background === "gradient" ? { backgroundImage: GRADIENT } : null, ...style },
9317
+ children: split ? /* @__PURE__ */ jsxs("div", { className: "mx-auto grid max-w-6xl items-center gap-10 lg:grid-cols-2", children: [
9318
+ copy,
9319
+ /* @__PURE__ */ jsx("div", { className: "overflow-hidden rounded-xl", children: media })
9320
+ ] }) : /* @__PURE__ */ jsxs("div", { className: "mx-auto flex max-w-4xl flex-col items-center", children: [
9321
+ copy,
9322
+ media != null && /* @__PURE__ */ jsx("div", { className: "mt-12 w-full overflow-hidden rounded-xl", children: media })
9323
+ ] })
9324
+ }
9325
+ );
9326
+ }
9327
+ var COLS = {
9328
+ 2: "sm:grid-cols-2",
9329
+ 3: "sm:grid-cols-2 lg:grid-cols-3",
9330
+ 4: "sm:grid-cols-2 lg:grid-cols-4"
9331
+ };
9332
+ function FeatureGrid({
9333
+ features,
9334
+ eyebrow,
9335
+ title,
9336
+ description,
9337
+ columns = 3,
9338
+ centeredHeader = true,
9339
+ className = "",
9340
+ style
9341
+ }) {
9342
+ const hasHeader = eyebrow != null || title != null || description != null;
9343
+ return /* @__PURE__ */ jsxs("section", { className: ["px-2", className].filter(Boolean).join(" "), style, children: [
9344
+ hasHeader && /* @__PURE__ */ jsxs("header", { className: ["mb-10 flex flex-col gap-3", centeredHeader ? "items-center text-center" : "items-start text-left"].join(" "), children: [
9345
+ eyebrow != null && /* @__PURE__ */ jsx("div", { className: "text-xs font-semibold uppercase tracking-wide text-accent", children: eyebrow }),
9346
+ title != null && /* @__PURE__ */ jsx("h2", { className: "text-3xl font-bold tracking-tight text-foreground", children: title }),
9347
+ description != null && /* @__PURE__ */ jsx("p", { className: "max-w-2xl text-base leading-relaxed text-foreground-secondary", children: description })
9348
+ ] }),
9349
+ /* @__PURE__ */ jsx("div", { className: ["grid grid-cols-1 gap-6", COLS[columns]].join(" "), children: features.map((f, i) => /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-3 rounded-xl border border-border bg-surface p-5", children: [
9350
+ f.icon != null && /* @__PURE__ */ jsx(
9351
+ "span",
9352
+ {
9353
+ className: "flex h-10 w-10 items-center justify-center rounded-lg text-accent",
9354
+ style: { backgroundColor: "color-mix(in oklab, var(--color-accent) 12%, var(--color-surface))" },
9355
+ children: f.icon
9356
+ }
9357
+ ),
9358
+ /* @__PURE__ */ jsx("h3", { className: "text-base font-semibold text-foreground", children: f.title }),
9359
+ f.description != null && /* @__PURE__ */ jsx("p", { className: "text-sm leading-relaxed text-foreground-secondary", children: f.description })
9360
+ ] }, f.key ?? i)) })
9361
+ ] });
9362
+ }
9363
+ var Check3 = () => /* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2.5, "aria-hidden": "true", className: "mt-0.5 h-4 w-4 flex-shrink-0 text-accent", children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M20 6 9 17l-5-5" }) });
9364
+ function PricingPlans({ plans, eyebrow, title, description, className = "", style }) {
9365
+ const hasHeader = eyebrow != null || title != null || description != null;
9366
+ return /* @__PURE__ */ jsxs("section", { className: ["px-2", className].filter(Boolean).join(" "), style, children: [
9367
+ hasHeader && /* @__PURE__ */ jsxs("header", { className: "mb-10 flex flex-col items-center gap-3 text-center", children: [
9368
+ eyebrow != null && /* @__PURE__ */ jsx("div", { className: "text-xs font-semibold uppercase tracking-wide text-accent", children: eyebrow }),
9369
+ title != null && /* @__PURE__ */ jsx("h2", { className: "text-3xl font-bold tracking-tight text-foreground", children: title }),
9370
+ description != null && /* @__PURE__ */ jsx("p", { className: "max-w-2xl text-base leading-relaxed text-foreground-secondary", children: description })
9371
+ ] }),
9372
+ /* @__PURE__ */ jsx("div", { className: "grid grid-cols-1 items-stretch gap-6 md:grid-cols-2 lg:grid-cols-3", children: plans.map((p, i) => /* @__PURE__ */ jsxs(
9373
+ "div",
9374
+ {
9375
+ className: [
9376
+ "relative flex flex-col rounded-2xl border bg-surface p-6",
9377
+ p.highlighted ? "border-accent shadow-lg lg:-my-2 lg:py-8" : "border-border"
9378
+ ].join(" "),
9379
+ children: [
9380
+ p.highlighted && p.badge != null && /* @__PURE__ */ jsx("span", { className: "absolute -top-3 left-1/2 -translate-x-1/2 rounded-full bg-accent px-3 py-0.5 text-xs font-semibold text-accent-fg shadow-sm", children: p.badge }),
9381
+ /* @__PURE__ */ jsx("div", { className: "text-sm font-semibold uppercase tracking-wide text-foreground-muted", children: p.name }),
9382
+ /* @__PURE__ */ jsxs("div", { className: "mt-3 flex items-baseline gap-1", children: [
9383
+ /* @__PURE__ */ jsx("span", { className: "text-4xl font-bold tracking-tight text-foreground", children: p.price }),
9384
+ p.period != null && /* @__PURE__ */ jsx("span", { className: "text-sm text-foreground-muted", children: p.period })
9385
+ ] }),
9386
+ p.description != null && /* @__PURE__ */ jsx("p", { className: "mt-2 text-sm leading-relaxed text-foreground-secondary", children: p.description }),
9387
+ /* @__PURE__ */ jsx("ul", { className: "mt-6 flex flex-1 flex-col gap-2.5", children: p.features.map((f, fi) => /* @__PURE__ */ jsxs("li", { className: "flex gap-2 text-sm text-foreground-secondary", children: [
9388
+ /* @__PURE__ */ jsx(Check3, {}),
9389
+ /* @__PURE__ */ jsx("span", { children: f })
9390
+ ] }, fi)) }),
9391
+ /* @__PURE__ */ jsx("div", { className: "mt-6", children: /* @__PURE__ */ jsx(
9392
+ Button_default,
9393
+ {
9394
+ content: p.cta.label,
9395
+ variant: p.highlighted ? "primary" : "outline",
9396
+ onClick: p.cta.onClick,
9397
+ style: { width: "100%" }
9398
+ }
9399
+ ) })
9400
+ ]
9401
+ },
9402
+ p.key ?? i
9403
+ )) })
9404
+ ] });
9405
+ }
9406
+ var COLS2 = {
9407
+ 1: "mx-auto max-w-2xl",
9408
+ 2: "sm:grid-cols-2",
9409
+ 3: "sm:grid-cols-2 lg:grid-cols-3"
9410
+ };
9411
+ var initials2 = (name) => typeof name === "string" ? name.trim().split(/\s+/).slice(0, 2).map((w) => w[0]?.toUpperCase() ?? "").join("") || void 0 : void 0;
9412
+ function Stars({ value }) {
9413
+ return /* @__PURE__ */ jsx("div", { className: "flex gap-0.5", "aria-label": `${value} out of 5`, children: Array.from({ length: 5 }, (_, i) => /* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", "aria-hidden": "true", className: `h-4 w-4 ${i < value ? "text-status-warning" : "text-border-strong"}`, fill: "currentColor", children: /* @__PURE__ */ jsx("path", { d: "M12 2l2.9 6.3 6.9.7-5.1 4.6 1.4 6.8L12 17.8 5.9 20.4l1.4-6.8L2.2 9l6.9-.7L12 2z" }) }, i)) });
9414
+ }
9415
+ function Testimonials({ testimonials, eyebrow, title, description, columns = 3, className = "", style }) {
9416
+ const hasHeader = eyebrow != null || title != null || description != null;
9417
+ return /* @__PURE__ */ jsxs("section", { className: ["px-2", className].filter(Boolean).join(" "), style, children: [
9418
+ hasHeader && /* @__PURE__ */ jsxs("header", { className: "mb-10 flex flex-col items-center gap-3 text-center", children: [
9419
+ eyebrow != null && /* @__PURE__ */ jsx("div", { className: "text-xs font-semibold uppercase tracking-wide text-accent", children: eyebrow }),
9420
+ title != null && /* @__PURE__ */ jsx("h2", { className: "text-3xl font-bold tracking-tight text-foreground", children: title }),
9421
+ description != null && /* @__PURE__ */ jsx("p", { className: "max-w-2xl text-base leading-relaxed text-foreground-secondary", children: description })
9422
+ ] }),
9423
+ /* @__PURE__ */ jsx("div", { className: ["grid grid-cols-1 gap-6", COLS2[columns]].join(" "), children: testimonials.map((tm, i) => /* @__PURE__ */ jsxs("figure", { className: "flex flex-col gap-4 rounded-xl border border-border bg-surface p-6", children: [
9424
+ tm.rating != null && /* @__PURE__ */ jsx(Stars, { value: tm.rating }),
9425
+ /* @__PURE__ */ jsxs("blockquote", { className: "flex-1 text-sm leading-relaxed text-foreground", children: [
9426
+ "\u201C",
9427
+ tm.quote,
9428
+ "\u201D"
9429
+ ] }),
9430
+ /* @__PURE__ */ jsxs("figcaption", { className: "flex items-center gap-3", children: [
9431
+ /* @__PURE__ */ jsx(Avatar, { src: tm.avatar, alt: typeof tm.author === "string" ? tm.author : "Reviewer", fallback: initials2(tm.author), size: "sm" }),
9432
+ /* @__PURE__ */ jsxs("div", { className: "min-w-0", children: [
9433
+ /* @__PURE__ */ jsx("div", { className: "truncate text-sm font-semibold text-foreground", children: tm.author }),
9434
+ tm.role != null && /* @__PURE__ */ jsx("div", { className: "truncate text-xs text-foreground-muted", children: tm.role })
9435
+ ] })
9436
+ ] })
9437
+ ] }, tm.key ?? i)) })
9438
+ ] });
9439
+ }
9286
9440
 
9287
- export { Accordion_default as Accordion, AppShell, AutoComplete, Avatar, Badge, Box, Breadcrumbs, Button_default as Button, CARD_BRANDS, Card_default as Card, CardCarousel, Cart, CartButton, CartProvider, Catalog, CatalogCarousel, CatalogGrid, Chat, Checkbox, Checkout, ColorPicker, ContextMenu, CreditCardForm, DateRangePicker, Drawer, Dropdown, EmptyCart, FAB, FadingBase, Field, FieldHelpIcon, FieldLabel, FileInput, Flex, Form, FormContext, FormField, FormStore, Grid2 as Grid, GridCard, icons_default as Icon, IconButton, Kbd, List2 as List, LoadingSpinner, LogoutTimer, MegaMenu_default as MegaMenu, MenuButton, Modal, NotificationProvider, NumberInput, OpaqueGridCard, OtpInput, Password, PopConfirm, Portal, RadioGroup, Rating, ScalableContainer, Scheduler, SearchInput_default as SearchInput, SecureLayout, SegmentedControl, Sidebar, SkeletonBox, SkeletonCard, SkeletonCircle, SkeletonText, Slider, Statistic, Stepper, Switch, Table, Tabs_default as Tabs, TagsInput, DatePicker as Temporal, TextArea, TextInput, ThemeProvider, ThemeSwitch, TimePicker, Timeline, Tooltip, TooltipProvider, TopBar, Tree, TreeSelect, Typography, Wizard, cardNumberError, cvvError, detectBrand, expiryError, fieldShell, formatCardNumber, formatExpiry, isRequired, luhnValid, onlyDigits, patterns, runFieldRules, useBreakpoint, useCart, useFieldArray, useForm, useFormField, useFormStore, useJwt, useLocalStorage, useMediaQuery, useNotification };
9441
+ export { Accordion_default as Accordion, AppShell, AutoComplete, Avatar, Badge, Box, Breadcrumbs, Button_default as Button, CARD_BRANDS, Card_default as Card, CardCarousel, Cart, CartButton, CartProvider, Catalog, CatalogCarousel, CatalogGrid, Chat, Checkbox, Checkout, ColorPicker, ContextMenu, CreditCardForm, DateRangePicker, Drawer, Dropdown, EmptyCart, FAB, FadingBase, FeatureGrid, Field, FieldHelpIcon, FieldLabel, FileInput, Flex, Form, FormContext, FormField, FormStore, Grid2 as Grid, GridCard, icons_default as Icon, IconButton, Jumbotron, Kbd, List2 as List, LoadingSpinner, LogoutTimer, MegaMenu_default as MegaMenu, MenuButton, Modal, NotificationProvider, NumberInput, OpaqueGridCard, OtpInput, Password, PopConfirm, Portal, PricingPlans, RadioGroup, Rating, ScalableContainer, Scheduler, SearchInput_default as SearchInput, SecureLayout, SegmentedControl, Sidebar, SkeletonBox, SkeletonCard, SkeletonCircle, SkeletonText, Slider, Statistic, Stepper, Switch, Table, Tabs_default as Tabs, TagsInput, DatePicker as Temporal, Testimonials, TextArea, TextInput, ThemeProvider, ThemeSwitch, TimePicker, Timeline, Tooltip, TooltipProvider, TopBar, Tree, TreeSelect, Typography, Wizard, cardNumberError, cvvError, detectBrand, expiryError, fieldShell, formatCardNumber, formatExpiry, isRequired, luhnValid, onlyDigits, patterns, runFieldRules, useBreakpoint, useCart, useFieldArray, useForm, useFormField, useFormStore, useJwt, useLocalStorage, useMediaQuery, useNotification };
9288
9442
  //# sourceMappingURL=index.js.map
9289
9443
  //# sourceMappingURL=index.js.map