@hachej/boring-ui-kit 0.1.104 → 0.1.105

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
@@ -252,7 +252,12 @@ function DialogContent({
252
252
  {
253
253
  "data-slot": "dialog-content",
254
254
  className: cn(
255
- "fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border bg-background p-6 shadow-lg duration-200 outline-none data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95 sm:max-w-lg",
255
+ // Compact viewports top-align: `fixed` resolves against the layout viewport, which
256
+ // the software keyboard never shrinks, so a centred dialog puts its lower half (and
257
+ // any footer) behind the keyboard. `sm:` restores the classic centred dialog.
258
+ // The height cap only subtracts `--keyboard-inset` (published on <html> by the host
259
+ // app, `0px` by default) so it stays a no-op for full-bleed `h-[100dvh]` consumers.
260
+ "fixed top-[max(1rem,env(safe-area-inset-top,0px))] left-[50%] z-50 grid max-h-[calc(100dvh-var(--keyboard-inset,0px))] w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-0 gap-4 overflow-y-auto rounded-lg border bg-background p-6 shadow-lg duration-200 outline-none data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95 sm:top-[50%] sm:max-w-lg sm:translate-y-[-50%]",
256
261
  className
257
262
  ),
258
263
  ...props,
@@ -743,7 +748,8 @@ function CommandInput({
743
748
  {
744
749
  "data-slot": "command-input",
745
750
  className: cn(
746
- "flex h-10 w-full rounded-md bg-transparent py-3 text-sm outline-hidden placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50",
751
+ // text-base below md: iOS auto-zooms the page on focus for inputs under 16px.
752
+ "flex h-10 w-full rounded-md bg-transparent py-3 text-base outline-hidden md:text-sm placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50",
747
753
  className
748
754
  ),
749
755
  ...props
@@ -1481,10 +1487,12 @@ function Toaster({ position = "bottom-right", className }) {
1481
1487
  "data-testid": "toaster",
1482
1488
  className: cn(
1483
1489
  "pointer-events-none fixed z-[1000] flex w-[340px] max-w-[calc(100vw-2rem)] flex-col gap-2",
1484
- position === "bottom-right" && "bottom-4 right-4 items-end",
1485
- position === "bottom-left" && "bottom-4 left-4 items-start",
1486
- position === "top-right" && "top-4 right-4 items-end",
1487
- position === "top-left" && "top-4 left-4 items-start",
1490
+ // Offsets stack on top of the safe area so toasts never sit in the home-indicator
1491
+ // gesture strip, where a dismiss swipe would hit the OS instead of the toast.
1492
+ position === "bottom-right" && "bottom-[calc(1rem+env(safe-area-inset-bottom,0px))] right-[calc(1rem+env(safe-area-inset-right,0px))] items-end",
1493
+ position === "bottom-left" && "bottom-[calc(1rem+env(safe-area-inset-bottom,0px))] left-[calc(1rem+env(safe-area-inset-left,0px))] items-start",
1494
+ position === "top-right" && "top-[calc(1rem+env(safe-area-inset-top,0px))] right-[calc(1rem+env(safe-area-inset-right,0px))] items-end",
1495
+ position === "top-left" && "top-[calc(1rem+env(safe-area-inset-top,0px))] left-[calc(1rem+env(safe-area-inset-left,0px))] items-start",
1488
1496
  className
1489
1497
  ),
1490
1498
  children: items.map((item) => {
@@ -1802,7 +1810,10 @@ function AlertDialogContent({
1802
1810
  "data-slot": "alert-dialog-content",
1803
1811
  "data-size": size,
1804
1812
  className: cn(
1805
- "group/alert-dialog-content fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border bg-background p-6 shadow-lg duration-200 data-[size=sm]:max-w-xs data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95 data-[size=default]:sm:max-w-lg",
1813
+ // Mirrors dialog.tsx: compact viewports top-align so confirm dialogs
1814
+ // (and their action buttons) cannot land behind the software keyboard;
1815
+ // `sm:` restores the classic centred dialog.
1816
+ "group/alert-dialog-content fixed top-[max(1rem,env(safe-area-inset-top,0px))] left-[50%] z-50 grid max-h-[calc(100dvh-var(--keyboard-inset,0px))] w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-0 gap-4 overflow-y-auto rounded-lg border bg-background p-6 shadow-lg duration-200 outline-none data-[size=sm]:max-w-xs data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95 data-[size=default]:sm:max-w-lg sm:top-[50%] sm:translate-y-[-50%]",
1806
1817
  className
1807
1818
  ),
1808
1819
  ...props
@@ -2099,16 +2110,20 @@ function SheetContent({
2099
2110
  "data-slot": "sheet-content",
2100
2111
  className: cn(
2101
2112
  "fixed z-50 flex flex-col gap-4 bg-background shadow-lg transition ease-in-out data-[state=closed]:animate-out data-[state=closed]:duration-300 data-[state=open]:animate-in data-[state=open]:duration-500",
2102
- side === "right" && "inset-y-0 right-0 h-full w-3/4 border-l data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right sm:max-w-sm",
2103
- side === "left" && "inset-y-0 left-0 h-full w-3/4 border-r data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left sm:max-w-sm",
2104
- side === "top" && "inset-x-0 top-0 h-auto border-b data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top",
2105
- side === "bottom" && "inset-x-0 bottom-0 h-auto border-t data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom",
2113
+ // Safe-area insets live on the root so the background/border still bleed to the
2114
+ // physical screen edge while content clears the notch and home indicator.
2115
+ side === "right" && "inset-y-0 right-0 h-full w-3/4 border-l pt-[env(safe-area-inset-top,0px)] pr-[env(safe-area-inset-right,0px)] pb-[env(safe-area-inset-bottom,0px)] data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right sm:max-w-sm",
2116
+ side === "left" && "inset-y-0 left-0 h-full w-3/4 border-r pt-[env(safe-area-inset-top,0px)] pb-[env(safe-area-inset-bottom,0px)] pl-[env(safe-area-inset-left,0px)] data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left sm:max-w-sm",
2117
+ side === "top" && "inset-x-0 top-0 h-auto border-b pt-[env(safe-area-inset-top,0px)] pr-[env(safe-area-inset-right,0px)] pl-[env(safe-area-inset-left,0px)] data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top",
2118
+ side === "bottom" && "inset-x-0 bottom-0 h-auto border-t pr-[env(safe-area-inset-right,0px)] pb-[calc(1rem+env(safe-area-inset-bottom,0px))] pl-[env(safe-area-inset-left,0px)] data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom",
2106
2119
  className
2107
2120
  ),
2108
2121
  ...props,
2109
2122
  children: [
2110
2123
  children,
2111
- showCloseButton && /* @__PURE__ */ jsxs15(SheetPrimitive.Close, { className: "absolute top-4 right-4 rounded-xs opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:ring-2 focus:ring-ring focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none data-[state=open]:bg-secondary", children: [
2124
+ showCloseButton && // Absolute positioning resolves against the padding box, so the root insets above
2125
+ // do not move this button; it needs its own offsets to clear the notch.
2126
+ /* @__PURE__ */ jsxs15(SheetPrimitive.Close, { className: "absolute top-[calc(1rem+env(safe-area-inset-top,0px))] right-[calc(1rem+env(safe-area-inset-right,0px))] rounded-xs opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:ring-2 focus:ring-ring focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none data-[state=open]:bg-secondary", children: [
2112
2127
  /* @__PURE__ */ jsx43("span", { "aria-hidden": "true", className: "text-base leading-none", children: "\xD7" }),
2113
2128
  /* @__PURE__ */ jsx43("span", { className: "sr-only", children: "Close" })
2114
2129
  ] })
package/dist/styles.css CHANGED
@@ -80,8 +80,11 @@
80
80
  .top-4 {
81
81
  top: calc(var(--spacing) * 4);
82
82
  }
83
- .top-\[50\%\] {
84
- top: 50%;
83
+ .top-\[calc\(1rem\+env\(safe-area-inset-top\,0px\)\)\] {
84
+ top: calc(1rem + env(safe-area-inset-top,0px));
85
+ }
86
+ .top-\[max\(1rem\,env\(safe-area-inset-top\,0px\)\)\] {
87
+ top: max(1rem, env(safe-area-inset-top,0px));
85
88
  }
86
89
  .right-0 {
87
90
  right: 0px;
@@ -92,11 +95,14 @@
92
95
  .right-4 {
93
96
  right: calc(var(--spacing) * 4);
94
97
  }
98
+ .right-\[calc\(1rem\+env\(safe-area-inset-right\,0px\)\)\] {
99
+ right: calc(1rem + env(safe-area-inset-right,0px));
100
+ }
95
101
  .bottom-0 {
96
102
  bottom: 0px;
97
103
  }
98
- .bottom-4 {
99
- bottom: calc(var(--spacing) * 4);
104
+ .bottom-\[calc\(1rem\+env\(safe-area-inset-bottom\,0px\)\)\] {
105
+ bottom: calc(1rem + env(safe-area-inset-bottom,0px));
100
106
  }
101
107
  .left-0 {
102
108
  left: 0px;
@@ -104,12 +110,12 @@
104
110
  .left-2 {
105
111
  left: calc(var(--spacing) * 2);
106
112
  }
107
- .left-4 {
108
- left: calc(var(--spacing) * 4);
109
- }
110
113
  .left-\[50\%\] {
111
114
  left: 50%;
112
115
  }
116
+ .left-\[calc\(1rem\+env\(safe-area-inset-left\,0px\)\)\] {
117
+ left: calc(1rem + env(safe-area-inset-left,0px));
118
+ }
113
119
  .z-50 {
114
120
  z-index: 50;
115
121
  }
@@ -249,6 +255,9 @@
249
255
  .h-10 {
250
256
  height: calc(var(--spacing) * 10);
251
257
  }
258
+ .h-\[100dvh\] {
259
+ height: 100dvh;
260
+ }
252
261
  .h-\[calc\(100\%-1px\)\] {
253
262
  height: calc(100% - 1px);
254
263
  }
@@ -276,6 +285,9 @@
276
285
  .max-h-\[300px\] {
277
286
  max-height: 300px;
278
287
  }
288
+ .max-h-\[calc\(100dvh-var\(--keyboard-inset\,0px\)\)\] {
289
+ max-height: calc(100dvh - var(--keyboard-inset,0px));
290
+ }
279
291
  .min-h-0 {
280
292
  min-height: 0px;
281
293
  }
@@ -379,8 +391,8 @@
379
391
  --tw-translate-x: -50%;
380
392
  translate: var(--tw-translate-x) var(--tw-translate-y);
381
393
  }
382
- .translate-y-\[-50\%\] {
383
- --tw-translate-y: -50%;
394
+ .translate-y-0 {
395
+ --tw-translate-y: 0px;
384
396
  translate: var(--tw-translate-x) var(--tw-translate-y);
385
397
  }
386
398
  .translate-y-\[calc\(-50\%_-_2px\)\] {
@@ -885,6 +897,9 @@
885
897
  .pt-3 {
886
898
  padding-top: calc(var(--spacing) * 3);
887
899
  }
900
+ .pt-\[env\(safe-area-inset-top\,0px\)\] {
901
+ padding-top: env(safe-area-inset-top,0px);
902
+ }
888
903
  .pr-2 {
889
904
  padding-right: calc(var(--spacing) * 2);
890
905
  }
@@ -894,12 +909,21 @@
894
909
  .pr-8 {
895
910
  padding-right: calc(var(--spacing) * 8);
896
911
  }
912
+ .pr-\[env\(safe-area-inset-right\,0px\)\] {
913
+ padding-right: env(safe-area-inset-right,0px);
914
+ }
897
915
  .pb-2 {
898
916
  padding-bottom: calc(var(--spacing) * 2);
899
917
  }
900
918
  .pb-3 {
901
919
  padding-bottom: calc(var(--spacing) * 3);
902
920
  }
921
+ .pb-\[calc\(1rem\+env\(safe-area-inset-bottom\,0px\)\)\] {
922
+ padding-bottom: calc(1rem + env(safe-area-inset-bottom,0px));
923
+ }
924
+ .pb-\[env\(safe-area-inset-bottom\,0px\)\] {
925
+ padding-bottom: env(safe-area-inset-bottom,0px);
926
+ }
903
927
  .pl-2 {
904
928
  padding-left: calc(var(--spacing) * 2);
905
929
  }
@@ -909,6 +933,9 @@
909
933
  .pl-8 {
910
934
  padding-left: calc(var(--spacing) * 8);
911
935
  }
936
+ .pl-\[env\(safe-area-inset-left\,0px\)\] {
937
+ padding-left: env(safe-area-inset-left,0px);
938
+ }
912
939
  .text-center {
913
940
  text-align: center;
914
941
  }
@@ -1708,12 +1735,19 @@
1708
1735
  border-radius: 0;
1709
1736
  }
1710
1737
  @media (width >= 40rem) {
1738
+ .sm\:top-\[50\%\] {
1739
+ top: 50%;
1740
+ }
1711
1741
  .sm\:max-w-lg {
1712
1742
  max-width: var(--container-lg);
1713
1743
  }
1714
1744
  .sm\:max-w-sm {
1715
1745
  max-width: var(--container-sm);
1716
1746
  }
1747
+ .sm\:translate-y-\[-50\%\] {
1748
+ --tw-translate-y: -50%;
1749
+ translate: var(--tw-translate-x) var(--tw-translate-y);
1750
+ }
1717
1751
  .sm\:flex-row {
1718
1752
  flex-direction: row;
1719
1753
  }
package/dist/tokens.css CHANGED
@@ -8,8 +8,15 @@
8
8
  * @import '@hachej/boring-ui-kit/tokens.css';
9
9
  * :root { --boring-accent: oklch(0.55 0.18 250); }
10
10
  *
11
- * Values mirror @hachej/boring-workspace/src/globals.css (the canonical
12
- * theme). This file is plain CSS — no Tailwind required; the utility-name
11
+ * This file is the palette source of truth. Two other places restate these
12
+ * values and must be kept in step:
13
+ * - packages/workspace/src/globals.css (the workspace :root palette)
14
+ * - packages/agent/src/front/styles/globals.css (var() fallbacks that keep
15
+ * standalone agent panes themed with no workspace CSS loaded)
16
+ * Both are enforced against this file by
17
+ * packages/agent/src/__tests__/theme-token-parity.test.ts.
18
+ *
19
+ * This file is plain CSS — no Tailwind required; the utility-name
13
20
  * mapping lives in styles.css (@theme inline → --boring-*).
14
21
  */
15
22
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hachej/boring-ui-kit",
3
- "version": "0.1.104",
3
+ "version": "0.1.105",
4
4
  "type": "module",
5
5
  "license": "MIT",
6
6
  "description": "Shared shadcn-style UI primitives for Boring packages and app-generated panes.",