@withpotter/components 0.13.0-next.110 → 0.13.0-next.112
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/shell/shell.css
CHANGED
|
@@ -2909,7 +2909,12 @@
|
|
|
2909
2909
|
/* ===================== Settings window (the modal) =====================
|
|
2910
2910
|
* One named variant: the window's own palette, so its rail, rows and panels draw the same values everywhere
|
|
2911
2911
|
* (the prototype's warm frame). Light takes the prototype's values; dark falls back to the theme tokens so the window
|
|
2912
|
-
* still follows the theme. Panels inside the window read the same variables, with their own fallbacks outside it.
|
|
2912
|
+
* still follows the theme. Panels inside the window read the same variables, with their own fallbacks outside it.
|
|
2913
|
+
*
|
|
2914
|
+
* "Dark" means the window itself is dark. On a desktop dashboard the root carries `.dark` for the sidebar while the
|
|
2915
|
+
* content card, and every dialog that opens over it, is light: the root then also says `data-shell-light` (see
|
|
2916
|
+
* lib/theme-context.tsx). So the dark fallback is for `.dark` WITHOUT that flag, or the light window would draw in
|
|
2917
|
+
* the theme's tokens (grey card, teal headings) instead of its own. */
|
|
2913
2918
|
.st-modal {
|
|
2914
2919
|
--st-rail: #f6f6f3;
|
|
2915
2920
|
--st-rail-line: #ecece8;
|
|
@@ -2927,8 +2932,21 @@
|
|
|
2927
2932
|
--st-pick-dot: #3f9c7a;
|
|
2928
2933
|
--st-chip: #f1f1ee;
|
|
2929
2934
|
--st-rule: #eeeeea;
|
|
2930
|
-
|
|
2931
|
-
|
|
2935
|
+
--st-ink-1: #141416;
|
|
2936
|
+
--st-btn: #ffffff;
|
|
2937
|
+
--st-btn-hover: #f6f6f4;
|
|
2938
|
+
--st-btn-ring: 0 0 0 1px rgba(0, 0, 29, 0.1), 0 1px 2px rgba(0, 0, 0, 0.05);
|
|
2939
|
+
--st-lime: #bbda4c;
|
|
2940
|
+
--st-lime-hover: #c7e25f;
|
|
2941
|
+
--st-lime-ink: #2b3806;
|
|
2942
|
+
--st-frame: #ffffff;
|
|
2943
|
+
--st-frame-ring: 0 0 0 1px rgba(0, 0, 29, 0.1);
|
|
2944
|
+
--st-th: #fafaf8;
|
|
2945
|
+
--st-seg: #ececea;
|
|
2946
|
+
--st-seg-on-ring: 0 1px 2px rgba(0, 0, 0, 0.12), 0 0 0 1px rgba(0, 0, 29, 0.05);
|
|
2947
|
+
--st-icon: #3c6462;
|
|
2948
|
+
}
|
|
2949
|
+
.dark:not([data-shell-light]) .st-modal {
|
|
2932
2950
|
--st-rail: var(--bg-muted);
|
|
2933
2951
|
--st-rail-line: var(--border-subtle);
|
|
2934
2952
|
--st-rail-rule: var(--border-subtle);
|
|
@@ -2945,4 +2963,17 @@
|
|
|
2945
2963
|
--st-pick-dot: #3f9c7a;
|
|
2946
2964
|
--st-chip: var(--bg-muted);
|
|
2947
2965
|
--st-rule: var(--border-subtle);
|
|
2966
|
+
--st-ink-1: var(--text-primary);
|
|
2967
|
+
--st-btn: var(--bg-muted);
|
|
2968
|
+
--st-btn-hover: var(--interactive-hover);
|
|
2969
|
+
--st-btn-ring: var(--shadow-button);
|
|
2970
|
+
--st-lime: var(--brand-500, #bbda4c);
|
|
2971
|
+
--st-lime-hover: var(--brand-600, #c7e25f);
|
|
2972
|
+
--st-lime-ink: #ffffff;
|
|
2973
|
+
--st-frame: var(--bg-base);
|
|
2974
|
+
--st-frame-ring: 0 0 0 1px var(--border-subtle);
|
|
2975
|
+
--st-th: var(--bg-muted);
|
|
2976
|
+
--st-seg: var(--bg-muted);
|
|
2977
|
+
--st-seg-on-ring: var(--shadow-sm);
|
|
2978
|
+
--st-icon: var(--text-secondary);
|
|
2948
2979
|
}
|
|
@@ -184,36 +184,33 @@ function UnifiedSettingsModal({
|
|
|
184
184
|
})
|
|
185
185
|
] }, group.key))
|
|
186
186
|
] }),
|
|
187
|
-
/* @__PURE__ */ jsxs("div", { className: "mt-1.5 shrink-0 border-t border-[var(--st-rail-rule)] pt-2", children: [
|
|
188
|
-
legalRow && /* @__PURE__ */ jsxs(
|
|
189
|
-
"button",
|
|
190
|
-
{
|
|
191
|
-
type: "button",
|
|
192
|
-
"data-row": true,
|
|
193
|
-
"aria-current": legalRow.id === current?.id ? "page" : void 0,
|
|
194
|
-
onClick: () => {
|
|
195
|
-
setPicked(legalRow.id);
|
|
196
|
-
setView(null);
|
|
197
|
-
},
|
|
198
|
-
className: `${ROW_CLASS} ${legalRow.id === current?.id ? ROW_ON : ROW_IDLE}`,
|
|
199
|
-
children: [
|
|
200
|
-
/* @__PURE__ */ jsx(legalRow.icon, { className: "size-4 shrink-0", strokeWidth: 1.75 }),
|
|
201
|
-
/* @__PURE__ */ jsx("span", { className: "truncate", children: legalRow.name })
|
|
202
|
-
]
|
|
203
|
-
}
|
|
204
|
-
),
|
|
187
|
+
/* @__PURE__ */ jsxs("div", { className: "mt-1.5 flex shrink-0 items-center gap-1 border-t border-[var(--st-rail-rule)] pt-2", children: [
|
|
205
188
|
/* @__PURE__ */ jsxs(
|
|
206
189
|
Link,
|
|
207
190
|
{
|
|
208
191
|
href: HELP_HREF,
|
|
209
192
|
onClick: onClose,
|
|
210
|
-
className: `${ROW_CLASS} ${ROW_IDLE}`,
|
|
193
|
+
className: `${ROW_CLASS} ${ROW_IDLE} min-w-0 flex-1`,
|
|
211
194
|
children: [
|
|
212
195
|
/* @__PURE__ */ jsx(HelpIcon, { className: "size-4 shrink-0", strokeWidth: 1.75 }),
|
|
213
196
|
/* @__PURE__ */ jsx("span", { children: "Get help" }),
|
|
214
197
|
/* @__PURE__ */ jsx(ArrowUpRight, { className: "ml-auto size-[13px] shrink-0" })
|
|
215
198
|
]
|
|
216
199
|
}
|
|
200
|
+
),
|
|
201
|
+
legalRow && /* @__PURE__ */ jsx(
|
|
202
|
+
"button",
|
|
203
|
+
{
|
|
204
|
+
type: "button",
|
|
205
|
+
"data-row": true,
|
|
206
|
+
"aria-current": legalRow.id === current?.id ? "page" : void 0,
|
|
207
|
+
onClick: () => {
|
|
208
|
+
setPicked(legalRow.id);
|
|
209
|
+
setView(null);
|
|
210
|
+
},
|
|
211
|
+
className: `flex h-[34px] shrink-0 items-center rounded-[9px] px-2.5 text-[13.5px] font-medium transition-colors ${legalRow.id === current?.id ? ROW_ON : ROW_IDLE}`,
|
|
212
|
+
children: legalRow.name
|
|
213
|
+
}
|
|
217
214
|
)
|
|
218
215
|
] })
|
|
219
216
|
]
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/shell/unified-settings-modal.tsx"],"sourcesContent":["'use client';\n\nimport { Fragment, useEffect, useMemo, useRef, useState, type ReactNode } from 'react';\nimport Link from 'next/link';\nimport { ArrowUpRight, ChevronLeft, Search, X } from 'lucide-react';\nimport { useAnimate, useReducedMotion } from 'motion/react';\nimport { BusinessMark } from '@withpotter/ui-kit/business-mark';\nimport { Dialog, DialogClose, DialogContent, DialogTitle } from '@withpotter/ui-kit/dialog';\nimport { Input } from '@withpotter/ui-kit/input';\nimport { TextMorph } from '@withpotter/ui-kit/text-morph';\nimport {\n SettingsStatusSlot,\n SettingsSurface,\n} from '@withpotter/pages-core/dashboard/settings/_components/settings-ui';\nimport {\n SettingsDrillProvider,\n type SettingsDrill,\n} from '@withpotter/pages-core/dashboard/settings/_components/settings-drill';\nimport { useAuth } from '@withpotter/lib/auth-context';\nimport { usePermissions } from '@withpotter/lib/use-permissions';\nimport { SettingsPanel } from './settings-panels';\nimport { groupRows } from './settings-groups';\nimport { useSidebarCards } from './sidebar-cards';\nimport { hostRowForHref, useSettingsHostRows } from './settings-host';\nimport {\n HELP_HREF,\n HELP_ICON,\n SETTINGS_ROWS,\n matchRows,\n rowForHref,\n type SettingsRowId,\n} from './settings-rows';\n\n/** A row of the window: the shared ones, or one a host added with the screen to draw. */\ntype ShownRow = Omit<(typeof SETTINGS_ROWS)[number], 'id'> & {\n id: string;\n render?: () => ReactNode;\n};\n\n/**\n * A row of the rail: 34px tall, 13.5px, an icon 16px wide at 1.75 stroke. The values are the settings prototype's; the\n * colours come from the window's own palette (`.st-modal` in shell.css), which falls back to the theme in dark.\n */\nconst ROW_CLASS =\n 'mb-px flex h-[34px] w-full items-center gap-[11px] rounded-[9px] px-2 text-left text-[13.5px] font-medium leading-5 transition-colors';\nconst ROW_IDLE =\n 'text-[var(--st-ink-2)] hover:bg-[var(--st-row-hover)] hover:text-[var(--text-primary)]';\nconst ROW_ON =\n 'bg-[var(--bg-base)] text-[var(--text-primary)] shadow-[var(--st-row-on-ring)]';\n\n/**\n * Settings, yours and the business's, in one window.\n *\n * It is the account modal's shell (a rail on the left, the page on the right):\n * the business at the top of the rail with the plan it is on when the host says,\n * then the rows in two groups, Business and You. A search matches row names and the\n * sections inside them, so \"passkeys\" or \"time zone\" finds its row. Rows the\n * member may not open are not drawn. Get help leaves the window, so it carries\n * an arrow.\n *\n * It replaces the window that showed each page in a frame: the pages are drawn\n * here directly, so there is no second copy of the app running behind it.\n */\nexport function UnifiedSettingsModal({\n open,\n href,\n onClose,\n}: {\n open: boolean;\n /** A settings address to open on. A row's own page when it owns it. */\n href?: string | null;\n onClose: () => void;\n}) {\n const { can, loading } = usePermissions();\n const [query, setQuery] = useState('');\n // A level inside the open row (a policy's editor). Cleared when the row, or\n // the address the window was opened on, changes.\n const [view, setView] = useState<SettingsDrill['view']>(null);\n // The row chosen inside the window, and the address it was opened on, so\n // opening on a different address moves the selection (adjusted in render).\n const [picked, setPicked] = useState<string | null>(null);\n const [seen, setSeen] = useState<string | null | undefined>(undefined);\n if (open && seen !== href) {\n setSeen(href);\n setPicked(null);\n setQuery('');\n setView(null);\n }\n\n const host = useSettingsHostRows();\n const rows = useMemo(() => {\n const own: ShownRow[] = SETTINGS_ROWS.filter(\n (r) => !r.permission || loading || r.permission.some((p) => can(p)),\n );\n\n // A host's rows go where they say, or after General.\n return host.reduce<ShownRow[]>((list, extra) => {\n const at = list.findIndex((r) => r.id === (extra.after ?? 'general'));\n\n const into = at === -1 ? list.length : at + 1;\n\n return [...list.slice(0, into), extra, ...list.slice(into)];\n }, own);\n }, [can, loading, host]);\n const shown = matchRows(rows, query);\n // Legal is not on the rail: it sits at the foot, beside Get help.\n const railRows = shown.filter((r) => r.id !== 'legal');\n const legalRow = shown.find((r) => r.id === 'legal');\n\n const drill = useMemo<SettingsDrill>(\n () => ({\n view,\n open: (key, title) => setView({ key, title }),\n openRow: (row, key, title) => {\n setPicked(row as SettingsRowId);\n setView({ key, title });\n },\n back: () => setView(null),\n }),\n [view],\n );\n\n const wanted = picked ?? hostRowForHref(host, href)?.id ?? rowForHref(href);\n // An address that names a row the member cannot see falls to their first.\n const current = rows.find((r) => r.id === wanted) ?? rows[0];\n const HelpIcon = HELP_ICON;\n\n const [statusSlot, setStatusSlot] = useState<HTMLElement | null>(null);\n\n // The business the window is about, and the plan it is on when the host says (Olive does; other products say nothing).\n const { tenant } = useAuth();\n const planLabel = useSidebarCards()?.planLabel;\n const name = tenant?.businessName?.trim() ?? '';\n\n // Moving to another row, or into and out of a level inside one, brings the content in: it fades up from 8px below. The\n // content itself is not remounted, so a screen keeps its own state and scroll; only its wrapper moves.\n const [scope, animate] = useAnimate<HTMLDivElement>();\n const reduced = useReducedMotion();\n const shownKey = `${current?.id ?? ''}:${view?.key ?? ''}`;\n const lastKey = useRef(shownKey);\n\n useEffect(() => {\n if (lastKey.current === shownKey) return;\n\n lastKey.current = shownKey;\n\n if (reduced || !scope.current) return;\n\n void animate(scope.current, { opacity: [0, 1], y: [8, 0] }, { duration: 0.22, ease: [0.22, 1, 0.36, 1] });\n }, [shownKey, reduced, animate, scope]);\n\n return (\n <Dialog open={open} onOpenChange={(next) => !next && onClose()}>\n <DialogContent\n aria-label=\"Settings\"\n showClose={false}\n className=\"st-modal flex h-[min(640px,calc(100dvh-2.5rem))] w-[calc(100%-2.5rem)] max-w-[920px] gap-0 overflow-hidden rounded-2xl border-0 p-0 text-[13.5px] shadow-[0_24px_60px_-20px_rgba(18,18,34,0.45),0_0_0_1px_rgba(0,0,0,0.04)]\"\n >\n <nav\n aria-label=\"Settings sections\"\n onKeyDown={(e) => {\n // Up and Down move between the rows, like the account modal's rail.\n if (e.key !== 'ArrowDown' && e.key !== 'ArrowUp') return;\n const rowsEls = Array.from(\n e.currentTarget.querySelectorAll<HTMLElement>('button[data-row]'),\n );\n const at = rowsEls.indexOf(document.activeElement as HTMLElement);\n if (at === -1) return;\n e.preventDefault();\n const next =\n e.key === 'ArrowDown'\n ? (at + 1) % rowsEls.length\n : (at - 1 + rowsEls.length) % rowsEls.length;\n rowsEls[next].focus();\n }}\n className=\"flex w-[248px] shrink-0 flex-col overflow-hidden border-r border-[var(--st-rail-line)] bg-[var(--st-rail)] px-3 pb-2.5 pt-4\"\n >\n {name && (\n <div className=\"flex items-center gap-2.5 px-1.5 pb-3.5 pt-0.5\">\n <BusinessMark name={name} src={tenant?.businessLogo} size={34} />\n <div className=\"min-w-0\">\n <p className=\"max-w-[150px] truncate text-[14px] font-semibold leading-[18px] text-[var(--text-primary)]\">\n {name}\n </p>\n {planLabel && (\n <p className=\"truncate text-[12px] leading-4 text-[var(--st-ink-3)]\">\n {planLabel}\n </p>\n )}\n </div>\n </div>\n )}\n <div className=\"mb-1.5 flex h-8 shrink-0 items-center gap-2 rounded-[10px] bg-[var(--bg-base)] px-2.5 text-[var(--st-ink-3)] shadow-[var(--st-search-ring)] focus-within:text-[var(--text-primary)]\">\n <Search className=\"size-[15px] shrink-0\" strokeWidth={1.8} />\n <Input\n variant=\"bare\"\n value={query}\n onChange={(e) => setQuery(e.target.value)}\n placeholder=\"Search settings\"\n aria-label=\"Search settings\"\n className=\"min-w-0 flex-1\"\n />\n </div>\n <div className=\"-mx-1 min-h-0 flex-1 overflow-y-auto px-1\">\n {shown.length === 0 && (\n <p className=\"px-2 py-2 text-[13px] text-[var(--st-ink-3)]\">\n Nothing matches “{query}”.\n </p>\n )}\n {groupRows(railRows).map((group) => (\n <Fragment key={group.key}>\n <p className=\"px-2 pb-1.5 pt-3.5 text-[12px] font-medium leading-5 text-[var(--st-ink-4)]\">\n {group.label}\n </p>\n {group.rows.map((r) => {\n const selected = r.id === current?.id;\n const Icon = r.icon;\n if (r.href) {\n return (\n <Link\n key={r.id}\n data-row\n href={r.href}\n onClick={onClose}\n className={`${ROW_CLASS} ${ROW_IDLE}`}\n >\n <Icon className=\"size-4 shrink-0\" strokeWidth={1.75} />\n <span className=\"truncate\">{r.name}</span>\n <ArrowUpRight className=\"ml-auto size-[13px] shrink-0 opacity-[.55]\" />\n </Link>\n );\n }\n return (\n <button\n key={r.id}\n data-row\n type=\"button\"\n aria-current={selected ? 'page' : undefined}\n onClick={() => {\n setPicked(r.id);\n setView(null);\n }}\n className={`${ROW_CLASS} ${selected ? ROW_ON : ROW_IDLE}`}\n >\n <Icon className=\"size-4 shrink-0\" strokeWidth={1.75} />\n <span className=\"truncate\">{r.name}</span>\n </button>\n );\n })}\n </Fragment>\n ))}\n </div>\n <div className=\"mt-1.5 shrink-0 border-t border-[var(--st-rail-rule)] pt-2\">\n {legalRow && (\n <button\n type=\"button\"\n data-row\n aria-current={legalRow.id === current?.id ? 'page' : undefined}\n onClick={() => {\n setPicked(legalRow.id);\n setView(null);\n }}\n className={`${ROW_CLASS} ${legalRow.id === current?.id ? ROW_ON : ROW_IDLE}`}\n >\n <legalRow.icon className=\"size-4 shrink-0\" strokeWidth={1.75} />\n <span className=\"truncate\">{legalRow.name}</span>\n </button>\n )}\n <Link\n href={HELP_HREF}\n onClick={onClose}\n className={`${ROW_CLASS} ${ROW_IDLE}`}\n >\n <HelpIcon className=\"size-4 shrink-0\" strokeWidth={1.75} />\n <span>Get help</span>\n <ArrowUpRight className=\"ml-auto size-[13px] shrink-0\" />\n </Link>\n </div>\n </nav>\n\n <div className=\"flex min-w-0 flex-1 flex-col\">\n <div className=\"flex flex-none items-start justify-between pb-4 pl-10 pr-6 pt-5\">\n <div className=\"min-w-0\">\n {view && (\n <button\n type=\"button\"\n onClick={drill.back}\n aria-label={`Back to ${current?.name ?? 'Settings'}`}\n className=\"-ml-0.5 mb-1.5 inline-flex items-center gap-1 text-[13px] font-medium text-[var(--st-ink-2)] transition-colors hover:text-[var(--text-primary)]\"\n >\n <ChevronLeft className=\"size-[15px]\" strokeWidth={2} />\n {current?.name ?? 'Settings'}\n </button>\n )}\n <DialogTitle\n aria-label={view?.title ?? current?.name ?? 'Settings'}\n className=\"truncate text-[18px] font-semibold leading-6 tracking-[-0.01em] text-[var(--text-primary)]\"\n >\n <TextMorph as=\"span\">\n {view?.title ?? current?.name ?? 'Settings'}\n </TextMorph>\n </DialogTitle>\n {!view && current?.subtitle && (\n <p className=\"mt-0.5 text-[13px] leading-[18px] text-[var(--st-ink-3)]\">\n {current.subtitle}\n </p>\n )}\n </div>\n <div className=\"flex items-center gap-2.5\">\n <div ref={setStatusSlot} className=\"flex items-center\" />\n <DialogClose\n aria-label=\"Close\"\n className=\"grid size-8 place-items-center rounded-[9px] text-[var(--st-ink-2)] transition-colors hover:bg-[var(--st-row-hover)] hover:text-[var(--text-primary)] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--focus-ring)]\"\n >\n <X className=\"size-[18px]\" strokeWidth={2} />\n </DialogClose>\n </div>\n </div>\n <div className=\"min-h-0 flex-1 overflow-y-auto px-6 pb-7 outline-none\">\n <div ref={scope}>\n {current && (\n <SettingsDrillProvider value={drill}>\n <SettingsSurface variant=\"plain\">\n <SettingsStatusSlot element={statusSlot}>\n {current.render ? (\n current.render()\n ) : (\n <SettingsPanel\n key={current.id}\n id={current.id as SettingsRowId}\n />\n )}\n </SettingsStatusSlot>\n </SettingsSurface>\n </SettingsDrillProvider>\n )}\n </div>\n </div>\n </div>\n </DialogContent>\n </Dialog>\n );\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/shell/unified-settings-modal.tsx"],"sourcesContent":["'use client';\n\nimport { Fragment, useEffect, useMemo, useRef, useState, type ReactNode } from 'react';\nimport Link from 'next/link';\nimport { ArrowUpRight, ChevronLeft, Search, X } from 'lucide-react';\nimport { useAnimate, useReducedMotion } from 'motion/react';\nimport { BusinessMark } from '@withpotter/ui-kit/business-mark';\nimport { Dialog, DialogClose, DialogContent, DialogTitle } from '@withpotter/ui-kit/dialog';\nimport { Input } from '@withpotter/ui-kit/input';\nimport { TextMorph } from '@withpotter/ui-kit/text-morph';\nimport {\n SettingsStatusSlot,\n SettingsSurface,\n} from '@withpotter/pages-core/dashboard/settings/_components/settings-ui';\nimport {\n SettingsDrillProvider,\n type SettingsDrill,\n} from '@withpotter/pages-core/dashboard/settings/_components/settings-drill';\nimport { useAuth } from '@withpotter/lib/auth-context';\nimport { usePermissions } from '@withpotter/lib/use-permissions';\nimport { SettingsPanel } from './settings-panels';\nimport { groupRows } from './settings-groups';\nimport { useSidebarCards } from './sidebar-cards';\nimport { hostRowForHref, useSettingsHostRows } from './settings-host';\nimport {\n HELP_HREF,\n HELP_ICON,\n SETTINGS_ROWS,\n matchRows,\n rowForHref,\n type SettingsRowId,\n} from './settings-rows';\n\n/** A row of the window: the shared ones, or one a host added with the screen to draw. */\ntype ShownRow = Omit<(typeof SETTINGS_ROWS)[number], 'id'> & {\n id: string;\n render?: () => ReactNode;\n};\n\n/**\n * A row of the rail: 34px tall, 13.5px, an icon 16px wide at 1.75 stroke. The values are the settings prototype's; the\n * colours come from the window's own palette (`.st-modal` in shell.css), which falls back to the theme in dark.\n */\nconst ROW_CLASS =\n 'mb-px flex h-[34px] w-full items-center gap-[11px] rounded-[9px] px-2 text-left text-[13.5px] font-medium leading-5 transition-colors';\nconst ROW_IDLE =\n 'text-[var(--st-ink-2)] hover:bg-[var(--st-row-hover)] hover:text-[var(--text-primary)]';\nconst ROW_ON =\n 'bg-[var(--bg-base)] text-[var(--text-primary)] shadow-[var(--st-row-on-ring)]';\n\n/**\n * Settings, yours and the business's, in one window.\n *\n * It is the account modal's shell (a rail on the left, the page on the right):\n * the business at the top of the rail with the plan it is on when the host says,\n * then the rows in two groups, Business and You. A search matches row names and the\n * sections inside them, so \"passkeys\" or \"time zone\" finds its row. Rows the\n * member may not open are not drawn. Get help leaves the window, so it carries\n * an arrow.\n *\n * It replaces the window that showed each page in a frame: the pages are drawn\n * here directly, so there is no second copy of the app running behind it.\n */\nexport function UnifiedSettingsModal({\n open,\n href,\n onClose,\n}: {\n open: boolean;\n /** A settings address to open on. A row's own page when it owns it. */\n href?: string | null;\n onClose: () => void;\n}) {\n const { can, loading } = usePermissions();\n const [query, setQuery] = useState('');\n // A level inside the open row (a policy's editor). Cleared when the row, or\n // the address the window was opened on, changes.\n const [view, setView] = useState<SettingsDrill['view']>(null);\n // The row chosen inside the window, and the address it was opened on, so\n // opening on a different address moves the selection (adjusted in render).\n const [picked, setPicked] = useState<string | null>(null);\n const [seen, setSeen] = useState<string | null | undefined>(undefined);\n if (open && seen !== href) {\n setSeen(href);\n setPicked(null);\n setQuery('');\n setView(null);\n }\n\n const host = useSettingsHostRows();\n const rows = useMemo(() => {\n const own: ShownRow[] = SETTINGS_ROWS.filter(\n (r) => !r.permission || loading || r.permission.some((p) => can(p)),\n );\n\n // A host's rows go where they say, or after General.\n return host.reduce<ShownRow[]>((list, extra) => {\n const at = list.findIndex((r) => r.id === (extra.after ?? 'general'));\n\n const into = at === -1 ? list.length : at + 1;\n\n return [...list.slice(0, into), extra, ...list.slice(into)];\n }, own);\n }, [can, loading, host]);\n const shown = matchRows(rows, query);\n // Legal is not on the rail: it sits at the foot, beside Get help.\n const railRows = shown.filter((r) => r.id !== 'legal');\n const legalRow = shown.find((r) => r.id === 'legal');\n\n const drill = useMemo<SettingsDrill>(\n () => ({\n view,\n open: (key, title) => setView({ key, title }),\n openRow: (row, key, title) => {\n setPicked(row as SettingsRowId);\n setView({ key, title });\n },\n back: () => setView(null),\n }),\n [view],\n );\n\n const wanted = picked ?? hostRowForHref(host, href)?.id ?? rowForHref(href);\n // An address that names a row the member cannot see falls to their first.\n const current = rows.find((r) => r.id === wanted) ?? rows[0];\n const HelpIcon = HELP_ICON;\n\n const [statusSlot, setStatusSlot] = useState<HTMLElement | null>(null);\n\n // The business the window is about, and the plan it is on when the host says (Olive does; other products say nothing).\n const { tenant } = useAuth();\n const planLabel = useSidebarCards()?.planLabel;\n const name = tenant?.businessName?.trim() ?? '';\n\n // Moving to another row, or into and out of a level inside one, brings the content in: it fades up from 8px below. The\n // content itself is not remounted, so a screen keeps its own state and scroll; only its wrapper moves.\n const [scope, animate] = useAnimate<HTMLDivElement>();\n const reduced = useReducedMotion();\n const shownKey = `${current?.id ?? ''}:${view?.key ?? ''}`;\n const lastKey = useRef(shownKey);\n\n useEffect(() => {\n if (lastKey.current === shownKey) return;\n\n lastKey.current = shownKey;\n\n if (reduced || !scope.current) return;\n\n void animate(scope.current, { opacity: [0, 1], y: [8, 0] }, { duration: 0.22, ease: [0.22, 1, 0.36, 1] });\n }, [shownKey, reduced, animate, scope]);\n\n return (\n <Dialog open={open} onOpenChange={(next) => !next && onClose()}>\n <DialogContent\n aria-label=\"Settings\"\n showClose={false}\n className=\"st-modal flex h-[min(640px,calc(100dvh-2.5rem))] w-[calc(100%-2.5rem)] max-w-[920px] gap-0 overflow-hidden rounded-2xl border-0 p-0 text-[13.5px] shadow-[0_24px_60px_-20px_rgba(18,18,34,0.45),0_0_0_1px_rgba(0,0,0,0.04)]\"\n >\n <nav\n aria-label=\"Settings sections\"\n onKeyDown={(e) => {\n // Up and Down move between the rows, like the account modal's rail.\n if (e.key !== 'ArrowDown' && e.key !== 'ArrowUp') return;\n const rowsEls = Array.from(\n e.currentTarget.querySelectorAll<HTMLElement>('button[data-row]'),\n );\n const at = rowsEls.indexOf(document.activeElement as HTMLElement);\n if (at === -1) return;\n e.preventDefault();\n const next =\n e.key === 'ArrowDown'\n ? (at + 1) % rowsEls.length\n : (at - 1 + rowsEls.length) % rowsEls.length;\n rowsEls[next].focus();\n }}\n className=\"flex w-[248px] shrink-0 flex-col overflow-hidden border-r border-[var(--st-rail-line)] bg-[var(--st-rail)] px-3 pb-2.5 pt-4\"\n >\n {name && (\n <div className=\"flex items-center gap-2.5 px-1.5 pb-3.5 pt-0.5\">\n <BusinessMark name={name} src={tenant?.businessLogo} size={34} />\n <div className=\"min-w-0\">\n <p className=\"max-w-[150px] truncate text-[14px] font-semibold leading-[18px] text-[var(--text-primary)]\">\n {name}\n </p>\n {planLabel && (\n <p className=\"truncate text-[12px] leading-4 text-[var(--st-ink-3)]\">\n {planLabel}\n </p>\n )}\n </div>\n </div>\n )}\n <div className=\"mb-1.5 flex h-8 shrink-0 items-center gap-2 rounded-[10px] bg-[var(--bg-base)] px-2.5 text-[var(--st-ink-3)] shadow-[var(--st-search-ring)] focus-within:text-[var(--text-primary)]\">\n <Search className=\"size-[15px] shrink-0\" strokeWidth={1.8} />\n <Input\n variant=\"bare\"\n value={query}\n onChange={(e) => setQuery(e.target.value)}\n placeholder=\"Search settings\"\n aria-label=\"Search settings\"\n className=\"min-w-0 flex-1\"\n />\n </div>\n <div className=\"-mx-1 min-h-0 flex-1 overflow-y-auto px-1\">\n {shown.length === 0 && (\n <p className=\"px-2 py-2 text-[13px] text-[var(--st-ink-3)]\">\n Nothing matches “{query}”.\n </p>\n )}\n {groupRows(railRows).map((group) => (\n <Fragment key={group.key}>\n <p className=\"px-2 pb-1.5 pt-3.5 text-[12px] font-medium leading-5 text-[var(--st-ink-4)]\">\n {group.label}\n </p>\n {group.rows.map((r) => {\n const selected = r.id === current?.id;\n const Icon = r.icon;\n if (r.href) {\n return (\n <Link\n key={r.id}\n data-row\n href={r.href}\n onClick={onClose}\n className={`${ROW_CLASS} ${ROW_IDLE}`}\n >\n <Icon className=\"size-4 shrink-0\" strokeWidth={1.75} />\n <span className=\"truncate\">{r.name}</span>\n <ArrowUpRight className=\"ml-auto size-[13px] shrink-0 opacity-[.55]\" />\n </Link>\n );\n }\n return (\n <button\n key={r.id}\n data-row\n type=\"button\"\n aria-current={selected ? 'page' : undefined}\n onClick={() => {\n setPicked(r.id);\n setView(null);\n }}\n className={`${ROW_CLASS} ${selected ? ROW_ON : ROW_IDLE}`}\n >\n <Icon className=\"size-4 shrink-0\" strokeWidth={1.75} />\n <span className=\"truncate\">{r.name}</span>\n </button>\n );\n })}\n </Fragment>\n ))}\n </div>\n {/* The foot is one row, as in the prototype: Get help, with Legal beside it so it stays one press away without\n taking a row of its own (a second row pushed the last rail rows out of view). */}\n <div className=\"mt-1.5 flex shrink-0 items-center gap-1 border-t border-[var(--st-rail-rule)] pt-2\">\n <Link\n href={HELP_HREF}\n onClick={onClose}\n className={`${ROW_CLASS} ${ROW_IDLE} min-w-0 flex-1`}\n >\n <HelpIcon className=\"size-4 shrink-0\" strokeWidth={1.75} />\n <span>Get help</span>\n <ArrowUpRight className=\"ml-auto size-[13px] shrink-0\" />\n </Link>\n {legalRow && (\n <button\n type=\"button\"\n data-row\n aria-current={legalRow.id === current?.id ? 'page' : undefined}\n onClick={() => {\n setPicked(legalRow.id);\n setView(null);\n }}\n className={`flex h-[34px] shrink-0 items-center rounded-[9px] px-2.5 text-[13.5px] font-medium transition-colors ${legalRow.id === current?.id ? ROW_ON : ROW_IDLE}`}\n >\n {legalRow.name}\n </button>\n )}\n </div>\n </nav>\n\n <div className=\"flex min-w-0 flex-1 flex-col\">\n <div className=\"flex flex-none items-start justify-between pb-4 pl-10 pr-6 pt-5\">\n <div className=\"min-w-0\">\n {view && (\n <button\n type=\"button\"\n onClick={drill.back}\n aria-label={`Back to ${current?.name ?? 'Settings'}`}\n className=\"-ml-0.5 mb-1.5 inline-flex items-center gap-1 text-[13px] font-medium text-[var(--st-ink-2)] transition-colors hover:text-[var(--text-primary)]\"\n >\n <ChevronLeft className=\"size-[15px]\" strokeWidth={2} />\n {current?.name ?? 'Settings'}\n </button>\n )}\n <DialogTitle\n aria-label={view?.title ?? current?.name ?? 'Settings'}\n className=\"truncate text-[18px] font-semibold leading-6 tracking-[-0.01em] text-[var(--text-primary)]\"\n >\n <TextMorph as=\"span\">\n {view?.title ?? current?.name ?? 'Settings'}\n </TextMorph>\n </DialogTitle>\n {!view && current?.subtitle && (\n <p className=\"mt-0.5 text-[13px] leading-[18px] text-[var(--st-ink-3)]\">\n {current.subtitle}\n </p>\n )}\n </div>\n <div className=\"flex items-center gap-2.5\">\n <div ref={setStatusSlot} className=\"flex items-center\" />\n <DialogClose\n aria-label=\"Close\"\n className=\"grid size-8 place-items-center rounded-[9px] text-[var(--st-ink-2)] transition-colors hover:bg-[var(--st-row-hover)] hover:text-[var(--text-primary)] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--focus-ring)]\"\n >\n <X className=\"size-[18px]\" strokeWidth={2} />\n </DialogClose>\n </div>\n </div>\n <div className=\"min-h-0 flex-1 overflow-y-auto px-6 pb-7 outline-none\">\n <div ref={scope}>\n {current && (\n <SettingsDrillProvider value={drill}>\n <SettingsSurface variant=\"plain\">\n <SettingsStatusSlot element={statusSlot}>\n {current.render ? (\n current.render()\n ) : (\n <SettingsPanel\n key={current.id}\n id={current.id as SettingsRowId}\n />\n )}\n </SettingsStatusSlot>\n </SettingsSurface>\n </SettingsDrillProvider>\n )}\n </div>\n </div>\n </div>\n </DialogContent>\n </Dialog>\n );\n}\n"],"mappings":"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","names":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@withpotter/components",
|
|
3
|
-
"version": "0.13.0-next.
|
|
3
|
+
"version": "0.13.0-next.112",
|
|
4
4
|
"description": "Box dashboard feature components: editors, mobile screens, pickers, and composite UI built on @withpotter/ui-kit.",
|
|
5
5
|
"license": "UNLICENSED",
|
|
6
6
|
"sideEffects": [
|
|
@@ -50,9 +50,9 @@
|
|
|
50
50
|
"@tiptap/react": "^3.22.5",
|
|
51
51
|
"@tiptap/starter-kit": "^3.22.5",
|
|
52
52
|
"@tiptap/suggestion": "^3.22.5",
|
|
53
|
-
"@withpotter/hooks": "^0.13.0-next.
|
|
54
|
-
"@withpotter/lib": "^0.13.0-next.
|
|
55
|
-
"@withpotter/ui-kit": "^0.13.0-next.
|
|
53
|
+
"@withpotter/hooks": "^0.13.0-next.112",
|
|
54
|
+
"@withpotter/lib": "^0.13.0-next.112",
|
|
55
|
+
"@withpotter/ui-kit": "^0.13.0-next.112",
|
|
56
56
|
"@xyflow/react": "^12.11.2",
|
|
57
57
|
"dompurify": "^3.3.1",
|
|
58
58
|
"jsqr": "1.4.0",
|