@xenide-io/the-old-ui-theme 0.7.0 → 0.9.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 +9 -10
- package/dist/{Chip-Cq3AiAji.d.mts → Chip-BzuNgJIa.d.mts} +81 -23
- package/dist/{Chip-Cq3AiAji.d.ts → Chip-BzuNgJIa.d.ts} +81 -23
- package/dist/{ai-message-blocknote-WABTHFY7.mjs → ai-message-blocknote-D4Z6DUCJ.mjs} +9 -3
- package/dist/chunk-2EO5VCXP.mjs +3912 -0
- package/dist/chunk-APKRZQRO.mjs +251 -0
- package/dist/chunk-BS7BZI5W.mjs +19 -0
- package/dist/chunk-IULORI3A.mjs +8 -0
- package/dist/index.d.mts +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.js +997 -576
- package/dist/index.mjs +49 -45
- package/dist/suite.d.mts +157 -55
- package/dist/suite.d.ts +157 -55
- package/dist/suite.js +4249 -801
- package/dist/suite.mjs +2578 -594
- package/dist/theme-boot-P-oqKVZF.d.mts +74 -0
- package/dist/theme-boot-P-oqKVZF.d.ts +74 -0
- package/dist/theme-boot.d.mts +2 -0
- package/dist/theme-boot.d.ts +2 -0
- package/dist/theme-boot.js +44 -0
- package/dist/theme-boot.mjs +8 -0
- package/dist/ui.d.mts +5 -29
- package/dist/ui.d.ts +5 -29
- package/dist/ui.js +647 -352
- package/dist/ui.mjs +10 -12
- package/docs/README.md +34 -0
- package/docs/ai-quick-reference.md +56 -0
- package/docs/component-library-improvement-plan.md +751 -0
- package/docs/component-reference.md +81 -0
- package/docs/components.md +48 -0
- package/docs/demos.md +19 -0
- package/docs/installation.md +117 -0
- package/docs/suite-audit.md +34 -0
- package/docs/theme-token-reference.md +67 -0
- package/docs/themes.md +164 -0
- package/package.json +22 -21
- package/public/fonts/OpenRunde-Bold.woff2 +0 -0
- package/public/fonts/OpenRunde-Medium.woff2 +0 -0
- package/public/fonts/OpenRunde-Regular.woff2 +0 -0
- package/public/fonts/OpenRunde-Semibold.woff2 +0 -0
- package/scripts/package-smoke.mjs +43 -0
- package/src/app/globals.css +2 -1
- package/src/components/ui/Accordion.tsx +20 -6
- package/src/components/ui/Avatar.tsx +5 -3
- package/src/components/ui/Calendar.tsx +187 -63
- package/src/components/ui/Card.test.tsx +38 -0
- package/src/components/ui/Card.tsx +77 -14
- package/src/components/ui/CollapsibleSection.tsx +12 -4
- package/src/components/ui/CommandPalette.test.tsx +91 -4
- package/src/components/ui/CommandPalette.tsx +138 -128
- package/src/components/ui/EmptyState.tsx +2 -2
- package/src/components/ui/FormField.tsx +1 -1
- package/src/components/ui/Input.tsx +42 -18
- package/src/components/ui/Kbd.tsx +18 -3
- package/src/components/ui/Modal.tsx +3 -1
- package/src/components/ui/Progress.tsx +14 -5
- package/src/components/ui/SegmentedControl.tsx +2 -2
- package/src/components/ui/SettingsLayout.tsx +1 -1
- package/src/components/ui/Stat.tsx +3 -2
- package/src/components/ui/Table.tsx +8 -3
- package/src/components/ui/Tooltip.test.tsx +70 -1
- package/src/components/ui/Tooltip.tsx +53 -29
- package/src/components/ui/Typography.tsx +103 -49
- package/src/components/ui/avatar-stat.test.tsx +23 -0
- package/src/components/ui/calendar.test.tsx +88 -0
- package/src/components/ui/disclosure.test.tsx +39 -0
- package/src/components/ui/index.ts +44 -6
- package/src/components/ui/progress.test.tsx +15 -0
- package/src/components/ui/typography.test.tsx +26 -1
- package/src/styles/suite-skin.css +8 -2
- package/src/styles/themes.css +184 -68
- package/src/suite/components/ai-message-blocknote.tsx +13 -2
- package/src/suite/components/ai-panel.tsx +41 -10
- package/src/suite/components/app-switcher.test.tsx +21 -6
- package/src/suite/components/app-switcher.tsx +7 -11
- package/src/suite/components/suite-app-layout.tsx +12 -3
- package/src/suite/components/suite-bottom-nav.tsx +0 -1
- package/src/suite/components/suite-clients-projects-directory.test.tsx +71 -0
- package/src/suite/components/suite-clients-projects-directory.tsx +943 -0
- package/src/suite/components/suite-integration-picker.test.tsx +224 -0
- package/src/suite/components/suite-integration-picker.tsx +939 -0
- package/src/suite/components/suite-integration-rules.test.tsx +157 -0
- package/src/suite/components/suite-integration-rules.tsx +471 -0
- package/src/suite/components/suite-mobile-drawer.test.tsx +18 -2
- package/src/suite/components/suite-mobile-drawer.tsx +65 -98
- package/src/suite/components/suite-notification-bell.tsx +29 -4
- package/src/suite/components/suite-sidebar.tsx +25 -25
- package/src/suite/components/suite-skeleton.tsx +2 -2
- package/src/suite/components/suite-user-menu.tsx +9 -8
- package/src/suite/components/theme-provider.test.tsx +87 -3
- package/src/suite/components/theme-provider.tsx +144 -23
- package/src/suite/components/today-ui.tsx +79 -68
- package/src/suite/components/workspace-switcher.test.tsx +56 -0
- package/src/suite/components/workspace-switcher.tsx +3 -3
- package/src/suite/icons/app-accents.ts +12 -12
- package/src/suite/icons/glyphs.ts +6 -12
- package/src/suite/index.ts +27 -0
- package/src/suite/lib/apps.test.ts +9 -1
- package/src/suite/lib/apps.ts +14 -8
- package/src/suite/lib/cookies.ts +53 -0
- package/src/suite/lib/theme-boot.ts +32 -0
- package/src/suite/lib/theme-cookie.ts +7 -0
- package/src/suite/lib/use-sidebar-width.ts +5 -51
- package/dist/chunk-KDR6HI6F.mjs +0 -1075
- package/dist/chunk-NOI42JNZ.mjs +0 -151
- package/dist/chunk-VXISSXTB.mjs +0 -2564
- package/src/suite/lib/use-lock-mobile-page-zoom.test.tsx +0 -65
- package/src/suite/lib/use-lock-mobile-page-zoom.ts +0 -51
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { fireEvent, render, screen } from "@testing-library/react";
|
|
2
|
+
import { describe, expect, it } from "vitest";
|
|
3
|
+
|
|
4
|
+
import { Accordion } from "./Accordion";
|
|
5
|
+
import { CollapsibleSection } from "./CollapsibleSection";
|
|
6
|
+
|
|
7
|
+
describe("disclosure components", () => {
|
|
8
|
+
it("keeps closed accordion content out of keyboard navigation", () => {
|
|
9
|
+
render(
|
|
10
|
+
<Accordion
|
|
11
|
+
items={[{ id: "details", title: "Details", content: <a href="/more">More</a> }]}
|
|
12
|
+
/>,
|
|
13
|
+
);
|
|
14
|
+
|
|
15
|
+
const trigger = screen.getByRole("button", { name: "Details" });
|
|
16
|
+
const content = document.getElementById(trigger.getAttribute("aria-controls")!);
|
|
17
|
+
expect(trigger).toHaveAttribute("aria-expanded", "false");
|
|
18
|
+
expect(content).toHaveAttribute("aria-hidden", "true");
|
|
19
|
+
expect(content).toHaveAttribute("inert");
|
|
20
|
+
|
|
21
|
+
fireEvent.click(trigger);
|
|
22
|
+
expect(trigger).toHaveAttribute("aria-expanded", "true");
|
|
23
|
+
expect(content).toHaveAttribute("aria-hidden", "false");
|
|
24
|
+
expect(content).not.toHaveAttribute("inert");
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
it("keeps closed collapsible content out of keyboard navigation", () => {
|
|
28
|
+
render(
|
|
29
|
+
<CollapsibleSection title="Tokens" defaultOpen={false}>
|
|
30
|
+
<button type="button">Copy token</button>
|
|
31
|
+
</CollapsibleSection>,
|
|
32
|
+
);
|
|
33
|
+
|
|
34
|
+
const trigger = screen.getByRole("button", { name: "Tokens" });
|
|
35
|
+
const content = document.getElementById(trigger.getAttribute("aria-controls")!);
|
|
36
|
+
expect(content).toHaveAttribute("aria-hidden", "true");
|
|
37
|
+
expect(content).toHaveAttribute("inert");
|
|
38
|
+
});
|
|
39
|
+
});
|
|
@@ -143,10 +143,25 @@ export {
|
|
|
143
143
|
type IconProps as IconProps,
|
|
144
144
|
type IconName as IconName,
|
|
145
145
|
} from "@/components/icons";
|
|
146
|
-
export {
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
146
|
+
export {
|
|
147
|
+
Accordion,
|
|
148
|
+
type AccordionItem,
|
|
149
|
+
type AccordionProps,
|
|
150
|
+
} from "@/components/ui/Accordion";
|
|
151
|
+
export {
|
|
152
|
+
SegmentedControl,
|
|
153
|
+
type SegmentedControlOption,
|
|
154
|
+
type SegmentedControlProps,
|
|
155
|
+
} from "@/components/ui/SegmentedControl";
|
|
156
|
+
export {
|
|
157
|
+
CommandPalette,
|
|
158
|
+
type CommandItem,
|
|
159
|
+
type CommandPaletteProps,
|
|
160
|
+
} from "@/components/ui/CommandPalette";
|
|
161
|
+
export {
|
|
162
|
+
Calendar,
|
|
163
|
+
type CalendarProps,
|
|
164
|
+
} from "@/components/ui/Calendar";
|
|
150
165
|
export {
|
|
151
166
|
Tooltip,
|
|
152
167
|
TooltipProvider,
|
|
@@ -155,7 +170,10 @@ export {
|
|
|
155
170
|
type TooltipProviderProps,
|
|
156
171
|
type TooltipSide,
|
|
157
172
|
} from "@/components/ui/Tooltip";
|
|
158
|
-
export {
|
|
173
|
+
export {
|
|
174
|
+
EmptyState,
|
|
175
|
+
type EmptyStateProps,
|
|
176
|
+
} from "@/components/ui/EmptyState";
|
|
159
177
|
export {
|
|
160
178
|
FilterChips,
|
|
161
179
|
type FilterChip,
|
|
@@ -181,7 +199,10 @@ export {
|
|
|
181
199
|
type ComponentPropRow,
|
|
182
200
|
} from "@/components/ui/ComponentDocs";
|
|
183
201
|
export { ShowcaseWrapper } from "@/components/ui/ShowcaseWrapper";
|
|
184
|
-
export {
|
|
202
|
+
export {
|
|
203
|
+
CollapsibleSection,
|
|
204
|
+
type CollapsibleSectionProps,
|
|
205
|
+
} from "@/components/ui/CollapsibleSection";
|
|
185
206
|
export {
|
|
186
207
|
Display,
|
|
187
208
|
SectionTitle,
|
|
@@ -197,6 +218,23 @@ export {
|
|
|
197
218
|
Lead,
|
|
198
219
|
Mono,
|
|
199
220
|
Label,
|
|
221
|
+
type CaptionProps,
|
|
222
|
+
type DisplayProps,
|
|
223
|
+
type H1Props,
|
|
224
|
+
type H2Props,
|
|
225
|
+
type H3Props,
|
|
226
|
+
type H4Props,
|
|
227
|
+
type H5Props,
|
|
228
|
+
type LabelProps,
|
|
229
|
+
type LeadProps,
|
|
230
|
+
type MonoProps,
|
|
231
|
+
type OverlineProps,
|
|
232
|
+
type PProps,
|
|
233
|
+
type SectionTitleProps,
|
|
234
|
+
type SmallProps,
|
|
235
|
+
type TextBaseProps,
|
|
236
|
+
type TextTone,
|
|
237
|
+
type TextWeight,
|
|
200
238
|
} from "@/components/ui/Typography";
|
|
201
239
|
export {
|
|
202
240
|
Avatar as Avatar,
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { render, screen } from "@testing-library/react";
|
|
2
|
+
import { describe, expect, it } from "vitest";
|
|
3
|
+
|
|
4
|
+
import { Progress } from "./Progress";
|
|
5
|
+
|
|
6
|
+
describe("Progress", () => {
|
|
7
|
+
it("normalises invalid ranges and associates its visible label", () => {
|
|
8
|
+
render(<Progress label="Upload" value={200} max={0} showPercentage />);
|
|
9
|
+
|
|
10
|
+
const progressbar = screen.getByRole("progressbar", { name: "Upload" });
|
|
11
|
+
expect(progressbar).toHaveAttribute("aria-valuenow", "100");
|
|
12
|
+
expect(progressbar).toHaveAttribute("aria-valuemax", "100");
|
|
13
|
+
expect(progressbar).toHaveStyle({ width: "100%" });
|
|
14
|
+
});
|
|
15
|
+
});
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
+
import { createRef } from "react";
|
|
1
2
|
import { render, screen } from "@testing-library/react";
|
|
2
3
|
import { describe, expect, it } from "vitest";
|
|
3
|
-
import { Display, Lead, H1, SectionTitle } from "@/components/ui/Typography";
|
|
4
|
+
import { Display, Label, Lead, H1, SectionTitle } from "@/components/ui/Typography";
|
|
4
5
|
|
|
5
6
|
describe("typography scale", () => {
|
|
6
7
|
it("puts marketing headings on the fluid classes", () => {
|
|
@@ -24,4 +25,28 @@ describe("typography scale", () => {
|
|
|
24
25
|
expect(heading).not.toHaveClass("ph-hero-title");
|
|
25
26
|
expect(heading.className).toContain("font-bold");
|
|
26
27
|
});
|
|
28
|
+
|
|
29
|
+
it("forwards native props and refs to its semantic elements", () => {
|
|
30
|
+
const headingRef = createRef<HTMLHeadingElement>();
|
|
31
|
+
const labelRef = createRef<HTMLLabelElement>();
|
|
32
|
+
|
|
33
|
+
render(
|
|
34
|
+
<>
|
|
35
|
+
<H1 ref={headingRef} id="reports-title" aria-describedby="reports-help">
|
|
36
|
+
Native report heading
|
|
37
|
+
</H1>
|
|
38
|
+
<Label ref={labelRef} htmlFor="report-name">
|
|
39
|
+
Report name
|
|
40
|
+
</Label>
|
|
41
|
+
<input id="report-name" />
|
|
42
|
+
</>,
|
|
43
|
+
);
|
|
44
|
+
|
|
45
|
+
const heading = screen.getByRole("heading", { name: "Native report heading" });
|
|
46
|
+
const label = screen.getByText("Report name");
|
|
47
|
+
expect(heading).toHaveAttribute("aria-describedby", "reports-help");
|
|
48
|
+
expect(label).toHaveAttribute("for", "report-name");
|
|
49
|
+
expect(headingRef.current).toBe(heading);
|
|
50
|
+
expect(labelRef.current).toBe(label);
|
|
51
|
+
});
|
|
27
52
|
});
|
|
@@ -224,7 +224,7 @@ html.dark .today-page-frame__cloud--2 {
|
|
|
224
224
|
|
|
225
225
|
/* Today primary action — compact geometry, colour supplied by the app theme. */
|
|
226
226
|
.today-primary-action {
|
|
227
|
-
color: var(--ph-
|
|
227
|
+
color: var(--ph-text-primary);
|
|
228
228
|
background: color-mix(in oklab, var(--ph-brand) 12%, var(--ph-surface));
|
|
229
229
|
border: 1px solid color-mix(in oklab, var(--ph-brand) 28%, var(--ph-border));
|
|
230
230
|
box-shadow: 0 1px 0 color-mix(in oklab, var(--ph-brand) 8%, transparent);
|
|
@@ -269,7 +269,7 @@ html.dark .today-page-frame__cloud--2 {
|
|
|
269
269
|
color: var(--ph-violet, var(--ph-brand));
|
|
270
270
|
}
|
|
271
271
|
.today-primary-action--shellstack {
|
|
272
|
-
background: color-mix(in oklab, var(--ph-
|
|
272
|
+
background: color-mix(in oklab, var(--ph-text-primary) 6%, var(--ph-surface));
|
|
273
273
|
}
|
|
274
274
|
.today-primary-action--active .today-primary-action__icon {
|
|
275
275
|
background: var(--ph-brand);
|
|
@@ -492,6 +492,12 @@ button:hover > .ph-card {
|
|
|
492
492
|
transition-duration: 80ms;
|
|
493
493
|
}
|
|
494
494
|
|
|
495
|
+
/* Radix focuses the first menu item on open. The menu's highlighted state is
|
|
496
|
+
sufficient feedback, so do not retain an app-wide focus ring on that row. */
|
|
497
|
+
#app-switcher-menu .ph-dropdown-item:focus-visible {
|
|
498
|
+
box-shadow: none;
|
|
499
|
+
}
|
|
500
|
+
|
|
495
501
|
/* ── App bar (mobile) / top bar (desktop) ───────────────────────────────
|
|
496
502
|
Translucent, blurred, content scrolls beneath — like every native
|
|
497
503
|
shell. Colour-mix keeps it on-theme in both modes. */
|
package/src/styles/themes.css
CHANGED
|
@@ -16,9 +16,9 @@
|
|
|
16
16
|
|
|
17
17
|
--ph-text-primary: hsl(0 0% 5%);
|
|
18
18
|
--ph-text-secondary: hsl(0 0% 25%);
|
|
19
|
-
--ph-text-tertiary: hsl(0 0%
|
|
19
|
+
--ph-text-tertiary: hsl(0 0% 40%);
|
|
20
20
|
|
|
21
|
-
--ph-accent: hsl(19deg 100%
|
|
21
|
+
--ph-accent: hsl(19deg 100% 39%);
|
|
22
22
|
--ph-accent-hover: hsl(19deg 100% 42%);
|
|
23
23
|
--ph-blue: hsl(228deg 100% 56%);
|
|
24
24
|
--ph-violet: hsl(277deg 70% 48%);
|
|
@@ -29,6 +29,10 @@
|
|
|
29
29
|
--ph-danger: hsl(9deg 70% 48%);
|
|
30
30
|
--ph-info: hsl(217deg 90% 52%);
|
|
31
31
|
|
|
32
|
+
/* Legacy 3000-series tokens (--ph-text-3000, --ph-border-3000, …) are
|
|
33
|
+
superseded by the semantic --ph-text-*, --ph-border-*, and button tokens
|
|
34
|
+
above. Kept only so older custom themes keep working; do not use them in
|
|
35
|
+
new themes or components. */
|
|
32
36
|
--ph-text-3000: #111111;
|
|
33
37
|
--ph-primary-button-face: #ffffff;
|
|
34
38
|
--ph-primary-button-border: #b17816;
|
|
@@ -68,7 +72,7 @@
|
|
|
68
72
|
--ph-surface-raised: #ffffff;
|
|
69
73
|
--ph-surface-overlay: #ffffff;
|
|
70
74
|
--ph-border-subtle: hsl(75 14% 90%);
|
|
71
|
-
--ph-on-accent: #
|
|
75
|
+
--ph-on-accent: #ffffff;
|
|
72
76
|
--ph-on-violet: #ffffff;
|
|
73
77
|
--ph-on-success: #071b10;
|
|
74
78
|
--ph-on-warning: #1c1504;
|
|
@@ -83,54 +87,55 @@
|
|
|
83
87
|
[data-theme="hedgehog-dark"] {
|
|
84
88
|
color-scheme: dark;
|
|
85
89
|
|
|
86
|
-
|
|
87
|
-
--ph-
|
|
88
|
-
--ph-
|
|
89
|
-
--ph-
|
|
90
|
-
--ph-
|
|
91
|
-
--ph-surface-
|
|
92
|
-
--ph-surface-
|
|
93
|
-
--ph-
|
|
94
|
-
--ph-border
|
|
95
|
-
--ph-border-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
--ph-text-
|
|
99
|
-
--ph-text-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
--ph-accent
|
|
103
|
-
--ph-
|
|
104
|
-
--ph-
|
|
105
|
-
--ph-
|
|
106
|
-
|
|
107
|
-
--ph-success: hsl(149deg 55% 48%);
|
|
108
|
-
--ph-warning: hsl(43deg 85% 52%);
|
|
109
|
-
--ph-danger: hsl(9deg 65% 55%);
|
|
110
|
-
--ph-info: hsl(217deg 85% 58%);
|
|
111
|
-
--ph-on-accent: hsl(220 14% 8%);
|
|
112
|
-
--ph-on-violet: hsl(220 14% 8%);
|
|
113
|
-
--ph-on-success: hsl(220 14% 8%);
|
|
114
|
-
--ph-on-warning: hsl(220 14% 8%);
|
|
115
|
-
--ph-on-danger: hsl(220 14% 8%);
|
|
116
|
-
--ph-on-info: hsl(220 14% 8%);
|
|
117
|
-
--ph-focus-ring: hsl(217deg 95% 72%);
|
|
118
|
-
--ph-selected-bg: hsl(19deg 70% 18%);
|
|
119
|
-
--ph-selected-text: hsl(19deg 100% 72%);
|
|
120
|
-
--ph-selected-border: hsl(19deg 90% 55%);
|
|
121
|
-
|
|
122
|
-
--ph-text-3000: hsl(0 0% 96%);
|
|
123
|
-
--ph-primary-button-face: hsl(220 10% 15%);
|
|
124
|
-
--ph-primary-button-border: #c4861f;
|
|
125
|
-
--ph-primary-button-border-hover: #eb9d2a;
|
|
126
|
-
--ph-primary-frame-bg: #eb9d2a;
|
|
127
|
-
--ph-secondary-button-bg: hsl(220 8% 20%);
|
|
128
|
-
--ph-secondary-frame-bg: hsl(220 7% 26%);
|
|
129
|
-
--ph-secondary-button-border: hsl(220 6% 32%);
|
|
130
|
-
--ph-secondary-button-border-hover: hsl(220 5% 42%);
|
|
90
|
+
/* Microsoft Copilot-style dark UI: neutral graphite surfaces, blue accent. */
|
|
91
|
+
--ph-canvas: hsl(240 7% 6%);
|
|
92
|
+
--ph-surface: hsl(240 6% 10%);
|
|
93
|
+
--ph-muted: hsl(240 5% 13%);
|
|
94
|
+
--ph-toolbar: hsl(240 5% 15%);
|
|
95
|
+
--ph-surface-inset: hsl(240 7% 7%);
|
|
96
|
+
--ph-surface-raised: hsl(240 5% 13%);
|
|
97
|
+
--ph-surface-overlay: hsl(240 5% 14%);
|
|
98
|
+
--ph-border: hsl(240 5% 21%);
|
|
99
|
+
--ph-border-subtle: hsl(240 5% 15%);
|
|
100
|
+
--ph-border-strong: hsl(240 4% 36%);
|
|
101
|
+
|
|
102
|
+
--ph-text-primary: hsl(240 8% 94%);
|
|
103
|
+
--ph-text-secondary: hsl(240 5% 78%);
|
|
104
|
+
--ph-text-tertiary: hsl(240 4% 58%);
|
|
105
|
+
|
|
106
|
+
--ph-accent: #0084e8;
|
|
107
|
+
--ph-accent-hover: #106ebe;
|
|
108
|
+
--ph-blue: #00bcf2;
|
|
109
|
+
--ph-violet: #b146c2;
|
|
110
|
+
--ph-purple: #b146c2;
|
|
131
111
|
|
|
132
|
-
--ph-
|
|
133
|
-
--ph-
|
|
112
|
+
--ph-success: #6bb700;
|
|
113
|
+
--ph-warning: #ffb900;
|
|
114
|
+
--ph-danger: #d13438;
|
|
115
|
+
--ph-info: #00bcf2;
|
|
116
|
+
--ph-on-accent: #111111;
|
|
117
|
+
--ph-on-violet: #ffffff;
|
|
118
|
+
--ph-on-success: #111114;
|
|
119
|
+
--ph-on-warning: #111114;
|
|
120
|
+
--ph-on-danger: #ffffff;
|
|
121
|
+
--ph-on-info: #111114;
|
|
122
|
+
--ph-focus-ring: #4ca3f5;
|
|
123
|
+
--ph-selected-bg: #0078d426;
|
|
124
|
+
--ph-selected-text: #4ca3f5;
|
|
125
|
+
--ph-selected-border: #0078d4;
|
|
126
|
+
|
|
127
|
+
--ph-text-3000: hsl(240 8% 94%);
|
|
128
|
+
--ph-primary-button-face: #0078d4;
|
|
129
|
+
--ph-primary-button-border: #0078d4;
|
|
130
|
+
--ph-primary-button-border-hover: #106ebe;
|
|
131
|
+
--ph-primary-frame-bg: #0078d4;
|
|
132
|
+
--ph-secondary-button-bg: hsl(240 5% 15%);
|
|
133
|
+
--ph-secondary-frame-bg: hsl(240 5% 18%);
|
|
134
|
+
--ph-secondary-button-border: hsl(240 4% 30%);
|
|
135
|
+
--ph-secondary-button-border-hover: hsl(240 4% 40%);
|
|
136
|
+
|
|
137
|
+
--ph-border-3000: hsl(240 5% 18%);
|
|
138
|
+
--ph-accent-highlight-secondary: #0078d424;
|
|
134
139
|
}
|
|
135
140
|
|
|
136
141
|
/* OneNote — brand purple #7719aa on lavender paper. */
|
|
@@ -144,7 +149,7 @@
|
|
|
144
149
|
--ph-border-strong: #9b7bb8;
|
|
145
150
|
--ph-text-primary: #2d1b3d;
|
|
146
151
|
--ph-text-secondary: #5c4a6e;
|
|
147
|
-
--ph-text-tertiary: #
|
|
152
|
+
--ph-text-tertiary: #716080;
|
|
148
153
|
--ph-accent: #7719aa;
|
|
149
154
|
--ph-accent-hover: #5f1488;
|
|
150
155
|
--ph-blue: #185abd;
|
|
@@ -238,7 +243,7 @@
|
|
|
238
243
|
--ph-border-strong: hsl(69 8% 65%);
|
|
239
244
|
--ph-text-primary: hsl(0 0% 5%);
|
|
240
245
|
--ph-text-secondary: hsl(0 0% 25%);
|
|
241
|
-
--ph-text-tertiary: hsl(0 0%
|
|
246
|
+
--ph-text-tertiary: hsl(0 0% 40%);
|
|
242
247
|
--ph-accent: #1f6f43;
|
|
243
248
|
--ph-accent-hover: #185c37;
|
|
244
249
|
--ph-blue: #2f7f73;
|
|
@@ -282,7 +287,7 @@
|
|
|
282
287
|
--ph-text-primary: #eef4e9;
|
|
283
288
|
--ph-text-secondary: #c7d5c0;
|
|
284
289
|
--ph-text-tertiary: #91a28a;
|
|
285
|
-
--ph-accent: #
|
|
290
|
+
--ph-accent: #419359;
|
|
286
291
|
--ph-accent-hover: #55a96b;
|
|
287
292
|
--ph-blue: #57b3a3;
|
|
288
293
|
--ph-violet: #d4861a;
|
|
@@ -291,7 +296,7 @@
|
|
|
291
296
|
--ph-warning: #e58a12;
|
|
292
297
|
--ph-danger: #e06a49;
|
|
293
298
|
--ph-info: #57b3a3;
|
|
294
|
-
--ph-on-accent: #
|
|
299
|
+
--ph-on-accent: #111111;
|
|
295
300
|
--ph-on-violet: #151b17;
|
|
296
301
|
--ph-on-success: #071b10;
|
|
297
302
|
--ph-on-warning: #211606;
|
|
@@ -330,9 +335,9 @@
|
|
|
330
335
|
--ph-border: #dfdad9;
|
|
331
336
|
--ph-border-strong: #9893a5;
|
|
332
337
|
--ph-text-primary: #575279;
|
|
333
|
-
--ph-text-secondary: #
|
|
334
|
-
--ph-text-tertiary: #
|
|
335
|
-
--ph-accent: #
|
|
338
|
+
--ph-text-secondary: #6a6683;
|
|
339
|
+
--ph-text-tertiary: #6c667b;
|
|
340
|
+
--ph-accent: #7e649b;
|
|
336
341
|
--ph-accent-hover: #7c6594;
|
|
337
342
|
--ph-blue: #56949f;
|
|
338
343
|
--ph-violet: #907aa9;
|
|
@@ -384,7 +389,7 @@
|
|
|
384
389
|
--ph-border-strong: #524f67;
|
|
385
390
|
--ph-text-primary: #e0def4;
|
|
386
391
|
--ph-text-secondary: #908caa;
|
|
387
|
-
--ph-text-tertiary: #
|
|
392
|
+
--ph-text-tertiary: #a5a1b8;
|
|
388
393
|
--ph-accent: #c4a7e7;
|
|
389
394
|
--ph-accent-hover: #d4bcf0;
|
|
390
395
|
--ph-blue: #9ccfd8;
|
|
@@ -437,7 +442,7 @@
|
|
|
437
442
|
--ph-border-strong: #a8a8a3;
|
|
438
443
|
--ph-text-primary: #242424;
|
|
439
444
|
--ph-text-secondary: #4f4f4f;
|
|
440
|
-
--ph-text-tertiary: #
|
|
445
|
+
--ph-text-tertiary: #666666;
|
|
441
446
|
--ph-accent: #242424;
|
|
442
447
|
--ph-accent-hover: #000000;
|
|
443
448
|
--ph-blue: #437aff;
|
|
@@ -490,7 +495,7 @@
|
|
|
490
495
|
--ph-border-strong: #686868;
|
|
491
496
|
--ph-text-primary: #f2f2f2;
|
|
492
497
|
--ph-text-secondary: #c4c4c4;
|
|
493
|
-
--ph-text-tertiary: #
|
|
498
|
+
--ph-text-tertiary: #adadad;
|
|
494
499
|
--ph-accent: #f2f2f2;
|
|
495
500
|
--ph-accent-hover: #ffffff;
|
|
496
501
|
--ph-blue: #7da3ff;
|
|
@@ -540,9 +545,9 @@
|
|
|
540
545
|
--ph-border: #c4c8da;
|
|
541
546
|
--ph-border-strong: #a8aecb;
|
|
542
547
|
--ph-text-primary: #343b58;
|
|
543
|
-
--ph-text-secondary: #
|
|
544
|
-
--ph-text-tertiary: #
|
|
545
|
-
--ph-accent: #
|
|
548
|
+
--ph-text-secondary: #485890;
|
|
549
|
+
--ph-text-tertiary: #4f5883;
|
|
550
|
+
--ph-accent: #155fc5;
|
|
546
551
|
--ph-accent-hover: #2368c6;
|
|
547
552
|
--ph-blue: #2e7de9;
|
|
548
553
|
--ph-violet: #9854f1;
|
|
@@ -595,7 +600,7 @@
|
|
|
595
600
|
--ph-border-strong: #565f89;
|
|
596
601
|
--ph-text-primary: #c0caf5;
|
|
597
602
|
--ph-text-secondary: #a9b1d6;
|
|
598
|
-
--ph-text-tertiary: #
|
|
603
|
+
--ph-text-tertiary: #8d95b8;
|
|
599
604
|
--ph-accent: #7aa2f7;
|
|
600
605
|
--ph-accent-hover: #97b4f9;
|
|
601
606
|
--ph-blue: #7aa2f7;
|
|
@@ -635,7 +640,7 @@
|
|
|
635
640
|
--ph-data-7: #ff9e64;
|
|
636
641
|
}
|
|
637
642
|
|
|
638
|
-
/* Malibu —
|
|
643
|
+
/* Malibu — Shelly's GTA San Andreas-inspired sunset command-deck palette. */
|
|
639
644
|
[data-theme="malibu-light"] {
|
|
640
645
|
color-scheme: light;
|
|
641
646
|
--ph-canvas: #f6efeb;
|
|
@@ -650,8 +655,8 @@
|
|
|
650
655
|
--ph-border-strong: #b38b98;
|
|
651
656
|
--ph-text-primary: #30202d;
|
|
652
657
|
--ph-text-secondary: #64495a;
|
|
653
|
-
--ph-text-tertiary: #
|
|
654
|
-
--ph-accent: #
|
|
658
|
+
--ph-text-tertiary: #745c6a;
|
|
659
|
+
--ph-accent: #c4335c;
|
|
655
660
|
--ph-accent-hover: #b93a60;
|
|
656
661
|
--ph-blue: #3b8793;
|
|
657
662
|
--ph-violet: #7d3ca4;
|
|
@@ -744,6 +749,116 @@
|
|
|
744
749
|
--ph-data-7: #f54b87;
|
|
745
750
|
}
|
|
746
751
|
|
|
752
|
+
/* Microsoft — Office Fluent neutrals with the signature brand blue. */
|
|
753
|
+
[data-theme="microsoft-light"] {
|
|
754
|
+
color-scheme: light;
|
|
755
|
+
--ph-canvas: #faf9f8;
|
|
756
|
+
--ph-surface: #ffffff;
|
|
757
|
+
--ph-muted: #f3f2f1;
|
|
758
|
+
--ph-toolbar: #edebe9;
|
|
759
|
+
--ph-surface-inset: #f3f2f1;
|
|
760
|
+
--ph-surface-raised: #ffffff;
|
|
761
|
+
--ph-surface-overlay: #ffffff;
|
|
762
|
+
--ph-border: #e1dfdd;
|
|
763
|
+
--ph-border-subtle: #edebe9;
|
|
764
|
+
--ph-border-strong: #a19f9d;
|
|
765
|
+
--ph-text-primary: #201f1e;
|
|
766
|
+
--ph-text-secondary: #605e5c;
|
|
767
|
+
--ph-text-tertiary: #6b6967;
|
|
768
|
+
--ph-accent: #0072ca;
|
|
769
|
+
--ph-accent-hover: #106ebe;
|
|
770
|
+
--ph-blue: #0078d4;
|
|
771
|
+
--ph-violet: #8661c5;
|
|
772
|
+
--ph-purple: #8764b8;
|
|
773
|
+
--ph-success: #107c10;
|
|
774
|
+
--ph-warning: #ca5010;
|
|
775
|
+
--ph-danger: #a4262c;
|
|
776
|
+
--ph-info: #0078d4;
|
|
777
|
+
--ph-on-accent: #ffffff;
|
|
778
|
+
--ph-on-violet: #ffffff;
|
|
779
|
+
--ph-on-success: #ffffff;
|
|
780
|
+
--ph-on-warning: #ffffff;
|
|
781
|
+
--ph-on-danger: #ffffff;
|
|
782
|
+
--ph-on-info: #ffffff;
|
|
783
|
+
--ph-focus-ring: #0078d4;
|
|
784
|
+
--ph-selected-bg: #eff6fc;
|
|
785
|
+
--ph-selected-text: #005a9e;
|
|
786
|
+
--ph-selected-border: #6cb8f6;
|
|
787
|
+
--ph-text-3000: #ffffff;
|
|
788
|
+
--ph-primary-button-face: #0078d4;
|
|
789
|
+
--ph-primary-button-border: #0078d4;
|
|
790
|
+
--ph-primary-button-border-hover: #106ebe;
|
|
791
|
+
--ph-primary-frame-bg: #106ebe;
|
|
792
|
+
--ph-secondary-button-bg: #f3f2f1;
|
|
793
|
+
--ph-secondary-frame-bg: #edebe9;
|
|
794
|
+
--ph-secondary-button-border: #8a8886;
|
|
795
|
+
--ph-secondary-button-border-hover: #605e5c;
|
|
796
|
+
--ph-border-3000: #e1dfdd;
|
|
797
|
+
--ph-accent-highlight-secondary: rgba(0, 120, 212, 0.08);
|
|
798
|
+
--ph-data-1: #0078d4;
|
|
799
|
+
--ph-data-2: #8764b8;
|
|
800
|
+
--ph-data-3: #038387;
|
|
801
|
+
--ph-data-4: #ca5010;
|
|
802
|
+
--ph-data-5: #107c10;
|
|
803
|
+
--ph-data-6: #e3008c;
|
|
804
|
+
--ph-data-7: #4f6bed;
|
|
805
|
+
--ph-select-chevron: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' fill='none' stroke='%23605e5c' stroke-width='2.25' stroke-linecap='round' stroke-linejoin='round' viewBox='0 0 24 24'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
|
|
806
|
+
}
|
|
807
|
+
|
|
808
|
+
[data-theme="microsoft-dark"] {
|
|
809
|
+
color-scheme: dark;
|
|
810
|
+
--ph-canvas: #1b1a19;
|
|
811
|
+
--ph-surface: #201f1e;
|
|
812
|
+
--ph-muted: #252423;
|
|
813
|
+
--ph-toolbar: #323130;
|
|
814
|
+
--ph-surface-inset: #1b1a19;
|
|
815
|
+
--ph-surface-raised: #252423;
|
|
816
|
+
--ph-surface-overlay: #3b3a39;
|
|
817
|
+
--ph-border: #3b3a39;
|
|
818
|
+
--ph-border-subtle: #292827;
|
|
819
|
+
--ph-border-strong: #605e5c;
|
|
820
|
+
--ph-text-primary: #f3f2f1;
|
|
821
|
+
--ph-text-secondary: #c8c6c4;
|
|
822
|
+
--ph-text-tertiary: #a19f9d;
|
|
823
|
+
--ph-accent: #2899f5;
|
|
824
|
+
--ph-accent-hover: #479ef5;
|
|
825
|
+
--ph-blue: #2899f5;
|
|
826
|
+
--ph-violet: #9a7fe8;
|
|
827
|
+
--ph-purple: #b4a0ff;
|
|
828
|
+
--ph-success: #54b054;
|
|
829
|
+
--ph-warning: #f7b355;
|
|
830
|
+
--ph-danger: #ff7171;
|
|
831
|
+
--ph-info: #2899f5;
|
|
832
|
+
--ph-on-accent: #1b1a19;
|
|
833
|
+
--ph-on-violet: #1b1a19;
|
|
834
|
+
--ph-on-success: #1b1a19;
|
|
835
|
+
--ph-on-warning: #1b1a19;
|
|
836
|
+
--ph-on-danger: #1b1a19;
|
|
837
|
+
--ph-on-info: #1b1a19;
|
|
838
|
+
--ph-focus-ring: #479ef5;
|
|
839
|
+
--ph-selected-bg: #203855;
|
|
840
|
+
--ph-selected-text: #6cb8f6;
|
|
841
|
+
--ph-selected-border: #2899f5;
|
|
842
|
+
--ph-text-3000: #1b1a19;
|
|
843
|
+
--ph-primary-button-face: #2899f5;
|
|
844
|
+
--ph-primary-button-border: #2899f5;
|
|
845
|
+
--ph-primary-button-border-hover: #479ef5;
|
|
846
|
+
--ph-primary-frame-bg: #479ef5;
|
|
847
|
+
--ph-secondary-button-bg: #252423;
|
|
848
|
+
--ph-secondary-frame-bg: #323130;
|
|
849
|
+
--ph-secondary-button-border: #605e5c;
|
|
850
|
+
--ph-secondary-button-border-hover: #c8c6c4;
|
|
851
|
+
--ph-border-3000: #323130;
|
|
852
|
+
--ph-accent-highlight-secondary: rgba(40, 153, 245, 0.14);
|
|
853
|
+
--ph-data-1: #2899f5;
|
|
854
|
+
--ph-data-2: #9a7fe8;
|
|
855
|
+
--ph-data-3: #45d1d6;
|
|
856
|
+
--ph-data-4: #f7b355;
|
|
857
|
+
--ph-data-5: #54b054;
|
|
858
|
+
--ph-data-6: #ff8ad4;
|
|
859
|
+
--ph-data-7: #7b9bff;
|
|
860
|
+
}
|
|
861
|
+
|
|
747
862
|
/* Semantic button contrast for dark palettes. */
|
|
748
863
|
:is(
|
|
749
864
|
[data-theme="hedgehog-dark"],
|
|
@@ -752,7 +867,8 @@
|
|
|
752
867
|
[data-theme="rosepine-dark"],
|
|
753
868
|
[data-theme="kraken-dark"],
|
|
754
869
|
[data-theme="deepsea-dark"],
|
|
755
|
-
[data-theme="malibu-dark"]
|
|
870
|
+
[data-theme="malibu-dark"],
|
|
871
|
+
[data-theme="microsoft-dark"]
|
|
756
872
|
) {
|
|
757
873
|
.ph-btn-signal {
|
|
758
874
|
--ph-btn-face: color-mix(in oklab, var(--ph-accent) 62%, black);
|
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
|
-
import { useEffect } from "react";
|
|
3
|
+
import { useEffect, useLayoutEffect } from "react";
|
|
4
4
|
import { BlockNoteSchema, defaultBlockSpecs } from "@blocknote/core";
|
|
5
5
|
import { BlockNoteViewRaw, useCreateBlockNote } from "@blocknote/react";
|
|
6
6
|
import "@blocknote/react/style.css";
|
|
7
7
|
|
|
8
8
|
import { useSuiteTheme } from "./theme-provider";
|
|
9
9
|
|
|
10
|
+
// Parse the message before first paint so the editor never flashes empty.
|
|
11
|
+
const useIsomorphicLayoutEffect =
|
|
12
|
+
typeof window !== "undefined" ? useLayoutEffect : useEffect;
|
|
13
|
+
|
|
10
14
|
const assistantSchema = BlockNoteSchema.create({
|
|
11
15
|
blockSpecs: {
|
|
12
16
|
paragraph: defaultBlockSpecs.paragraph,
|
|
@@ -29,7 +33,7 @@ export default function SuiteAiBlockNoteMessage({
|
|
|
29
33
|
const { resolvedTheme } = useSuiteTheme();
|
|
30
34
|
const editor = useCreateBlockNote({ schema: assistantSchema });
|
|
31
35
|
|
|
32
|
-
|
|
36
|
+
useIsomorphicLayoutEffect(() => {
|
|
33
37
|
try {
|
|
34
38
|
const blocks = editor.tryParseMarkdownToBlocks(markdown);
|
|
35
39
|
editor.replaceBlocks(
|
|
@@ -43,6 +47,13 @@ export default function SuiteAiBlockNoteMessage({
|
|
|
43
47
|
}
|
|
44
48
|
}, [editor, markdown]);
|
|
45
49
|
|
|
50
|
+
// BlockNote renders the body as a ProseMirror contenteditable (.tiptap);
|
|
51
|
+
// give that node an accessible name so axe's aria-input-field-name passes.
|
|
52
|
+
useEffect(() => {
|
|
53
|
+
const el = (editor as unknown as { domElement?: HTMLElement }).domElement;
|
|
54
|
+
el?.setAttribute("aria-label", "Assistant message");
|
|
55
|
+
}, [editor]);
|
|
56
|
+
|
|
46
57
|
return (
|
|
47
58
|
<BlockNoteViewRaw
|
|
48
59
|
editor={editor}
|