@sevenfold/setto-client 0.4.0 → 0.5.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/README.md +36 -23
- package/dist/admin/App.d.ts +2 -3
- package/dist/edit-mode/constants.d.ts +4 -2
- package/dist/edit-mode/document-layout.d.ts +4 -2
- package/dist/edit-mode/mount.d.ts +2 -2
- package/dist/edit-mode/setto-mark.d.ts +16 -0
- package/dist/lib/theme-store.d.ts +2 -0
- package/dist/lib/urls.d.ts +8 -4
- package/dist/lib/use-site-access.d.ts +16 -0
- package/dist/provider.d.ts +10 -5
- package/dist/setto-client.js +311 -189
- package/dist/setto-client.js.map +1 -1
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -8,29 +8,34 @@ Editors authenticate via Supabase, edit text inline on the live page, pick secti
|
|
|
8
8
|
|
|
9
9
|
## Install
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
Sevenfold sites pin a git tag, not an npm version, so changes ship without an npm round-trip:
|
|
12
|
+
|
|
13
|
+
```json
|
|
14
|
+
"@setto/client": "github:nitech/setto-client#v0.5.0"
|
|
13
15
|
```
|
|
14
16
|
|
|
15
|
-
|
|
17
|
+
Bun clones the repo on `bun install`, runs the package's `prepare` script to build `dist/`, and links it as `@setto/client`. Vercel does the same automatically when it installs build deps.
|
|
16
18
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
+
The package is also still published to npm (`@sevenfold/setto-client`) for external consumers:
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
bun add @setto/client@npm:@sevenfold/setto-client
|
|
19
23
|
```
|
|
20
24
|
|
|
21
25
|
Peer deps: `react`, `react-dom`, `react-i18next`, `i18next`.
|
|
22
26
|
|
|
23
|
-
For local monorepo development
|
|
24
|
-
|
|
25
|
-
### Publishing a new version
|
|
27
|
+
For local monorepo development the consumer's `vite.config.ts` aliases `@setto/client` to setto-client source — see [Local development](#local-development-sevenfold-monorepo).
|
|
26
28
|
|
|
27
|
-
|
|
28
|
-
2. Commit and push a tag: `git tag v0.1.1 && git push origin v0.1.1`
|
|
29
|
-
3. GitHub Actions publishes to npm automatically
|
|
29
|
+
### Releasing a new version
|
|
30
30
|
|
|
31
|
-
|
|
31
|
+
1. Bump `version` in `package.json` following semver (patch / minor / major).
|
|
32
|
+
2. Commit and tag: `git tag v0.5.1 && git push origin main --follow-tags`.
|
|
33
|
+
3. In each consumer (`carryon.no`, `setto-site`):
|
|
34
|
+
- Update the tag in `package.json` (e.g. `#v0.5.0` → `#v0.5.1`).
|
|
35
|
+
- Run `bun install` to refresh the lockfile.
|
|
36
|
+
- Push — Vercel pulls the new tag on the next deploy.
|
|
32
37
|
|
|
33
|
-
|
|
38
|
+
GitHub Actions still publishes to npm automatically when `package.json` lands on `main` (requires `NPM_TOKEN` secret), but Sevenfold consumers no longer wait for it.
|
|
34
39
|
|
|
35
40
|
---
|
|
36
41
|
|
|
@@ -69,7 +74,7 @@ createRoot(document.getElementById('root')!).render(
|
|
|
69
74
|
|
|
70
75
|
### 2. Mount the Setto route
|
|
71
76
|
|
|
72
|
-
Editors
|
|
77
|
+
Editors sign in once at `sitenavn.no/setto`. After that, every visit to the public site auto-enters edit mode for as long as the Supabase session persists.
|
|
73
78
|
|
|
74
79
|
```tsx
|
|
75
80
|
// App.tsx
|
|
@@ -126,24 +131,32 @@ function ValuesSection() {
|
|
|
126
131
|
|
|
127
132
|
## Edit mode
|
|
128
133
|
|
|
129
|
-
Edit mode activates
|
|
134
|
+
Edit mode activates whenever **all** of these are true:
|
|
130
135
|
|
|
131
|
-
1.
|
|
132
|
-
2.
|
|
136
|
+
1. The user has an authenticated Supabase session.
|
|
137
|
+
2. The user has access to `config.siteId` (a row in the `sites` table that they can read).
|
|
138
|
+
3. The current path is not `/setto` (the dashboard is rendered without inline editing).
|
|
133
139
|
|
|
134
|
-
|
|
140
|
+
Sign-in at `/setto` persists via Supabase, so subsequent visits drop straight into edit mode — no URL flag, no extra step.
|
|
135
141
|
|
|
136
142
|
### What editors see
|
|
137
143
|
|
|
144
|
+
A small round Setto button floats in the bottom-right corner. While there are no unpublished changes it stays as a circle showing only the Setto mark. As soon as you edit something it grows into a pill containing **Publiser** and a **⋯** menu with:
|
|
145
|
+
|
|
146
|
+
| Item | Effect |
|
|
147
|
+
|------|--------|
|
|
148
|
+
| **Avbryt** | Discards every unsaved draft (text, section colours, image uploads) |
|
|
149
|
+
| **Logg ut** | Signs out via Supabase and exits edit mode |
|
|
150
|
+
| **Historikk** | Opens the `/setto` dashboard with deployment history |
|
|
151
|
+
|
|
138
152
|
| Action | How |
|
|
139
153
|
|--------|-----|
|
|
140
154
|
| Edit text | Click any `<T>` element — it becomes `contentEditable` |
|
|
141
155
|
| Edit section colours | Click a section or block background (not text) |
|
|
142
156
|
| Follow a link | Ctrl/Cmd + click (desktop) · **Naviger ↗** chip when focused (touch) |
|
|
143
|
-
| Publish |
|
|
144
|
-
| Exit | Top toolbar → **Avslutt** (removes `?setto=edit`) |
|
|
157
|
+
| Publish | FAB → **Publiser** (visible once you have drafts) |
|
|
145
158
|
|
|
146
|
-
|
|
159
|
+
When you click a section or block, a compact colour toolbar appears above it. Click again or press Escape to dismiss.
|
|
147
160
|
|
|
148
161
|
---
|
|
149
162
|
|
|
@@ -308,7 +321,7 @@ Keeping this in the repo means content shape lives with the code that defines it
|
|
|
308
321
|
|
|
309
322
|
## Publish flow
|
|
310
323
|
|
|
311
|
-
1. Editor clicks **Publiser** in the
|
|
324
|
+
1. Editor clicks **Publiser** in the floating FAB.
|
|
312
325
|
2. Client serialises changed locale bundles + `sections.json` (if theme drafts exist).
|
|
313
326
|
3. `POST /sites/:siteId/publish` with `{ files: [{ path, content }] }`.
|
|
314
327
|
4. setto-server validates paths against `content_paths`, commits to GitHub.
|
|
@@ -322,7 +335,7 @@ Drafts are cleared after a successful publish.
|
|
|
322
335
|
|
|
323
336
|
Route: `/setto/*`
|
|
324
337
|
|
|
325
|
-
Provides Supabase email/password login (invite-only — no self-service sign-up), password reset, and a dashboard
|
|
338
|
+
Provides Supabase email/password login (invite-only — no self-service sign-up), password reset, and a dashboard. After sign-in the dashboard redirects to the site home, where edit mode auto-activates. Invite links from Supabase land on `/setto` to set a password. Does not render the inline editor itself.
|
|
326
339
|
|
|
327
340
|
---
|
|
328
341
|
|
package/dist/admin/App.d.ts
CHANGED
|
@@ -2,10 +2,9 @@
|
|
|
2
2
|
* Drop-in admin SPA. Mount under a route like `<Route path="/setto/*" .../>`.
|
|
3
3
|
*
|
|
4
4
|
* Behaviour after login:
|
|
5
|
-
* - Redirects to
|
|
5
|
+
* - Redirects to the site home `/`. Edit mode activates automatically there
|
|
6
|
+
* via `SettoProvider` when the user has access to `config.siteId`.
|
|
6
7
|
* - Shows the dashboard only when the user lacks access to this site, or on
|
|
7
8
|
* `/setto?deployment=…` for publish progress / history.
|
|
8
|
-
*
|
|
9
|
-
* Editing happens on the public site at `/?setto=edit`.
|
|
10
9
|
*/
|
|
11
10
|
export declare function SettoAdminApp(): import("react/jsx-runtime").JSX.Element;
|
|
@@ -1,2 +1,4 @@
|
|
|
1
|
-
/**
|
|
2
|
-
export declare const
|
|
1
|
+
/** Diameter of the collapsed FAB and height of the expanded pill (px). */
|
|
2
|
+
export declare const FAB_SIZE = 52;
|
|
3
|
+
/** Distance from the viewport edges to the FAB (px). */
|
|
4
|
+
export declare const FAB_INSET = 16;
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
2
|
+
* Applies the document-level CSS for inline edit mode. The fixed top toolbar
|
|
3
|
+
* has been replaced with a floating FAB anchored bottom-right, so the host
|
|
4
|
+
* page no longer needs vertical padding — only edit-affordance hover styles
|
|
5
|
+
* and the portal layers above the page.
|
|
4
6
|
*/
|
|
5
7
|
export declare function useSettoDocumentLayout(active: boolean): void;
|
|
@@ -5,8 +5,8 @@ interface EditModeShellProps {
|
|
|
5
5
|
themeStore: ThemeStore | null;
|
|
6
6
|
}
|
|
7
7
|
/**
|
|
8
|
-
* Edit mode: full-width page with a
|
|
9
|
-
* inline via contentEditable on `<T>` — no sidebar.
|
|
8
|
+
* Edit mode: full-width page with a floating Setto FAB anchored bottom-right.
|
|
9
|
+
* Text is edited inline via contentEditable on `<T>` — no sidebar.
|
|
10
10
|
*/
|
|
11
11
|
export declare function EditModeShell({ children, themeStore }: EditModeShellProps): import("react/jsx-runtime").JSX.Element;
|
|
12
12
|
/** @deprecated Use EditModeShell */
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { CSSProperties } from 'react';
|
|
2
|
+
interface SettoMarkProps {
|
|
3
|
+
size?: number;
|
|
4
|
+
/** Color of the "S" letter. Defaults to the Setto crema tone. */
|
|
5
|
+
letterColor?: string;
|
|
6
|
+
/** Color of the accent dot. Defaults to the Setto terracotta. */
|
|
7
|
+
dotColor?: string;
|
|
8
|
+
style?: CSSProperties;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Setto brand mark — the foreground of the setto-site favicon (italic "S" with
|
|
12
|
+
* a terracotta dot) on a transparent background. The FAB renders the dark
|
|
13
|
+
* Blekk background itself so the mark only carries the glyphs.
|
|
14
|
+
*/
|
|
15
|
+
export declare function SettoMark({ size, letterColor, dotColor, style, }: SettoMarkProps): import("react/jsx-runtime").JSX.Element;
|
|
16
|
+
export {};
|
|
@@ -27,6 +27,8 @@ export declare class ThemeStore {
|
|
|
27
27
|
set(sectionId: string, field: string, value: string): void;
|
|
28
28
|
/** Replace baseline from GitHub without creating drafts. */
|
|
29
29
|
loadBaseline(next: SectionsTheme): void;
|
|
30
|
+
/** Resets every draft back to its original value. */
|
|
31
|
+
revertAll(): void;
|
|
30
32
|
commit(): void;
|
|
31
33
|
size(): number;
|
|
32
34
|
serialise(): SectionsTheme;
|
package/dist/lib/urls.d.ts
CHANGED
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Base path where the Setto login + dashboard SPA is mounted on the host site.
|
|
3
|
-
* Editors reach
|
|
4
|
-
* mount `<SettoAdminApp>` at this path (e.g. `<Route path="/setto/*" …>`).
|
|
3
|
+
* Editors reach the dashboard by visiting `sitenavn.no/setto`. The host app
|
|
4
|
+
* must mount `<SettoAdminApp>` at this path (e.g. `<Route path="/setto/*" …>`).
|
|
5
5
|
*/
|
|
6
6
|
export declare const SETTO_BASE = "/setto";
|
|
7
|
-
/**
|
|
8
|
-
|
|
7
|
+
/**
|
|
8
|
+
* Site home URL used after sign-in. Edit mode itself is now driven by the
|
|
9
|
+
* Supabase session + site access — no URL flag required — so this just sends
|
|
10
|
+
* the editor to the public site root.
|
|
11
|
+
*/
|
|
12
|
+
export declare function siteHomeUrl(pathname?: string): string;
|
|
9
13
|
export declare function isAdminRoute(): boolean;
|
|
10
14
|
/** Setto deployment progress panel (`/setto?deployment=…`). */
|
|
11
15
|
export declare function isAdminDeploymentView(): boolean;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { Session, SupabaseClient } from '@supabase/supabase-js';
|
|
2
|
+
import type { SiteRow } from '../types';
|
|
3
|
+
export interface SiteAccessState {
|
|
4
|
+
/** All sites the current user can access. `null` until loaded. */
|
|
5
|
+
sites: SiteRow[] | null;
|
|
6
|
+
/** The site matching `siteId`, or `null` if the user has no access. */
|
|
7
|
+
currentSite: SiteRow | null;
|
|
8
|
+
loading: boolean;
|
|
9
|
+
error: string | null;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Loads the sites table for the current Supabase session and resolves whether
|
|
13
|
+
* the user has access to `siteId`. Returns a stable shape across loading,
|
|
14
|
+
* success, and failure so callers can read `currentSite` directly.
|
|
15
|
+
*/
|
|
16
|
+
export declare function useSiteAccess(supabase: SupabaseClient, session: Session | null, siteId: string): SiteAccessState;
|
package/dist/provider.d.ts
CHANGED
|
@@ -4,7 +4,7 @@ import { type SettoApi } from './lib/api';
|
|
|
4
4
|
import { I18nStore } from './lib/i18n-store';
|
|
5
5
|
import { AssetStore } from './lib/asset-store';
|
|
6
6
|
import { ThemeStore } from './lib/theme-store';
|
|
7
|
-
import type { SettoConfig } from './types';
|
|
7
|
+
import type { SettoConfig, SiteRow } from './types';
|
|
8
8
|
interface SettoContextValue {
|
|
9
9
|
config: SettoConfig;
|
|
10
10
|
supabase: SupabaseClient;
|
|
@@ -12,8 +12,12 @@ interface SettoContextValue {
|
|
|
12
12
|
session: Session | null;
|
|
13
13
|
/** True while the initial auth state is being read from local storage. */
|
|
14
14
|
authLoading: boolean;
|
|
15
|
-
/** True when inline edit mode is active (
|
|
15
|
+
/** True when inline edit mode is active (session + site access). */
|
|
16
16
|
editMode: boolean;
|
|
17
|
+
/** Site row matching `config.siteId`, or `null` if the user has no access. */
|
|
18
|
+
currentSite: SiteRow | null;
|
|
19
|
+
/** All sites the user can access (loaded after sign-in). */
|
|
20
|
+
sites: SiteRow[] | null;
|
|
17
21
|
/**
|
|
18
22
|
* Lazily created when i18next is initialised. Components that need it
|
|
19
23
|
* should `if (!store) return null;` until then.
|
|
@@ -32,10 +36,11 @@ export interface SettoProviderProps {
|
|
|
32
36
|
*
|
|
33
37
|
* Edit mode is on when ALL of:
|
|
34
38
|
* 1. There is an authenticated Supabase session.
|
|
35
|
-
* 2. The
|
|
39
|
+
* 2. The user has access to `config.siteId` in the Setto sites table.
|
|
40
|
+
* 3. The current path is not the `/setto` admin SPA.
|
|
36
41
|
*
|
|
37
|
-
*
|
|
38
|
-
*
|
|
42
|
+
* Once an editor signs in via `/setto`, returning visits auto-enter edit mode
|
|
43
|
+
* for as long as the Supabase session persists.
|
|
39
44
|
*/
|
|
40
45
|
export declare function SettoProvider({ config, children }: SettoProviderProps): import("react/jsx-runtime").JSX.Element;
|
|
41
46
|
export declare function useSetto(): SettoContextValue;
|