@esphome/compose-ui 0.1.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/dist/index.js ADDED
@@ -0,0 +1,686 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ Button: () => Button,
24
+ COMPOSE_UI_INTENTS: () => COMPOSE_UI_INTENTS,
25
+ Card: () => Card,
26
+ Col: () => Col,
27
+ DropdownField: () => DropdownField,
28
+ Grid: () => Grid,
29
+ GridItem: () => GridItem,
30
+ HStack: () => HStack,
31
+ Row: () => Row,
32
+ Screen: () => Screen,
33
+ SliderField: () => SliderField,
34
+ Space: () => Space,
35
+ SwitchField: () => SwitchField,
36
+ Text: () => Text,
37
+ ThemeContext: () => ThemeContext,
38
+ ThemeProvider: () => ThemeProvider,
39
+ VStack: () => VStack,
40
+ darkTheme: () => darkTheme,
41
+ fontDefToLvgl: () => fontDefToLvgl,
42
+ lightTheme: () => lightTheme,
43
+ resolveRadius: () => resolveRadius,
44
+ resolveSize: () => resolveSize,
45
+ resolveSpacing: () => resolveSpacing,
46
+ resolveStatus: () => resolveStatus,
47
+ resolveTypography: () => resolveTypography,
48
+ themeFromJSON: () => themeFromJSON,
49
+ themeToJSON: () => themeToJSON,
50
+ useTheme: () => useTheme
51
+ });
52
+ module.exports = __toCommonJS(index_exports);
53
+
54
+ // src/theme/context.ts
55
+ var import_compose = require("@esphome/compose");
56
+
57
+ // src/theme/dark.ts
58
+ var darkTheme = {
59
+ name: "Dark",
60
+ colors: {
61
+ primary: { bg: "#1E88E5", text: "#FFFFFF", bgPressed: "#1565C0" },
62
+ secondary: { bg: "#546E7A", text: "#FFFFFF", bgPressed: "#37474F" },
63
+ success: { bg: "#43A047", text: "#FFFFFF", bgPressed: "#2E7D32" },
64
+ warning: { bg: "#FB8C00", text: "#000000", bgPressed: "#E65100" },
65
+ danger: { bg: "#E53935", text: "#FFFFFF", bgPressed: "#C62828" },
66
+ background: "#121212",
67
+ surface: "#1E1E1E",
68
+ surfaceAlt: "#2C2C2C",
69
+ border: "#3A3A3A",
70
+ textPrimary: "#E0E0E0",
71
+ textSecondary: "#9E9E9E",
72
+ textDisabled: "#616161"
73
+ },
74
+ typography: {
75
+ title: { fontFamily: "montserrat", fontSize: 28 },
76
+ subtitle: { fontFamily: "montserrat", fontSize: 20 },
77
+ body: { fontFamily: "montserrat", fontSize: 16 },
78
+ caption: { fontFamily: "montserrat", fontSize: 12 }
79
+ },
80
+ spacing: {
81
+ none: 0,
82
+ xs: 4,
83
+ sm: 8,
84
+ md: 16,
85
+ lg: 24,
86
+ xl: 32
87
+ },
88
+ radii: {
89
+ none: 0,
90
+ sm: 4,
91
+ md: 8,
92
+ lg: 16,
93
+ full: 9999
94
+ },
95
+ sizes: {
96
+ xs: { height: 28, fontSize: 12, paddingX: 8, paddingY: 4 },
97
+ sm: { height: 36, fontSize: 14, paddingX: 12, paddingY: 6 },
98
+ md: { height: 44, fontSize: 16, paddingX: 16, paddingY: 8 },
99
+ lg: { height: 52, fontSize: 18, paddingX: 20, paddingY: 10 },
100
+ xl: { height: 64, fontSize: 22, paddingX: 24, paddingY: 12 }
101
+ }
102
+ };
103
+
104
+ // src/theme/context.ts
105
+ var ThemeContext = (0, import_compose.createContext)(darkTheme);
106
+ function useTheme() {
107
+ return (0, import_compose.useContext)(ThemeContext);
108
+ }
109
+ var ThemeProvider = (0, import_compose.createContextProvider)(ThemeContext);
110
+
111
+ // src/theme/light.ts
112
+ var lightTheme = {
113
+ name: "Light",
114
+ colors: {
115
+ primary: { bg: "#1565C0", text: "#FFFFFF", bgPressed: "#0D47A1" },
116
+ secondary: { bg: "#78909C", text: "#FFFFFF", bgPressed: "#546E7A" },
117
+ success: { bg: "#2E7D32", text: "#FFFFFF", bgPressed: "#1B5E20" },
118
+ warning: { bg: "#EF6C00", text: "#000000", bgPressed: "#E65100" },
119
+ danger: { bg: "#C62828", text: "#FFFFFF", bgPressed: "#B71C1C" },
120
+ background: "#FAFAFA",
121
+ surface: "#FFFFFF",
122
+ surfaceAlt: "#F5F5F5",
123
+ border: "#E0E0E0",
124
+ textPrimary: "#212121",
125
+ textSecondary: "#757575",
126
+ textDisabled: "#BDBDBD"
127
+ },
128
+ typography: {
129
+ title: { fontFamily: "montserrat", fontSize: 28 },
130
+ subtitle: { fontFamily: "montserrat", fontSize: 20 },
131
+ body: { fontFamily: "montserrat", fontSize: 16 },
132
+ caption: { fontFamily: "montserrat", fontSize: 12 }
133
+ },
134
+ spacing: {
135
+ none: 0,
136
+ xs: 4,
137
+ sm: 8,
138
+ md: 16,
139
+ lg: 24,
140
+ xl: 32
141
+ },
142
+ radii: {
143
+ none: 0,
144
+ sm: 4,
145
+ md: 8,
146
+ lg: 16,
147
+ full: 9999
148
+ },
149
+ sizes: {
150
+ xs: { height: 28, fontSize: 12, paddingX: 8, paddingY: 4 },
151
+ sm: { height: 36, fontSize: 14, paddingX: 12, paddingY: 6 },
152
+ md: { height: 44, fontSize: 16, paddingX: 16, paddingY: 8 },
153
+ lg: { height: 52, fontSize: 18, paddingX: 20, paddingY: 10 },
154
+ xl: { height: 64, fontSize: 22, paddingX: 24, paddingY: 12 }
155
+ }
156
+ };
157
+
158
+ // src/theme/json.ts
159
+ function themeToJSON(theme) {
160
+ return JSON.stringify(theme, null, 2);
161
+ }
162
+ function themeFromJSON(json) {
163
+ return JSON.parse(json);
164
+ }
165
+
166
+ // src/theme/resolvers.ts
167
+ function resolveSpacing(value) {
168
+ if (typeof value === "number") return value;
169
+ return useTheme().spacing[value];
170
+ }
171
+ function resolveSize(value) {
172
+ return useTheme().sizes[value];
173
+ }
174
+ function resolveStatus(value) {
175
+ return useTheme().colors[value];
176
+ }
177
+ function resolveTypography(variant) {
178
+ return useTheme().typography[variant];
179
+ }
180
+ function fontDefToLvgl(def) {
181
+ return `${def.fontFamily}_${def.fontSize}`;
182
+ }
183
+ function resolveRadius(value) {
184
+ if (typeof value === "number") return value;
185
+ return useTheme().radii[value];
186
+ }
187
+
188
+ // src/intents.ts
189
+ var COMPOSE_UI_INTENTS = {
190
+ /** Col can only be placed inside Row. */
191
+ COL: "compose-ui:col",
192
+ /** GridItem can only be placed inside Grid. */
193
+ GRID_ITEM: "compose-ui:grid-item"
194
+ };
195
+
196
+ // src/components/Screen.ts
197
+ var import_compose2 = require("@esphome/compose");
198
+ var Screen = (0, import_compose2.createIntentComponent)(
199
+ (props) => {
200
+ const padding = props.padding != null ? resolveSpacing(props.padding) : void 0;
201
+ const theme = useTheme();
202
+ const bgColor = props.bgColor ?? theme.colors.background;
203
+ return {
204
+ type: "lvgl-page",
205
+ props: {
206
+ bgColor,
207
+ borderWidth: props.borderWidth ?? 0,
208
+ ...props.borderColor != null ? { borderColor: props.borderColor } : {},
209
+ ...padding != null ? { padAll: padding } : {},
210
+ ...props.skip != null ? { skip: props.skip } : {},
211
+ ...props.children ? { children: Array.isArray(props.children) ? props.children : [props.children] } : {}
212
+ }
213
+ };
214
+ },
215
+ {
216
+ intents: [import_compose2.LVGL_INTENTS.WIDGET],
217
+ allowedChildIntents: [import_compose2.LVGL_INTENTS.WIDGET]
218
+ }
219
+ );
220
+
221
+ // src/components/Space.ts
222
+ var import_compose3 = require("@esphome/compose");
223
+ function buildFlexLayout(flow, gapKey, props) {
224
+ const gap = props.gap != null ? resolveSpacing(props.gap) : void 0;
225
+ return {
226
+ type: "flex",
227
+ flex_flow: flow,
228
+ ...props.align ? { flex_align_main: props.align } : {},
229
+ ...props.crossAlign ? { flex_align_cross: props.crossAlign } : {},
230
+ ...gap != null ? { [gapKey]: gap } : {}
231
+ };
232
+ }
233
+ function buildSpaceElement(props) {
234
+ const isRow = (props.direction ?? "vertical") === "horizontal";
235
+ const baseFlow = isRow ? "ROW" : "COLUMN";
236
+ const flow = props.wrap ? `${baseFlow}_WRAP` : baseFlow;
237
+ const gapKey = isRow ? "pad_column" : "pad_row";
238
+ const padding = props.padding != null ? resolveSpacing(props.padding) : void 0;
239
+ return {
240
+ type: "lvgl-obj",
241
+ props: {
242
+ ...props.width != null ? { width: props.width } : {},
243
+ ...props.height != null ? { height: props.height } : {},
244
+ ...padding != null ? { padAll: padding } : {},
245
+ ...props.bgColor != null ? { bgColor: props.bgColor } : {},
246
+ ...props.bgOpa != null ? { bgOpa: props.bgOpa } : { bgOpa: "TRANSP" },
247
+ ...props.radius != null ? { radius: props.radius } : {},
248
+ borderWidth: props.borderWidth ?? 0,
249
+ ...props.borderColor != null ? { borderColor: props.borderColor } : {},
250
+ "x:custom": {
251
+ layout: buildFlexLayout(flow, gapKey, props)
252
+ },
253
+ ...props.children ? { children: Array.isArray(props.children) ? props.children : [props.children] } : {}
254
+ }
255
+ };
256
+ }
257
+ var LAYOUT_INTENTS = {
258
+ intents: [import_compose3.LVGL_INTENTS.WIDGET],
259
+ allowedChildIntents: [import_compose3.LVGL_INTENTS.WIDGET],
260
+ contextTransparent: true
261
+ };
262
+ var Space = (0, import_compose3.createIntentComponent)(
263
+ (props) => buildSpaceElement(props),
264
+ LAYOUT_INTENTS
265
+ );
266
+ var VStack = (0, import_compose3.createIntentComponent)(
267
+ (props) => buildSpaceElement({ ...props, direction: "vertical" }),
268
+ LAYOUT_INTENTS
269
+ );
270
+ var HStack = (0, import_compose3.createIntentComponent)(
271
+ (props) => buildSpaceElement({ ...props, direction: "horizontal" }),
272
+ LAYOUT_INTENTS
273
+ );
274
+
275
+ // src/components/Row.ts
276
+ var import_compose4 = require("@esphome/compose");
277
+ var Row = (0, import_compose4.createIntentComponent)(
278
+ (props) => {
279
+ const wrap = props.wrap !== false;
280
+ const flow = wrap ? "ROW_WRAP" : "ROW";
281
+ let padColumn;
282
+ let padRow;
283
+ if (Array.isArray(props.gutter)) {
284
+ padColumn = resolveSpacing(props.gutter[0]);
285
+ padRow = resolveSpacing(props.gutter[1]);
286
+ } else if (props.gutter != null) {
287
+ padColumn = resolveSpacing(props.gutter);
288
+ }
289
+ return {
290
+ type: "lvgl-obj",
291
+ props: {
292
+ width: props.width ?? "100%",
293
+ ...props.height != null ? { height: props.height } : {},
294
+ bgOpa: "TRANSP",
295
+ borderWidth: props.borderWidth ?? 0,
296
+ ...props.borderColor != null ? { borderColor: props.borderColor } : {},
297
+ "x:custom": {
298
+ layout: {
299
+ type: "flex",
300
+ flex_flow: flow,
301
+ ...props.justify ? { flex_align_main: props.justify } : {},
302
+ ...props.align ? { flex_align_cross: props.align } : {},
303
+ ...padColumn != null ? { pad_column: padColumn } : {},
304
+ ...padRow != null ? { pad_row: padRow } : {}
305
+ }
306
+ },
307
+ ...props.children ? { children: Array.isArray(props.children) ? props.children : [props.children] } : {}
308
+ }
309
+ };
310
+ },
311
+ {
312
+ intents: [import_compose4.LVGL_INTENTS.WIDGET],
313
+ allowedChildIntents: [COMPOSE_UI_INTENTS.COL],
314
+ contextTransparent: true
315
+ }
316
+ );
317
+ var Col = (0, import_compose4.createIntentComponent)(
318
+ (props) => {
319
+ const span = props.span ?? 1;
320
+ return {
321
+ type: "lvgl-obj",
322
+ props: {
323
+ bgOpa: "TRANSP",
324
+ borderWidth: props.borderWidth ?? 0,
325
+ ...props.borderColor != null ? { borderColor: props.borderColor } : {},
326
+ ...props.width != null ? { width: props.width } : {},
327
+ ...props.height != null ? { height: props.height } : {},
328
+ "x:custom": {
329
+ flex_grow: span
330
+ },
331
+ ...props.children ? { children: Array.isArray(props.children) ? props.children : [props.children] } : {}
332
+ }
333
+ };
334
+ },
335
+ {
336
+ intents: [COMPOSE_UI_INTENTS.COL, import_compose4.LVGL_INTENTS.WIDGET],
337
+ allowedChildIntents: [import_compose4.LVGL_INTENTS.WIDGET],
338
+ contextTransparent: true
339
+ }
340
+ );
341
+
342
+ // src/components/Grid.ts
343
+ var import_compose5 = require("@esphome/compose");
344
+ var Grid = (0, import_compose5.createIntentComponent)(
345
+ (props) => {
346
+ const colGap = props.columnGap != null ? resolveSpacing(props.columnGap) : props.gap != null ? resolveSpacing(props.gap) : void 0;
347
+ const rowGap = props.rowGap != null ? resolveSpacing(props.rowGap) : props.gap != null ? resolveSpacing(props.gap) : void 0;
348
+ return {
349
+ type: "lvgl-obj",
350
+ props: {
351
+ ...props.width != null ? { width: props.width } : {},
352
+ ...props.height != null ? { height: props.height } : {},
353
+ ...props.bgColor != null ? { bgColor: props.bgColor } : {},
354
+ ...props.bgOpa != null ? { bgOpa: props.bgOpa } : { bgOpa: "TRANSP" },
355
+ borderWidth: props.borderWidth ?? 0,
356
+ ...props.borderColor != null ? { borderColor: props.borderColor } : {},
357
+ "x:custom": {
358
+ layout: {
359
+ type: "grid",
360
+ grid_columns: props.columns,
361
+ grid_rows: props.rows,
362
+ ...colGap != null ? { pad_column: colGap } : {},
363
+ ...rowGap != null ? { pad_row: rowGap } : {},
364
+ ...props.alignColumns ? { grid_column_align: props.alignColumns } : {},
365
+ ...props.alignRows ? { grid_row_align: props.alignRows } : {}
366
+ }
367
+ },
368
+ ...props.children ? { children: Array.isArray(props.children) ? props.children : [props.children] } : {}
369
+ }
370
+ };
371
+ },
372
+ {
373
+ intents: [import_compose5.LVGL_INTENTS.WIDGET],
374
+ allowedChildIntents: [COMPOSE_UI_INTENTS.GRID_ITEM],
375
+ contextTransparent: true
376
+ }
377
+ );
378
+ var GridItem = (0, import_compose5.createIntentComponent)(
379
+ (props) => {
380
+ return {
381
+ type: "lvgl-obj",
382
+ props: {
383
+ bgOpa: "TRANSP",
384
+ borderWidth: props.borderWidth ?? 0,
385
+ ...props.borderColor != null ? { borderColor: props.borderColor } : {},
386
+ "x:custom": {
387
+ grid_cell_column_pos: props.col,
388
+ grid_cell_row_pos: props.row,
389
+ ...props.colSpan != null && props.colSpan !== 1 ? { grid_cell_column_span: props.colSpan } : {},
390
+ ...props.rowSpan != null && props.rowSpan !== 1 ? { grid_cell_row_span: props.rowSpan } : {},
391
+ ...props.colAlign ? { grid_cell_x_align: props.colAlign } : {},
392
+ ...props.rowAlign ? { grid_cell_y_align: props.rowAlign } : {}
393
+ },
394
+ ...props.children ? { children: Array.isArray(props.children) ? props.children : [props.children] } : {}
395
+ }
396
+ };
397
+ },
398
+ {
399
+ intents: [COMPOSE_UI_INTENTS.GRID_ITEM, import_compose5.LVGL_INTENTS.WIDGET],
400
+ allowedChildIntents: [import_compose5.LVGL_INTENTS.WIDGET],
401
+ contextTransparent: true
402
+ }
403
+ );
404
+
405
+ // src/components/Text.ts
406
+ var import_compose6 = require("@esphome/compose");
407
+ var Text = (0, import_compose6.createIntentComponent)(
408
+ (props) => {
409
+ const variant = props.variant ?? "body";
410
+ const fontDef = resolveTypography(variant);
411
+ const color = props.color ?? useTheme().colors.textPrimary;
412
+ return {
413
+ type: "lvgl-label",
414
+ props: {
415
+ ...props.text != null ? { text: props.text } : {},
416
+ textFont: fontDefToLvgl(fontDef),
417
+ ...props.align != null ? { textAlign: props.align } : {},
418
+ textColor: color,
419
+ ...props.longMode != null ? { longMode: props.longMode } : {},
420
+ ...props.x != null ? { x: props.x } : {},
421
+ ...props.y != null ? { y: props.y } : {},
422
+ ...props.width != null ? { width: props.width } : {}
423
+ }
424
+ };
425
+ },
426
+ {
427
+ intents: [import_compose6.LVGL_INTENTS.WIDGET],
428
+ allowedChildIntents: []
429
+ }
430
+ );
431
+
432
+ // src/components/Button.ts
433
+ var import_compose7 = require("@esphome/compose");
434
+ var Button = (0, import_compose7.createIntentComponent)(
435
+ (props) => {
436
+ const status = props.status ?? "primary";
437
+ const size = props.size ?? "md";
438
+ const variant = props.variant ?? "solid";
439
+ const colors = resolveStatus(status);
440
+ const dims = resolveSize(size);
441
+ const theme = useTheme();
442
+ const isSolid = variant === "solid";
443
+ const textFont = fontDefToLvgl({ fontFamily: theme.typography.body.fontFamily, fontSize: dims.fontSize });
444
+ const buttonProps = {
445
+ width: props.width ?? dims.paddingX * 2 + 80,
446
+ height: props.height ?? dims.height,
447
+ ...props.x != null ? { x: props.x } : {},
448
+ ...props.y != null ? { y: props.y } : {},
449
+ ...isSolid ? {
450
+ bgColor: colors.bg,
451
+ pressed: { bgColor: colors.bgPressed }
452
+ } : {
453
+ bgOpa: "TRANSP",
454
+ borderColor: colors.bg,
455
+ borderWidth: 2,
456
+ pressed: { bgColor: colors.bg, bgOpa: "COVER" }
457
+ },
458
+ ...props.onPress != null ? { "x:custom": { on_press: props.onPress } } : {}
459
+ };
460
+ const label = {
461
+ type: "lvgl-label",
462
+ props: {
463
+ text: props.text ?? "",
464
+ textColor: isSolid ? colors.text : colors.bg,
465
+ textFont,
466
+ align: "CENTER"
467
+ }
468
+ };
469
+ return {
470
+ type: "lvgl-button",
471
+ props: {
472
+ ...buttonProps,
473
+ children: [label]
474
+ }
475
+ };
476
+ },
477
+ {
478
+ intents: [import_compose7.LVGL_INTENTS.WIDGET],
479
+ allowedChildIntents: []
480
+ }
481
+ );
482
+
483
+ // src/components/Card.ts
484
+ var import_compose8 = require("@esphome/compose");
485
+ var Card = (0, import_compose8.createIntentComponent)(
486
+ (props) => {
487
+ const padding = resolveSpacing(props.padding ?? "md");
488
+ const radius = resolveRadius(props.radius ?? "md");
489
+ const theme = useTheme();
490
+ const gap = props.gap != null ? resolveSpacing(props.gap) : void 0;
491
+ return {
492
+ type: "lvgl-obj",
493
+ props: {
494
+ padAll: padding,
495
+ radius,
496
+ bgColor: props.bgColor ?? theme.colors.surfaceAlt,
497
+ ...props.borderColor != null ? { borderColor: props.borderColor } : {},
498
+ borderWidth: props.borderWidth ?? 0,
499
+ ...props.width != null ? { width: props.width } : {},
500
+ ...props.height != null ? { height: props.height } : {},
501
+ "x:custom": {
502
+ layout: {
503
+ type: "flex",
504
+ flex_flow: "COLUMN",
505
+ ...gap != null ? { pad_row: gap } : {}
506
+ }
507
+ },
508
+ ...props.children ? { children: Array.isArray(props.children) ? props.children : [props.children] } : {}
509
+ }
510
+ };
511
+ },
512
+ {
513
+ intents: [import_compose8.LVGL_INTENTS.WIDGET],
514
+ allowedChildIntents: [import_compose8.LVGL_INTENTS.WIDGET],
515
+ contextTransparent: true
516
+ }
517
+ );
518
+
519
+ // src/components/SliderField.ts
520
+ var import_compose9 = require("@esphome/compose");
521
+ var SliderField = (0, import_compose9.createIntentComponent)(
522
+ (props) => {
523
+ const theme = useTheme();
524
+ const gap = props.gap != null ? resolveSpacing(props.gap) : void 0;
525
+ const label = {
526
+ type: "lvgl-label",
527
+ props: {
528
+ text: props.label,
529
+ textFont: fontDefToLvgl(theme.typography.body),
530
+ textColor: theme.colors.textPrimary
531
+ }
532
+ };
533
+ const sliderProps = {
534
+ ...props.min != null ? { minValue: props.min } : {},
535
+ ...props.max != null ? { maxValue: props.max } : {},
536
+ ...props.value != null ? { value: props.value } : {},
537
+ ...props.onChange != null ? { "x:custom": { on_change: props.onChange } } : {}
538
+ };
539
+ const slider = {
540
+ type: "lvgl-slider",
541
+ props: sliderProps
542
+ };
543
+ return {
544
+ type: "lvgl-obj",
545
+ props: {
546
+ bgOpa: "TRANSP",
547
+ ...props.width != null ? { width: props.width } : { width: "100%" },
548
+ height: "SIZE_CONTENT",
549
+ "x:custom": {
550
+ layout: {
551
+ type: "flex",
552
+ flex_flow: "COLUMN",
553
+ ...gap != null ? { pad_row: gap } : {}
554
+ }
555
+ },
556
+ children: [label, slider]
557
+ }
558
+ };
559
+ },
560
+ {
561
+ intents: [import_compose9.LVGL_INTENTS.WIDGET],
562
+ allowedChildIntents: []
563
+ }
564
+ );
565
+
566
+ // src/components/SwitchField.ts
567
+ var import_compose10 = require("@esphome/compose");
568
+ var SwitchField = (0, import_compose10.createIntentComponent)(
569
+ (props) => {
570
+ const theme = useTheme();
571
+ const label = {
572
+ type: "lvgl-label",
573
+ props: {
574
+ text: props.label,
575
+ textFont: fontDefToLvgl(theme.typography.body),
576
+ textColor: theme.colors.textPrimary
577
+ }
578
+ };
579
+ const switchProps = {
580
+ ...props.value != null ? { "x:custom": { value: props.value } } : {},
581
+ ...props.onChange != null ? { "x:custom": { on_change: props.onChange } } : {}
582
+ };
583
+ const switchEl = {
584
+ type: "lvgl-switch",
585
+ props: switchProps
586
+ };
587
+ return {
588
+ type: "lvgl-obj",
589
+ props: {
590
+ bgOpa: "TRANSP",
591
+ ...props.width != null ? { width: props.width } : { width: "100%" },
592
+ height: "SIZE_CONTENT",
593
+ "x:custom": {
594
+ layout: {
595
+ type: "flex",
596
+ flex_flow: "ROW",
597
+ flex_align_main: "SPACE_BETWEEN",
598
+ flex_align_cross: "CENTER"
599
+ }
600
+ },
601
+ children: [label, switchEl]
602
+ }
603
+ };
604
+ },
605
+ {
606
+ intents: [import_compose10.LVGL_INTENTS.WIDGET],
607
+ allowedChildIntents: []
608
+ }
609
+ );
610
+
611
+ // src/components/DropdownField.ts
612
+ var import_compose11 = require("@esphome/compose");
613
+ var DropdownField = (0, import_compose11.createIntentComponent)(
614
+ (props) => {
615
+ const theme = useTheme();
616
+ const gap = props.gap != null ? resolveSpacing(props.gap) : void 0;
617
+ const label = {
618
+ type: "lvgl-label",
619
+ props: {
620
+ text: props.label,
621
+ textFont: fontDefToLvgl(theme.typography.body),
622
+ textColor: theme.colors.textPrimary
623
+ }
624
+ };
625
+ const dropdownProps = {
626
+ options: props.options,
627
+ ...props.value != null ? { selected: props.value } : {},
628
+ ...props.onChange != null ? { "x:custom": { on_change: props.onChange } } : {}
629
+ };
630
+ const dropdown = {
631
+ type: "lvgl-dropdown",
632
+ props: dropdownProps
633
+ };
634
+ return {
635
+ type: "lvgl-obj",
636
+ props: {
637
+ bgOpa: "TRANSP",
638
+ ...props.width != null ? { width: props.width } : { width: "100%" },
639
+ height: "SIZE_CONTENT",
640
+ "x:custom": {
641
+ layout: {
642
+ type: "flex",
643
+ flex_flow: "COLUMN",
644
+ ...gap != null ? { pad_row: gap } : {}
645
+ }
646
+ },
647
+ children: [label, dropdown]
648
+ }
649
+ };
650
+ },
651
+ {
652
+ intents: [import_compose11.LVGL_INTENTS.WIDGET],
653
+ allowedChildIntents: []
654
+ }
655
+ );
656
+ // Annotate the CommonJS export names for ESM import in node:
657
+ 0 && (module.exports = {
658
+ Button,
659
+ COMPOSE_UI_INTENTS,
660
+ Card,
661
+ Col,
662
+ DropdownField,
663
+ Grid,
664
+ GridItem,
665
+ HStack,
666
+ Row,
667
+ Screen,
668
+ SliderField,
669
+ Space,
670
+ SwitchField,
671
+ Text,
672
+ ThemeContext,
673
+ ThemeProvider,
674
+ VStack,
675
+ darkTheme,
676
+ fontDefToLvgl,
677
+ lightTheme,
678
+ resolveRadius,
679
+ resolveSize,
680
+ resolveSpacing,
681
+ resolveStatus,
682
+ resolveTypography,
683
+ themeFromJSON,
684
+ themeToJSON,
685
+ useTheme
686
+ });