Skip to content

Commit ee534c5

Browse files
committed
...
1 parent 089159e commit ee534c5

File tree

16 files changed

+1864
-1509
lines changed

16 files changed

+1864
-1509
lines changed

homedocs/src/examples/theme-editor/Preview.tsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import {
66
Prop,
77
} from "cx/ui";
88
import { Repeater } from "cx/widgets";
9-
import { ThemeVarsDiv } from "cx-theme-variables";
9+
import { ThemeVarsDiv, ThemeVarsRoot } from "cx-theme-variables";
1010
import { m } from "./model";
1111
import { examples, ExampleDef } from "./examples";
1212
import { categoriesToTheme, fontOptions } from "./data";
@@ -43,9 +43,14 @@ function getGoogleFontUrl(fontId: string | null): string | undefined {
4343
export const Preview = createFunctionalComponent(() => (
4444
<ThemeVarsDiv
4545
theme={computable(m.categories, categoriesToTheme)}
46+
cssSelector=".theme-editor-preview"
4647
class="flex-1 p-6 overflow-y-auto border-r border-border"
4748
applyReset
4849
>
50+
<ThemeVarsRoot
51+
theme={computable(m.categories, categoriesToTheme)}
52+
cssSelector=".theme-editor-preview"
53+
/>
4954
<link
5055
href={computable(m.font, getGoogleFontUrl)}
5156
rel="stylesheet"

homedocs/src/examples/theme-editor/data.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,12 @@ const variableMetadata: Array<{
223223
type: "size",
224224
category: "inputs",
225225
},
226+
{
227+
key: "inputBorderWidth",
228+
label: "Border width",
229+
type: "size",
230+
category: "inputs",
231+
},
226232
// Checks & Switches
227233
{
228234
key: "checkboxSize",
@@ -525,6 +531,14 @@ const variableMetadata: Array<{
525531
type: "size",
526532
category: "sections",
527533
},
534+
// Dropdowns
535+
{
536+
key: "dropdownBorderWidth",
537+
label: "Border width",
538+
type: "size",
539+
category: "dropdowns",
540+
},
541+
528542
// Toasts
529543
{
530544
key: "toastBackgroundColor",
@@ -564,6 +578,12 @@ const variableMetadata: Array<{
564578
},
565579

566580
// Calendar
581+
{
582+
key: "calendarBorderWidth",
583+
label: "Border width",
584+
type: "size",
585+
category: "calendar",
586+
},
567587
{
568588
key: "calendarBackgroundColor",
569589
label: "Background",
@@ -625,6 +645,7 @@ const categoryMetadata = [
625645
{ id: "calendar", name: "Calendar", icon: "calendar", group: "Components" },
626646
{ id: "sections", name: "Sections", icon: "panel-top", group: "Components" },
627647
{ id: "toasts", name: "Toasts", icon: "bell", group: "Components" },
648+
{ id: "dropdowns", name: "Dropdowns", icon: "drop-down", group: "Components" },
628649
];
629650

630651
export const categoryGroups = [

homedocs/src/examples/theme-editor/examples.ts

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ export const examples: ExampleDef[] = [
6969
{
7070
id: "lookup-field",
7171
name: "LookupField",
72-
categories: ["colors", "inputs", "sizing", "effects"],
72+
categories: ["colors", "inputs", "dropdowns", "sizing", "effects"],
7373
component: () => import("../forms/LookupFieldExample"),
7474
},
7575
{
@@ -154,6 +154,18 @@ export const examples: ExampleDef[] = [
154154
categories: ["colors", "toasts", "effects"],
155155
component: () => import("../layout/ToastDeclarativeExample"),
156156
},
157+
{
158+
id: "dropdown-basic",
159+
name: "Dropdown",
160+
categories: ["colors", "dropdowns", "effects"],
161+
component: () => import("../layout/DropdownBasicExample"),
162+
},
163+
{
164+
id: "dropdown-search",
165+
name: "Dropdown Search",
166+
categories: ["colors", "dropdowns", "effects"],
167+
component: () => import("../layout/DropdownSearchExample"),
168+
},
157169
{
158170
id: "tooltip",
159171
name: "Tooltip",
@@ -263,9 +275,15 @@ export const examples: ExampleDef[] = [
263275
{
264276
id: "menu",
265277
name: "Menu",
266-
categories: ["colors", "sizing", "effects"],
278+
categories: ["colors", "dropdowns", "sizing", "effects"],
267279
component: () => import("../layout/MenuVerticalExample"),
268280
},
281+
{
282+
id: "context-menu",
283+
name: "Context Menu",
284+
categories: ["colors", "dropdowns", "effects"],
285+
component: () => import("../layout/ContextMenuExample"),
286+
},
269287

270288
// Icons
271289
{

packages/cx-theme-variables/src/ThemeVariables.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ export interface ThemeVariables {
4848
inputLineHeight: string;
4949
inputPaddingX: string;
5050
inputPaddingY: string;
51+
inputBorderWidth: string;
5152
checkboxSize: string;
5253

5354
buttonBackgroundColor: string;
@@ -83,6 +84,8 @@ export interface ThemeVariables {
8384
gridDataBackgroundColor: string;
8485
gridDataBorderColor: string;
8586

87+
dropdownBorderWidth: string;
88+
8689
toastBackgroundColor: string;
8790
toastBorderWidth: string;
8891
toastBorderColor: string;
@@ -102,6 +105,7 @@ export interface ThemeVariables {
102105
sectionFooterMargin: string;
103106
sectionFooterBorderWidth: string;
104107

108+
calendarBorderWidth: string;
105109
calendarBackgroundColor: string;
106110
calendarPadding: string;
107111
calendarHeaderFontWeight: string;
@@ -162,6 +166,7 @@ export const variableMap: Record<keyof ThemeVariables, string> = {
162166
inputLineHeight: "--cx-input-line-height",
163167
inputPaddingX: "--cx-input-padding-x",
164168
inputPaddingY: "--cx-input-padding-y",
169+
inputBorderWidth: "--cx-input-border-width",
165170
checkboxSize: "--cx-checkbox-size",
166171

167172
buttonBackgroundColor: "--cx-button-background-color",
@@ -197,6 +202,8 @@ export const variableMap: Record<keyof ThemeVariables, string> = {
197202
gridDataBackgroundColor: "--cx-grid-data-background-color",
198203
gridDataBorderColor: "--cx-grid-data-border-color",
199204

205+
dropdownBorderWidth: "--cx-dropdown-border-width",
206+
200207
toastBackgroundColor: "--cx-toast-background-color",
201208
toastBorderWidth: "--cx-toast-border-width",
202209
toastBorderColor: "--cx-toast-border-color",
@@ -216,6 +223,7 @@ export const variableMap: Record<keyof ThemeVariables, string> = {
216223
sectionFooterMargin: "--cx-section-footer-margin",
217224
sectionFooterBorderWidth: "--cx-section-footer-border-width",
218225

226+
calendarBorderWidth: "--cx-calendar-border-width",
219227
calendarBackgroundColor: "--cx-calendar-background-color",
220228
calendarPadding: "--cx-calendar-padding",
221229
calendarHeaderFontWeight: "--cx-calendar-header-font-weight",

packages/cx-theme-variables/src/ThemeVarsDiv.tsx

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,12 @@ export interface ThemeVarsDivConfig extends StyledContainerConfig {
2020

2121
/** Apply reset styles (background, color, font) to the div */
2222
applyReset?: boolean;
23+
24+
/** CSS selector (e.g. ".my-theme") to use class-based scoping instead of inline styles.
25+
* When provided, the class is applied to the div and a data-theme-container-class attribute
26+
* is set so portaled overlays can inherit the scoped theme. A separate ThemeVarsRoot with
27+
* the same cssSelector must define the actual CSS variables. */
28+
cssSelector?: string;
2329
}
2430

2531
/**
@@ -29,6 +35,7 @@ export interface ThemeVarsDivConfig extends StyledContainerConfig {
2935
export class ThemeVarsDiv extends StyledContainer {
3036
declare theme: Partial<ThemeVariables>;
3137
declare applyReset: boolean;
38+
declare cssSelector: string;
3239

3340
constructor(config: ThemeVarsDivConfig) {
3441
super(config);
@@ -43,18 +50,20 @@ export class ThemeVarsDiv extends StyledContainer {
4350
render(context: any, instance: any, key: string) {
4451
const { data } = instance;
4552
const { theme } = data;
46-
4753
const themeStyle = themeVariablesToStyle(theme);
4854

55+
let themeCssClass = this.cssSelector?.startsWith(".") ? this.cssSelector.substring(1) : this.cssSelector;
56+
4957
return (
5058
<div
5159
key={key}
52-
className={data.classNames}
60+
className={this.CSS.expand(data.classNames, themeCssClass)}
5361
style={{
5462
...themeStyle,
5563
...(this.applyReset ? resetStyle : null),
5664
...data.style,
5765
}}
66+
data-theme-container-class={themeCssClass}
5867
>
5968
{this.renderChildren(context, instance)}
6069
</div>
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { ConfigureOverlayContainerContext } from "cx/widgets";
2+
3+
export function configureOverlayContainer(
4+
containerEl: HTMLElement,
5+
context: ConfigureOverlayContainerContext
6+
) {
7+
let { relatedElement } = context;
8+
if (!relatedElement) return;
9+
let el: HTMLElement | null = relatedElement;
10+
while (el) {
11+
if (el.dataset?.themeContainerClass) {
12+
containerEl.classList.add(el.dataset.themeContainerClass);
13+
return;
14+
}
15+
el = el.parentElement;
16+
}
17+
}

packages/cx-theme-variables/src/index.scss

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,12 @@ $mod: map.get($cx-besm, mod);
3232
}
3333
}
3434

35+
@if (cx-included("cx/widgets/Dropdown") and cx-included("cx/widgets/Calendar")) {
36+
.#{$block}dropdown > .#{$block}calendar {
37+
--cx-calendar-border-width: 0;
38+
}
39+
}
40+
3541
@if (cx-included("cx/widgets/Grid")) {
3642
.#{$element}grid-data:last-child {
3743
border-bottom-left-radius: var(--cx-grid-border-radius);

packages/cx-theme-variables/src/index.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,15 @@
11
import { Localization } from "cx/ui";
2+
import { OverlayBase } from "cx/widgets";
3+
import { configureOverlayContainer } from "./configureOverlayContainer";
24

35
export * from "./ThemeVariables";
46
export * from "./ThemeVarsRoot";
57
export * from "./ThemeVarsDiv";
68
export * from "./presets";
79

810
export function applyThemeOverrides() {
11+
OverlayBase.configureOverlayContainer = configureOverlayContainer;
12+
913
Localization.override("cx/widgets/Window", {
1014
animate: true,
1115
destroyDelay: 200,
@@ -23,6 +27,11 @@ export function applyThemeOverrides() {
2327
footerDirection: "row-reverse",
2428
footerJustify: "start",
2529
});
30+
31+
Localization.override("cx/widgets/ContextMenu", {
32+
arrow: true,
33+
offset: 5,
34+
});
2635
}
2736

2837
applyThemeOverrides();

packages/cx-theme-variables/src/maps.scss

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
@use "./widgets/form/Calendar.scss" as *;
1616
@use "./widgets/form/Label.scss" as *;
1717
@use "./widgets/Section.scss" as *;
18+
@use "./widgets/overlay/Dropdown.scss" as *;
1819
@use "./widgets/overlay/Toast.scss" as *;
1920

2021
// =============================================================================
@@ -125,18 +126,7 @@ $cx-section-mods: cx-deep-map-merge(
125126
)
126127
);
127128

128-
// MENU
129-
$cx-dropdown-styles: map-merge(
130-
$cx-dropdown-styles,
131-
(
132-
font-size: $cx-default-box-font-size - 1px,
133-
font-weight: var(--cx-theme-font-weight),
134-
border-width: 1px,
135-
border-style: solid,
136-
border-color: var(--cx-theme-border-color),
137-
box-shadow: var(--cx-theme-box-shadow-elevated),
138-
)
139-
);
129+
// MENU / DROPDOWN - see widgets/overlay/Dropdown.scss
140130

141131
$cx-menu-state-style-map: map-merge(
142132
$cx-menu-state-style-map,

packages/cx-theme-variables/src/presets/default.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ const defaultPreset: ThemeVariables = {
1313
borderColor: "lightgray",
1414
boxShadow: "0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24)",
1515
boxShadowElevated:
16-
"0 4px 8px rgba(0, 0, 0, 0.2), 0 4px 8px rgba(0, 0, 0, 0.3)",
16+
"0 4px 8px rgba(0, 0, 0, 0.17), 0 4px 8px rgba(0, 0, 0, 0.23)",
1717
focusBoxShadow: "0 0 0 2px rgba(25, 118, 210, 0.4)",
1818
borderRadius: "4px",
1919
baseFontSize: "14px",
@@ -53,6 +53,7 @@ const defaultPreset: ThemeVariables = {
5353
inputLineHeight: "22px",
5454
inputPaddingX: "6px",
5555
inputPaddingY: "6px",
56+
inputBorderWidth: "1px",
5657
checkboxSize: "16px",
5758

5859
buttonBackgroundColor: "#f5f5f5",
@@ -88,6 +89,8 @@ const defaultPreset: ThemeVariables = {
8889
gridDataBackgroundColor: "none",
8990
gridDataBorderColor: "#e0e0e0",
9091

92+
dropdownBorderWidth: "1px",
93+
9194
toastBackgroundColor: "var(--cx-theme-surface-color)",
9295
toastBorderWidth: "1px",
9396
toastBorderColor: "var(--cx-theme-border-color)",
@@ -110,6 +113,7 @@ const defaultPreset: ThemeVariables = {
110113
sectionFooterMargin: "0",
111114
sectionFooterBorderWidth: "0",
112115

116+
calendarBorderWidth: "var(--cx-input-border-width)",
113117
calendarBackgroundColor: "white",
114118
calendarPadding: "var(--cx-input-padding-y)",
115119
calendarHeaderFontWeight: "500",

0 commit comments

Comments
 (0)