@av-pi-studio/ui-library 0.0.0-stage → 0.0.115
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/CHANGELOG.md +24 -0
- package/README.md +137 -2
- package/dist/brand/config.d.ts +125 -0
- package/dist/brand/index.d.ts +3 -0
- package/dist/brand/index.js +6 -0
- package/dist/brand/theme-injection.d.ts +9 -0
- package/dist/breakpoints.d.ts +34 -0
- package/dist/breakpoints.js +32 -0
- package/dist/chunks/theme-injection-BHAAhBYz.js +103 -0
- package/dist/chunks/token-guard-B85Ysv3w.js +813 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.js +1049 -0
- package/dist/kv-store.d.ts +3 -0
- package/dist/primitives/Announcer.d.ts +13 -0
- package/dist/primitives/Avatar.d.ts +15 -0
- package/dist/primitives/Button.d.ts +18 -0
- package/dist/primitives/Checkbox.d.ts +11 -0
- package/dist/primitives/Dialog.d.ts +58 -0
- package/dist/primitives/Divider.d.ts +10 -0
- package/dist/primitives/EmptyState.d.ts +11 -0
- package/dist/primitives/Icon.d.ts +20 -0
- package/dist/primitives/IconButton.d.ts +25 -0
- package/dist/primitives/Menu.d.ts +50 -0
- package/dist/primitives/Panel.d.ts +9 -0
- package/dist/primitives/Popover.d.ts +25 -0
- package/dist/primitives/ResizeHandle.d.ts +20 -0
- package/dist/primitives/ScreenTitle.d.ts +15 -0
- package/dist/primitives/ScrollArea.d.ts +11 -0
- package/dist/primitives/Select.d.ts +25 -0
- package/dist/primitives/Shortcut.d.ts +15 -0
- package/dist/primitives/Spinner.d.ts +14 -0
- package/dist/primitives/StatusBadge.d.ts +13 -0
- package/dist/primitives/StatusDot.d.ts +17 -0
- package/dist/primitives/Surface.d.ts +13 -0
- package/dist/primitives/Switch.d.ts +14 -0
- package/dist/primitives/TextInput.d.ts +14 -0
- package/dist/primitives/ToastViewport.d.ts +17 -0
- package/dist/primitives/helpers.d.ts +47 -0
- package/dist/primitives/index.d.ts +24 -0
- package/dist/primitives/useHover.d.ts +16 -0
- package/dist/reset.css +43 -0
- package/dist/stores/announcer-store.d.ts +37 -0
- package/dist/stores/toast-store.d.ts +37 -0
- package/dist/styles.css +1 -0
- package/dist/theme/ThemeBoundary.d.ts +38 -0
- package/dist/theme/appearance-store.d.ts +37 -0
- package/dist/theme/color-utils.d.ts +13 -0
- package/dist/theme/colors.d.ts +111 -0
- package/dist/theme/css-bridge.d.ts +21 -0
- package/dist/theme/dev-warnings.d.ts +23 -0
- package/dist/theme/index.d.ts +10 -0
- package/dist/theme/index.js +39 -0
- package/dist/theme/palette.d.ts +19 -0
- package/dist/theme/theme.d.ts +47 -0
- package/dist/theme/token-guard.d.ts +20 -0
- package/dist/theme/tokens.d.ts +105 -0
- package/dist/theme/variants.d.ts +12 -0
- package/dist/ui/avatar.d.ts +11 -0
- package/dist/ui/button.d.ts +34 -0
- package/dist/ui/combobox.d.ts +55 -0
- package/dist/ui/index.d.ts +10 -0
- package/dist/ui/index.js +406 -0
- package/dist/ui/option-groups.d.ts +36 -0
- package/dist/ui/screen-header.d.ts +23 -0
- package/dist/ui/shortcut.d.ts +13 -0
- package/dist/ui/status-badge.d.ts +15 -0
- package/dist/ui/status-dot.d.ts +20 -0
- package/dist/ui/toast.d.ts +60 -0
- package/package.json +68 -4
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Announcer store — the single visually-hidden `aria-live` region's current text
|
|
3
|
+
* (sprint-069/task-008, § 08/§ 11). One region for the whole app, not one per row/tab/header, so a
|
|
4
|
+
* pending-question transition, a `notify` effect, or a background `set_editor_text` replacement
|
|
5
|
+
* are all heard the same way regardless of which session or pane produced them.
|
|
6
|
+
*
|
|
7
|
+
* `announce.ts` (§ 08 pending-question transitions) and `agent-ui-store.ts`'s `notifyEffect`/
|
|
8
|
+
* `composerTextEffect` (§ 11) are this store's only writers, via `speak`/`clearWhenIdle` below —
|
|
9
|
+
* never `useAnnouncerStore.setState` directly from elsewhere.
|
|
10
|
+
*/
|
|
11
|
+
export type AnnouncementPoliteness = "polite" | "assertive";
|
|
12
|
+
interface AnnouncerStoreState {
|
|
13
|
+
message: string;
|
|
14
|
+
politeness: AnnouncementPoliteness;
|
|
15
|
+
}
|
|
16
|
+
export declare const useAnnouncerStore: import("zustand").UseBoundStore<import("zustand").StoreApi<AnnouncerStoreState>>;
|
|
17
|
+
/** § 08 "nothing pending anywhere: region emptied, nothing spoken" — the delay between the last
|
|
18
|
+
* resolution's own announcement (if any fired in the same commit) and the region being emptied.
|
|
19
|
+
* Emptying it in the *same* synchronous update as the resolution's `speak()` would let React
|
|
20
|
+
* coalesce both `setState` calls into one commit, so the intermediate "Answered in …" text would
|
|
21
|
+
* never actually reach the DOM for a screen reader to read — this delay is what makes the
|
|
22
|
+
* resolution announcement itself observable before the region goes quiet. */
|
|
23
|
+
export declare const ANNOUNCE_CLEAR_DELAY_MS = 4000;
|
|
24
|
+
/** Sets the live region's current text. A fresh announcement always pre-empts any clear scheduled
|
|
25
|
+
* by an earlier `clearWhenIdle` call — a new pending question arriving inside the clear delay
|
|
26
|
+
* above must not be silently wiped out by it. */
|
|
27
|
+
export declare function speak(text: string, politeness?: AnnouncementPoliteness): void;
|
|
28
|
+
/** Schedules the region to empty itself once nothing is pending anywhere. See
|
|
29
|
+
* `ANNOUNCE_CLEAR_DELAY_MS` for why this is deferred rather than immediate. Calling this again
|
|
30
|
+
* before the timer fires (e.g. two sessions both clear out in quick succession) simply restarts
|
|
31
|
+
* the same delay rather than stacking timers. */
|
|
32
|
+
export declare function clearWhenIdle(): void;
|
|
33
|
+
/** Test-only: reset to initial state and cancel any pending timer, so one test's scheduled clear
|
|
34
|
+
* cannot fire during a later, unrelated test. */
|
|
35
|
+
export declare function resetAnnouncerStoreForTests(): void;
|
|
36
|
+
export {};
|
|
37
|
+
//# sourceMappingURL=announcer-store.d.ts.map
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Toast store — sprint-069/task-005, the first consumer of `ui/toast.ts`'s previously-unimported
|
|
3
|
+
* logic. Owns queueing/stacking/dismissal decisions (plain data, testable under Node) plus the
|
|
4
|
+
* real dismiss timers (`setTimeout`, kept in a module-level `Map` — a timer handle is not display
|
|
5
|
+
* data, so it never enters the reactive state; mirrors `agent-ui-store.ts`'s module-level cache
|
|
6
|
+
* convention for the identical reason).
|
|
7
|
+
*
|
|
8
|
+
* Stacking (§ 11): at most `MAX_VISIBLE_TOASTS` are ever visible. `toasts` is the full FIFO queue,
|
|
9
|
+
* oldest first; `toasts.slice(0, MAX_VISIBLE_TOASTS)` is what's actually shown —
|
|
10
|
+
* `ToastViewport.tsx` renders exactly that slice, and the store itself never trims the array. A
|
|
11
|
+
* queued (not-yet-visible) entry's dismiss countdown starts the moment it is *promoted* into a
|
|
12
|
+
* visible slot, not at `show()` time — `promoteIfNewlyVisible` resets `shownAt` to that instant, so
|
|
13
|
+
* a toast that waited behind others still gets its full nominal duration once actually shown.
|
|
14
|
+
*
|
|
15
|
+
* "Top" — what `dismissTop()` (Esc) removes, and the visually topmost slot in the top-anchored
|
|
16
|
+
* viewport — is `toasts[0]`, the longest-visible entry; new toasts append below it, growing the
|
|
17
|
+
* stack downward from the anchor edge.
|
|
18
|
+
*/
|
|
19
|
+
import { type ToastEntry, type ToastOptions } from "../ui/toast.js";
|
|
20
|
+
export declare const MAX_VISIBLE_TOASTS = 3;
|
|
21
|
+
interface ToastStoreState {
|
|
22
|
+
toasts: ToastEntry[];
|
|
23
|
+
show(content: string, opts?: ToastOptions): string;
|
|
24
|
+
copied(label?: string): string;
|
|
25
|
+
error(message: string): string;
|
|
26
|
+
dismiss(id: string): void;
|
|
27
|
+
dismissTop(): void;
|
|
28
|
+
pause(id: string): void;
|
|
29
|
+
resume(id: string): void;
|
|
30
|
+
}
|
|
31
|
+
export declare const useToastStore: import("zustand").UseBoundStore<import("zustand").StoreApi<ToastStoreState>>;
|
|
32
|
+
/** Test-only: clears live timers and resets state — a fresh `useToastStore.setState({ toasts: [] })`
|
|
33
|
+
* alone would leak `timers`/`nextId` across test cases, the same class of bug `test/reset-stores.ts`'s
|
|
34
|
+
* header comment warns about for every other store. */
|
|
35
|
+
export declare function resetToastStoreForTests(): void;
|
|
36
|
+
export {};
|
|
37
|
+
//# sourceMappingURL=toast-store.d.ts.map
|
package/dist/styles.css
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
:root{--piui-stylesheet: 1}.piui-Button_btn_Gurhr{display:inline-flex;align-items:center;justify-content:center;gap:var(--pi-spacing-8);border-radius:var(--pi-radius-lg);border:1px solid transparent;font-family:var(--pi-font-ui);font-weight:500;cursor:pointer;user-select:none;white-space:nowrap;text-decoration:none;outline:none;transition:opacity .12s ease,background-color .12s ease,border-color .12s ease;box-sizing:border-box}.piui-Button_btn_Gurhr:focus-visible{outline:2px solid var(--pi-color-accent);outline-offset:2px}.piui-Button_btn_Gurhr:disabled,.piui-Button_btn_Gurhr[aria-disabled=true]{cursor:not-allowed;pointer-events:none}.piui-Button_default_6Na6E{background-color:var(--pi-color-accent);color:var(--pi-color-accentForeground);border-color:var(--pi-color-accent)}.piui-Button_default_6Na6E:hover:not(:disabled){filter:brightness(1.08)}.piui-Button_secondary_RrsWU{background-color:var(--pi-color-surface3);color:var(--pi-color-foreground);border-color:var(--pi-color-border)}.piui-Button_secondary_RrsWU:hover:not(:disabled){background-color:var(--pi-color-surface2)}.piui-Button_outline_u49OM{background-color:transparent;color:var(--pi-color-accentBright);border-color:var(--pi-color-accent)}.piui-Button_outline_u49OM:hover:not(:disabled){background-color:var(--pi-color-surface1)}.piui-Button_ghost_4QL_5{background-color:transparent;color:var(--pi-color-foregroundMuted);border-color:transparent}.piui-Button_ghost_4QL_5:hover:not(:disabled){color:var(--pi-color-foreground);background-color:var(--pi-color-surface1)}.piui-Button_destructive_BMEqt{background-color:var(--pi-color-destructive);color:var(--pi-color-destructiveForeground);border-color:var(--pi-color-destructive)}.piui-Button_destructive_BMEqt:hover:not(:disabled){filter:brightness(1.1)}.piui-Button_iconOnly_7pcHE{padding-left:0!important;padding-right:0!important;aspect-ratio:1}.piui-Button_loadingSpinner_4QsZM{animation:piui-Button_piSpin_jrY7S .75s linear infinite;flex-shrink:0}@keyframes piui-Button_piSpin_jrY7S{0%{transform:rotate(0)}to{transform:rotate(360deg)}}@media(prefers-reduced-motion:reduce){.piui-Button_loadingSpinner_4QsZM{animation:none}}.piui-IconButton_iconBtn_1pjCh{display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;padding:0;background:none;border:none;border-radius:var(--pi-radius-base);color:var(--pi-color-foregroundMuted);cursor:pointer}.piui-IconButton_iconBtn_1pjCh:hover{color:var(--pi-color-foreground);background:color-mix(in srgb,var(--icon-btn-hover-base, var(--pi-color-surface1)) 85%,var(--pi-color-foreground) 15%)}.piui-IconButton_iconBtn_1pjCh:focus-visible{outline:2px solid var(--pi-color-accent);outline-offset:2px}.piui-IconButton_iconBtn_1pjCh:disabled{opacity:.4;cursor:default}.piui-IconButton_xs_XuhGZ{width:20px;height:20px}.piui-IconButton_sm_K4UxD{width:28px;height:28px}.piui-StatusDot_dot_FazEE{display:inline-block;width:8px;height:8px;border-radius:var(--pi-radius-full);flex-shrink:0}.piui-StatusDot_spinner_6EanG{display:inline-block;width:var(--status-dot-size, 12px);height:var(--status-dot-size, 12px);border-radius:var(--pi-radius-full);border:var(--status-dot-border-width, 2px) solid var(--pi-color-border);flex-shrink:0;animation:piui-StatusDot_statusSpin_SLBl_ .7s linear infinite}@keyframes piui-StatusDot_statusSpin_SLBl_{to{transform:rotate(360deg)}}.piui-StatusDot_pulse_6SVAx{animation:piui-StatusDot_statusDotPulse_3EXPH 1.8s ease-in-out infinite}@keyframes piui-StatusDot_statusDotPulse_3EXPH{0%{box-shadow:0 0 color-mix(in srgb,var(--pi-color-statusWarning) 55%,transparent)}to{box-shadow:0 0 0 4px transparent}}@media(prefers-reduced-motion:reduce){.piui-StatusDot_pulse_6SVAx{animation:none}}.piui-StatusBadge_badge_dpv2y{display:inline-flex;align-items:center;justify-content:center;padding:var(--pi-spacing-1) var(--pi-spacing-6);border-radius:var(--pi-radius-full);border:1px solid;font-size:var(--pi-font-size-xs);font-family:var(--pi-font-ui);font-weight:500;white-space:nowrap;line-height:1.5}.piui-Avatar_avatar_tU-uh{display:inline-flex;align-items:center;justify-content:center;overflow:hidden;border-radius:var(--pi-radius-md);flex-shrink:0;user-select:none}.piui-Avatar_avatarImg_Hvsfw{width:100%;height:100%;object-fit:cover}.piui-Avatar_avatarFallback_D9Coh{font-weight:600;color:#fff;font-family:var(--pi-font-ui);line-height:1}.piui-Shortcut_row_wIVo8{display:inline-flex;align-items:center;gap:var(--pi-spacing-4);flex-wrap:wrap}.piui-Shortcut_chip_7oXln{display:inline-flex;align-items:center;justify-content:center;padding:var(--pi-spacing-1) var(--pi-spacing-5);border-radius:var(--pi-radius-base);background-color:var(--pi-color-surface2);border:1px solid var(--pi-color-border);color:var(--pi-color-foregroundMuted);font-size:var(--pi-font-size-xs);font-family:var(--pi-font-mono);line-height:1.4;white-space:nowrap;user-select:none}.piui-Spinner_spinner_i0Eo6{display:inline-block;border-radius:var(--pi-radius-full);border-style:solid;border-color:currentColor transparent transparent transparent;animation:piui-Spinner_piSpinnerRotate_pjnJn .7s linear infinite;flex-shrink:0}@keyframes piui-Spinner_piSpinnerRotate_pjnJn{0%{transform:rotate(0)}to{transform:rotate(360deg)}}@media(prefers-reduced-motion:reduce){.piui-Spinner_spinner_i0Eo6{animation:none}}.piui-Divider_divider_kxikv{border:none;margin:0;flex-shrink:0}.piui-Divider_horizontal_xrBl1{width:100%;height:1px;background-color:var(--pi-color-border)}.piui-Divider_vertical_X1mlS{height:100%;width:1px;background-color:var(--pi-color-border);display:inline-block}.piui-Switch_track_aPbaj{display:inline-flex;align-items:center;width:34px;height:20px;border-radius:var(--pi-radius-full);padding:var(--pi-spacing-2);cursor:pointer;transition:background-color .18s ease;flex-shrink:0;background-color:var(--pi-color-surface3);border:none;outline:none}.piui-Switch_track_aPbaj:focus-visible{outline:2px solid var(--pi-color-accent);outline-offset:2px}.piui-Switch_track_aPbaj.piui-Switch_checked_0nldb{background-color:var(--pi-color-accent)}.piui-Switch_track_aPbaj.piui-Switch_disabled_eqcyL{opacity:.5;cursor:not-allowed}.piui-Switch_thumb_LMs9-{width:16px;height:16px;border-radius:var(--pi-radius-full);background-color:#fff;transition:transform .18s ease;transform:translate(0);flex-shrink:0;box-shadow:0 1px 3px #0000004d}.piui-Switch_track_aPbaj.piui-Switch_checked_0nldb .piui-Switch_thumb_LMs9-{transform:translate(14px)}.piui-Surface_surface_LiS4_{background-color:var(--pi-color-surface1);border:1px solid var(--pi-color-border);border-radius:var(--pi-radius-xl);overflow:hidden}.piui-Surface_el0_2XZ1U{background-color:var(--pi-color-surface0)}.piui-Surface_el1_rbrNL{background-color:var(--pi-color-surface1)}.piui-Surface_el2_E0qPY{background-color:var(--pi-color-surface2)}.piui-Surface_el3_8AFvC{background-color:var(--pi-color-surface3)}.piui-Surface_noBorder_DFpH9{border-color:transparent}.piui-Panel_panel_TgAA7{display:flex;flex-direction:column;height:100%;min-height:0}.piui-EmptyState_emptyState__PSfF{display:flex;align-items:center;justify-content:center;gap:var(--pi-spacing-8);color:var(--pi-color-foregroundMuted);font-size:var(--pi-font-size-xs);padding:var(--pi-spacing-20);text-align:center}.piui-TextInput_input_CP24i{width:100%;padding:var(--pi-spacing-8) var(--pi-spacing-12);border-radius:var(--pi-radius-md);border:1px solid var(--pi-color-border);background-color:var(--pi-color-surface2);color:var(--pi-color-foreground);font-size:var(--pi-font-size-base);font-family:var(--pi-font-ui);outline:none;transition:border-color .12s ease;box-sizing:border-box}.piui-TextInput_input_CP24i::placeholder{color:var(--pi-color-foregroundMuted)}.piui-TextInput_input_CP24i:focus{border-color:var(--pi-color-accent);outline:2px solid var(--pi-color-accent);outline-offset:-1px}.piui-TextInput_input_CP24i:disabled{opacity:.5;cursor:not-allowed}.piui-TextInput_textarea_qA5om{resize:vertical;min-height:80px}.piui-ScrollArea_scrollArea_OyLlW{overflow:auto;scrollbar-width:thin;scrollbar-color:var(--pi-color-scrollbarHandle) transparent}.piui-ScrollArea_scrollArea_OyLlW::-webkit-scrollbar{width:6px;height:6px}.piui-ScrollArea_scrollArea_OyLlW::-webkit-scrollbar-track{background:transparent}.piui-ScrollArea_scrollArea_OyLlW::-webkit-scrollbar-thumb{background-color:var(--pi-color-scrollbarHandle);border-radius:var(--pi-radius-full)}.piui-ScrollArea_x_UYHZv{overflow-x:auto;overflow-y:hidden}.piui-ScrollArea_y_T2Ik1{overflow-y:auto;overflow-x:hidden}.piui-Checkbox_wrapper_fHQQB{display:inline-flex;align-items:center;gap:var(--pi-spacing-8);cursor:pointer;font-family:var(--pi-font-ui);font-size:var(--pi-font-size-md);color:var(--pi-color-foreground)}.piui-Checkbox_wrapper_fHQQB[data-disabled=true]{opacity:.5;pointer-events:none}.piui-Checkbox_box_vmxOG{width:16px;height:16px;border-radius:var(--pi-radius-sm);border:1.5px solid var(--pi-color-border);background-color:transparent;display:flex;align-items:center;justify-content:center;transition:background-color .1s,border-color .1s;flex-shrink:0}.piui-Checkbox_box_vmxOG[data-checked=true]{background-color:var(--pi-color-accent);border-color:var(--pi-color-accent)}.piui-Checkbox_checkmark_wpvgs{color:var(--pi-color-accentForeground)}.piui-Checkbox_nativeInput_c7VIf{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.piui-Select_select_UcnXJ{appearance:none;background-color:var(--pi-color-surface1);border:1px solid var(--pi-color-border);border-radius:var(--pi-radius-base);padding:var(--pi-spacing-8) var(--pi-spacing-32) var(--pi-spacing-8) var(--pi-spacing-10);font-family:var(--pi-font-ui);font-size:var(--pi-font-size-md);color:var(--pi-color-foreground);width:100%;outline:none;transition:border-color .1s;cursor:pointer;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='%23a1a1aa' viewBox='0 0 24 24'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");background-repeat:no-repeat;background-position:right 10px center}.piui-Select_select_UcnXJ:focus{border-color:var(--pi-color-accent)}.piui-Select_select_UcnXJ:disabled{opacity:.5;cursor:not-allowed}.piui-Select_comboboxWrapper_3-YEh{position:relative;width:100%}.piui-Select_comboboxInput_7_5QP{width:100%;background-color:var(--pi-color-surface1);border:1px solid var(--pi-color-border);border-radius:var(--pi-radius-base);padding:var(--pi-spacing-8) var(--pi-spacing-10);font-family:var(--pi-font-ui);font-size:var(--pi-font-size-md);color:var(--pi-color-foreground);outline:none;box-sizing:border-box}.piui-Select_comboboxInput_7_5QP:focus{border-color:var(--pi-color-accent)}.piui-Select_comboboxList_pC6Rv{position:absolute;top:100%;left:0;right:0;z-index:80;max-height:200px;overflow-y:auto;background-color:var(--pi-color-surface1);border:1px solid var(--pi-color-border);border-radius:var(--pi-radius-base);margin-top:var(--pi-spacing-4);padding:var(--pi-spacing-4);box-shadow:var(--pi-shadow-md)}.piui-Select_comboboxOption_Up6ZY{padding:var(--pi-spacing-6) var(--pi-spacing-8);border-radius:var(--pi-radius-sm);font-size:var(--pi-font-size-md);font-family:var(--pi-font-ui);color:var(--pi-color-foreground);cursor:pointer;background:none;border:none;width:100%;text-align:left}.piui-Select_comboboxOption_Up6ZY:hover,.piui-Select_comboboxOptionHighlighted_kRH77{background-color:var(--pi-color-surface2)}.piui-Dialog_overlay_URgjn{position:fixed;inset:0;background:#0009;z-index:100}.piui-Dialog_contentWrapper_8Fiwj{position:fixed;inset:0;z-index:101;display:flex;align-items:center;justify-content:center;pointer-events:none}.piui-Dialog_dialog_Ip92p{pointer-events:auto;width:500px;max-width:90vw;max-height:70vh;background:var(--pi-color-surface1);border:1px solid var(--pi-color-border);border-radius:var(--pi-radius-lg);display:flex;flex-direction:column;box-shadow:0 8px 32px #00000080}.piui-Dialog_header_kRqVC{padding:var(--pi-spacing-12) var(--pi-spacing-14);border-bottom:1px solid var(--pi-color-border);display:flex;align-items:center;gap:var(--pi-spacing-8);flex-shrink:0}.piui-Dialog_title_RjMb_{font-size:var(--pi-font-size-sm);margin:0;flex:1;color:var(--pi-color-foreground);font-weight:600}.piui-Dialog_body_ZZ4NM{flex:1;display:flex;flex-direction:column;min-height:0}.piui-Dialog_footer_hfN9E{padding:var(--pi-spacing-10) var(--pi-spacing-14);border-top:1px solid var(--pi-color-border);display:flex;align-items:center;gap:var(--pi-spacing-8);justify-content:flex-end;flex-shrink:0}.piui-Dialog_bare_4a9gB{border:none;background:transparent;box-shadow:none;position:relative}.piui-Dialog_bareBody_Ix_qq{border-radius:var(--pi-radius-lg);overflow:hidden}.piui-Dialog_bareCloseBtn_Ml68W{position:absolute;top:-12px;right:-12px}.piui-Dialog_visuallyHidden_VsPG9{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap}.piui-ResizeHandle_handle_BuoJL{position:absolute;top:0;bottom:0;width:5px;cursor:col-resize;z-index:5;background:transparent;transition:background .12s ease}.piui-ResizeHandle_handle_BuoJL:hover,.piui-ResizeHandle_handle_BuoJL:active{background:var(--pi-color-accent)}.piui-Menu_trigger_YtxLF{position:fixed;width:1px;height:1px;padding:0;border:0;background:none;appearance:none;opacity:0;pointer-events:none}.piui-Menu_content_8knxX{min-width:140px;padding:var(--pi-spacing-4);border-radius:var(--pi-radius-md);background:var(--pi-color-surface1);border:1px solid var(--pi-color-border);box-shadow:0 8px 24px #0006;z-index:1000}.piui-Menu_item_zEpmQ{display:flex;align-items:center;gap:var(--pi-spacing-8);padding:var(--pi-spacing-6) var(--pi-spacing-10);border-radius:var(--pi-radius-base);font-size:var(--pi-font-size-sm);cursor:pointer;outline:none}.piui-Menu_item_zEpmQ:hover,.piui-Menu_item_zEpmQ[data-highlighted]{background:color-mix(in srgb,var(--pi-color-surface1) 85%,var(--pi-color-foreground) 15%)}.piui-Menu_item_zEpmQ[data-disabled]{opacity:.4;cursor:default}.piui-Menu_danger_5l7uC{color:var(--pi-color-statusDanger)}.piui-Menu_groupLabel_QPkyV{position:sticky;top:0;z-index:1;padding:var(--pi-spacing-6) var(--pi-spacing-8) var(--pi-spacing-4);background:var(--pi-color-surface1);color:var(--pi-color-foregroundMuted);font-size:var(--pi-font-size-3xs);font-weight:var(--pi-font-weight-bold);text-transform:uppercase;letter-spacing:.1em}.piui-Menu_sep_Lb8Po{height:1px;margin:var(--pi-spacing-4) 0;background:var(--pi-color-border)}.piui-Popover_content_zAtsY{max-width:calc(100vw - 16px);padding:var(--pi-spacing-12);border-radius:var(--pi-radius-md);background:var(--pi-color-surface1);border:1px solid var(--pi-color-border);box-shadow:0 8px 24px #0006;color:var(--pi-color-foreground);font-size:var(--pi-font-size-sm);z-index:1000}.piui-Announcer_visuallyHidden_L1DnS{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap}.piui-ToastViewport_viewport_Yx5mS{position:fixed;top:var(--pi-spacing-16);left:50%;transform:translate(-50%);z-index:200;display:flex;flex-direction:column;align-items:center;gap:var(--pi-spacing-8);pointer-events:none}.piui-ToastViewport_toast_Tzr1T{pointer-events:auto;display:flex;align-items:center;gap:var(--pi-spacing-8);max-width:420px;padding:var(--pi-spacing-8) var(--pi-spacing-8) var(--pi-spacing-8) var(--pi-spacing-12);background:var(--pi-color-surface1);border:var(--pi-border-width-1) solid var(--pi-color-border);border-left:var(--pi-border-width-2) solid var(--toast-rail, transparent);border-radius:var(--pi-radius-base);box-shadow:var(--pi-shadow-md);font-size:var(--pi-font-size-2xs);color:var(--pi-color-foreground);opacity:1;transform:translateY(0);transition:opacity .18s ease,transform .18s ease}@starting-style{.piui-ToastViewport_toast_Tzr1T{opacity:0;transform:translateY(-8px)}}.piui-ToastViewport_toast_Tzr1T.piui-ToastViewport_exiting_J8_Ab{opacity:0;transform:translateY(-8px);pointer-events:none}.piui-ToastViewport_content_GCPPy{flex:1;min-width:0;overflow-wrap:break-word}.piui-ToastViewport_close_KWFx7{flex:none;display:flex;align-items:center;justify-content:center;padding:var(--pi-spacing-1);border:none;background:transparent;border-radius:var(--pi-radius-base);color:var(--pi-color-foregroundMuted);cursor:pointer}.piui-ToastViewport_close_KWFx7:hover{background:color-mix(in srgb,var(--pi-color-background) 85%,var(--pi-color-foreground) 15%)}@media(prefers-reduced-motion:reduce){.piui-ToastViewport_toast_Tzr1T{transition:none}}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ThemeBoundary — applies theme CSS variables before first paint, and publishes the resolved
|
|
3
|
+
* `AppearanceState` through React context so components that cannot consume CSS variables (an
|
|
4
|
+
* emulator configured through JavaScript) can follow the theme, mono font, and font-size setting.
|
|
5
|
+
* Wraps the app so no flash of wrong theme occurs.
|
|
6
|
+
*/
|
|
7
|
+
import { type ReactNode } from "react";
|
|
8
|
+
import { type AppearanceMode, type AppearanceState, type KeyValueStore } from "./appearance-store.js";
|
|
9
|
+
import { type AppearanceSettings, type Theme } from "./theme.js";
|
|
10
|
+
import { type BrandConfig } from "../brand/config.js";
|
|
11
|
+
export interface ThemeBoundaryProps {
|
|
12
|
+
/** Where appearance is persisted. Defaults to `localStorage` (`localStorageKvStore`). */
|
|
13
|
+
store?: KeyValueStore;
|
|
14
|
+
/** Key the appearance JSON lives under. Defaults to `pi-studio-appearance`. */
|
|
15
|
+
storageKey?: string;
|
|
16
|
+
brandConfig?: BrandConfig;
|
|
17
|
+
children: ReactNode;
|
|
18
|
+
}
|
|
19
|
+
/** Write side of the appearance controller, for settings UIs and theme switchers. */
|
|
20
|
+
export interface AppearanceControls {
|
|
21
|
+
setMode(mode: AppearanceMode): void;
|
|
22
|
+
updateSettings(patch: Partial<AppearanceSettings>): void;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Synchronously applies theme on first render, then listens for system changes.
|
|
26
|
+
*/
|
|
27
|
+
export declare function ThemeBoundary({ store, storageKey, brandConfig, children, }: ThemeBoundaryProps): import("react").JSX.Element;
|
|
28
|
+
/** Read the current appearance state (mode, settings, resolved theme). Must be under `ThemeBoundary`. */
|
|
29
|
+
export declare function useAppearance(): AppearanceState;
|
|
30
|
+
/** Read the resolved `Theme` (colors, fontSize, fontFamily, ...). Must be under `ThemeBoundary`. */
|
|
31
|
+
export declare function useResolvedTheme(): Theme;
|
|
32
|
+
/**
|
|
33
|
+
* Change the theme (`setMode`) or appearance settings (`updateSettings`); the new value is applied
|
|
34
|
+
* to the document and persisted. The returned object is stable for the life of the boundary.
|
|
35
|
+
* Must be under `ThemeBoundary`.
|
|
36
|
+
*/
|
|
37
|
+
export declare function useAppearanceControls(): AppearanceControls;
|
|
38
|
+
//# sourceMappingURL=ThemeBoundary.d.ts.map
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Appearance store: persisted theme + appearance settings, system dark-mode following.
|
|
3
|
+
* design-system.md § Theme variants, § Behavior (Appearance)
|
|
4
|
+
*/
|
|
5
|
+
import { type ThemeName } from "./variants.js";
|
|
6
|
+
import { type AppearanceSettings } from "./theme.js";
|
|
7
|
+
import { type Theme } from "./theme.js";
|
|
8
|
+
import { type BrandConfig } from "../brand/config.js";
|
|
9
|
+
export interface KeyValueStore {
|
|
10
|
+
get(key: string): string | null;
|
|
11
|
+
set(key: string, value: string): void;
|
|
12
|
+
}
|
|
13
|
+
/** Default `localStorage` key for the persisted appearance JSON; existing installs keep theirs. */
|
|
14
|
+
export declare const DEFAULT_APPEARANCE_STORAGE_KEY = "pi-studio-appearance";
|
|
15
|
+
export interface AppearanceControllerOptions {
|
|
16
|
+
/** Key the appearance JSON is read from / written to. Defaults to `pi-studio-appearance`. */
|
|
17
|
+
storageKey?: string;
|
|
18
|
+
}
|
|
19
|
+
export type AppearanceMode = ThemeName | "system";
|
|
20
|
+
export interface AppearanceState {
|
|
21
|
+
mode: AppearanceMode;
|
|
22
|
+
settings: AppearanceSettings;
|
|
23
|
+
resolvedTheme: Theme;
|
|
24
|
+
}
|
|
25
|
+
export interface AppearanceController {
|
|
26
|
+
getState(): AppearanceState;
|
|
27
|
+
setMode(mode: AppearanceMode): void;
|
|
28
|
+
updateSettings(patch: Partial<AppearanceSettings>): void;
|
|
29
|
+
/** Call to apply current theme to DOM (call on init + changes). */
|
|
30
|
+
apply(): void;
|
|
31
|
+
/** Start system-follow listener; returns cleanup. */
|
|
32
|
+
listen(): () => void;
|
|
33
|
+
/** Subscribe to state changes (mode/settings/system-follow). Returns an unsubscribe function. */
|
|
34
|
+
subscribe(listener: () => void): () => void;
|
|
35
|
+
}
|
|
36
|
+
export declare function createAppearanceController(store: KeyValueStore, brandInput?: BrandConfig, options?: AppearanceControllerOptions): AppearanceController;
|
|
37
|
+
//# sourceMappingURL=appearance-store.d.ts.map
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export type Rgb = {
|
|
2
|
+
r: number;
|
|
3
|
+
g: number;
|
|
4
|
+
b: number;
|
|
5
|
+
};
|
|
6
|
+
export declare function hexToRgb(hex: string): Rgb;
|
|
7
|
+
export declare function rgbToHex({ r, g, b }: Rgb): string;
|
|
8
|
+
export declare function relativeLuminance(hex: string): number;
|
|
9
|
+
export declare function contrastForeground(hex: string, dark?: string, light?: string): string;
|
|
10
|
+
export declare function lighten(hex: string, amount: number): string;
|
|
11
|
+
export declare function darken(hex: string, amount: number): string;
|
|
12
|
+
export declare function isHexColor(value: string): boolean;
|
|
13
|
+
//# sourceMappingURL=color-utils.d.ts.map
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { lighten } from "./color-utils.js";
|
|
2
|
+
import { palette } from "./palette.js";
|
|
3
|
+
export type SyntaxColors = {
|
|
4
|
+
keyword: string;
|
|
5
|
+
string: string;
|
|
6
|
+
number: string;
|
|
7
|
+
boolean: string;
|
|
8
|
+
comment: string;
|
|
9
|
+
function: string;
|
|
10
|
+
variable: string;
|
|
11
|
+
type: string;
|
|
12
|
+
class: string;
|
|
13
|
+
constant: string;
|
|
14
|
+
operator: string;
|
|
15
|
+
punctuation: string;
|
|
16
|
+
tag: string;
|
|
17
|
+
attribute: string;
|
|
18
|
+
property: string;
|
|
19
|
+
regexp: string;
|
|
20
|
+
escape: string;
|
|
21
|
+
heading: string;
|
|
22
|
+
link: string;
|
|
23
|
+
deleted: string;
|
|
24
|
+
inserted: string;
|
|
25
|
+
};
|
|
26
|
+
export type TerminalTheme = {
|
|
27
|
+
background: string;
|
|
28
|
+
foreground: string;
|
|
29
|
+
cursor: string;
|
|
30
|
+
cursorAccent: string;
|
|
31
|
+
selectionBackground: string;
|
|
32
|
+
black: string;
|
|
33
|
+
red: string;
|
|
34
|
+
green: string;
|
|
35
|
+
yellow: string;
|
|
36
|
+
blue: string;
|
|
37
|
+
magenta: string;
|
|
38
|
+
cyan: string;
|
|
39
|
+
white: string;
|
|
40
|
+
brightBlack: string;
|
|
41
|
+
brightRed: string;
|
|
42
|
+
brightGreen: string;
|
|
43
|
+
brightYellow: string;
|
|
44
|
+
brightBlue: string;
|
|
45
|
+
brightMagenta: string;
|
|
46
|
+
brightCyan: string;
|
|
47
|
+
brightWhite: string;
|
|
48
|
+
};
|
|
49
|
+
export type ThemeColors = {
|
|
50
|
+
surface0: string;
|
|
51
|
+
surface1: string;
|
|
52
|
+
surface2: string;
|
|
53
|
+
surface3: string;
|
|
54
|
+
surface4: string;
|
|
55
|
+
surfaceDiffEmpty: string;
|
|
56
|
+
surfaceSidebar: string;
|
|
57
|
+
surfaceSidebarHover: string;
|
|
58
|
+
surfaceWorkspace: string;
|
|
59
|
+
foreground: string;
|
|
60
|
+
foregroundMuted: string;
|
|
61
|
+
accent: string;
|
|
62
|
+
accentBright: string;
|
|
63
|
+
accentForeground: string;
|
|
64
|
+
destructive: string;
|
|
65
|
+
destructiveForeground: string;
|
|
66
|
+
success: string;
|
|
67
|
+
successForeground: string;
|
|
68
|
+
border: string;
|
|
69
|
+
borderAccent: string;
|
|
70
|
+
statusSuccess: string;
|
|
71
|
+
statusDanger: string;
|
|
72
|
+
statusWarning: string;
|
|
73
|
+
statusMerged: string;
|
|
74
|
+
statusInfo: string;
|
|
75
|
+
diffAddition: string;
|
|
76
|
+
diffDeletion: string;
|
|
77
|
+
scrollbarHandle: string;
|
|
78
|
+
background: string;
|
|
79
|
+
popover: string;
|
|
80
|
+
popoverForeground: string;
|
|
81
|
+
primary: string;
|
|
82
|
+
secondary: string;
|
|
83
|
+
muted: string;
|
|
84
|
+
mutedForeground: string;
|
|
85
|
+
input: string;
|
|
86
|
+
ring: string;
|
|
87
|
+
palette: typeof palette;
|
|
88
|
+
syntax: SyntaxColors;
|
|
89
|
+
terminal: TerminalTheme;
|
|
90
|
+
};
|
|
91
|
+
export type DarkTintConfig = {
|
|
92
|
+
surface0: string;
|
|
93
|
+
surface1: string;
|
|
94
|
+
surface2: string;
|
|
95
|
+
surface3: string;
|
|
96
|
+
surface4: string;
|
|
97
|
+
surfaceDiffEmpty: string;
|
|
98
|
+
surfaceSidebar: string;
|
|
99
|
+
surfaceSidebarHover: string;
|
|
100
|
+
mutedForeground: string;
|
|
101
|
+
scrollbarHandle: string;
|
|
102
|
+
border: string;
|
|
103
|
+
borderAccent: string;
|
|
104
|
+
accent: string;
|
|
105
|
+
accentBright: string;
|
|
106
|
+
destructive: string;
|
|
107
|
+
};
|
|
108
|
+
export declare function buildDarkColors(tint: DarkTintConfig): ThemeColors;
|
|
109
|
+
export declare function buildLightColors(): ThemeColors;
|
|
110
|
+
export { lighten };
|
|
111
|
+
//# sourceMappingURL=colors.d.ts.map
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Theme → CSS custom properties bridge.
|
|
3
|
+
* Flattens a Theme object into `--pi-*` CSS variables on :root.
|
|
4
|
+
* design-system.md § Purpose (render-stack decision)
|
|
5
|
+
*/
|
|
6
|
+
import { type Theme } from "./theme.js";
|
|
7
|
+
/**
|
|
8
|
+
* Given a Theme, produces a flat Record<`--pi-${path}`, value> map
|
|
9
|
+
* suitable for setting on `document.documentElement.style`.
|
|
10
|
+
*/
|
|
11
|
+
export declare function flattenThemeToVars(theme: Theme): Record<string, string>;
|
|
12
|
+
/**
|
|
13
|
+
* Apply a flattened variable map to the document root.
|
|
14
|
+
* Idempotent — re-applying the same map is a no-op (DOM diffing).
|
|
15
|
+
*/
|
|
16
|
+
export declare function applyVarsToRoot(vars: Record<string, string>): void;
|
|
17
|
+
/**
|
|
18
|
+
* Full pipeline: flatten a Theme and apply to the DOM.
|
|
19
|
+
*/
|
|
20
|
+
export declare function applyThemeToDOM(theme: Theme): void;
|
|
21
|
+
//# sourceMappingURL=css-bridge.d.ts.map
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Development-only diagnostics for `ThemeBoundary`. The decision logic is pure and injectable so it
|
|
3
|
+
* is testable without a DOM; `ThemeBoundary` only wires it to the document and to the environment.
|
|
4
|
+
* Each diagnostic fires at most once per page.
|
|
5
|
+
*/
|
|
6
|
+
/** Custom property `styles.css` defines on `:root`; absent after mount ⇒ the stylesheet was never imported. */
|
|
7
|
+
export declare const STYLESHEET_SENTINEL_VAR = "--piui-stylesheet";
|
|
8
|
+
export declare const MISSING_STYLESHEET_MESSAGE = "[ui-library] styles.css is not loaded, so components render unstyled. Add `import \"@av-pi-studio/ui-library/styles.css\"` to your app entry.";
|
|
9
|
+
export declare const MULTIPLE_BOUNDARIES_MESSAGE = "[ui-library] More than one ThemeBoundary is mounted. Only one per document is supported: each writes the same CSS variables on <html>, so the last write wins.";
|
|
10
|
+
export interface DevWarnings {
|
|
11
|
+
/** Warn (once) when the sentinel custom property is empty. `readVar` returns its computed value. */
|
|
12
|
+
checkStylesheet(readVar: (name: string) => string): void;
|
|
13
|
+
/** Count a mounted boundary; warns (once) when a second is live. Returns the unregister function. */
|
|
14
|
+
registerBoundary(): () => void;
|
|
15
|
+
}
|
|
16
|
+
export declare function createDevWarnings(warn: (message: string) => void): DevWarnings;
|
|
17
|
+
/**
|
|
18
|
+
* Page-wide instance used by `ThemeBoundary`. `ThemeBoundary` guards every use with an inline
|
|
19
|
+
* `process.env.NODE_ENV` check, which the *consumer's* bundler folds in a production build; with
|
|
20
|
+
* the `@__PURE__` mark the whole module (and its message strings) is then tree-shaken away.
|
|
21
|
+
*/
|
|
22
|
+
export declare const devWarnings: DevWarnings;
|
|
23
|
+
//# sourceMappingURL=dev-warnings.d.ts.map
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export { palette, type Palette, type PaletteScale, type PaletteShade } from "./palette.js";
|
|
2
|
+
export { hexToRgb, rgbToHex, relativeLuminance, contrastForeground, lighten, darken, isHexColor, type Rgb, } from "./color-utils.js";
|
|
3
|
+
export { spacing, baseFontSize, baseLineHeight, fontWeight, borderRadius, borderWidth, opacity, iconSize, buildShadows, DEFAULT_UI_FONT, DEFAULT_MONO_FONT, TERMINAL_FONT_STACK, type SpacingKey, type FontSizeKey, type Shadow, type ShadowSet, } from "./tokens.js";
|
|
4
|
+
export { buildDarkColors, buildLightColors, type ThemeColors, type DarkTintConfig, type SyntaxColors, type TerminalTheme, } from "./colors.js";
|
|
5
|
+
export { THEME_NAMES, THEME_VARIANTS, THEME_SWATCHES, type ThemeName, type ThemeVariant, } from "./variants.js";
|
|
6
|
+
export { getTheme, applyAppearance, DEFAULT_THEME_NAME, type Theme, type AppearanceSettings, } from "./theme.js";
|
|
7
|
+
export { flattenThemeToVars, applyVarsToRoot, applyThemeToDOM } from "./css-bridge.js";
|
|
8
|
+
export { createAppearanceController, DEFAULT_APPEARANCE_STORAGE_KEY, type AppearanceControllerOptions, type AppearanceController, type AppearanceState, type AppearanceMode, type KeyValueStore, } from "./appearance-store.js";
|
|
9
|
+
export { findTokenProblems, countTokenUsage, type TokenProblem, type TokenProblemKind, type TokenSourceFile, type TokenUsage, } from "./token-guard.js";
|
|
10
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { D as e, a as o, b as r, c as T, T as t, d as i, e as n, f as E, g as l, h as A, i as p, j as _, k as d, l as b, m as h, n as c, o as g, p as F, q as M, r as N, s as S, t as m, u, v as H, w as L, x as C, y as D, z as O } from "../chunks/token-guard-B85Ysv3w.js";
|
|
2
|
+
import { c as f, d as x, h as U, a as k, l as y, b as z, e as I } from "../chunks/theme-injection-BHAAhBYz.js";
|
|
3
|
+
export {
|
|
4
|
+
e as DEFAULT_APPEARANCE_STORAGE_KEY,
|
|
5
|
+
o as DEFAULT_MONO_FONT,
|
|
6
|
+
r as DEFAULT_THEME_NAME,
|
|
7
|
+
T as DEFAULT_UI_FONT,
|
|
8
|
+
t as TERMINAL_FONT_STACK,
|
|
9
|
+
i as THEME_NAMES,
|
|
10
|
+
n as THEME_SWATCHES,
|
|
11
|
+
E as THEME_VARIANTS,
|
|
12
|
+
l as applyAppearance,
|
|
13
|
+
A as applyThemeToDOM,
|
|
14
|
+
p as applyVarsToRoot,
|
|
15
|
+
_ as baseFontSize,
|
|
16
|
+
d as baseLineHeight,
|
|
17
|
+
b as borderRadius,
|
|
18
|
+
h as borderWidth,
|
|
19
|
+
c as buildDarkColors,
|
|
20
|
+
g as buildLightColors,
|
|
21
|
+
F as buildShadows,
|
|
22
|
+
f as contrastForeground,
|
|
23
|
+
M as countTokenUsage,
|
|
24
|
+
N as createAppearanceController,
|
|
25
|
+
x as darken,
|
|
26
|
+
S as findTokenProblems,
|
|
27
|
+
m as flattenThemeToVars,
|
|
28
|
+
u as fontWeight,
|
|
29
|
+
H as getTheme,
|
|
30
|
+
U as hexToRgb,
|
|
31
|
+
L as iconSize,
|
|
32
|
+
k as isHexColor,
|
|
33
|
+
y as lighten,
|
|
34
|
+
C as opacity,
|
|
35
|
+
D as palette,
|
|
36
|
+
z as relativeLuminance,
|
|
37
|
+
I as rgbToHex,
|
|
38
|
+
O as spacing
|
|
39
|
+
};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export type PaletteShade = "50" | "100" | "200" | "300" | "400" | "500" | "600" | "700" | "800" | "900" | "950";
|
|
2
|
+
export type PaletteScale = Readonly<Record<PaletteShade, string>>;
|
|
3
|
+
export declare const palette: {
|
|
4
|
+
readonly zinc: Readonly<Record<PaletteShade, string>>;
|
|
5
|
+
readonly gray: Readonly<Record<PaletteShade, string>>;
|
|
6
|
+
readonly slate: Readonly<Record<PaletteShade, string>>;
|
|
7
|
+
readonly blue: Readonly<Record<PaletteShade, string>>;
|
|
8
|
+
readonly green: Readonly<Record<PaletteShade, string>>;
|
|
9
|
+
readonly red: Readonly<Record<PaletteShade, string>>;
|
|
10
|
+
readonly teal: Readonly<Record<PaletteShade, string>>;
|
|
11
|
+
readonly amber: Readonly<Record<PaletteShade, string>>;
|
|
12
|
+
readonly yellow: Readonly<Record<PaletteShade, string>>;
|
|
13
|
+
readonly purple: Readonly<Record<PaletteShade, string>>;
|
|
14
|
+
readonly orange: Readonly<Record<PaletteShade, string>>;
|
|
15
|
+
readonly white: "#ffffff";
|
|
16
|
+
readonly black: "#000000";
|
|
17
|
+
};
|
|
18
|
+
export type Palette = typeof palette;
|
|
19
|
+
//# sourceMappingURL=palette.d.ts.map
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { borderRadius, borderWidth, fontWeight, iconSize, opacity, spacing, type FontSizeKey, type ShadowSet } from "./tokens.js";
|
|
2
|
+
import { type ThemeColors } from "./colors.js";
|
|
3
|
+
import { type ThemeName } from "./variants.js";
|
|
4
|
+
export type Theme = {
|
|
5
|
+
name: ThemeName;
|
|
6
|
+
colorScheme: "light" | "dark";
|
|
7
|
+
colors: ThemeColors;
|
|
8
|
+
spacing: typeof spacing;
|
|
9
|
+
fontSize: Record<FontSizeKey, number>;
|
|
10
|
+
fontFamily: {
|
|
11
|
+
ui: string;
|
|
12
|
+
mono: string;
|
|
13
|
+
};
|
|
14
|
+
lineHeight: Record<"diff", number>;
|
|
15
|
+
iconSize: typeof iconSize;
|
|
16
|
+
fontWeight: typeof fontWeight;
|
|
17
|
+
borderRadius: typeof borderRadius;
|
|
18
|
+
borderWidth: typeof borderWidth;
|
|
19
|
+
opacity: typeof opacity;
|
|
20
|
+
shadow: ShadowSet;
|
|
21
|
+
swatch: string;
|
|
22
|
+
};
|
|
23
|
+
export type AppearanceSettings = {
|
|
24
|
+
/** One of the six named theme variants. */
|
|
25
|
+
themeName?: ThemeName;
|
|
26
|
+
/** Custom UI font family string; empty/undefined → platform default. */
|
|
27
|
+
uiFont?: string;
|
|
28
|
+
/** Custom mono font family string; empty/undefined → platform default. */
|
|
29
|
+
monoFont?: string;
|
|
30
|
+
/**
|
|
31
|
+
* Desired base font size (px). Every fontSize rung is scaled relative to `baseFontSize.base`,
|
|
32
|
+
* so passing that value through is a no-op. Clamped 10–24.
|
|
33
|
+
*/
|
|
34
|
+
fontSize?: number;
|
|
35
|
+
};
|
|
36
|
+
/**
|
|
37
|
+
* Apply appearance settings to a base theme and return a new patched theme.
|
|
38
|
+
* The base theme object is never mutated.
|
|
39
|
+
* Code/mono surfaces keep the mono font because they reference `fontFamily.mono`
|
|
40
|
+
* independently — a custom `uiFont` only patches `fontFamily.ui`.
|
|
41
|
+
*/
|
|
42
|
+
export declare function applyAppearance(base: Theme, settings: AppearanceSettings): Theme;
|
|
43
|
+
/** Build a fresh Theme for the given name with default appearance settings. */
|
|
44
|
+
export declare function getTheme(name: ThemeName): Theme;
|
|
45
|
+
export declare const DEFAULT_THEME_NAME: ThemeName;
|
|
46
|
+
export { type ThemeName };
|
|
47
|
+
//# sourceMappingURL=theme.d.ts.map
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export type TokenProblemKind = "dangling-var" | "illegal-key" | "literal-font-size" | "unknown-font-rung";
|
|
2
|
+
export interface TokenProblem {
|
|
3
|
+
kind: TokenProblemKind;
|
|
4
|
+
/** Source file, or `"(theme)"` for problems in emitted keys. */
|
|
5
|
+
path: string;
|
|
6
|
+
message: string;
|
|
7
|
+
}
|
|
8
|
+
export interface TokenSourceFile {
|
|
9
|
+
path: string;
|
|
10
|
+
text: string;
|
|
11
|
+
}
|
|
12
|
+
export interface TokenUsage {
|
|
13
|
+
/** Static `var(--pi-*)`/`var(--syntax-*)` references examined. */
|
|
14
|
+
varRefs: number;
|
|
15
|
+
/** `font-size` declarations examined in `.css` files. */
|
|
16
|
+
fontSizeDeclarations: number;
|
|
17
|
+
}
|
|
18
|
+
export declare function countTokenUsage(files: readonly TokenSourceFile[]): TokenUsage;
|
|
19
|
+
export declare function findTokenProblems(files: readonly TokenSourceFile[]): TokenProblem[];
|
|
20
|
+
//# sourceMappingURL=token-guard.d.ts.map
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
export declare const spacing: {
|
|
2
|
+
readonly "0": 0;
|
|
3
|
+
readonly "1": 1;
|
|
4
|
+
readonly "2": 2;
|
|
5
|
+
readonly "3": 3;
|
|
6
|
+
readonly "4": 4;
|
|
7
|
+
readonly "5": 5;
|
|
8
|
+
readonly "6": 6;
|
|
9
|
+
readonly "7": 7;
|
|
10
|
+
readonly "8": 8;
|
|
11
|
+
readonly "10": 10;
|
|
12
|
+
readonly "11": 11;
|
|
13
|
+
readonly "12": 12;
|
|
14
|
+
readonly "14": 14;
|
|
15
|
+
readonly "16": 16;
|
|
16
|
+
readonly "20": 20;
|
|
17
|
+
readonly "24": 24;
|
|
18
|
+
readonly "26": 26;
|
|
19
|
+
readonly "30": 30;
|
|
20
|
+
readonly "32": 32;
|
|
21
|
+
readonly "48": 48;
|
|
22
|
+
readonly "64": 64;
|
|
23
|
+
readonly "80": 80;
|
|
24
|
+
readonly "96": 96;
|
|
25
|
+
readonly "128": 128;
|
|
26
|
+
};
|
|
27
|
+
export type Spacing = typeof spacing;
|
|
28
|
+
export type SpacingKey = keyof Spacing;
|
|
29
|
+
export type FontSizeKey = "4xs" | "3xs" | "2xs" | "xs" | "code" | "sm" | "md" | "base" | "lg" | "xl" | "2xl" | "3xl" | "4xl";
|
|
30
|
+
export declare const baseFontSize: Readonly<Record<FontSizeKey, number>>;
|
|
31
|
+
export declare const fontWeight: {
|
|
32
|
+
readonly normal: "400";
|
|
33
|
+
readonly medium: "500";
|
|
34
|
+
readonly semibold: "600";
|
|
35
|
+
readonly bold: "700";
|
|
36
|
+
};
|
|
37
|
+
export type FontWeight = typeof fontWeight;
|
|
38
|
+
export declare const borderRadius: {
|
|
39
|
+
readonly none: 0;
|
|
40
|
+
readonly sm: 2;
|
|
41
|
+
readonly base: 4;
|
|
42
|
+
readonly md: 6;
|
|
43
|
+
readonly lg: 8;
|
|
44
|
+
readonly xl: 12;
|
|
45
|
+
readonly "2xl": 16;
|
|
46
|
+
readonly full: 9999;
|
|
47
|
+
};
|
|
48
|
+
export type BorderRadius = typeof borderRadius;
|
|
49
|
+
export declare const borderWidth: {
|
|
50
|
+
readonly "0": 0;
|
|
51
|
+
readonly "1": 1;
|
|
52
|
+
readonly "2": 2;
|
|
53
|
+
};
|
|
54
|
+
export type BorderWidth = typeof borderWidth;
|
|
55
|
+
export declare const opacity: {
|
|
56
|
+
readonly "0": 0;
|
|
57
|
+
readonly "50": 0.5;
|
|
58
|
+
readonly "100": 1;
|
|
59
|
+
};
|
|
60
|
+
export type Opacity = typeof opacity;
|
|
61
|
+
export declare const iconSize: {
|
|
62
|
+
readonly xs: 12;
|
|
63
|
+
readonly sm: 14;
|
|
64
|
+
readonly md: 16;
|
|
65
|
+
readonly lg: 20;
|
|
66
|
+
};
|
|
67
|
+
export type IconSize = typeof iconSize;
|
|
68
|
+
export declare const baseLineHeight: {
|
|
69
|
+
readonly diff: 22;
|
|
70
|
+
};
|
|
71
|
+
export declare const DEFAULT_UI_FONT = "system-ui, -apple-system, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif";
|
|
72
|
+
export declare const DEFAULT_MONO_FONT = "ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", monospace";
|
|
73
|
+
/**
|
|
74
|
+
* Terminal-only font stack (`features/terminal/TerminalPanel.tsx`).
|
|
75
|
+
*
|
|
76
|
+
* Separate from `DEFAULT_MONO_FONT` on purpose: the app's mono surfaces render *our* text, where a
|
|
77
|
+
* platform font is the right default, while the terminal renders a real shell whose prompt may
|
|
78
|
+
* paint Nerd Font glyphs (powerlevel10k's own docs recommend MesloLGS NF). Those glyphs live in
|
|
79
|
+
* the private-use planes and simply do not exist in `ui-monospace`.
|
|
80
|
+
*
|
|
81
|
+
* Order is the whole design:
|
|
82
|
+
* 1-2. A locally installed MesloLGS NF — a user who followed the p10k font instructions gets
|
|
83
|
+
* exactly what their desktop terminal shows, and downloads nothing.
|
|
84
|
+
* 3. "Cascadia Mono NF", the bundled webfont (`theme/fonts.css`) — the guaranteed floor, so
|
|
85
|
+
* icons render on a machine that has no Nerd Font installed at all.
|
|
86
|
+
* 4+. Platform monospace, for the case where even the bundled face fails to load.
|
|
87
|
+
* Fallback is resolved by the browser per character, which is what makes 1-3 compose: MesloLGS NF
|
|
88
|
+
* has no braille glyphs, so a spinner falls through to the bundled face while the rest of the line
|
|
89
|
+
* stays Meslo.
|
|
90
|
+
*/
|
|
91
|
+
export declare const TERMINAL_FONT_STACK = "\"MesloLGS NF\", \"MesloLGS Nerd Font Mono\", \"Cascadia Mono NF\", ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", monospace";
|
|
92
|
+
export type Shadow = {
|
|
93
|
+
color: string;
|
|
94
|
+
offsetX: number;
|
|
95
|
+
offsetY: number;
|
|
96
|
+
radius: number;
|
|
97
|
+
elevation: number;
|
|
98
|
+
};
|
|
99
|
+
export type ShadowSet = {
|
|
100
|
+
sm: Shadow;
|
|
101
|
+
md: Shadow;
|
|
102
|
+
lg: Shadow;
|
|
103
|
+
};
|
|
104
|
+
export declare function buildShadows(colorScheme: "light" | "dark"): ShadowSet;
|
|
105
|
+
//# sourceMappingURL=tokens.d.ts.map
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { type ThemeColors } from "./colors.js";
|
|
2
|
+
export declare const THEME_SWATCHES: Readonly<Record<ThemeName, string>>;
|
|
3
|
+
export type ThemeName = "light" | "dark" | "zinc" | "midnight" | "claude" | "ghostty";
|
|
4
|
+
export declare const THEME_NAMES: readonly ThemeName[];
|
|
5
|
+
export type ThemeVariant = {
|
|
6
|
+
name: ThemeName;
|
|
7
|
+
colorScheme: "light" | "dark";
|
|
8
|
+
colors: ThemeColors;
|
|
9
|
+
swatch: string;
|
|
10
|
+
};
|
|
11
|
+
export declare const THEME_VARIANTS: Readonly<Record<ThemeName, ThemeVariant>>;
|
|
12
|
+
//# sourceMappingURL=variants.d.ts.map
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Deterministic avatar background color derived from a project key string.
|
|
3
|
+
* The same key always produces the same color — stable across renders.
|
|
4
|
+
*/
|
|
5
|
+
export declare function avatarColor(key: string): string;
|
|
6
|
+
/**
|
|
7
|
+
* Returns the initial letter to display in the avatar fallback.
|
|
8
|
+
* Uses the first alphanumeric character of the key, uppercased.
|
|
9
|
+
*/
|
|
10
|
+
export declare function avatarInitial(key: string): string;
|
|
11
|
+
//# sourceMappingURL=avatar.d.ts.map
|