Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion editor/theme/theme.ts
Original file line number Diff line number Diff line change
Expand Up @@ -375,6 +375,8 @@ export const theme: v0_8.Types.Theme = {
h1: h1Light,
h2: h2Light,
h3: h3Light,
h4: {},
h5: {},
iframe,
input: inputLight,
p: pLight,
Expand All @@ -389,7 +391,6 @@ export const theme: v0_8.Types.Theme = {
h3: [...Object.keys(h3Light)],
h4: [],
h5: [],
h6: [],
ul: [...Object.keys(unorderedListLight)],
ol: [...Object.keys(orderedListLight)],
li: [...Object.keys(listItemLight)],
Expand Down
8 changes: 6 additions & 2 deletions renderers/lit/src/0.8/styles/colors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@ const color = <C extends PaletteKeyVals>(src: PaletteKey<C>) =>
background-color: light-dark(oklch(from var(${toProp(
key
)}) l c h / calc(alpha * ${o.toFixed(1)})), oklch(from var(${toProp(
inverseKey
)}) l c h / calc(alpha * ${o.toFixed(1)})) );
inverseKey
)}) l c h / calc(alpha * ${o.toFixed(1)})) );
}
`);
}
Expand Down Expand Up @@ -92,5 +92,9 @@ export const colors = [
.color-bgc-transparent {
background-color: transparent;
}

:host {
color-scheme: var(--color-scheme);
}
`,
];
8 changes: 8 additions & 0 deletions renderers/lit/src/0.8/styles/type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,14 @@ export const type = `
white-space: pre-line;
}

.typography-ws-nw {
white-space: nowrap;
}

.typography-td-none {
text-decoration: none;
}

/** Weights **/

${new Array(9)
Expand Down
17 changes: 14 additions & 3 deletions renderers/lit/src/0.8/types/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,8 @@ export type Theme = {
h1: Record<string, boolean>;
h2: Record<string, boolean>;
h3: Record<string, boolean>;
h4: Record<string, boolean>;
h5: Record<string, boolean>;
iframe: Record<string, boolean>;
input: Record<string, boolean>;
p: Record<string, boolean>;
Expand All @@ -152,7 +154,6 @@ export type Theme = {
h3: string[];
h4: string[];
h5: string[];
h6: string[];
ul: string[];
ol: string[];
li: string[];
Expand All @@ -177,7 +178,17 @@ export type Theme = {
Row?: Record<string, string>;
Slider?: Record<string, string>;
Tabs?: Record<string, string>;
Text?: Record<string, string>;
Text?:
| Record<string, string>
| {
h1: Record<string, string>;
h2: Record<string, string>;
h3: Record<string, string>;
h4: Record<string, string>;
h5: Record<string, string>;
body: Record<string, string>;
caption: Record<string, string>;
};
TextField?: Record<string, string>;
Video?: Record<string, string>;
};
Expand Down Expand Up @@ -274,7 +285,7 @@ export type ValueMap = DataObject & {
valueNumber?: number;
valueBoolean?: boolean;
valueMap?: ValueMap[];
}
};

export interface DeleteSurfaceMessage {
surfaceId: string;
Expand Down
1 change: 0 additions & 1 deletion renderers/lit/src/0.8/ui/button.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ export class Button extends Root {
display: block;
flex: var(--weight);
min-height: 0;
overflow: auto;
}
`,
];
Expand Down
13 changes: 9 additions & 4 deletions renderers/lit/src/0.8/ui/component-registry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,18 @@
import { CustomElementConstructorOf } from "./ui.js";

export class ComponentRegistry {
private registry: Map<string, CustomElementConstructorOf<HTMLElement>> = new Map();
private registry: Map<string, CustomElementConstructorOf<HTMLElement>> =
new Map();

register(
typeName: string,
constructor: CustomElementConstructorOf<HTMLElement>,
tagName?: string
) {
if (!/^[a-zA-Z0-9]+$/.test(typeName)) {
throw new Error(`[Registry] Invalid typeName '${typeName}'. Must be alphanumeric.`);
throw new Error(
`[Registry] Invalid typeName '${typeName}'. Must be alphanumeric.`
);
}

this.registry.set(typeName, constructor);
Expand All @@ -35,7 +38,9 @@ export class ComponentRegistry {
if (existingName) {
// Constructor is already registered.
if (existingName !== actualTagName) {
throw new Error(`Component ${typeName} is already registered as ${existingName}, but requested as ${actualTagName}.`);
throw new Error(
`Component ${typeName} is already registered as ${existingName}, but requested as ${actualTagName}.`
);
}
return;
}
Expand All @@ -50,4 +55,4 @@ export class ComponentRegistry {
}
}

export const REGISTRY = new ComponentRegistry();
export const componentRegistry = new ComponentRegistry();
21 changes: 7 additions & 14 deletions renderers/lit/src/0.8/ui/directives/markdown.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ class MarkdownDirective extends Directive {

#originalClassMap = new Map<string, RenderRule | undefined>();
#applyTagClassMap(tagClassMap: Record<string, string[]>) {
Object.entries(tagClassMap).forEach(([tag, classes]) => {
Object.entries(tagClassMap).forEach(([tag]) => {
let tokenName;
switch (tag) {
case "p":
Expand Down Expand Up @@ -100,34 +100,27 @@ class MarkdownDirective extends Directive {
}

const key = `${tokenName}_open`;
const original: RenderRule | undefined =
this.#markdownIt.renderer.rules[key];
this.#originalClassMap.set(key, original);

this.#markdownIt.renderer.rules[key] = (
tokens,
idx,
options,
env,
_env,
self
) => {
const token = tokens[idx];
for (const clazz of classes) {
const tokenClasses = tagClassMap[token.tag] ?? [];
for (const clazz of tokenClasses) {
token.attrJoin("class", clazz);
}

if (original) {
return original.call(this, tokens, idx, options, env, self);
} else {
return self.renderToken(tokens, idx, options);
}
return self.renderToken(tokens, idx, options);
};
});
}

#unapplyTagClassMap() {
for (const [key, original] of this.#originalClassMap) {
this.#markdownIt.renderer.rules[key] = original;
for (const [key] of this.#originalClassMap) {
delete this.#markdownIt.renderer.rules[key];
}

this.#originalClassMap.clear();
Expand Down
29 changes: 4 additions & 25 deletions renderers/lit/src/0.8/ui/root.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,7 @@ import { StringValue } from "../types/primitives.js";
import { Theme, AnyComponentNode, SurfaceID } from "../types/types.js";
import { themeContext } from "./context/theme.js";
import { structuralStyles } from "./styles.js";
import { ComponentRegistry, REGISTRY } from './component-registry.js';
import { ThemeManager } from "./theme/manager.js";
import { componentRegistry } from "./component-registry.js";

type NodeOfType<T extends AnyComponentNode["type"]> = Extract<
AnyComponentNode,
Expand Down Expand Up @@ -82,6 +81,7 @@ export class Root extends SignalWatcher(LitElement) {
css`
:host {
display: flex;
flex-direction: column;
gap: 8px;
max-height: 80%;
}
Expand All @@ -94,23 +94,6 @@ export class Root extends SignalWatcher(LitElement) {
*/
#lightDomEffectDisposer: null | (() => void) = null;

#themeUnsubscribe: null | (() => void) = null;

connectedCallback() {
super.connectedCallback();
this.#themeUnsubscribe = ThemeManager.subscribe((sheets) => {
if (this.shadowRoot) {
const elementStyles = (this.constructor as typeof LitElement).elementStyles;
const baseStyles = elementStyles.map(s => {
if (s instanceof CSSStyleSheet) return s;
return s.styleSheet;
}).filter((s): s is CSSStyleSheet => !!s);

this.shadowRoot.adoptedStyleSheets = [...baseStyles, ...sheets];
}
});
}

protected willUpdate(changedProperties: PropertyValues<this>): void {
if (changedProperties.has("childComponents")) {
if (this.#lightDomEffectDisposer) {
Expand Down Expand Up @@ -140,10 +123,6 @@ export class Root extends SignalWatcher(LitElement) {
if (this.#lightDomEffectDisposer) {
this.#lightDomEffectDisposer();
}

if (this.#themeUnsubscribe) {
this.#themeUnsubscribe();
}
}

/**
Expand All @@ -163,7 +142,7 @@ export class Root extends SignalWatcher(LitElement) {
return html` ${map(components, (component) => {
// 1. Check if there is a registered custom component or override.
if (this.enableCustomElements) {
const registeredCtor = REGISTRY.get(component.type);
const registeredCtor = componentRegistry.get(component.type);
// We also check customElements.get for non-registered but defined elements
const elCtor = registeredCtor || customElements.get(component.type);

Expand Down Expand Up @@ -522,7 +501,7 @@ export class Root extends SignalWatcher(LitElement) {
}

const node = component as AnyComponentNode;
const registeredCtor = REGISTRY.get(component.type);
const registeredCtor = componentRegistry.get(component.type);
const elCtor = registeredCtor || customElements.get(component.type);

if (!elCtor) {
Expand Down
17 changes: 9 additions & 8 deletions renderers/lit/src/0.8/ui/surface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ export class Surface extends Root {
:host {
display: flex;
min-height: 0;
overflow: auto;
max-height: 100%;
flex-direction: column;
gap: 16px;
Expand Down Expand Up @@ -75,17 +74,19 @@ export class Surface extends Root {
for (const [key, value] of Object.entries(this.surface.styles)) {
switch (key) {
case "primaryColor": {
for (let i = 0; i <= 100; i++) {
styles[`--p-${i}`] = `color-mix(in srgb, ${value} ${
100 - i
}%, #fff ${i}%)`;
}
// Ignored for now.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NIT: Is it worth clarifying why this is being ignored? Here and below.

// for (let i = 0; i <= 100; i++) {
// styles[`--p-${i}`] = `color-mix(in srgb, ${value} ${
// 100 - i
// }%, #fff ${i}%)`;
// }
break;
}

case "font": {
styles["--font-family"] = value;
styles["--font-family-flex"] = value;
// Ignored for now.
// styles["--font-family"] = value;
// styles["--font-family-flex"] = value;
break;
}
}
Expand Down
22 changes: 21 additions & 1 deletion renderers/lit/src/0.8/ui/text.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,15 @@ export class Text extends Root {
display: block;
flex: var(--weight);
}

h1,
h2,
h3,
h4,
h5 {
line-height: inherit;
font: inherit;
}
`,
];

Expand Down Expand Up @@ -109,10 +118,21 @@ export class Text extends Root {
this.usageHint ? this.theme.components.Text[this.usageHint] : {}
);

let additionalStyles: Record<string, string> = {};
const styles = this.theme.additionalStyles?.Text;
if (styles) {
if ("h1" in styles) {
const hint = this.usageHint ?? "body";
additionalStyles = styles[hint] as Record<string, string>;
} else {
additionalStyles = styles;
}
}
Comment on lines +121 to +130
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NIT: this logic smells to me like it would be better served as its own private method for readability, as you could improve the readability by using guard clauses instead of nested conditionals; something like:

#getAdditionalStyles(...): Record<string, string> {
  const styles = this.theme.additionalStyles?.Text;
  if (!styles) return {};

  // etc.
}

Feel free to do this in a followup PR if you want.


return html`<section
class=${classMap(classes)}
style=${this.theme.additionalStyles?.Text
? styleMap(this.theme.additionalStyles?.Text)
? styleMap(additionalStyles)
: nothing}
>
${this.#renderText()}
Expand Down
42 changes: 0 additions & 42 deletions renderers/lit/src/0.8/ui/theme/manager.ts

This file was deleted.

4 changes: 1 addition & 3 deletions renderers/lit/src/0.8/ui/ui.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,8 @@ import { Video } from "./video.js";

export * as Context from "./context/theme.js";
export * as Utils from "./utils/utils.js";
export { ComponentRegistry, REGISTRY } from "./component-registry.js";
export { ComponentRegistry, componentRegistry } from "./component-registry.js";
export { registerCustomComponents } from "./custom-components/index.js";
export { ThemeManager } from "./theme/manager.js";


export {
Audio,
Expand Down
Binary file modified samples/agent/adk/contact_lookup/images/profile1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified samples/agent/adk/contact_lookup/images/profile2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified samples/agent/adk/contact_lookup/images/profile3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading