@ceebee/ui 1.5.3 → 1.6.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/client.d.ts CHANGED
@@ -367,9 +367,11 @@ interface PanZoomCanvasProps {
367
367
  zoomOutLabel?: string;
368
368
  resetLabel?: string;
369
369
  zoomStatusLabel?: string;
370
+ fullscreenLabel?: string;
371
+ exitFullscreenLabel?: string;
370
372
  motion?: boolean;
371
373
  }
372
- declare function PanZoomCanvasRoot({ label, children, hint, zoomInLabel, zoomOutLabel, resetLabel, zoomStatusLabel, motion: motionEnabled, }: PanZoomCanvasProps): react.JSX.Element;
374
+ declare function PanZoomCanvasRoot({ label, children, hint, zoomInLabel, zoomOutLabel, resetLabel, zoomStatusLabel, fullscreenLabel, exitFullscreenLabel, motion: motionEnabled, }: PanZoomCanvasProps): react.JSX.Element;
373
375
  declare const PanZoomCanvas: typeof PanZoomCanvasRoot & {
374
376
  Skeleton: typeof PanZoomCanvasSkeleton;
375
377
  };
package/dist/client.js CHANGED
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  import { Modal as Modal$1, Button, theme, ConfigProvider, Progress } from 'antd';
3
3
  export * from 'antd';
4
- import { createContext, useId, useRef, useCallback, useInsertionEffect, useLayoutEffect, useState, useContext, useMemo, useEffect, Children } from 'react';
4
+ import { createContext, useId, useRef, useCallback, useInsertionEffect, useLayoutEffect, useState, useEffect, useContext, useMemo, Children } from 'react';
5
5
  import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
6
6
  import { StyleProvider, createCache, extractStyle } from '@ant-design/cssinjs';
7
7
  export { default as enUSLocale } from 'antd/locale/en_US.js';
@@ -9,7 +9,7 @@ export { default as enUSDatePickerLocale } from 'antd/lib/date-picker/locale/en_
9
9
  export { default as idIDLocale } from 'antd/locale/id_ID.js';
10
10
  export { default as zhCNLocale } from 'antd/locale/zh_CN.js';
11
11
  import { Dialog } from '@base-ui/react/dialog';
12
- import { X, Minus, Plus, RotateCcw, Search, Check, ChevronRight, PanelLeftOpen, PanelLeftClose, Info, XCircle, AlertTriangle, CheckCircle2 } from 'lucide-react';
12
+ import { X, Minus, Plus, RotateCcw, Minimize2, Maximize2, Search, Check, ChevronRight, PanelLeftOpen, PanelLeftClose, Info, XCircle, AlertTriangle, CheckCircle2 } from 'lucide-react';
13
13
  import { Toast } from '@base-ui/react/toast';
14
14
  import { Popover } from '@base-ui/react/popover';
15
15
  import { AnimatePresence, motion } from 'motion/react';
@@ -866,6 +866,20 @@ function readCeebeeThemeToken(root) {
866
866
  surface, so placeholders take the muted foreground that clears it against every surface a
867
867
  control can sit on. */
868
868
  colorTextPlaceholder: color("--cb-fg-muted"),
869
+ /* The same defect as the placeholder above, in the same shape: Ant derives its disabled
870
+ foreground from its own algorithm and lands on a 25%-alpha grey — measured at 1.19:1 on a
871
+ light stage and 2.08:1 on a dark one, which is a word you can see the shape of and not read.
872
+ WCAG exempts inactive controls, and that exemption is the wrong thing to lean on: the label on
873
+ a disabled control is exactly what tells you why it is disabled and what would enable it, so
874
+ it is the one piece of text on the control that has to survive.
875
+
876
+ The muted foreground rather than the subtle one, for the reason the placeholder note above
877
+ already records: subtle clears AA against the plain surface and nothing else, and a disabled
878
+ control sits on a translucent wash over whatever surface the product put it on. Measured on a
879
+ consumer's own panel, subtle came back at 4.37:1 — under the bar, from the one step that
880
+ looked quiet enough. Disabled still reads as disabled: the control also loses its border and
881
+ its ground, which are cues that do not depend on colour at all. */
882
+ colorTextDisabled: color("--cb-fg-muted"),
869
883
  colorTextLightSolid: color("--cb-fg-on-brand"),
870
884
  colorBgBase: color("--cb-bg"),
871
885
  colorBgContainer: color("--cb-surface"),
@@ -1503,9 +1517,14 @@ function PanZoomCanvasRoot({
1503
1517
  zoomOutLabel = "Zoom out",
1504
1518
  resetLabel = "Reset canvas",
1505
1519
  zoomStatusLabel = "Canvas zoom",
1520
+ fullscreenLabel = "Enter fullscreen",
1521
+ exitFullscreenLabel = "Exit fullscreen",
1506
1522
  motion: motionEnabled = true
1507
1523
  }) {
1508
1524
  const motionSettings = useMotionSettings();
1525
+ const rootRef = useRef(null);
1526
+ const [fullscreenAvailable, setFullscreenAvailable] = useState(false);
1527
+ const [fullscreen, setFullscreen] = useState(false);
1509
1528
  const [pan, setPan] = useState({ x: 0, y: 0 });
1510
1529
  const [scale, setScale] = useState(1);
1511
1530
  const pointers = useRef(/* @__PURE__ */ new Map());
@@ -1513,6 +1532,21 @@ function PanZoomCanvasRoot({
1513
1532
  const pinchOrigin = useRef(null);
1514
1533
  const stepRef = useRef(null);
1515
1534
  const shouldAnimate = motionEnabled && motionSettings.enabled;
1535
+ useEffect(() => {
1536
+ setFullscreenAvailable(typeof document !== "undefined" && document.fullscreenEnabled === true && typeof rootRef.current?.requestFullscreen === "function");
1537
+ function onChange() {
1538
+ setFullscreen(document.fullscreenElement === rootRef.current);
1539
+ }
1540
+ document.addEventListener("fullscreenchange", onChange);
1541
+ return () => document.removeEventListener("fullscreenchange", onChange);
1542
+ }, []);
1543
+ function toggleFullscreen() {
1544
+ if (document.fullscreenElement === rootRef.current) {
1545
+ void document.exitFullscreen();
1546
+ return;
1547
+ }
1548
+ void rootRef.current?.requestFullscreen();
1549
+ }
1516
1550
  function reset() {
1517
1551
  setPan({ x: 0, y: 0 });
1518
1552
  setScale(1);
@@ -1586,7 +1620,7 @@ function PanZoomCanvasRoot({
1586
1620
  "--cb-pan-zoom-y": pan.y,
1587
1621
  "--cb-pan-zoom-scale": scale
1588
1622
  };
1589
- return /* @__PURE__ */ jsxs("section", { className: "cb-pan-zoom-canvas", "data-motion": String(shouldAnimate), children: [
1623
+ return /* @__PURE__ */ jsxs("section", { ref: rootRef, className: "cb-pan-zoom-canvas", "data-motion": String(shouldAnimate), "data-fullscreen": String(fullscreen), children: [
1590
1624
  /* @__PURE__ */ jsxs("div", { className: "cb-pan-zoom-canvas__toolbar", children: [
1591
1625
  hint ? /* @__PURE__ */ jsx("p", { className: "cb-pan-zoom-canvas__hint", children: hint }) : /* @__PURE__ */ jsx("span", {}),
1592
1626
  /* @__PURE__ */ jsxs("div", { className: "cb-pan-zoom-canvas__controls", children: [
@@ -1596,7 +1630,18 @@ function PanZoomCanvasRoot({
1596
1630
  "%"
1597
1631
  ] }),
1598
1632
  /* @__PURE__ */ jsx(Button, { type: "text", size: "small", icon: /* @__PURE__ */ jsx(Plus, { "aria-hidden": "true" }), "aria-label": zoomInLabel, onClick: () => zoom(SCALE_STEP), disabled: scale >= MAX_SCALE }),
1599
- /* @__PURE__ */ jsx(Button, { type: "text", size: "small", icon: /* @__PURE__ */ jsx(RotateCcw, { "aria-hidden": "true" }), "aria-label": resetLabel, onClick: reset })
1633
+ /* @__PURE__ */ jsx(Button, { type: "text", size: "small", icon: /* @__PURE__ */ jsx(RotateCcw, { "aria-hidden": "true" }), "aria-label": resetLabel, onClick: reset }),
1634
+ fullscreenAvailable ? /* @__PURE__ */ jsx(
1635
+ Button,
1636
+ {
1637
+ type: "text",
1638
+ size: "small",
1639
+ icon: fullscreen ? /* @__PURE__ */ jsx(Minimize2, { "aria-hidden": "true" }) : /* @__PURE__ */ jsx(Maximize2, { "aria-hidden": "true" }),
1640
+ "aria-label": fullscreen ? exitFullscreenLabel : fullscreenLabel,
1641
+ "aria-pressed": fullscreen,
1642
+ onClick: toggleFullscreen
1643
+ }
1644
+ ) : null
1600
1645
  ] })
1601
1646
  ] }),
1602
1647
  /* @__PURE__ */ jsxs(
package/dist/styles.css CHANGED
@@ -1073,6 +1073,19 @@ html, body { background: var(--cb-bg); color: var(--cb-fg); }
1073
1073
  inset-inline: calc(var(--cb-space-8) * 3);
1074
1074
  }
1075
1075
 
1076
+ /* Fullscreen hands the element the whole screen, so the fixed canvas height stops being the right
1077
+ size: the viewport takes the space the toolbar leaves instead of leaving the rest blank. */
1078
+ .cb-pan-zoom-canvas:fullscreen {
1079
+ border-radius: var(--cb-radius-none);
1080
+ display: flex;
1081
+ flex-direction: column;
1082
+ }
1083
+
1084
+ .cb-pan-zoom-canvas:fullscreen .cb-pan-zoom-canvas__viewport {
1085
+ block-size: auto;
1086
+ flex: 1;
1087
+ }
1088
+
1076
1089
  @media (prefers-reduced-motion: reduce) {
1077
1090
  .cb-pan-zoom-canvas__content { transition: none; }
1078
1091
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ceebee/ui",
3
- "version": "1.5.3",
3
+ "version": "1.6.0",
4
4
  "description": "Ceebee's design system: tokens, themed primitives, motion, and onboarding.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -35,10 +35,6 @@
35
35
  "./styles.css": "./dist/styles.css",
36
36
  "./skins/*.css": "./dist/skins/*.css"
37
37
  },
38
- "scripts": {
39
- "build": "tsup && node ./stamp-client.mjs && node ./build-css.mjs",
40
- "lint": "tsc -p tsconfig.json --noEmit"
41
- },
42
38
  "peerDependencies": {
43
39
  "@base-ui/react": "^1.7.0",
44
40
  "lucide-react": ">=0.400.0",
@@ -61,5 +57,9 @@
61
57
  "@ant-design/cssinjs": "2.1.2",
62
58
  "antd": "6.6.1",
63
59
  "dayjs": "1.11.18"
60
+ },
61
+ "scripts": {
62
+ "build": "tsup && node ./stamp-client.mjs && node ./build-css.mjs",
63
+ "lint": "tsc -p tsconfig.json --noEmit"
64
64
  }
65
- }
65
+ }