@jimmy_harika/websitekit 0.5.3 → 0.5.5

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.
@@ -14,21 +14,35 @@ import { useEditorUi } from "./ui-context";
14
14
  import { useDraggable, useDropTarget } from "./dnd";
15
15
  import { cn } from "../lib/cn";
16
16
 
17
- export function SectionsPanel({ catalog }: { catalog: Catalog }) {
17
+ export function SectionsPanel({
18
+ catalog,
19
+ embedded,
20
+ }: {
21
+ catalog: Catalog;
22
+ /** Dock owns the title — only show the Add control. */
23
+ embedded?: boolean;
24
+ }) {
18
25
  const sections = useBuilder((s) => s.doc.sections);
19
26
  const ui = useEditorUi();
20
27
 
21
28
  return (
22
29
  <div className="flex h-full min-h-0 flex-col">
23
- <div className="flex items-center justify-between border-b border-border px-3 py-2.5">
24
- <span className="text-xs font-semibold uppercase tracking-wide text-muted-foreground">
25
- Sections
26
- </span>
30
+ <div
31
+ className={cn(
32
+ "flex items-center border-b border-border px-3 py-2.5",
33
+ embedded ? "justify-end" : "justify-between",
34
+ )}
35
+ >
36
+ {!embedded && (
37
+ <span className="text-xs font-semibold uppercase tracking-wide text-muted-foreground">
38
+ Sections
39
+ </span>
40
+ )}
27
41
  <button
28
42
  onClick={() => ui.openLibrary(sections.length)}
29
- className="flex items-center gap-1 rounded-md bg-secondary px-2 py-1 text-xs font-medium text-secondary-foreground transition hover:opacity-90"
43
+ className="flex items-center gap-1 rounded-md bg-primary px-2 py-1 text-xs font-medium text-primary-foreground transition hover:opacity-90"
30
44
  >
31
- <Plus className="size-3.5" /> Add
45
+ <Plus className="size-3.5" /> Add block
32
46
  </button>
33
47
  </div>
34
48
  <div className="min-h-0 flex-1 overflow-auto p-2">
@@ -139,7 +153,7 @@ function SectionRow({
139
153
  <button
140
154
  title="Delete section"
141
155
  onClick={stop(() => remove(id))}
142
- className="rounded p-0.5 text-muted-foreground hover:text-red-500"
156
+ className="rounded p-0.5 text-muted-foreground hover:text-destructive"
143
157
  >
144
158
  <Trash2 className="size-3.5" />
145
159
  </button>
@@ -53,7 +53,7 @@ export function ThemePanel() {
53
53
  {[p.colors.bg, p.colors.text, p.colors.accent].map((c, i) => (
54
54
  <span
55
55
  key={i}
56
- className="size-4 rounded-full border border-black/10"
56
+ className="size-4 rounded-full border border-border"
57
57
  style={{ background: c }}
58
58
  />
59
59
  ))}
@@ -1,14 +1,11 @@
1
1
  "use client";
2
2
 
3
- /** Editor header glass-friendly surface, device switcher, undo/redo, publish. */
3
+ /** Clean editor header: leading · devices · undo · preview · publish. */
4
4
  import type { ReactNode } from "react";
5
5
  import {
6
6
  ExternalLink,
7
- LayoutGrid,
8
- List,
9
7
  Monitor,
10
- Palette,
11
- PanelRight,
8
+ Plus,
12
9
  Redo2,
13
10
  Smartphone,
14
11
  Tablet,
@@ -27,30 +24,29 @@ const DEVICES: { id: Device; icon: typeof Monitor; label: string }[] = [
27
24
  export function Toolbar({
28
25
  onPublish,
29
26
  saving = "idle",
30
- designOpen,
31
- onToggleDesign,
32
- hasTemplates,
27
+ designOpen: _designOpen,
28
+ onToggleDesign: _onToggleDesign,
29
+ hasTemplates: _hasTemplates,
33
30
  leading,
34
31
  viewUrl,
35
32
  floating,
36
- inspectorOpen,
37
- onToggleInspector,
38
- sectionsOpen,
39
- onToggleSections,
33
+ compact,
34
+ onAddBlock,
40
35
  }: {
41
36
  onPublish?: () => void;
42
37
  saving?: "idle" | "saving" | "saved";
43
- designOpen: boolean;
44
- onToggleDesign: () => void;
38
+ designOpen?: boolean;
39
+ onToggleDesign?: () => void;
45
40
  hasTemplates?: boolean;
46
41
  leading?: ReactNode;
47
42
  viewUrl?: string;
48
43
  floating?: boolean;
49
- inspectorOpen?: boolean;
50
- onToggleInspector?: () => void;
51
- sectionsOpen?: boolean;
52
- onToggleSections?: () => void;
44
+ compact?: boolean;
45
+ onAddBlock?: () => void;
53
46
  }) {
47
+ void _designOpen;
48
+ void _onToggleDesign;
49
+ void _hasTemplates;
54
50
  const ui = useEditorUi();
55
51
  const undo = useTemporal((s) => s.undo);
56
52
  const redo = useTemporal((s) => s.redo);
@@ -60,45 +56,18 @@ export function Toolbar({
60
56
  return (
61
57
  <header
62
58
  className={cn(
63
- "relative z-40 flex h-12 shrink-0 items-center gap-1 px-2 text-foreground sm:px-3",
59
+ "relative z-40 flex h-12 shrink-0 items-center gap-2 px-2 text-foreground sm:px-3",
64
60
  floating
65
61
  ? "border-b border-border/40 bg-card/50 backdrop-blur-xl"
66
62
  : "border-b border-border bg-card",
67
63
  )}
68
64
  >
69
65
  {leading && (
70
- <div className="flex min-w-0 items-center gap-1.5 pr-1.5 sm:border-r sm:border-border/40">
66
+ <div className="flex min-w-0 flex-1 items-center gap-1.5 overflow-hidden">
71
67
  {leading}
72
68
  </div>
73
69
  )}
74
- <div className="flex items-center gap-0.5 pl-0.5">
75
- {floating && onToggleSections && (
76
- <ToolButton active={!!sectionsOpen} onClick={onToggleSections} title="Sections">
77
- <List className="size-4" />
78
- <span className="hidden text-xs lg:inline">Sections</span>
79
- </ToolButton>
80
- )}
81
- <ToolButton active={designOpen} onClick={onToggleDesign} title="Design">
82
- <Palette className="size-4" />
83
- <span className="hidden text-xs lg:inline">Design</span>
84
- </ToolButton>
85
- {hasTemplates && (
86
- <ToolButton onClick={() => ui.setTemplatesOpen(true)} title="Templates">
87
- <LayoutGrid className="size-4" />
88
- <span className="hidden text-xs lg:inline">Templates</span>
89
- </ToolButton>
90
- )}
91
- {floating && onToggleInspector && (
92
- <ToolButton
93
- active={!!inspectorOpen}
94
- onClick={onToggleInspector}
95
- title="Inspector"
96
- >
97
- <PanelRight className="size-4" />
98
- <span className="hidden text-xs lg:inline">Inspect</span>
99
- </ToolButton>
100
- )}
101
- </div>
70
+ {!leading && <div className="flex-1" />}
102
71
 
103
72
  <div className="absolute left-1/2 flex -translate-x-1/2 items-center rounded-xl border border-border/50 bg-background/70 p-0.5 backdrop-blur-md">
104
73
  {DEVICES.map((d) => {
@@ -121,7 +90,16 @@ export function Toolbar({
121
90
  })}
122
91
  </div>
123
92
 
124
- <div className="ml-auto flex items-center gap-0.5">
93
+ <div className="ml-auto flex shrink-0 items-center gap-0.5">
94
+ {onAddBlock && !compact && (
95
+ <button
96
+ type="button"
97
+ onClick={onAddBlock}
98
+ className="mr-1 hidden items-center gap-1 rounded-xl border border-border/50 px-2.5 py-1.5 text-xs font-medium text-foreground hover:bg-muted sm:inline-flex"
99
+ >
100
+ <Plus className="size-3.5" /> Add
101
+ </button>
102
+ )}
125
103
  <button
126
104
  onClick={() => undo()}
127
105
  disabled={!canUndo}
@@ -143,19 +121,19 @@ export function Toolbar({
143
121
  href={viewUrl}
144
122
  target="_blank"
145
123
  rel="noreferrer"
146
- title="View live site"
147
- className="ml-1 hidden items-center gap-1 rounded-lg px-2 py-1.5 text-xs text-muted-foreground hover:bg-muted hover:text-foreground lg:flex"
124
+ title="Preview live site"
125
+ className="ml-0.5 hidden items-center gap-1 rounded-lg px-2 py-1.5 text-xs text-muted-foreground hover:bg-muted hover:text-foreground sm:flex"
148
126
  >
149
- <ExternalLink className="size-3.5" /> Preview
127
+ <ExternalLink className="size-3.5" />
150
128
  </a>
151
129
  )}
152
- <span className="mx-1 w-12 text-right text-[11px] text-muted-foreground/70">
153
- {saving === "saving" ? "Saving…" : saving === "saved" ? "Saved" : ""}
130
+ <span className="mx-1 hidden w-10 text-right text-[10px] text-muted-foreground/70 sm:block">
131
+ {saving === "saving" ? "…" : saving === "saved" ? "Saved" : ""}
154
132
  </span>
155
133
  {onPublish && (
156
134
  <button
157
135
  onClick={onPublish}
158
- className="rounded-xl bg-primary px-3.5 py-1.5 text-sm font-semibold text-primary-foreground shadow-sm transition hover:opacity-90 sm:px-4"
136
+ className="rounded-xl bg-primary px-3.5 py-1.5 text-sm font-semibold text-primary-foreground shadow-sm transition hover:opacity-90"
159
137
  >
160
138
  Publish
161
139
  </button>
@@ -164,30 +142,3 @@ export function Toolbar({
164
142
  </header>
165
143
  );
166
144
  }
167
-
168
- function ToolButton({
169
- active,
170
- onClick,
171
- title,
172
- children,
173
- }: {
174
- active?: boolean;
175
- onClick: () => void;
176
- title: string;
177
- children: React.ReactNode;
178
- }) {
179
- return (
180
- <button
181
- onClick={onClick}
182
- title={title}
183
- className={cn(
184
- "flex items-center gap-1.5 rounded-xl px-2 py-1.5 sm:px-2.5",
185
- active
186
- ? "bg-secondary text-secondary-foreground"
187
- : "text-muted-foreground hover:bg-muted hover:text-foreground",
188
- )}
189
- >
190
- {children}
191
- </button>
192
- );
193
- }
@@ -62,7 +62,7 @@ function EditableText({
62
62
  Tag,
63
63
  {
64
64
  ref,
65
- className: cn("outline-none focus:ring-2 focus:ring-sky-400/60 rounded-sm", className),
65
+ className: cn("outline-none focus:ring-2 focus:ring-primary/60 rounded-sm", className),
66
66
  style,
67
67
  contentEditable: true,
68
68
  suppressContentEditableWarning: true,
@@ -175,8 +175,8 @@ function EditableImage({ field, src, alt, className, style, width, height, prior
175
175
  loading={priority ? "eager" : "lazy"}
176
176
  fetchPriority={priority ? "high" : "auto"}
177
177
  className={cn(
178
- "cursor-pointer outline-2 outline-offset-2 outline-transparent hover:outline-sky-400",
179
- dragOver && "outline-sky-400",
178
+ "cursor-pointer outline-2 outline-offset-2 outline-transparent hover:outline-primary",
179
+ dragOver && "outline-primary",
180
180
  className,
181
181
  )}
182
182
  style={style}
@@ -187,8 +187,8 @@ function EditableImage({ field, src, alt, className, style, width, height, prior
187
187
  ) : (
188
188
  <div
189
189
  className={cn(
190
- "flex cursor-pointer items-center justify-center bg-black/[0.04] text-[11px] uppercase tracking-wider opacity-50 outline-2 outline-dashed outline-black/15 hover:outline-sky-400",
191
- dragOver && "outline-sky-400 opacity-80",
190
+ "flex cursor-pointer items-center justify-center bg-foreground/[0.04] text-[11px] uppercase tracking-wider opacity-50 outline-2 outline-dashed outline-foreground/15 hover:outline-primary",
191
+ dragOver && "outline-primary opacity-80",
192
192
  className,
193
193
  )}
194
194
  style={style}
@@ -199,7 +199,7 @@ function EditableImage({ field, src, alt, className, style, width, height, prior
199
199
  </div>
200
200
  )}
201
201
  {err && (
202
- <p className="mt-1 text-[10px] text-red-600 dark:text-red-400" title={err}>
202
+ <p className="mt-1 text-[10px] text-destructive" title={err}>
203
203
  {err}
204
204
  </p>
205
205
  )}
@@ -2,7 +2,13 @@
2
2
 
3
3
  /** Client editor entry. Production rendering lives at
4
4
  * "@jimmy_harika/websitekit/renderer"; the model/registry at the package root. */
5
- export { PageBuilder, type PageBuilderProps } from "./PageBuilder";
5
+ export {
6
+ PageBuilder,
7
+ type PageBuilderProps,
8
+ type HostRailItem,
9
+ type DockMode,
10
+ } from "./PageBuilder";
11
+ export { EditorDock, EditorRail } from "./EditorDock";
6
12
  export { type TemplateMeta } from "./TemplateGallery";
7
13
  export { type Device } from "./ui-context";
8
14
  export { type EditorCapabilities } from "./edit-primitives";