@olwiba/ui 0.1.11 → 0.1.12

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@olwiba/ui",
3
- "version": "0.1.11",
3
+ "version": "0.1.12",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "sideEffects": false,
@@ -41,7 +41,7 @@
41
41
  "@dnd-kit/modifiers": "^9.0.0",
42
42
  "@dnd-kit/sortable": "^10.0.0",
43
43
  "@dnd-kit/utilities": "^3.2.2",
44
- "@olwiba/dx": "0.0.18",
44
+ "@olwiba/dx": "0.0.19",
45
45
  "@tanstack/react-table": "^8.21.3",
46
46
  "clsx": "^2.1.1",
47
47
  "lucide-react": "^0.562.0",
@@ -64,7 +64,7 @@
64
64
  "devDependencies": {
65
65
  "@content-collections/mdx": "^0.2.2",
66
66
  "@olwiba/cn": "0.1.21",
67
- "@olwiba/docs": "0.1.29",
67
+ "@olwiba/docs": "0.1.31",
68
68
  "@tailwindcss/vite": "^4.1.18",
69
69
  "@tanstack/react-router": "1.154.8",
70
70
  "@tanstack/react-router-devtools": "1.154.8",
@@ -113,7 +113,8 @@ function DefaultForm({
113
113
  return (
114
114
  <Card className="w-full">
115
115
  {hasPrefill && (
116
- <style>{`@keyframes auth-prefill{0%{box-shadow:0 0 0 0 hsl(var(--primary)/0)}40%{box-shadow:0 0 0 3px hsl(var(--primary)/0.4)}100%{box-shadow:0 0 0 0 hsl(var(--primary)/0)}}`}</style>
116
+ // Theme tokens hold full color values (oklch), so opacity must come from color-mix, not hsl(var()/a)
117
+ <style>{`@keyframes auth-prefill{0%{box-shadow:0 0 0 0 transparent}40%{box-shadow:0 0 0 3px color-mix(in oklab,var(--primary) 45%,transparent),0 0 16px 2px color-mix(in oklab,var(--primary) 35%,transparent)}100%{box-shadow:0 0 0 0 transparent}}`}</style>
117
118
  )}
118
119
  <CardHeader>
119
120
  {brand && <div className="mb-2">{brand}</div>}
@@ -129,7 +129,9 @@ export function BrandColorSwitchMinimal() {
129
129
  <span className="relative inline-flex size-4 items-center justify-center">
130
130
  <Palette className="size-4" />
131
131
  <span
132
- className="absolute -bottom-0.5 -right-0.5 size-1.5 rounded-full ring-1 ring-background"
132
+ className={`absolute -bottom-0.5 -right-0.5 size-1.5 rounded-full ring-1 ring-background${
133
+ active === 'zinc' ? ' dark:ring-white/25' : ''
134
+ }`}
133
135
  style={{ background: activeHex }}
134
136
  />
135
137
  </span>
@@ -147,7 +149,11 @@ export function BrandColorSwitchMinimal() {
147
149
  className="group flex flex-col items-center gap-1"
148
150
  >
149
151
  <span
150
- className="flex size-7 items-center justify-center rounded-full ring-offset-background transition-all group-hover:scale-110"
152
+ // Zinc's swatch is near-black give it a border in dark mode so it
153
+ // doesn't vanish into the popover background (transparent in light)
154
+ className={`flex size-7 items-center justify-center rounded-full ring-offset-background transition-all group-hover:scale-110${
155
+ color.name === 'zinc' ? ' border border-transparent dark:border-white/25' : ''
156
+ }`}
151
157
  style={{
152
158
  background: PREVIEW_HEX[color.name],
153
159
  boxShadow:
@@ -8,6 +8,10 @@ export interface FlowBracketProps {
8
8
  * Defaults to 8 (near the top of the first child).
9
9
  */
10
10
  anchorTop?: number;
11
+ /** Per-side override for the top anchor of the left bracket. Falls back to anchorTop. */
12
+ anchorTopLeft?: number;
13
+ /** Per-side override for the top anchor of the right bracket. Falls back to anchorTop. */
14
+ anchorTopRight?: number;
11
15
  /**
12
16
  * Vertical anchor for the bottom connection as a percentage of the wrapper height (0–100).
13
17
  * Defaults to 92 (near the bottom of the last child).
@@ -57,6 +61,8 @@ export interface FlowBracketProps {
57
61
  */
58
62
  export function FlowBracket({
59
63
  anchorTop = 8,
64
+ anchorTopLeft,
65
+ anchorTopRight,
60
66
  anchorBottom = 92,
61
67
  extent = 22,
62
68
  arrow = true,
@@ -77,13 +83,15 @@ export function FlowBracket({
77
83
 
78
84
  const cl = colorLeft ?? color;
79
85
  const cr = colorRight ?? color;
86
+ const aTL = anchorTopLeft ?? anchorTop;
87
+ const aTR = anchorTopRight ?? anchorTop;
80
88
 
81
89
  // Left bracket: bottom → top (arrowhead at top, pointing right into genesis)
82
- const leftD = `M 0,${anchorBottom} L ${L},${anchorBottom} L ${L},${anchorTop} L 0,${anchorTop}`;
90
+ const leftD = `M 0,${anchorBottom} L ${L},${anchorBottom} L ${L},${aTL} L 0,${aTL}`;
83
91
  // Right bracket: reversed = top → bottom (arrowhead at bottom, pointing left into sync)
84
92
  const rightD = reverseRight
85
- ? `M 1000,${anchorTop} L ${R},${anchorTop} L ${R},${anchorBottom} L 1000,${anchorBottom}`
86
- : `M 1000,${anchorBottom} L ${R},${anchorBottom} L ${R},${anchorTop} L 1000,${anchorTop}`;
93
+ ? `M 1000,${aTR} L ${R},${aTR} L ${R},${anchorBottom} L 1000,${anchorBottom}`
94
+ : `M 1000,${anchorBottom} L ${R},${anchorBottom} L ${R},${aTR} L 1000,${aTR}`;
87
95
 
88
96
  // CSS dot: extent as % of container width
89
97
  const ep = `${(extent / 10).toFixed(1)}%`;
@@ -92,22 +100,22 @@ export function FlowBracket({
92
100
  0%{top:${anchorBottom}%;left:0;opacity:0}
93
101
  6%{opacity:1}
94
102
  20%{top:${anchorBottom}%;left:-${ep}}
95
- 80%{top:${anchorTop}%;left:-${ep};opacity:1}
96
- 94%{top:${anchorTop}%;left:0;opacity:0}
97
- 100%{top:${anchorTop}%;left:0;opacity:0}
103
+ 80%{top:${aTL}%;left:-${ep};opacity:1}
104
+ 94%{top:${aTL}%;left:0;opacity:0}
105
+ 100%{top:${aTL}%;left:0;opacity:0}
98
106
  }
99
107
  @keyframes fb-dr{
100
108
  0%{top:${anchorBottom}%;left:100%;opacity:0}
101
109
  6%{opacity:1}
102
110
  20%{top:${anchorBottom}%;left:calc(100% + ${ep})}
103
- 80%{top:${anchorTop}%;left:calc(100% + ${ep});opacity:1}
104
- 94%{top:${anchorTop}%;left:100%;opacity:0}
105
- 100%{top:${anchorTop}%;left:100%;opacity:0}
111
+ 80%{top:${aTR}%;left:calc(100% + ${ep});opacity:1}
112
+ 94%{top:${aTR}%;left:100%;opacity:0}
113
+ 100%{top:${aTR}%;left:100%;opacity:0}
106
114
  }
107
115
  @keyframes fb-drr{
108
- 0%{top:${anchorTop}%;left:100%;opacity:0}
116
+ 0%{top:${aTR}%;left:100%;opacity:0}
109
117
  6%{opacity:1}
110
- 20%{top:${anchorTop}%;left:calc(100% + ${ep})}
118
+ 20%{top:${aTR}%;left:calc(100% + ${ep})}
111
119
  80%{top:${anchorBottom}%;left:calc(100% + ${ep});opacity:1}
112
120
  94%{top:${anchorBottom}%;left:100%;opacity:0}
113
121
  100%{top:${anchorBottom}%;left:100%;opacity:0}
@@ -167,7 +175,7 @@ export function FlowBracket({
167
175
  <svg
168
176
  aria-hidden
169
177
  viewBox="0 0 10 8"
170
- style={{ ...arrowBase, top: `${anchorTop}%`, left: 0 }}
178
+ style={{ ...arrowBase, top: `${aTL}%`, left: 0 }}
171
179
  >
172
180
  <polyline points="1,1 8,4 1,7" style={{ stroke: cl }} {...chevronProps} />
173
181
  </svg>
@@ -180,7 +188,7 @@ export function FlowBracket({
180
188
  viewBox="0 0 10 8"
181
189
  style={{
182
190
  ...arrowBase,
183
- top: reverseRight ? `${anchorBottom}%` : `${anchorTop}%`,
191
+ top: reverseRight ? `${anchorBottom}%` : `${aTR}%`,
184
192
  left: '100%',
185
193
  }}
186
194
  >
@@ -1,7 +1,7 @@
1
1
  'use client';
2
2
 
3
3
  import * as React from 'react';
4
- import { Menu, X } from 'lucide-react';
4
+ import { Menu } from 'lucide-react';
5
5
  import { Button, Separator, Sheet, SheetContent, SheetTrigger } from '@olwiba/cn';
6
6
  import type { AppShellRenderLink } from '../app/AppShell';
7
7
 
@@ -81,16 +81,17 @@ export function Navbar({
81
81
  </div>
82
82
  )}
83
83
 
84
- {/* Mobile drawer — right column on small screens */}
84
+ {/* Mobile drawer — trigger on the right, panel slides in from the left */}
85
85
  <Sheet open={open} onOpenChange={setOpen}>
86
86
  <SheetTrigger asChild>
87
- <Button variant="ghost" size="icon" className="justify-self-end md:hidden">
87
+ <Button variant="ghost" size="icon" className="col-start-3 justify-self-end md:hidden">
88
88
  <Menu className="size-5" />
89
89
  <span className="sr-only">Open menu</span>
90
90
  </Button>
91
91
  </SheetTrigger>
92
- <SheetContent side="right" className="w-72">
93
- <div className="flex items-center justify-between pb-4">
92
+ <SheetContent side="left" className="w-72">
93
+ {/* Brand row alone at the top — leaves the top-right corner to the built-in close */}
94
+ <div className="flex items-center pb-4">
94
95
  <span onClick={() => setOpen(false)} className="cursor-pointer">
95
96
  {renderLink({
96
97
  href: brandHref,
@@ -102,16 +103,14 @@ export function Navbar({
102
103
  ),
103
104
  })}
104
105
  </span>
105
- <div className="flex items-center gap-1">
106
- {controls?.map((control, i) => (
106
+ </div>
107
+ {controls?.length ? (
108
+ <div className="mb-4 flex w-full items-center justify-between gap-1">
109
+ {controls.map((control, i) => (
107
110
  <React.Fragment key={i}>{control}</React.Fragment>
108
111
  ))}
109
- <Button variant="ghost" size="icon" onClick={() => setOpen(false)}>
110
- <X className="size-4" />
111
- <span className="sr-only">Close menu</span>
112
- </Button>
113
112
  </div>
114
- </div>
113
+ ) : null}
115
114
  <Separator />
116
115
  <nav className="mt-4 flex flex-col gap-1">
117
116
  {navLinks.map((link) => (