sdui-web 0.1.1 → 0.2.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.cjs CHANGED
@@ -20,6 +20,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
20
20
  // src/index.ts
21
21
  var index_exports = {};
22
22
  __export(index_exports, {
23
+ getComponents: () => getComponents,
23
24
  render: () => render
24
25
  });
25
26
  module.exports = __toCommonJS(index_exports);
@@ -494,6 +495,264 @@ function renderComponent(component, theme) {
494
495
  return el;
495
496
  }
496
497
 
498
+ // src/component-meta.ts
499
+ function sizeModelProperties() {
500
+ return [
501
+ { name: "value", label: "Value", type: "number" },
502
+ { name: "unit", label: "Unit", type: "enum", enumValues: ["dp", "match_parent", "wrap_content"] }
503
+ ];
504
+ }
505
+ function spacingModelProperties() {
506
+ return [
507
+ { name: "top", label: "Top", type: "number" },
508
+ { name: "bottom", label: "Bottom", type: "number" },
509
+ { name: "start", label: "Start", type: "number" },
510
+ { name: "end", label: "End", type: "number" }
511
+ ];
512
+ }
513
+ function colorModelProperties() {
514
+ return [
515
+ { name: "light", label: "Light", type: "color" },
516
+ { name: "dark", label: "Dark", type: "color" }
517
+ ];
518
+ }
519
+ function actionModelProperties() {
520
+ return [
521
+ { name: "type", label: "Action Type", type: "enum", enumValues: ["navigate"] },
522
+ {
523
+ name: "params",
524
+ label: "Params",
525
+ type: "object",
526
+ properties: [
527
+ { name: "route", label: "Route", type: "string" },
528
+ { name: "args", label: "Args", type: "object" }
529
+ ]
530
+ }
531
+ ];
532
+ }
533
+ function backgroundColorModelProperties() {
534
+ return [
535
+ {
536
+ name: "colors",
537
+ label: "Colors",
538
+ type: "object",
539
+ isArray: true,
540
+ properties: colorModelProperties()
541
+ },
542
+ {
543
+ name: "type",
544
+ label: "Background Type",
545
+ type: "enum",
546
+ enumValues: ["single", "vertical_gradient", "horizontal_gradient", "linear_gradient"]
547
+ }
548
+ ];
549
+ }
550
+ function modifierBaseProperties() {
551
+ return [
552
+ {
553
+ name: "alignment",
554
+ label: "Alignment",
555
+ type: "enum",
556
+ enumValues: ["center", "center_horizontally", "center_vertically", "start", "top", "top_start", "end", "bottom", "bottom_end"]
557
+ },
558
+ { name: "weight", label: "Weight", type: "number" },
559
+ { name: "action", label: "Action", type: "object", properties: actionModelProperties() }
560
+ ];
561
+ }
562
+ function textModifierDescriptor() {
563
+ return {
564
+ name: "modifier",
565
+ label: "Modifier",
566
+ type: "object",
567
+ properties: [
568
+ ...modifierBaseProperties(),
569
+ { name: "width", label: "Width", type: "object", properties: sizeModelProperties() },
570
+ { name: "margin", label: "Margin", type: "object", properties: spacingModelProperties() }
571
+ ]
572
+ };
573
+ }
574
+ function imageModifierDescriptor() {
575
+ return {
576
+ name: "modifier",
577
+ label: "Modifier",
578
+ type: "object",
579
+ properties: [
580
+ ...modifierBaseProperties(),
581
+ { name: "width", label: "Width", type: "object", properties: sizeModelProperties() },
582
+ { name: "height", label: "Height", type: "object", properties: sizeModelProperties() },
583
+ { name: "padding", label: "Padding", type: "object", properties: spacingModelProperties() },
584
+ { name: "margin", label: "Margin", type: "object", properties: spacingModelProperties() },
585
+ { name: "aspectRatio", label: "Aspect Ratio", type: "number" }
586
+ ]
587
+ };
588
+ }
589
+ function containerModifierDescriptor() {
590
+ return {
591
+ name: "modifier",
592
+ label: "Modifier",
593
+ type: "object",
594
+ properties: [
595
+ ...modifierBaseProperties(),
596
+ { name: "backgroundColor", label: "Background Color", type: "object", properties: backgroundColorModelProperties() },
597
+ { name: "width", label: "Width", type: "object", properties: sizeModelProperties() },
598
+ { name: "height", label: "Height", type: "object", properties: sizeModelProperties() },
599
+ { name: "padding", label: "Padding", type: "object", properties: spacingModelProperties() },
600
+ { name: "margin", label: "Margin", type: "object", properties: spacingModelProperties() },
601
+ { name: "aspectRatio", label: "Aspect Ratio", type: "number" }
602
+ ]
603
+ };
604
+ }
605
+ function verticalArrangementDescriptor() {
606
+ return {
607
+ name: "verticalArrangement",
608
+ label: "Vertical Arrangement",
609
+ type: "object",
610
+ properties: [
611
+ {
612
+ name: "type",
613
+ label: "Type",
614
+ type: "enum",
615
+ enumValues: ["top", "center", "bottom", "space_evenly", "space_between", "space_around", "spaced_by"]
616
+ },
617
+ { name: "spacing", label: "Spacing", type: "number" }
618
+ ]
619
+ };
620
+ }
621
+ function horizontalArrangementDescriptor() {
622
+ return {
623
+ name: "horizontalArrangement",
624
+ label: "Horizontal Arrangement",
625
+ type: "object",
626
+ properties: [
627
+ {
628
+ name: "type",
629
+ label: "Type",
630
+ type: "enum",
631
+ enumValues: ["start", "center", "end", "space_between", "space_evenly", "space_around", "spaced_by"]
632
+ },
633
+ { name: "spacing", label: "Spacing", type: "number" }
634
+ ]
635
+ };
636
+ }
637
+ var COMPONENT_DEFINITIONS = [
638
+ {
639
+ type: "text",
640
+ label: "Text",
641
+ acceptsChildren: false,
642
+ properties: [
643
+ textModifierDescriptor(),
644
+ { name: "text", label: "Text", type: "string", required: true },
645
+ { name: "fontSize", label: "Font Size", type: "number" },
646
+ { name: "color", label: "Color", type: "object", properties: colorModelProperties() },
647
+ {
648
+ name: "fontWeight",
649
+ label: "Font Weight",
650
+ type: "enum",
651
+ enumValues: ["bold", "medium", "normal", "semi_bold"]
652
+ },
653
+ {
654
+ name: "textAlign",
655
+ label: "Text Align",
656
+ type: "enum",
657
+ enumValues: ["left", "right", "center", "justify", "start", "end", "unspecified"]
658
+ },
659
+ {
660
+ name: "overflow",
661
+ label: "Overflow",
662
+ type: "enum",
663
+ enumValues: ["none", "ellipsis"]
664
+ },
665
+ { name: "maxLines", label: "Max Lines", type: "number" },
666
+ { name: "minLines", label: "Min Lines", type: "number" }
667
+ ]
668
+ },
669
+ {
670
+ type: "image",
671
+ label: "Image",
672
+ acceptsChildren: false,
673
+ properties: [
674
+ imageModifierDescriptor(),
675
+ { name: "image", label: "Image URL", type: "string", required: true },
676
+ {
677
+ name: "scaleType",
678
+ label: "Scale Type",
679
+ type: "enum",
680
+ enumValues: ["fit", "crop", "fill_height", "fill_width", "fill_bounds", "inside", "none"]
681
+ },
682
+ { name: "contentDescription", label: "Content Description", type: "string" },
683
+ { name: "tintColor", label: "Tint Color", type: "object", properties: colorModelProperties() }
684
+ ]
685
+ },
686
+ {
687
+ type: "box",
688
+ label: "Box",
689
+ acceptsChildren: true,
690
+ properties: [
691
+ containerModifierDescriptor(),
692
+ {
693
+ name: "alignment",
694
+ label: "Alignment",
695
+ type: "enum",
696
+ enumValues: [
697
+ "top_start",
698
+ "top_center",
699
+ "top_end",
700
+ "center_start",
701
+ "center",
702
+ "center_end",
703
+ "bottom_start",
704
+ "bottom_center",
705
+ "bottom_end"
706
+ ]
707
+ }
708
+ ]
709
+ },
710
+ {
711
+ type: "column",
712
+ label: "Column",
713
+ acceptsChildren: true,
714
+ properties: [
715
+ containerModifierDescriptor(),
716
+ verticalArrangementDescriptor(),
717
+ {
718
+ name: "horizontalAlignment",
719
+ label: "Horizontal Alignment",
720
+ type: "enum",
721
+ enumValues: ["start", "end", "center_horizontally"]
722
+ },
723
+ { name: "canScroll", label: "Can Scroll", type: "boolean" }
724
+ ]
725
+ },
726
+ {
727
+ type: "row",
728
+ label: "Row",
729
+ acceptsChildren: true,
730
+ properties: [
731
+ containerModifierDescriptor(),
732
+ {
733
+ name: "verticalAlignment",
734
+ label: "Vertical Alignment",
735
+ type: "enum",
736
+ enumValues: ["top", "bottom", "center_vertically"]
737
+ },
738
+ horizontalArrangementDescriptor(),
739
+ { name: "canScroll", label: "Can Scroll", type: "boolean" }
740
+ ]
741
+ },
742
+ {
743
+ type: "lazy_column",
744
+ label: "Lazy Column",
745
+ acceptsChildren: true,
746
+ properties: [
747
+ containerModifierDescriptor(),
748
+ verticalArrangementDescriptor()
749
+ ]
750
+ }
751
+ ];
752
+ function getComponents() {
753
+ return JSON.parse(JSON.stringify(COMPONENT_DEFINITIONS));
754
+ }
755
+
497
756
  // src/index.ts
498
757
  function render(json, container, options) {
499
758
  const screen = JSON.parse(json);
@@ -504,6 +763,7 @@ function render(json, container, options) {
504
763
  }
505
764
  // Annotate the CommonJS export names for ESM import in node:
506
765
  0 && (module.exports = {
766
+ getComponents,
507
767
  render
508
768
  });
509
769
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/utils.ts","../src/modifiers.ts","../src/components/text.ts","../src/components/image.ts","../src/components/box.ts","../src/components/column.ts","../src/components/row.ts","../src/components/lazy-column.ts","../src/components/index.ts","../src/render.ts"],"sourcesContent":["import type { SduiScreen, Theme } from './types';\nimport { renderComponent } from './render';\n\nexport type { SduiScreen, SduiComponent, Theme } from './types';\nexport type { PropertiesModel, TextUiProperties, ImageUiProperties, BoxUiProperties, ColumnUiProperties, RowUiProperties, LazyColumnUiProperties } from './types';\n\nexport interface RenderOptions {\n theme?: Theme;\n}\n\nexport function render(json: string, container: HTMLElement, options?: RenderOptions): void {\n const screen: SduiScreen = JSON.parse(json);\n const theme: Theme = options?.theme ?? 'light';\n\n const root = renderComponent(screen.root, theme);\n\n container.innerHTML = '';\n container.appendChild(root);\n}\n","import type { ColorModel, SizeModel, SpacingModel, Theme } from './types';\n\nexport function resolveColor(color: ColorModel | undefined, theme: Theme): string | undefined {\n if (!color) return undefined;\n if (theme === 'dark') {\n return color.dark ?? color.light;\n }\n return color.light ?? color.dark;\n}\n\nexport function resolveSize(size: SizeModel | undefined): string | undefined {\n if (!size || !size.unit) return undefined;\n switch (size.unit) {\n case 'dp':\n return `${size.value ?? 0}px`;\n case 'match_parent':\n return '100%';\n case 'wrap_content':\n return 'fit-content';\n default:\n return undefined;\n }\n}\n\nexport function resolveSpacing(spacing: SpacingModel | undefined): {\n top?: string;\n bottom?: string;\n left?: string;\n right?: string;\n} {\n if (!spacing) return {};\n return {\n top: spacing.top != null ? `${spacing.top}px` : undefined,\n bottom: spacing.bottom != null ? `${spacing.bottom}px` : undefined,\n left: spacing.start != null ? `${spacing.start}px` : undefined,\n right: spacing.end != null ? `${spacing.end}px` : undefined,\n };\n}\n","import type { BackgroundColorModel, ContainerUiModifier, ImageUiModifier, ModifierBase, TextUiModifier, Theme } from './types';\nimport { resolveColor, resolveSize, resolveSpacing } from './utils';\n\nexport function applyModifier(element: HTMLElement, modifier: ModifierBase | undefined, theme: Theme): void {\n if (!modifier) return;\n\n const s = element.style;\n\n // alignment → align-self mapping\n if (modifier.alignment) {\n switch (modifier.alignment) {\n case 'center':\n case 'center_horizontally':\n case 'center_vertically':\n s.alignSelf = 'center';\n break;\n case 'start':\n case 'top':\n case 'top_start':\n s.alignSelf = 'flex-start';\n break;\n case 'end':\n case 'bottom':\n case 'bottom_end':\n s.alignSelf = 'flex-end';\n break;\n }\n }\n\n // weight → flex\n if (modifier.weight != null) {\n s.flex = `${modifier.weight}`;\n }\n\n // action → click handler\n if (modifier.action) {\n const action = modifier.action;\n element.style.cursor = 'pointer';\n element.addEventListener('click', (e) => {\n e.stopPropagation();\n if (action.type === 'navigate') {\n const event = new CustomEvent('sdui:navigate', {\n bubbles: true,\n detail: { route: action.params?.route, args: action.params?.args },\n });\n element.dispatchEvent(event);\n console.log('[sdui] navigate →', action.params?.route, action.params?.args);\n }\n });\n }\n\n // Container-like modifiers (width, height, padding, margin, backgroundColor, aspectRatio)\n const containerMod = modifier as ContainerUiModifier | ImageUiModifier | TextUiModifier;\n\n const hasAspectRatio = 'aspectRatio' in containerMod && containerMod.aspectRatio != null;\n const hasWidth = 'width' in containerMod && containerMod.width;\n const hasHeight = 'height' in containerMod && (containerMod as ContainerUiModifier).height;\n\n if (hasWidth) {\n const w = resolveSize(containerMod.width);\n if (w) s.width = w;\n }\n\n // In Compose, aspectRatio overrides the unconstrained dimension.\n // For CSS aspect-ratio to work, we must not set both width and height explicitly.\n // If aspectRatio + width → skip height (height = width / ratio).\n // If aspectRatio + height only → skip width (width = height * ratio).\n if (hasHeight && !(hasAspectRatio && hasWidth)) {\n const h = resolveSize((containerMod as ContainerUiModifier).height);\n if (h) s.height = h;\n }\n\n if (hasAspectRatio) {\n s.aspectRatio = `${(containerMod as ContainerUiModifier).aspectRatio}`;\n }\n\n if ('padding' in containerMod && containerMod.padding) {\n const p = resolveSpacing((containerMod as ContainerUiModifier).padding);\n if (p.top) s.paddingTop = p.top;\n if (p.bottom) s.paddingBottom = p.bottom;\n if (p.left) s.paddingLeft = p.left;\n if (p.right) s.paddingRight = p.right;\n }\n\n if ('margin' in containerMod && containerMod.margin) {\n const m = resolveSpacing(containerMod.margin);\n if (m.top) s.marginTop = m.top;\n if (m.bottom) s.marginBottom = m.bottom;\n if (m.left) s.marginLeft = m.left;\n if (m.right) s.marginRight = m.right;\n }\n\n if ('backgroundColor' in containerMod && containerMod.backgroundColor) {\n applyBackground(s, (containerMod as ContainerUiModifier).backgroundColor!, theme);\n }\n}\n\nfunction applyBackground(s: CSSStyleDeclaration, bg: BackgroundColorModel, theme: Theme): void {\n if (!bg.colors || bg.colors.length === 0) return;\n\n const colors = bg.colors.map((c) => resolveColor(c, theme)).filter(Boolean) as string[];\n if (colors.length === 0) return;\n\n switch (bg.type) {\n case 'single':\n s.backgroundColor = colors[0];\n break;\n case 'vertical_gradient':\n s.background = `linear-gradient(to bottom, ${colors.join(', ')})`;\n break;\n case 'horizontal_gradient':\n s.background = `linear-gradient(to right, ${colors.join(', ')})`;\n break;\n case 'linear_gradient':\n s.background = `linear-gradient(${colors.join(', ')})`;\n break;\n default:\n if (colors.length === 1) {\n s.backgroundColor = colors[0];\n }\n break;\n }\n}\n","import type { SduiComponent, TextUiProperties, Theme } from '../types';\nimport { resolveColor } from '../utils';\nimport { applyModifier } from '../modifiers';\n\nexport function renderText(component: SduiComponent, theme: Theme): HTMLElement {\n const props = component.properties as TextUiProperties | undefined;\n const el = document.createElement('span');\n\n el.textContent = props?.text ?? '';\n\n if (props?.fontSize != null) {\n el.style.fontSize = `${props.fontSize}px`;\n }\n\n if (props?.color) {\n const c = resolveColor(props.color, theme);\n if (c) el.style.color = c;\n }\n\n if (props?.fontWeight) {\n switch (props.fontWeight) {\n case 'bold':\n el.style.fontWeight = '700';\n break;\n case 'semi_bold':\n el.style.fontWeight = '600';\n break;\n case 'medium':\n el.style.fontWeight = '500';\n break;\n case 'normal':\n el.style.fontWeight = '400';\n break;\n }\n }\n\n if (props?.textAlign) {\n el.style.display = 'block';\n switch (props.textAlign) {\n case 'left':\n case 'start':\n el.style.textAlign = 'left';\n break;\n case 'right':\n case 'end':\n el.style.textAlign = 'right';\n break;\n case 'center':\n el.style.textAlign = 'center';\n break;\n case 'justify':\n el.style.textAlign = 'justify';\n break;\n }\n }\n\n if (props?.overflow === 'ellipsis') {\n el.style.textOverflow = 'ellipsis';\n el.style.overflow = 'hidden';\n el.style.whiteSpace = props.maxLines === 1 ? 'nowrap' : 'normal';\n }\n\n if (props?.maxLines != null) {\n el.style.display = '-webkit-box';\n el.style.webkitLineClamp = `${props.maxLines}`;\n (el.style as unknown as Record<string, string>)['-webkit-box-orient'] = 'vertical';\n el.style.overflow = 'hidden';\n }\n\n if (props?.minLines != null) {\n el.style.minHeight = `${props.minLines * (props.fontSize ?? 16) * 1.4}px`;\n }\n\n applyModifier(el, props?.modifier, theme);\n\n return el;\n}\n","import type { SduiComponent, ImageUiProperties, Theme } from '../types';\nimport { resolveColor } from '../utils';\nimport { applyModifier } from '../modifiers';\n\nexport function renderImage(component: SduiComponent, theme: Theme): HTMLElement {\n const props = component.properties as ImageUiProperties | undefined;\n const el = document.createElement('img');\n\n if (props?.image) {\n el.src = props.image;\n }\n\n if (props?.contentDescription) {\n el.alt = props.contentDescription;\n }\n\n if (props?.scaleType) {\n switch (props.scaleType) {\n case 'fit':\n case 'inside':\n el.style.objectFit = 'contain';\n break;\n case 'crop':\n el.style.objectFit = 'cover';\n break;\n case 'fill_bounds':\n el.style.objectFit = 'fill';\n break;\n case 'fill_width':\n el.style.objectFit = 'cover';\n el.style.width = '100%';\n break;\n case 'fill_height':\n el.style.objectFit = 'cover';\n el.style.height = '100%';\n break;\n case 'none':\n el.style.objectFit = 'none';\n break;\n }\n }\n\n if (props?.tintColor) {\n const c = resolveColor(props.tintColor, theme);\n if (c) {\n // Use CSS filter to approximate tint; for precise tinting a SVG filter would be needed\n el.style.filter = `opacity(0.5) drop-shadow(0 0 0 ${c})`;\n }\n }\n\n applyModifier(el, props?.modifier, theme);\n\n return el;\n}\n","import type { SduiComponent, BoxUiProperties, Theme } from '../types';\nimport { applyModifier } from '../modifiers';\n\nexport function renderBox(component: SduiComponent, theme: Theme): HTMLElement {\n const props = component.properties as BoxUiProperties | undefined;\n const el = document.createElement('div');\n\n el.style.display = 'flex';\n el.style.position = 'relative';\n\n if (props?.alignment) {\n // Map alignment to flex alignment\n switch (props.alignment) {\n case 'top_start':\n el.style.justifyContent = 'flex-start';\n el.style.alignItems = 'flex-start';\n break;\n case 'top_center':\n el.style.justifyContent = 'center';\n el.style.alignItems = 'flex-start';\n break;\n case 'top_end':\n el.style.justifyContent = 'flex-end';\n el.style.alignItems = 'flex-start';\n break;\n case 'center_start':\n el.style.justifyContent = 'flex-start';\n el.style.alignItems = 'center';\n break;\n case 'center':\n el.style.justifyContent = 'center';\n el.style.alignItems = 'center';\n break;\n case 'center_end':\n el.style.justifyContent = 'flex-end';\n el.style.alignItems = 'center';\n break;\n case 'bottom_start':\n el.style.justifyContent = 'flex-start';\n el.style.alignItems = 'flex-end';\n break;\n case 'bottom_center':\n el.style.justifyContent = 'center';\n el.style.alignItems = 'flex-end';\n break;\n case 'bottom_end':\n el.style.justifyContent = 'flex-end';\n el.style.alignItems = 'flex-end';\n break;\n }\n }\n\n applyModifier(el, props?.modifier, theme);\n\n return el;\n}\n","import type { SduiComponent, ColumnUiProperties, Theme } from '../types';\nimport { applyModifier } from '../modifiers';\n\nexport function renderColumn(component: SduiComponent, theme: Theme): HTMLElement {\n const props = component.properties as ColumnUiProperties | undefined;\n const el = document.createElement('div');\n\n el.style.display = 'flex';\n el.style.flexDirection = 'column';\n\n // verticalArrangement → justify-content + gap\n if (props?.verticalArrangement) {\n const arr = props.verticalArrangement;\n switch (arr.type) {\n case 'top':\n el.style.justifyContent = 'flex-start';\n break;\n case 'center':\n el.style.justifyContent = 'center';\n break;\n case 'bottom':\n el.style.justifyContent = 'flex-end';\n break;\n case 'space_between':\n el.style.justifyContent = 'space-between';\n break;\n case 'space_evenly':\n el.style.justifyContent = 'space-evenly';\n break;\n case 'space_around':\n el.style.justifyContent = 'space-around';\n break;\n case 'spaced_by':\n if (arr.spacing != null) {\n el.style.gap = `${arr.spacing}px`;\n }\n break;\n }\n }\n\n // horizontalAlignment → align-items\n if (props?.horizontalAlignment) {\n switch (props.horizontalAlignment) {\n case 'start':\n el.style.alignItems = 'flex-start';\n break;\n case 'end':\n el.style.alignItems = 'flex-end';\n break;\n case 'center_horizontally':\n el.style.alignItems = 'center';\n break;\n }\n }\n\n if (props?.canScroll) {\n el.style.overflowY = 'auto';\n }\n\n applyModifier(el, props?.modifier, theme);\n\n return el;\n}\n","import type { SduiComponent, RowUiProperties, Theme } from '../types';\nimport { applyModifier } from '../modifiers';\n\nexport function renderRow(component: SduiComponent, theme: Theme): HTMLElement {\n const props = component.properties as RowUiProperties | undefined;\n const el = document.createElement('div');\n\n el.style.display = 'flex';\n el.style.flexDirection = 'row';\n\n // horizontalArrangement → justify-content + gap\n if (props?.horizontalArrangement) {\n const arr = props.horizontalArrangement;\n switch (arr.type) {\n case 'start':\n el.style.justifyContent = 'flex-start';\n break;\n case 'center':\n el.style.justifyContent = 'center';\n break;\n case 'end':\n el.style.justifyContent = 'flex-end';\n break;\n case 'space_between':\n el.style.justifyContent = 'space-between';\n break;\n case 'space_evenly':\n el.style.justifyContent = 'space-evenly';\n break;\n case 'space_around':\n el.style.justifyContent = 'space-around';\n break;\n case 'spaced_by':\n if (arr.spacing != null) {\n el.style.gap = `${arr.spacing}px`;\n }\n break;\n }\n }\n\n // verticalAlignment → align-items\n if (props?.verticalAlignment) {\n switch (props.verticalAlignment) {\n case 'top':\n el.style.alignItems = 'flex-start';\n break;\n case 'bottom':\n el.style.alignItems = 'flex-end';\n break;\n case 'center_vertically':\n el.style.alignItems = 'center';\n break;\n }\n }\n\n if (props?.canScroll) {\n el.style.overflowX = 'auto';\n }\n\n applyModifier(el, props?.modifier, theme);\n\n return el;\n}\n","import type { SduiComponent, LazyColumnUiProperties, Theme } from '../types';\nimport { applyModifier } from '../modifiers';\n\nexport function renderLazyColumn(component: SduiComponent, theme: Theme): HTMLElement {\n const props = component.properties as LazyColumnUiProperties | undefined;\n const el = document.createElement('div');\n\n el.style.display = 'flex';\n el.style.flexDirection = 'column';\n el.style.overflowY = 'auto';\n\n if (props?.verticalArrangement) {\n const arr = props.verticalArrangement;\n switch (arr.type) {\n case 'top':\n el.style.justifyContent = 'flex-start';\n break;\n case 'center':\n el.style.justifyContent = 'center';\n break;\n case 'bottom':\n el.style.justifyContent = 'flex-end';\n break;\n case 'space_between':\n el.style.justifyContent = 'space-between';\n break;\n case 'space_evenly':\n el.style.justifyContent = 'space-evenly';\n break;\n case 'space_around':\n el.style.justifyContent = 'space-around';\n break;\n case 'spaced_by':\n if (arr.spacing != null) {\n el.style.gap = `${arr.spacing}px`;\n }\n break;\n }\n }\n\n applyModifier(el, props?.modifier, theme);\n\n return el;\n}\n","import type { SduiComponent, Theme } from '../types';\nimport { renderText } from './text';\nimport { renderImage } from './image';\nimport { renderBox } from './box';\nimport { renderColumn } from './column';\nimport { renderRow } from './row';\nimport { renderLazyColumn } from './lazy-column';\n\nexport type ComponentRenderer = (component: SduiComponent, theme: Theme) => HTMLElement;\n\nconst renderers: Record<string, ComponentRenderer> = {\n text: renderText,\n image: renderImage,\n box: renderBox,\n column: renderColumn,\n row: renderRow,\n lazy_column: renderLazyColumn,\n};\n\nexport function getRenderer(type: string): ComponentRenderer | undefined {\n return renderers[type];\n}\n","import type { SduiComponent, Theme } from './types';\nimport { getRenderer } from './components';\n\nexport function renderComponent(component: SduiComponent, theme: Theme): HTMLElement {\n const renderer = getRenderer(component.type);\n\n if (!renderer) {\n console.warn(`[sdui] Unknown component type: \"${component.type}\"`);\n const el = document.createElement('div');\n el.dataset.sduiUnknown = component.type;\n return el;\n }\n\n const el = renderer(component, theme);\n el.dataset.sduiType = component.type;\n\n // Recursively render children\n if (component.children && component.children.length > 0) {\n for (const child of component.children) {\n const childEl = renderComponent(child, theme);\n el.appendChild(childEl);\n }\n }\n\n return el;\n}\n"],"mappings":"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","names":["el"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/utils.ts","../src/modifiers.ts","../src/components/text.ts","../src/components/image.ts","../src/components/box.ts","../src/components/column.ts","../src/components/row.ts","../src/components/lazy-column.ts","../src/components/index.ts","../src/render.ts","../src/component-meta.ts"],"sourcesContent":["import type { SduiScreen, Theme } from './types';\nimport { renderComponent } from './render';\n\nexport type { SduiScreen, SduiComponent, Theme } from './types';\nexport type { PropertiesModel, TextUiProperties, ImageUiProperties, BoxUiProperties, ColumnUiProperties, RowUiProperties, LazyColumnUiProperties } from './types';\nexport type { ComponentMeta, PropertyDescriptor, PropertyType } from './component-meta';\nexport { getComponents } from './component-meta';\n\nexport interface RenderOptions {\n theme?: Theme;\n}\n\nexport function render(json: string, container: HTMLElement, options?: RenderOptions): void {\n const screen: SduiScreen = JSON.parse(json);\n const theme: Theme = options?.theme ?? 'light';\n\n const root = renderComponent(screen.root, theme);\n\n container.innerHTML = '';\n container.appendChild(root);\n}\n","import type { ColorModel, SizeModel, SpacingModel, Theme } from './types';\n\nexport function resolveColor(color: ColorModel | undefined, theme: Theme): string | undefined {\n if (!color) return undefined;\n if (theme === 'dark') {\n return color.dark ?? color.light;\n }\n return color.light ?? color.dark;\n}\n\nexport function resolveSize(size: SizeModel | undefined): string | undefined {\n if (!size || !size.unit) return undefined;\n switch (size.unit) {\n case 'dp':\n return `${size.value ?? 0}px`;\n case 'match_parent':\n return '100%';\n case 'wrap_content':\n return 'fit-content';\n default:\n return undefined;\n }\n}\n\nexport function resolveSpacing(spacing: SpacingModel | undefined): {\n top?: string;\n bottom?: string;\n left?: string;\n right?: string;\n} {\n if (!spacing) return {};\n return {\n top: spacing.top != null ? `${spacing.top}px` : undefined,\n bottom: spacing.bottom != null ? `${spacing.bottom}px` : undefined,\n left: spacing.start != null ? `${spacing.start}px` : undefined,\n right: spacing.end != null ? `${spacing.end}px` : undefined,\n };\n}\n","import type { BackgroundColorModel, ContainerUiModifier, ImageUiModifier, ModifierBase, TextUiModifier, Theme } from './types';\nimport { resolveColor, resolveSize, resolveSpacing } from './utils';\n\nexport function applyModifier(element: HTMLElement, modifier: ModifierBase | undefined, theme: Theme): void {\n if (!modifier) return;\n\n const s = element.style;\n\n // alignment → align-self mapping\n if (modifier.alignment) {\n switch (modifier.alignment) {\n case 'center':\n case 'center_horizontally':\n case 'center_vertically':\n s.alignSelf = 'center';\n break;\n case 'start':\n case 'top':\n case 'top_start':\n s.alignSelf = 'flex-start';\n break;\n case 'end':\n case 'bottom':\n case 'bottom_end':\n s.alignSelf = 'flex-end';\n break;\n }\n }\n\n // weight → flex\n if (modifier.weight != null) {\n s.flex = `${modifier.weight}`;\n }\n\n // action → click handler\n if (modifier.action) {\n const action = modifier.action;\n element.style.cursor = 'pointer';\n element.addEventListener('click', (e) => {\n e.stopPropagation();\n if (action.type === 'navigate') {\n const event = new CustomEvent('sdui:navigate', {\n bubbles: true,\n detail: { route: action.params?.route, args: action.params?.args },\n });\n element.dispatchEvent(event);\n console.log('[sdui] navigate →', action.params?.route, action.params?.args);\n }\n });\n }\n\n // Container-like modifiers (width, height, padding, margin, backgroundColor, aspectRatio)\n const containerMod = modifier as ContainerUiModifier | ImageUiModifier | TextUiModifier;\n\n const hasAspectRatio = 'aspectRatio' in containerMod && containerMod.aspectRatio != null;\n const hasWidth = 'width' in containerMod && containerMod.width;\n const hasHeight = 'height' in containerMod && (containerMod as ContainerUiModifier).height;\n\n if (hasWidth) {\n const w = resolveSize(containerMod.width);\n if (w) s.width = w;\n }\n\n // In Compose, aspectRatio overrides the unconstrained dimension.\n // For CSS aspect-ratio to work, we must not set both width and height explicitly.\n // If aspectRatio + width → skip height (height = width / ratio).\n // If aspectRatio + height only → skip width (width = height * ratio).\n if (hasHeight && !(hasAspectRatio && hasWidth)) {\n const h = resolveSize((containerMod as ContainerUiModifier).height);\n if (h) s.height = h;\n }\n\n if (hasAspectRatio) {\n s.aspectRatio = `${(containerMod as ContainerUiModifier).aspectRatio}`;\n }\n\n if ('padding' in containerMod && containerMod.padding) {\n const p = resolveSpacing((containerMod as ContainerUiModifier).padding);\n if (p.top) s.paddingTop = p.top;\n if (p.bottom) s.paddingBottom = p.bottom;\n if (p.left) s.paddingLeft = p.left;\n if (p.right) s.paddingRight = p.right;\n }\n\n if ('margin' in containerMod && containerMod.margin) {\n const m = resolveSpacing(containerMod.margin);\n if (m.top) s.marginTop = m.top;\n if (m.bottom) s.marginBottom = m.bottom;\n if (m.left) s.marginLeft = m.left;\n if (m.right) s.marginRight = m.right;\n }\n\n if ('backgroundColor' in containerMod && containerMod.backgroundColor) {\n applyBackground(s, (containerMod as ContainerUiModifier).backgroundColor!, theme);\n }\n}\n\nfunction applyBackground(s: CSSStyleDeclaration, bg: BackgroundColorModel, theme: Theme): void {\n if (!bg.colors || bg.colors.length === 0) return;\n\n const colors = bg.colors.map((c) => resolveColor(c, theme)).filter(Boolean) as string[];\n if (colors.length === 0) return;\n\n switch (bg.type) {\n case 'single':\n s.backgroundColor = colors[0];\n break;\n case 'vertical_gradient':\n s.background = `linear-gradient(to bottom, ${colors.join(', ')})`;\n break;\n case 'horizontal_gradient':\n s.background = `linear-gradient(to right, ${colors.join(', ')})`;\n break;\n case 'linear_gradient':\n s.background = `linear-gradient(${colors.join(', ')})`;\n break;\n default:\n if (colors.length === 1) {\n s.backgroundColor = colors[0];\n }\n break;\n }\n}\n","import type { SduiComponent, TextUiProperties, Theme } from '../types';\nimport { resolveColor } from '../utils';\nimport { applyModifier } from '../modifiers';\n\nexport function renderText(component: SduiComponent, theme: Theme): HTMLElement {\n const props = component.properties as TextUiProperties | undefined;\n const el = document.createElement('span');\n\n el.textContent = props?.text ?? '';\n\n if (props?.fontSize != null) {\n el.style.fontSize = `${props.fontSize}px`;\n }\n\n if (props?.color) {\n const c = resolveColor(props.color, theme);\n if (c) el.style.color = c;\n }\n\n if (props?.fontWeight) {\n switch (props.fontWeight) {\n case 'bold':\n el.style.fontWeight = '700';\n break;\n case 'semi_bold':\n el.style.fontWeight = '600';\n break;\n case 'medium':\n el.style.fontWeight = '500';\n break;\n case 'normal':\n el.style.fontWeight = '400';\n break;\n }\n }\n\n if (props?.textAlign) {\n el.style.display = 'block';\n switch (props.textAlign) {\n case 'left':\n case 'start':\n el.style.textAlign = 'left';\n break;\n case 'right':\n case 'end':\n el.style.textAlign = 'right';\n break;\n case 'center':\n el.style.textAlign = 'center';\n break;\n case 'justify':\n el.style.textAlign = 'justify';\n break;\n }\n }\n\n if (props?.overflow === 'ellipsis') {\n el.style.textOverflow = 'ellipsis';\n el.style.overflow = 'hidden';\n el.style.whiteSpace = props.maxLines === 1 ? 'nowrap' : 'normal';\n }\n\n if (props?.maxLines != null) {\n el.style.display = '-webkit-box';\n el.style.webkitLineClamp = `${props.maxLines}`;\n (el.style as unknown as Record<string, string>)['-webkit-box-orient'] = 'vertical';\n el.style.overflow = 'hidden';\n }\n\n if (props?.minLines != null) {\n el.style.minHeight = `${props.minLines * (props.fontSize ?? 16) * 1.4}px`;\n }\n\n applyModifier(el, props?.modifier, theme);\n\n return el;\n}\n","import type { SduiComponent, ImageUiProperties, Theme } from '../types';\nimport { resolveColor } from '../utils';\nimport { applyModifier } from '../modifiers';\n\nexport function renderImage(component: SduiComponent, theme: Theme): HTMLElement {\n const props = component.properties as ImageUiProperties | undefined;\n const el = document.createElement('img');\n\n if (props?.image) {\n el.src = props.image;\n }\n\n if (props?.contentDescription) {\n el.alt = props.contentDescription;\n }\n\n if (props?.scaleType) {\n switch (props.scaleType) {\n case 'fit':\n case 'inside':\n el.style.objectFit = 'contain';\n break;\n case 'crop':\n el.style.objectFit = 'cover';\n break;\n case 'fill_bounds':\n el.style.objectFit = 'fill';\n break;\n case 'fill_width':\n el.style.objectFit = 'cover';\n el.style.width = '100%';\n break;\n case 'fill_height':\n el.style.objectFit = 'cover';\n el.style.height = '100%';\n break;\n case 'none':\n el.style.objectFit = 'none';\n break;\n }\n }\n\n if (props?.tintColor) {\n const c = resolveColor(props.tintColor, theme);\n if (c) {\n // Use CSS filter to approximate tint; for precise tinting a SVG filter would be needed\n el.style.filter = `opacity(0.5) drop-shadow(0 0 0 ${c})`;\n }\n }\n\n applyModifier(el, props?.modifier, theme);\n\n return el;\n}\n","import type { SduiComponent, BoxUiProperties, Theme } from '../types';\nimport { applyModifier } from '../modifiers';\n\nexport function renderBox(component: SduiComponent, theme: Theme): HTMLElement {\n const props = component.properties as BoxUiProperties | undefined;\n const el = document.createElement('div');\n\n el.style.display = 'flex';\n el.style.position = 'relative';\n\n if (props?.alignment) {\n // Map alignment to flex alignment\n switch (props.alignment) {\n case 'top_start':\n el.style.justifyContent = 'flex-start';\n el.style.alignItems = 'flex-start';\n break;\n case 'top_center':\n el.style.justifyContent = 'center';\n el.style.alignItems = 'flex-start';\n break;\n case 'top_end':\n el.style.justifyContent = 'flex-end';\n el.style.alignItems = 'flex-start';\n break;\n case 'center_start':\n el.style.justifyContent = 'flex-start';\n el.style.alignItems = 'center';\n break;\n case 'center':\n el.style.justifyContent = 'center';\n el.style.alignItems = 'center';\n break;\n case 'center_end':\n el.style.justifyContent = 'flex-end';\n el.style.alignItems = 'center';\n break;\n case 'bottom_start':\n el.style.justifyContent = 'flex-start';\n el.style.alignItems = 'flex-end';\n break;\n case 'bottom_center':\n el.style.justifyContent = 'center';\n el.style.alignItems = 'flex-end';\n break;\n case 'bottom_end':\n el.style.justifyContent = 'flex-end';\n el.style.alignItems = 'flex-end';\n break;\n }\n }\n\n applyModifier(el, props?.modifier, theme);\n\n return el;\n}\n","import type { SduiComponent, ColumnUiProperties, Theme } from '../types';\nimport { applyModifier } from '../modifiers';\n\nexport function renderColumn(component: SduiComponent, theme: Theme): HTMLElement {\n const props = component.properties as ColumnUiProperties | undefined;\n const el = document.createElement('div');\n\n el.style.display = 'flex';\n el.style.flexDirection = 'column';\n\n // verticalArrangement → justify-content + gap\n if (props?.verticalArrangement) {\n const arr = props.verticalArrangement;\n switch (arr.type) {\n case 'top':\n el.style.justifyContent = 'flex-start';\n break;\n case 'center':\n el.style.justifyContent = 'center';\n break;\n case 'bottom':\n el.style.justifyContent = 'flex-end';\n break;\n case 'space_between':\n el.style.justifyContent = 'space-between';\n break;\n case 'space_evenly':\n el.style.justifyContent = 'space-evenly';\n break;\n case 'space_around':\n el.style.justifyContent = 'space-around';\n break;\n case 'spaced_by':\n if (arr.spacing != null) {\n el.style.gap = `${arr.spacing}px`;\n }\n break;\n }\n }\n\n // horizontalAlignment → align-items\n if (props?.horizontalAlignment) {\n switch (props.horizontalAlignment) {\n case 'start':\n el.style.alignItems = 'flex-start';\n break;\n case 'end':\n el.style.alignItems = 'flex-end';\n break;\n case 'center_horizontally':\n el.style.alignItems = 'center';\n break;\n }\n }\n\n if (props?.canScroll) {\n el.style.overflowY = 'auto';\n }\n\n applyModifier(el, props?.modifier, theme);\n\n return el;\n}\n","import type { SduiComponent, RowUiProperties, Theme } from '../types';\nimport { applyModifier } from '../modifiers';\n\nexport function renderRow(component: SduiComponent, theme: Theme): HTMLElement {\n const props = component.properties as RowUiProperties | undefined;\n const el = document.createElement('div');\n\n el.style.display = 'flex';\n el.style.flexDirection = 'row';\n\n // horizontalArrangement → justify-content + gap\n if (props?.horizontalArrangement) {\n const arr = props.horizontalArrangement;\n switch (arr.type) {\n case 'start':\n el.style.justifyContent = 'flex-start';\n break;\n case 'center':\n el.style.justifyContent = 'center';\n break;\n case 'end':\n el.style.justifyContent = 'flex-end';\n break;\n case 'space_between':\n el.style.justifyContent = 'space-between';\n break;\n case 'space_evenly':\n el.style.justifyContent = 'space-evenly';\n break;\n case 'space_around':\n el.style.justifyContent = 'space-around';\n break;\n case 'spaced_by':\n if (arr.spacing != null) {\n el.style.gap = `${arr.spacing}px`;\n }\n break;\n }\n }\n\n // verticalAlignment → align-items\n if (props?.verticalAlignment) {\n switch (props.verticalAlignment) {\n case 'top':\n el.style.alignItems = 'flex-start';\n break;\n case 'bottom':\n el.style.alignItems = 'flex-end';\n break;\n case 'center_vertically':\n el.style.alignItems = 'center';\n break;\n }\n }\n\n if (props?.canScroll) {\n el.style.overflowX = 'auto';\n }\n\n applyModifier(el, props?.modifier, theme);\n\n return el;\n}\n","import type { SduiComponent, LazyColumnUiProperties, Theme } from '../types';\nimport { applyModifier } from '../modifiers';\n\nexport function renderLazyColumn(component: SduiComponent, theme: Theme): HTMLElement {\n const props = component.properties as LazyColumnUiProperties | undefined;\n const el = document.createElement('div');\n\n el.style.display = 'flex';\n el.style.flexDirection = 'column';\n el.style.overflowY = 'auto';\n\n if (props?.verticalArrangement) {\n const arr = props.verticalArrangement;\n switch (arr.type) {\n case 'top':\n el.style.justifyContent = 'flex-start';\n break;\n case 'center':\n el.style.justifyContent = 'center';\n break;\n case 'bottom':\n el.style.justifyContent = 'flex-end';\n break;\n case 'space_between':\n el.style.justifyContent = 'space-between';\n break;\n case 'space_evenly':\n el.style.justifyContent = 'space-evenly';\n break;\n case 'space_around':\n el.style.justifyContent = 'space-around';\n break;\n case 'spaced_by':\n if (arr.spacing != null) {\n el.style.gap = `${arr.spacing}px`;\n }\n break;\n }\n }\n\n applyModifier(el, props?.modifier, theme);\n\n return el;\n}\n","import type { SduiComponent, Theme } from '../types';\nimport { renderText } from './text';\nimport { renderImage } from './image';\nimport { renderBox } from './box';\nimport { renderColumn } from './column';\nimport { renderRow } from './row';\nimport { renderLazyColumn } from './lazy-column';\n\nexport type ComponentRenderer = (component: SduiComponent, theme: Theme) => HTMLElement;\n\nconst renderers: Record<string, ComponentRenderer> = {\n text: renderText,\n image: renderImage,\n box: renderBox,\n column: renderColumn,\n row: renderRow,\n lazy_column: renderLazyColumn,\n};\n\nexport function getRenderer(type: string): ComponentRenderer | undefined {\n return renderers[type];\n}\n","import type { SduiComponent, Theme } from './types';\nimport { getRenderer } from './components';\n\nexport function renderComponent(component: SduiComponent, theme: Theme): HTMLElement {\n const renderer = getRenderer(component.type);\n\n if (!renderer) {\n console.warn(`[sdui] Unknown component type: \"${component.type}\"`);\n const el = document.createElement('div');\n el.dataset.sduiUnknown = component.type;\n return el;\n }\n\n const el = renderer(component, theme);\n el.dataset.sduiType = component.type;\n\n // Recursively render children\n if (component.children && component.children.length > 0) {\n for (const child of component.children) {\n const childEl = renderComponent(child, theme);\n el.appendChild(childEl);\n }\n }\n\n return el;\n}\n","// ── Public types ──\n\nexport type PropertyType = 'string' | 'number' | 'boolean' | 'enum' | 'color' | 'object';\n\nexport interface PropertyDescriptor {\n name: string;\n label: string;\n type: PropertyType;\n required?: boolean;\n defaultValue?: unknown;\n enumValues?: string[];\n properties?: PropertyDescriptor[];\n isArray?: boolean;\n}\n\nexport interface ComponentMeta {\n type: string;\n label: string;\n acceptsChildren: boolean;\n properties: PropertyDescriptor[];\n}\n\n// ── Reusable sub-object property builders ──\n\nfunction sizeModelProperties(): PropertyDescriptor[] {\n return [\n { name: 'value', label: 'Value', type: 'number' },\n { name: 'unit', label: 'Unit', type: 'enum', enumValues: ['dp', 'match_parent', 'wrap_content'] },\n ];\n}\n\nfunction spacingModelProperties(): PropertyDescriptor[] {\n return [\n { name: 'top', label: 'Top', type: 'number' },\n { name: 'bottom', label: 'Bottom', type: 'number' },\n { name: 'start', label: 'Start', type: 'number' },\n { name: 'end', label: 'End', type: 'number' },\n ];\n}\n\nfunction colorModelProperties(): PropertyDescriptor[] {\n return [\n { name: 'light', label: 'Light', type: 'color' },\n { name: 'dark', label: 'Dark', type: 'color' },\n ];\n}\n\nfunction actionModelProperties(): PropertyDescriptor[] {\n return [\n { name: 'type', label: 'Action Type', type: 'enum', enumValues: ['navigate'] },\n {\n name: 'params',\n label: 'Params',\n type: 'object',\n properties: [\n { name: 'route', label: 'Route', type: 'string' },\n { name: 'args', label: 'Args', type: 'object' },\n ],\n },\n ];\n}\n\nfunction backgroundColorModelProperties(): PropertyDescriptor[] {\n return [\n {\n name: 'colors',\n label: 'Colors',\n type: 'object',\n isArray: true,\n properties: colorModelProperties(),\n },\n {\n name: 'type',\n label: 'Background Type',\n type: 'enum',\n enumValues: ['single', 'vertical_gradient', 'horizontal_gradient', 'linear_gradient'],\n },\n ];\n}\n\n// ── Modifier builders ──\n\nfunction modifierBaseProperties(): PropertyDescriptor[] {\n return [\n {\n name: 'alignment',\n label: 'Alignment',\n type: 'enum',\n enumValues: ['center', 'center_horizontally', 'center_vertically', 'start', 'top', 'top_start', 'end', 'bottom', 'bottom_end'],\n },\n { name: 'weight', label: 'Weight', type: 'number' },\n { name: 'action', label: 'Action', type: 'object', properties: actionModelProperties() },\n ];\n}\n\nfunction textModifierDescriptor(): PropertyDescriptor {\n return {\n name: 'modifier',\n label: 'Modifier',\n type: 'object',\n properties: [\n ...modifierBaseProperties(),\n { name: 'width', label: 'Width', type: 'object', properties: sizeModelProperties() },\n { name: 'margin', label: 'Margin', type: 'object', properties: spacingModelProperties() },\n ],\n };\n}\n\nfunction imageModifierDescriptor(): PropertyDescriptor {\n return {\n name: 'modifier',\n label: 'Modifier',\n type: 'object',\n properties: [\n ...modifierBaseProperties(),\n { name: 'width', label: 'Width', type: 'object', properties: sizeModelProperties() },\n { name: 'height', label: 'Height', type: 'object', properties: sizeModelProperties() },\n { name: 'padding', label: 'Padding', type: 'object', properties: spacingModelProperties() },\n { name: 'margin', label: 'Margin', type: 'object', properties: spacingModelProperties() },\n { name: 'aspectRatio', label: 'Aspect Ratio', type: 'number' },\n ],\n };\n}\n\nfunction containerModifierDescriptor(): PropertyDescriptor {\n return {\n name: 'modifier',\n label: 'Modifier',\n type: 'object',\n properties: [\n ...modifierBaseProperties(),\n { name: 'backgroundColor', label: 'Background Color', type: 'object', properties: backgroundColorModelProperties() },\n { name: 'width', label: 'Width', type: 'object', properties: sizeModelProperties() },\n { name: 'height', label: 'Height', type: 'object', properties: sizeModelProperties() },\n { name: 'padding', label: 'Padding', type: 'object', properties: spacingModelProperties() },\n { name: 'margin', label: 'Margin', type: 'object', properties: spacingModelProperties() },\n { name: 'aspectRatio', label: 'Aspect Ratio', type: 'number' },\n ],\n };\n}\n\n// ── Arrangement sub-object builders ──\n\nfunction verticalArrangementDescriptor(): PropertyDescriptor {\n return {\n name: 'verticalArrangement',\n label: 'Vertical Arrangement',\n type: 'object',\n properties: [\n {\n name: 'type',\n label: 'Type',\n type: 'enum',\n enumValues: ['top', 'center', 'bottom', 'space_evenly', 'space_between', 'space_around', 'spaced_by'],\n },\n { name: 'spacing', label: 'Spacing', type: 'number' },\n ],\n };\n}\n\nfunction horizontalArrangementDescriptor(): PropertyDescriptor {\n return {\n name: 'horizontalArrangement',\n label: 'Horizontal Arrangement',\n type: 'object',\n properties: [\n {\n name: 'type',\n label: 'Type',\n type: 'enum',\n enumValues: ['start', 'center', 'end', 'space_between', 'space_evenly', 'space_around', 'spaced_by'],\n },\n { name: 'spacing', label: 'Spacing', type: 'number' },\n ],\n };\n}\n\n// ── Component definitions ──\n\nconst COMPONENT_DEFINITIONS: ComponentMeta[] = [\n {\n type: 'text',\n label: 'Text',\n acceptsChildren: false,\n properties: [\n textModifierDescriptor(),\n { name: 'text', label: 'Text', type: 'string', required: true },\n { name: 'fontSize', label: 'Font Size', type: 'number' },\n { name: 'color', label: 'Color', type: 'object', properties: colorModelProperties() },\n {\n name: 'fontWeight',\n label: 'Font Weight',\n type: 'enum',\n enumValues: ['bold', 'medium', 'normal', 'semi_bold'],\n },\n {\n name: 'textAlign',\n label: 'Text Align',\n type: 'enum',\n enumValues: ['left', 'right', 'center', 'justify', 'start', 'end', 'unspecified'],\n },\n {\n name: 'overflow',\n label: 'Overflow',\n type: 'enum',\n enumValues: ['none', 'ellipsis'],\n },\n { name: 'maxLines', label: 'Max Lines', type: 'number' },\n { name: 'minLines', label: 'Min Lines', type: 'number' },\n ],\n },\n {\n type: 'image',\n label: 'Image',\n acceptsChildren: false,\n properties: [\n imageModifierDescriptor(),\n { name: 'image', label: 'Image URL', type: 'string', required: true },\n {\n name: 'scaleType',\n label: 'Scale Type',\n type: 'enum',\n enumValues: ['fit', 'crop', 'fill_height', 'fill_width', 'fill_bounds', 'inside', 'none'],\n },\n { name: 'contentDescription', label: 'Content Description', type: 'string' },\n { name: 'tintColor', label: 'Tint Color', type: 'object', properties: colorModelProperties() },\n ],\n },\n {\n type: 'box',\n label: 'Box',\n acceptsChildren: true,\n properties: [\n containerModifierDescriptor(),\n {\n name: 'alignment',\n label: 'Alignment',\n type: 'enum',\n enumValues: [\n 'top_start', 'top_center', 'top_end',\n 'center_start', 'center', 'center_end',\n 'bottom_start', 'bottom_center', 'bottom_end',\n ],\n },\n ],\n },\n {\n type: 'column',\n label: 'Column',\n acceptsChildren: true,\n properties: [\n containerModifierDescriptor(),\n verticalArrangementDescriptor(),\n {\n name: 'horizontalAlignment',\n label: 'Horizontal Alignment',\n type: 'enum',\n enumValues: ['start', 'end', 'center_horizontally'],\n },\n { name: 'canScroll', label: 'Can Scroll', type: 'boolean' },\n ],\n },\n {\n type: 'row',\n label: 'Row',\n acceptsChildren: true,\n properties: [\n containerModifierDescriptor(),\n {\n name: 'verticalAlignment',\n label: 'Vertical Alignment',\n type: 'enum',\n enumValues: ['top', 'bottom', 'center_vertically'],\n },\n horizontalArrangementDescriptor(),\n { name: 'canScroll', label: 'Can Scroll', type: 'boolean' },\n ],\n },\n {\n type: 'lazy_column',\n label: 'Lazy Column',\n acceptsChildren: true,\n properties: [\n containerModifierDescriptor(),\n verticalArrangementDescriptor(),\n ],\n },\n];\n\n// ── Public API ──\n\nexport function getComponents(): ComponentMeta[] {\n return JSON.parse(JSON.stringify(COMPONENT_DEFINITIONS));\n}\n"],"mappings":"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","names":["el"]}
package/dist/index.d.cts CHANGED
@@ -123,9 +123,28 @@ type HorizontalArrangementType = 'start' | 'center' | 'end' | 'space_between' |
123
123
  type VerticalArrangementType = 'top' | 'center' | 'bottom' | 'space_evenly' | 'space_between' | 'space_around' | 'spaced_by';
124
124
  type BackgroundColorType = 'single' | 'vertical_gradient' | 'linear_gradient' | 'horizontal_gradient';
125
125
 
126
+ type PropertyType = 'string' | 'number' | 'boolean' | 'enum' | 'color' | 'object';
127
+ interface PropertyDescriptor {
128
+ name: string;
129
+ label: string;
130
+ type: PropertyType;
131
+ required?: boolean;
132
+ defaultValue?: unknown;
133
+ enumValues?: string[];
134
+ properties?: PropertyDescriptor[];
135
+ isArray?: boolean;
136
+ }
137
+ interface ComponentMeta {
138
+ type: string;
139
+ label: string;
140
+ acceptsChildren: boolean;
141
+ properties: PropertyDescriptor[];
142
+ }
143
+ declare function getComponents(): ComponentMeta[];
144
+
126
145
  interface RenderOptions {
127
146
  theme?: Theme;
128
147
  }
129
148
  declare function render(json: string, container: HTMLElement, options?: RenderOptions): void;
130
149
 
131
- export { type BoxUiProperties, type ColumnUiProperties, type ImageUiProperties, type LazyColumnUiProperties, type PropertiesModel, type RenderOptions, type RowUiProperties, type SduiComponent, type SduiScreen, type TextUiProperties, type Theme, render };
150
+ export { type BoxUiProperties, type ColumnUiProperties, type ComponentMeta, type ImageUiProperties, type LazyColumnUiProperties, type PropertiesModel, type PropertyDescriptor, type PropertyType, type RenderOptions, type RowUiProperties, type SduiComponent, type SduiScreen, type TextUiProperties, type Theme, getComponents, render };
package/dist/index.d.ts CHANGED
@@ -123,9 +123,28 @@ type HorizontalArrangementType = 'start' | 'center' | 'end' | 'space_between' |
123
123
  type VerticalArrangementType = 'top' | 'center' | 'bottom' | 'space_evenly' | 'space_between' | 'space_around' | 'spaced_by';
124
124
  type BackgroundColorType = 'single' | 'vertical_gradient' | 'linear_gradient' | 'horizontal_gradient';
125
125
 
126
+ type PropertyType = 'string' | 'number' | 'boolean' | 'enum' | 'color' | 'object';
127
+ interface PropertyDescriptor {
128
+ name: string;
129
+ label: string;
130
+ type: PropertyType;
131
+ required?: boolean;
132
+ defaultValue?: unknown;
133
+ enumValues?: string[];
134
+ properties?: PropertyDescriptor[];
135
+ isArray?: boolean;
136
+ }
137
+ interface ComponentMeta {
138
+ type: string;
139
+ label: string;
140
+ acceptsChildren: boolean;
141
+ properties: PropertyDescriptor[];
142
+ }
143
+ declare function getComponents(): ComponentMeta[];
144
+
126
145
  interface RenderOptions {
127
146
  theme?: Theme;
128
147
  }
129
148
  declare function render(json: string, container: HTMLElement, options?: RenderOptions): void;
130
149
 
131
- export { type BoxUiProperties, type ColumnUiProperties, type ImageUiProperties, type LazyColumnUiProperties, type PropertiesModel, type RenderOptions, type RowUiProperties, type SduiComponent, type SduiScreen, type TextUiProperties, type Theme, render };
150
+ export { type BoxUiProperties, type ColumnUiProperties, type ComponentMeta, type ImageUiProperties, type LazyColumnUiProperties, type PropertiesModel, type PropertyDescriptor, type PropertyType, type RenderOptions, type RowUiProperties, type SduiComponent, type SduiScreen, type TextUiProperties, type Theme, getComponents, render };
package/dist/index.js CHANGED
@@ -468,6 +468,264 @@ function renderComponent(component, theme) {
468
468
  return el;
469
469
  }
470
470
 
471
+ // src/component-meta.ts
472
+ function sizeModelProperties() {
473
+ return [
474
+ { name: "value", label: "Value", type: "number" },
475
+ { name: "unit", label: "Unit", type: "enum", enumValues: ["dp", "match_parent", "wrap_content"] }
476
+ ];
477
+ }
478
+ function spacingModelProperties() {
479
+ return [
480
+ { name: "top", label: "Top", type: "number" },
481
+ { name: "bottom", label: "Bottom", type: "number" },
482
+ { name: "start", label: "Start", type: "number" },
483
+ { name: "end", label: "End", type: "number" }
484
+ ];
485
+ }
486
+ function colorModelProperties() {
487
+ return [
488
+ { name: "light", label: "Light", type: "color" },
489
+ { name: "dark", label: "Dark", type: "color" }
490
+ ];
491
+ }
492
+ function actionModelProperties() {
493
+ return [
494
+ { name: "type", label: "Action Type", type: "enum", enumValues: ["navigate"] },
495
+ {
496
+ name: "params",
497
+ label: "Params",
498
+ type: "object",
499
+ properties: [
500
+ { name: "route", label: "Route", type: "string" },
501
+ { name: "args", label: "Args", type: "object" }
502
+ ]
503
+ }
504
+ ];
505
+ }
506
+ function backgroundColorModelProperties() {
507
+ return [
508
+ {
509
+ name: "colors",
510
+ label: "Colors",
511
+ type: "object",
512
+ isArray: true,
513
+ properties: colorModelProperties()
514
+ },
515
+ {
516
+ name: "type",
517
+ label: "Background Type",
518
+ type: "enum",
519
+ enumValues: ["single", "vertical_gradient", "horizontal_gradient", "linear_gradient"]
520
+ }
521
+ ];
522
+ }
523
+ function modifierBaseProperties() {
524
+ return [
525
+ {
526
+ name: "alignment",
527
+ label: "Alignment",
528
+ type: "enum",
529
+ enumValues: ["center", "center_horizontally", "center_vertically", "start", "top", "top_start", "end", "bottom", "bottom_end"]
530
+ },
531
+ { name: "weight", label: "Weight", type: "number" },
532
+ { name: "action", label: "Action", type: "object", properties: actionModelProperties() }
533
+ ];
534
+ }
535
+ function textModifierDescriptor() {
536
+ return {
537
+ name: "modifier",
538
+ label: "Modifier",
539
+ type: "object",
540
+ properties: [
541
+ ...modifierBaseProperties(),
542
+ { name: "width", label: "Width", type: "object", properties: sizeModelProperties() },
543
+ { name: "margin", label: "Margin", type: "object", properties: spacingModelProperties() }
544
+ ]
545
+ };
546
+ }
547
+ function imageModifierDescriptor() {
548
+ return {
549
+ name: "modifier",
550
+ label: "Modifier",
551
+ type: "object",
552
+ properties: [
553
+ ...modifierBaseProperties(),
554
+ { name: "width", label: "Width", type: "object", properties: sizeModelProperties() },
555
+ { name: "height", label: "Height", type: "object", properties: sizeModelProperties() },
556
+ { name: "padding", label: "Padding", type: "object", properties: spacingModelProperties() },
557
+ { name: "margin", label: "Margin", type: "object", properties: spacingModelProperties() },
558
+ { name: "aspectRatio", label: "Aspect Ratio", type: "number" }
559
+ ]
560
+ };
561
+ }
562
+ function containerModifierDescriptor() {
563
+ return {
564
+ name: "modifier",
565
+ label: "Modifier",
566
+ type: "object",
567
+ properties: [
568
+ ...modifierBaseProperties(),
569
+ { name: "backgroundColor", label: "Background Color", type: "object", properties: backgroundColorModelProperties() },
570
+ { name: "width", label: "Width", type: "object", properties: sizeModelProperties() },
571
+ { name: "height", label: "Height", type: "object", properties: sizeModelProperties() },
572
+ { name: "padding", label: "Padding", type: "object", properties: spacingModelProperties() },
573
+ { name: "margin", label: "Margin", type: "object", properties: spacingModelProperties() },
574
+ { name: "aspectRatio", label: "Aspect Ratio", type: "number" }
575
+ ]
576
+ };
577
+ }
578
+ function verticalArrangementDescriptor() {
579
+ return {
580
+ name: "verticalArrangement",
581
+ label: "Vertical Arrangement",
582
+ type: "object",
583
+ properties: [
584
+ {
585
+ name: "type",
586
+ label: "Type",
587
+ type: "enum",
588
+ enumValues: ["top", "center", "bottom", "space_evenly", "space_between", "space_around", "spaced_by"]
589
+ },
590
+ { name: "spacing", label: "Spacing", type: "number" }
591
+ ]
592
+ };
593
+ }
594
+ function horizontalArrangementDescriptor() {
595
+ return {
596
+ name: "horizontalArrangement",
597
+ label: "Horizontal Arrangement",
598
+ type: "object",
599
+ properties: [
600
+ {
601
+ name: "type",
602
+ label: "Type",
603
+ type: "enum",
604
+ enumValues: ["start", "center", "end", "space_between", "space_evenly", "space_around", "spaced_by"]
605
+ },
606
+ { name: "spacing", label: "Spacing", type: "number" }
607
+ ]
608
+ };
609
+ }
610
+ var COMPONENT_DEFINITIONS = [
611
+ {
612
+ type: "text",
613
+ label: "Text",
614
+ acceptsChildren: false,
615
+ properties: [
616
+ textModifierDescriptor(),
617
+ { name: "text", label: "Text", type: "string", required: true },
618
+ { name: "fontSize", label: "Font Size", type: "number" },
619
+ { name: "color", label: "Color", type: "object", properties: colorModelProperties() },
620
+ {
621
+ name: "fontWeight",
622
+ label: "Font Weight",
623
+ type: "enum",
624
+ enumValues: ["bold", "medium", "normal", "semi_bold"]
625
+ },
626
+ {
627
+ name: "textAlign",
628
+ label: "Text Align",
629
+ type: "enum",
630
+ enumValues: ["left", "right", "center", "justify", "start", "end", "unspecified"]
631
+ },
632
+ {
633
+ name: "overflow",
634
+ label: "Overflow",
635
+ type: "enum",
636
+ enumValues: ["none", "ellipsis"]
637
+ },
638
+ { name: "maxLines", label: "Max Lines", type: "number" },
639
+ { name: "minLines", label: "Min Lines", type: "number" }
640
+ ]
641
+ },
642
+ {
643
+ type: "image",
644
+ label: "Image",
645
+ acceptsChildren: false,
646
+ properties: [
647
+ imageModifierDescriptor(),
648
+ { name: "image", label: "Image URL", type: "string", required: true },
649
+ {
650
+ name: "scaleType",
651
+ label: "Scale Type",
652
+ type: "enum",
653
+ enumValues: ["fit", "crop", "fill_height", "fill_width", "fill_bounds", "inside", "none"]
654
+ },
655
+ { name: "contentDescription", label: "Content Description", type: "string" },
656
+ { name: "tintColor", label: "Tint Color", type: "object", properties: colorModelProperties() }
657
+ ]
658
+ },
659
+ {
660
+ type: "box",
661
+ label: "Box",
662
+ acceptsChildren: true,
663
+ properties: [
664
+ containerModifierDescriptor(),
665
+ {
666
+ name: "alignment",
667
+ label: "Alignment",
668
+ type: "enum",
669
+ enumValues: [
670
+ "top_start",
671
+ "top_center",
672
+ "top_end",
673
+ "center_start",
674
+ "center",
675
+ "center_end",
676
+ "bottom_start",
677
+ "bottom_center",
678
+ "bottom_end"
679
+ ]
680
+ }
681
+ ]
682
+ },
683
+ {
684
+ type: "column",
685
+ label: "Column",
686
+ acceptsChildren: true,
687
+ properties: [
688
+ containerModifierDescriptor(),
689
+ verticalArrangementDescriptor(),
690
+ {
691
+ name: "horizontalAlignment",
692
+ label: "Horizontal Alignment",
693
+ type: "enum",
694
+ enumValues: ["start", "end", "center_horizontally"]
695
+ },
696
+ { name: "canScroll", label: "Can Scroll", type: "boolean" }
697
+ ]
698
+ },
699
+ {
700
+ type: "row",
701
+ label: "Row",
702
+ acceptsChildren: true,
703
+ properties: [
704
+ containerModifierDescriptor(),
705
+ {
706
+ name: "verticalAlignment",
707
+ label: "Vertical Alignment",
708
+ type: "enum",
709
+ enumValues: ["top", "bottom", "center_vertically"]
710
+ },
711
+ horizontalArrangementDescriptor(),
712
+ { name: "canScroll", label: "Can Scroll", type: "boolean" }
713
+ ]
714
+ },
715
+ {
716
+ type: "lazy_column",
717
+ label: "Lazy Column",
718
+ acceptsChildren: true,
719
+ properties: [
720
+ containerModifierDescriptor(),
721
+ verticalArrangementDescriptor()
722
+ ]
723
+ }
724
+ ];
725
+ function getComponents() {
726
+ return JSON.parse(JSON.stringify(COMPONENT_DEFINITIONS));
727
+ }
728
+
471
729
  // src/index.ts
472
730
  function render(json, container, options) {
473
731
  const screen = JSON.parse(json);
@@ -477,6 +735,7 @@ function render(json, container, options) {
477
735
  container.appendChild(root);
478
736
  }
479
737
  export {
738
+ getComponents,
480
739
  render
481
740
  };
482
741
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/utils.ts","../src/modifiers.ts","../src/components/text.ts","../src/components/image.ts","../src/components/box.ts","../src/components/column.ts","../src/components/row.ts","../src/components/lazy-column.ts","../src/components/index.ts","../src/render.ts","../src/index.ts"],"sourcesContent":["import type { ColorModel, SizeModel, SpacingModel, Theme } from './types';\n\nexport function resolveColor(color: ColorModel | undefined, theme: Theme): string | undefined {\n if (!color) return undefined;\n if (theme === 'dark') {\n return color.dark ?? color.light;\n }\n return color.light ?? color.dark;\n}\n\nexport function resolveSize(size: SizeModel | undefined): string | undefined {\n if (!size || !size.unit) return undefined;\n switch (size.unit) {\n case 'dp':\n return `${size.value ?? 0}px`;\n case 'match_parent':\n return '100%';\n case 'wrap_content':\n return 'fit-content';\n default:\n return undefined;\n }\n}\n\nexport function resolveSpacing(spacing: SpacingModel | undefined): {\n top?: string;\n bottom?: string;\n left?: string;\n right?: string;\n} {\n if (!spacing) return {};\n return {\n top: spacing.top != null ? `${spacing.top}px` : undefined,\n bottom: spacing.bottom != null ? `${spacing.bottom}px` : undefined,\n left: spacing.start != null ? `${spacing.start}px` : undefined,\n right: spacing.end != null ? `${spacing.end}px` : undefined,\n };\n}\n","import type { BackgroundColorModel, ContainerUiModifier, ImageUiModifier, ModifierBase, TextUiModifier, Theme } from './types';\nimport { resolveColor, resolveSize, resolveSpacing } from './utils';\n\nexport function applyModifier(element: HTMLElement, modifier: ModifierBase | undefined, theme: Theme): void {\n if (!modifier) return;\n\n const s = element.style;\n\n // alignment → align-self mapping\n if (modifier.alignment) {\n switch (modifier.alignment) {\n case 'center':\n case 'center_horizontally':\n case 'center_vertically':\n s.alignSelf = 'center';\n break;\n case 'start':\n case 'top':\n case 'top_start':\n s.alignSelf = 'flex-start';\n break;\n case 'end':\n case 'bottom':\n case 'bottom_end':\n s.alignSelf = 'flex-end';\n break;\n }\n }\n\n // weight → flex\n if (modifier.weight != null) {\n s.flex = `${modifier.weight}`;\n }\n\n // action → click handler\n if (modifier.action) {\n const action = modifier.action;\n element.style.cursor = 'pointer';\n element.addEventListener('click', (e) => {\n e.stopPropagation();\n if (action.type === 'navigate') {\n const event = new CustomEvent('sdui:navigate', {\n bubbles: true,\n detail: { route: action.params?.route, args: action.params?.args },\n });\n element.dispatchEvent(event);\n console.log('[sdui] navigate →', action.params?.route, action.params?.args);\n }\n });\n }\n\n // Container-like modifiers (width, height, padding, margin, backgroundColor, aspectRatio)\n const containerMod = modifier as ContainerUiModifier | ImageUiModifier | TextUiModifier;\n\n const hasAspectRatio = 'aspectRatio' in containerMod && containerMod.aspectRatio != null;\n const hasWidth = 'width' in containerMod && containerMod.width;\n const hasHeight = 'height' in containerMod && (containerMod as ContainerUiModifier).height;\n\n if (hasWidth) {\n const w = resolveSize(containerMod.width);\n if (w) s.width = w;\n }\n\n // In Compose, aspectRatio overrides the unconstrained dimension.\n // For CSS aspect-ratio to work, we must not set both width and height explicitly.\n // If aspectRatio + width → skip height (height = width / ratio).\n // If aspectRatio + height only → skip width (width = height * ratio).\n if (hasHeight && !(hasAspectRatio && hasWidth)) {\n const h = resolveSize((containerMod as ContainerUiModifier).height);\n if (h) s.height = h;\n }\n\n if (hasAspectRatio) {\n s.aspectRatio = `${(containerMod as ContainerUiModifier).aspectRatio}`;\n }\n\n if ('padding' in containerMod && containerMod.padding) {\n const p = resolveSpacing((containerMod as ContainerUiModifier).padding);\n if (p.top) s.paddingTop = p.top;\n if (p.bottom) s.paddingBottom = p.bottom;\n if (p.left) s.paddingLeft = p.left;\n if (p.right) s.paddingRight = p.right;\n }\n\n if ('margin' in containerMod && containerMod.margin) {\n const m = resolveSpacing(containerMod.margin);\n if (m.top) s.marginTop = m.top;\n if (m.bottom) s.marginBottom = m.bottom;\n if (m.left) s.marginLeft = m.left;\n if (m.right) s.marginRight = m.right;\n }\n\n if ('backgroundColor' in containerMod && containerMod.backgroundColor) {\n applyBackground(s, (containerMod as ContainerUiModifier).backgroundColor!, theme);\n }\n}\n\nfunction applyBackground(s: CSSStyleDeclaration, bg: BackgroundColorModel, theme: Theme): void {\n if (!bg.colors || bg.colors.length === 0) return;\n\n const colors = bg.colors.map((c) => resolveColor(c, theme)).filter(Boolean) as string[];\n if (colors.length === 0) return;\n\n switch (bg.type) {\n case 'single':\n s.backgroundColor = colors[0];\n break;\n case 'vertical_gradient':\n s.background = `linear-gradient(to bottom, ${colors.join(', ')})`;\n break;\n case 'horizontal_gradient':\n s.background = `linear-gradient(to right, ${colors.join(', ')})`;\n break;\n case 'linear_gradient':\n s.background = `linear-gradient(${colors.join(', ')})`;\n break;\n default:\n if (colors.length === 1) {\n s.backgroundColor = colors[0];\n }\n break;\n }\n}\n","import type { SduiComponent, TextUiProperties, Theme } from '../types';\nimport { resolveColor } from '../utils';\nimport { applyModifier } from '../modifiers';\n\nexport function renderText(component: SduiComponent, theme: Theme): HTMLElement {\n const props = component.properties as TextUiProperties | undefined;\n const el = document.createElement('span');\n\n el.textContent = props?.text ?? '';\n\n if (props?.fontSize != null) {\n el.style.fontSize = `${props.fontSize}px`;\n }\n\n if (props?.color) {\n const c = resolveColor(props.color, theme);\n if (c) el.style.color = c;\n }\n\n if (props?.fontWeight) {\n switch (props.fontWeight) {\n case 'bold':\n el.style.fontWeight = '700';\n break;\n case 'semi_bold':\n el.style.fontWeight = '600';\n break;\n case 'medium':\n el.style.fontWeight = '500';\n break;\n case 'normal':\n el.style.fontWeight = '400';\n break;\n }\n }\n\n if (props?.textAlign) {\n el.style.display = 'block';\n switch (props.textAlign) {\n case 'left':\n case 'start':\n el.style.textAlign = 'left';\n break;\n case 'right':\n case 'end':\n el.style.textAlign = 'right';\n break;\n case 'center':\n el.style.textAlign = 'center';\n break;\n case 'justify':\n el.style.textAlign = 'justify';\n break;\n }\n }\n\n if (props?.overflow === 'ellipsis') {\n el.style.textOverflow = 'ellipsis';\n el.style.overflow = 'hidden';\n el.style.whiteSpace = props.maxLines === 1 ? 'nowrap' : 'normal';\n }\n\n if (props?.maxLines != null) {\n el.style.display = '-webkit-box';\n el.style.webkitLineClamp = `${props.maxLines}`;\n (el.style as unknown as Record<string, string>)['-webkit-box-orient'] = 'vertical';\n el.style.overflow = 'hidden';\n }\n\n if (props?.minLines != null) {\n el.style.minHeight = `${props.minLines * (props.fontSize ?? 16) * 1.4}px`;\n }\n\n applyModifier(el, props?.modifier, theme);\n\n return el;\n}\n","import type { SduiComponent, ImageUiProperties, Theme } from '../types';\nimport { resolveColor } from '../utils';\nimport { applyModifier } from '../modifiers';\n\nexport function renderImage(component: SduiComponent, theme: Theme): HTMLElement {\n const props = component.properties as ImageUiProperties | undefined;\n const el = document.createElement('img');\n\n if (props?.image) {\n el.src = props.image;\n }\n\n if (props?.contentDescription) {\n el.alt = props.contentDescription;\n }\n\n if (props?.scaleType) {\n switch (props.scaleType) {\n case 'fit':\n case 'inside':\n el.style.objectFit = 'contain';\n break;\n case 'crop':\n el.style.objectFit = 'cover';\n break;\n case 'fill_bounds':\n el.style.objectFit = 'fill';\n break;\n case 'fill_width':\n el.style.objectFit = 'cover';\n el.style.width = '100%';\n break;\n case 'fill_height':\n el.style.objectFit = 'cover';\n el.style.height = '100%';\n break;\n case 'none':\n el.style.objectFit = 'none';\n break;\n }\n }\n\n if (props?.tintColor) {\n const c = resolveColor(props.tintColor, theme);\n if (c) {\n // Use CSS filter to approximate tint; for precise tinting a SVG filter would be needed\n el.style.filter = `opacity(0.5) drop-shadow(0 0 0 ${c})`;\n }\n }\n\n applyModifier(el, props?.modifier, theme);\n\n return el;\n}\n","import type { SduiComponent, BoxUiProperties, Theme } from '../types';\nimport { applyModifier } from '../modifiers';\n\nexport function renderBox(component: SduiComponent, theme: Theme): HTMLElement {\n const props = component.properties as BoxUiProperties | undefined;\n const el = document.createElement('div');\n\n el.style.display = 'flex';\n el.style.position = 'relative';\n\n if (props?.alignment) {\n // Map alignment to flex alignment\n switch (props.alignment) {\n case 'top_start':\n el.style.justifyContent = 'flex-start';\n el.style.alignItems = 'flex-start';\n break;\n case 'top_center':\n el.style.justifyContent = 'center';\n el.style.alignItems = 'flex-start';\n break;\n case 'top_end':\n el.style.justifyContent = 'flex-end';\n el.style.alignItems = 'flex-start';\n break;\n case 'center_start':\n el.style.justifyContent = 'flex-start';\n el.style.alignItems = 'center';\n break;\n case 'center':\n el.style.justifyContent = 'center';\n el.style.alignItems = 'center';\n break;\n case 'center_end':\n el.style.justifyContent = 'flex-end';\n el.style.alignItems = 'center';\n break;\n case 'bottom_start':\n el.style.justifyContent = 'flex-start';\n el.style.alignItems = 'flex-end';\n break;\n case 'bottom_center':\n el.style.justifyContent = 'center';\n el.style.alignItems = 'flex-end';\n break;\n case 'bottom_end':\n el.style.justifyContent = 'flex-end';\n el.style.alignItems = 'flex-end';\n break;\n }\n }\n\n applyModifier(el, props?.modifier, theme);\n\n return el;\n}\n","import type { SduiComponent, ColumnUiProperties, Theme } from '../types';\nimport { applyModifier } from '../modifiers';\n\nexport function renderColumn(component: SduiComponent, theme: Theme): HTMLElement {\n const props = component.properties as ColumnUiProperties | undefined;\n const el = document.createElement('div');\n\n el.style.display = 'flex';\n el.style.flexDirection = 'column';\n\n // verticalArrangement → justify-content + gap\n if (props?.verticalArrangement) {\n const arr = props.verticalArrangement;\n switch (arr.type) {\n case 'top':\n el.style.justifyContent = 'flex-start';\n break;\n case 'center':\n el.style.justifyContent = 'center';\n break;\n case 'bottom':\n el.style.justifyContent = 'flex-end';\n break;\n case 'space_between':\n el.style.justifyContent = 'space-between';\n break;\n case 'space_evenly':\n el.style.justifyContent = 'space-evenly';\n break;\n case 'space_around':\n el.style.justifyContent = 'space-around';\n break;\n case 'spaced_by':\n if (arr.spacing != null) {\n el.style.gap = `${arr.spacing}px`;\n }\n break;\n }\n }\n\n // horizontalAlignment → align-items\n if (props?.horizontalAlignment) {\n switch (props.horizontalAlignment) {\n case 'start':\n el.style.alignItems = 'flex-start';\n break;\n case 'end':\n el.style.alignItems = 'flex-end';\n break;\n case 'center_horizontally':\n el.style.alignItems = 'center';\n break;\n }\n }\n\n if (props?.canScroll) {\n el.style.overflowY = 'auto';\n }\n\n applyModifier(el, props?.modifier, theme);\n\n return el;\n}\n","import type { SduiComponent, RowUiProperties, Theme } from '../types';\nimport { applyModifier } from '../modifiers';\n\nexport function renderRow(component: SduiComponent, theme: Theme): HTMLElement {\n const props = component.properties as RowUiProperties | undefined;\n const el = document.createElement('div');\n\n el.style.display = 'flex';\n el.style.flexDirection = 'row';\n\n // horizontalArrangement → justify-content + gap\n if (props?.horizontalArrangement) {\n const arr = props.horizontalArrangement;\n switch (arr.type) {\n case 'start':\n el.style.justifyContent = 'flex-start';\n break;\n case 'center':\n el.style.justifyContent = 'center';\n break;\n case 'end':\n el.style.justifyContent = 'flex-end';\n break;\n case 'space_between':\n el.style.justifyContent = 'space-between';\n break;\n case 'space_evenly':\n el.style.justifyContent = 'space-evenly';\n break;\n case 'space_around':\n el.style.justifyContent = 'space-around';\n break;\n case 'spaced_by':\n if (arr.spacing != null) {\n el.style.gap = `${arr.spacing}px`;\n }\n break;\n }\n }\n\n // verticalAlignment → align-items\n if (props?.verticalAlignment) {\n switch (props.verticalAlignment) {\n case 'top':\n el.style.alignItems = 'flex-start';\n break;\n case 'bottom':\n el.style.alignItems = 'flex-end';\n break;\n case 'center_vertically':\n el.style.alignItems = 'center';\n break;\n }\n }\n\n if (props?.canScroll) {\n el.style.overflowX = 'auto';\n }\n\n applyModifier(el, props?.modifier, theme);\n\n return el;\n}\n","import type { SduiComponent, LazyColumnUiProperties, Theme } from '../types';\nimport { applyModifier } from '../modifiers';\n\nexport function renderLazyColumn(component: SduiComponent, theme: Theme): HTMLElement {\n const props = component.properties as LazyColumnUiProperties | undefined;\n const el = document.createElement('div');\n\n el.style.display = 'flex';\n el.style.flexDirection = 'column';\n el.style.overflowY = 'auto';\n\n if (props?.verticalArrangement) {\n const arr = props.verticalArrangement;\n switch (arr.type) {\n case 'top':\n el.style.justifyContent = 'flex-start';\n break;\n case 'center':\n el.style.justifyContent = 'center';\n break;\n case 'bottom':\n el.style.justifyContent = 'flex-end';\n break;\n case 'space_between':\n el.style.justifyContent = 'space-between';\n break;\n case 'space_evenly':\n el.style.justifyContent = 'space-evenly';\n break;\n case 'space_around':\n el.style.justifyContent = 'space-around';\n break;\n case 'spaced_by':\n if (arr.spacing != null) {\n el.style.gap = `${arr.spacing}px`;\n }\n break;\n }\n }\n\n applyModifier(el, props?.modifier, theme);\n\n return el;\n}\n","import type { SduiComponent, Theme } from '../types';\nimport { renderText } from './text';\nimport { renderImage } from './image';\nimport { renderBox } from './box';\nimport { renderColumn } from './column';\nimport { renderRow } from './row';\nimport { renderLazyColumn } from './lazy-column';\n\nexport type ComponentRenderer = (component: SduiComponent, theme: Theme) => HTMLElement;\n\nconst renderers: Record<string, ComponentRenderer> = {\n text: renderText,\n image: renderImage,\n box: renderBox,\n column: renderColumn,\n row: renderRow,\n lazy_column: renderLazyColumn,\n};\n\nexport function getRenderer(type: string): ComponentRenderer | undefined {\n return renderers[type];\n}\n","import type { SduiComponent, Theme } from './types';\nimport { getRenderer } from './components';\n\nexport function renderComponent(component: SduiComponent, theme: Theme): HTMLElement {\n const renderer = getRenderer(component.type);\n\n if (!renderer) {\n console.warn(`[sdui] Unknown component type: \"${component.type}\"`);\n const el = document.createElement('div');\n el.dataset.sduiUnknown = component.type;\n return el;\n }\n\n const el = renderer(component, theme);\n el.dataset.sduiType = component.type;\n\n // Recursively render children\n if (component.children && component.children.length > 0) {\n for (const child of component.children) {\n const childEl = renderComponent(child, theme);\n el.appendChild(childEl);\n }\n }\n\n return el;\n}\n","import type { SduiScreen, Theme } from './types';\nimport { renderComponent } from './render';\n\nexport type { SduiScreen, SduiComponent, Theme } from './types';\nexport type { PropertiesModel, TextUiProperties, ImageUiProperties, BoxUiProperties, ColumnUiProperties, RowUiProperties, LazyColumnUiProperties } from './types';\n\nexport interface RenderOptions {\n theme?: Theme;\n}\n\nexport function render(json: string, container: HTMLElement, options?: RenderOptions): void {\n const screen: SduiScreen = JSON.parse(json);\n const theme: Theme = options?.theme ?? 'light';\n\n const root = renderComponent(screen.root, theme);\n\n container.innerHTML = '';\n container.appendChild(root);\n}\n"],"mappings":"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","names":["el"]}
1
+ {"version":3,"sources":["../src/utils.ts","../src/modifiers.ts","../src/components/text.ts","../src/components/image.ts","../src/components/box.ts","../src/components/column.ts","../src/components/row.ts","../src/components/lazy-column.ts","../src/components/index.ts","../src/render.ts","../src/component-meta.ts","../src/index.ts"],"sourcesContent":["import type { ColorModel, SizeModel, SpacingModel, Theme } from './types';\n\nexport function resolveColor(color: ColorModel | undefined, theme: Theme): string | undefined {\n if (!color) return undefined;\n if (theme === 'dark') {\n return color.dark ?? color.light;\n }\n return color.light ?? color.dark;\n}\n\nexport function resolveSize(size: SizeModel | undefined): string | undefined {\n if (!size || !size.unit) return undefined;\n switch (size.unit) {\n case 'dp':\n return `${size.value ?? 0}px`;\n case 'match_parent':\n return '100%';\n case 'wrap_content':\n return 'fit-content';\n default:\n return undefined;\n }\n}\n\nexport function resolveSpacing(spacing: SpacingModel | undefined): {\n top?: string;\n bottom?: string;\n left?: string;\n right?: string;\n} {\n if (!spacing) return {};\n return {\n top: spacing.top != null ? `${spacing.top}px` : undefined,\n bottom: spacing.bottom != null ? `${spacing.bottom}px` : undefined,\n left: spacing.start != null ? `${spacing.start}px` : undefined,\n right: spacing.end != null ? `${spacing.end}px` : undefined,\n };\n}\n","import type { BackgroundColorModel, ContainerUiModifier, ImageUiModifier, ModifierBase, TextUiModifier, Theme } from './types';\nimport { resolveColor, resolveSize, resolveSpacing } from './utils';\n\nexport function applyModifier(element: HTMLElement, modifier: ModifierBase | undefined, theme: Theme): void {\n if (!modifier) return;\n\n const s = element.style;\n\n // alignment → align-self mapping\n if (modifier.alignment) {\n switch (modifier.alignment) {\n case 'center':\n case 'center_horizontally':\n case 'center_vertically':\n s.alignSelf = 'center';\n break;\n case 'start':\n case 'top':\n case 'top_start':\n s.alignSelf = 'flex-start';\n break;\n case 'end':\n case 'bottom':\n case 'bottom_end':\n s.alignSelf = 'flex-end';\n break;\n }\n }\n\n // weight → flex\n if (modifier.weight != null) {\n s.flex = `${modifier.weight}`;\n }\n\n // action → click handler\n if (modifier.action) {\n const action = modifier.action;\n element.style.cursor = 'pointer';\n element.addEventListener('click', (e) => {\n e.stopPropagation();\n if (action.type === 'navigate') {\n const event = new CustomEvent('sdui:navigate', {\n bubbles: true,\n detail: { route: action.params?.route, args: action.params?.args },\n });\n element.dispatchEvent(event);\n console.log('[sdui] navigate →', action.params?.route, action.params?.args);\n }\n });\n }\n\n // Container-like modifiers (width, height, padding, margin, backgroundColor, aspectRatio)\n const containerMod = modifier as ContainerUiModifier | ImageUiModifier | TextUiModifier;\n\n const hasAspectRatio = 'aspectRatio' in containerMod && containerMod.aspectRatio != null;\n const hasWidth = 'width' in containerMod && containerMod.width;\n const hasHeight = 'height' in containerMod && (containerMod as ContainerUiModifier).height;\n\n if (hasWidth) {\n const w = resolveSize(containerMod.width);\n if (w) s.width = w;\n }\n\n // In Compose, aspectRatio overrides the unconstrained dimension.\n // For CSS aspect-ratio to work, we must not set both width and height explicitly.\n // If aspectRatio + width → skip height (height = width / ratio).\n // If aspectRatio + height only → skip width (width = height * ratio).\n if (hasHeight && !(hasAspectRatio && hasWidth)) {\n const h = resolveSize((containerMod as ContainerUiModifier).height);\n if (h) s.height = h;\n }\n\n if (hasAspectRatio) {\n s.aspectRatio = `${(containerMod as ContainerUiModifier).aspectRatio}`;\n }\n\n if ('padding' in containerMod && containerMod.padding) {\n const p = resolveSpacing((containerMod as ContainerUiModifier).padding);\n if (p.top) s.paddingTop = p.top;\n if (p.bottom) s.paddingBottom = p.bottom;\n if (p.left) s.paddingLeft = p.left;\n if (p.right) s.paddingRight = p.right;\n }\n\n if ('margin' in containerMod && containerMod.margin) {\n const m = resolveSpacing(containerMod.margin);\n if (m.top) s.marginTop = m.top;\n if (m.bottom) s.marginBottom = m.bottom;\n if (m.left) s.marginLeft = m.left;\n if (m.right) s.marginRight = m.right;\n }\n\n if ('backgroundColor' in containerMod && containerMod.backgroundColor) {\n applyBackground(s, (containerMod as ContainerUiModifier).backgroundColor!, theme);\n }\n}\n\nfunction applyBackground(s: CSSStyleDeclaration, bg: BackgroundColorModel, theme: Theme): void {\n if (!bg.colors || bg.colors.length === 0) return;\n\n const colors = bg.colors.map((c) => resolveColor(c, theme)).filter(Boolean) as string[];\n if (colors.length === 0) return;\n\n switch (bg.type) {\n case 'single':\n s.backgroundColor = colors[0];\n break;\n case 'vertical_gradient':\n s.background = `linear-gradient(to bottom, ${colors.join(', ')})`;\n break;\n case 'horizontal_gradient':\n s.background = `linear-gradient(to right, ${colors.join(', ')})`;\n break;\n case 'linear_gradient':\n s.background = `linear-gradient(${colors.join(', ')})`;\n break;\n default:\n if (colors.length === 1) {\n s.backgroundColor = colors[0];\n }\n break;\n }\n}\n","import type { SduiComponent, TextUiProperties, Theme } from '../types';\nimport { resolveColor } from '../utils';\nimport { applyModifier } from '../modifiers';\n\nexport function renderText(component: SduiComponent, theme: Theme): HTMLElement {\n const props = component.properties as TextUiProperties | undefined;\n const el = document.createElement('span');\n\n el.textContent = props?.text ?? '';\n\n if (props?.fontSize != null) {\n el.style.fontSize = `${props.fontSize}px`;\n }\n\n if (props?.color) {\n const c = resolveColor(props.color, theme);\n if (c) el.style.color = c;\n }\n\n if (props?.fontWeight) {\n switch (props.fontWeight) {\n case 'bold':\n el.style.fontWeight = '700';\n break;\n case 'semi_bold':\n el.style.fontWeight = '600';\n break;\n case 'medium':\n el.style.fontWeight = '500';\n break;\n case 'normal':\n el.style.fontWeight = '400';\n break;\n }\n }\n\n if (props?.textAlign) {\n el.style.display = 'block';\n switch (props.textAlign) {\n case 'left':\n case 'start':\n el.style.textAlign = 'left';\n break;\n case 'right':\n case 'end':\n el.style.textAlign = 'right';\n break;\n case 'center':\n el.style.textAlign = 'center';\n break;\n case 'justify':\n el.style.textAlign = 'justify';\n break;\n }\n }\n\n if (props?.overflow === 'ellipsis') {\n el.style.textOverflow = 'ellipsis';\n el.style.overflow = 'hidden';\n el.style.whiteSpace = props.maxLines === 1 ? 'nowrap' : 'normal';\n }\n\n if (props?.maxLines != null) {\n el.style.display = '-webkit-box';\n el.style.webkitLineClamp = `${props.maxLines}`;\n (el.style as unknown as Record<string, string>)['-webkit-box-orient'] = 'vertical';\n el.style.overflow = 'hidden';\n }\n\n if (props?.minLines != null) {\n el.style.minHeight = `${props.minLines * (props.fontSize ?? 16) * 1.4}px`;\n }\n\n applyModifier(el, props?.modifier, theme);\n\n return el;\n}\n","import type { SduiComponent, ImageUiProperties, Theme } from '../types';\nimport { resolveColor } from '../utils';\nimport { applyModifier } from '../modifiers';\n\nexport function renderImage(component: SduiComponent, theme: Theme): HTMLElement {\n const props = component.properties as ImageUiProperties | undefined;\n const el = document.createElement('img');\n\n if (props?.image) {\n el.src = props.image;\n }\n\n if (props?.contentDescription) {\n el.alt = props.contentDescription;\n }\n\n if (props?.scaleType) {\n switch (props.scaleType) {\n case 'fit':\n case 'inside':\n el.style.objectFit = 'contain';\n break;\n case 'crop':\n el.style.objectFit = 'cover';\n break;\n case 'fill_bounds':\n el.style.objectFit = 'fill';\n break;\n case 'fill_width':\n el.style.objectFit = 'cover';\n el.style.width = '100%';\n break;\n case 'fill_height':\n el.style.objectFit = 'cover';\n el.style.height = '100%';\n break;\n case 'none':\n el.style.objectFit = 'none';\n break;\n }\n }\n\n if (props?.tintColor) {\n const c = resolveColor(props.tintColor, theme);\n if (c) {\n // Use CSS filter to approximate tint; for precise tinting a SVG filter would be needed\n el.style.filter = `opacity(0.5) drop-shadow(0 0 0 ${c})`;\n }\n }\n\n applyModifier(el, props?.modifier, theme);\n\n return el;\n}\n","import type { SduiComponent, BoxUiProperties, Theme } from '../types';\nimport { applyModifier } from '../modifiers';\n\nexport function renderBox(component: SduiComponent, theme: Theme): HTMLElement {\n const props = component.properties as BoxUiProperties | undefined;\n const el = document.createElement('div');\n\n el.style.display = 'flex';\n el.style.position = 'relative';\n\n if (props?.alignment) {\n // Map alignment to flex alignment\n switch (props.alignment) {\n case 'top_start':\n el.style.justifyContent = 'flex-start';\n el.style.alignItems = 'flex-start';\n break;\n case 'top_center':\n el.style.justifyContent = 'center';\n el.style.alignItems = 'flex-start';\n break;\n case 'top_end':\n el.style.justifyContent = 'flex-end';\n el.style.alignItems = 'flex-start';\n break;\n case 'center_start':\n el.style.justifyContent = 'flex-start';\n el.style.alignItems = 'center';\n break;\n case 'center':\n el.style.justifyContent = 'center';\n el.style.alignItems = 'center';\n break;\n case 'center_end':\n el.style.justifyContent = 'flex-end';\n el.style.alignItems = 'center';\n break;\n case 'bottom_start':\n el.style.justifyContent = 'flex-start';\n el.style.alignItems = 'flex-end';\n break;\n case 'bottom_center':\n el.style.justifyContent = 'center';\n el.style.alignItems = 'flex-end';\n break;\n case 'bottom_end':\n el.style.justifyContent = 'flex-end';\n el.style.alignItems = 'flex-end';\n break;\n }\n }\n\n applyModifier(el, props?.modifier, theme);\n\n return el;\n}\n","import type { SduiComponent, ColumnUiProperties, Theme } from '../types';\nimport { applyModifier } from '../modifiers';\n\nexport function renderColumn(component: SduiComponent, theme: Theme): HTMLElement {\n const props = component.properties as ColumnUiProperties | undefined;\n const el = document.createElement('div');\n\n el.style.display = 'flex';\n el.style.flexDirection = 'column';\n\n // verticalArrangement → justify-content + gap\n if (props?.verticalArrangement) {\n const arr = props.verticalArrangement;\n switch (arr.type) {\n case 'top':\n el.style.justifyContent = 'flex-start';\n break;\n case 'center':\n el.style.justifyContent = 'center';\n break;\n case 'bottom':\n el.style.justifyContent = 'flex-end';\n break;\n case 'space_between':\n el.style.justifyContent = 'space-between';\n break;\n case 'space_evenly':\n el.style.justifyContent = 'space-evenly';\n break;\n case 'space_around':\n el.style.justifyContent = 'space-around';\n break;\n case 'spaced_by':\n if (arr.spacing != null) {\n el.style.gap = `${arr.spacing}px`;\n }\n break;\n }\n }\n\n // horizontalAlignment → align-items\n if (props?.horizontalAlignment) {\n switch (props.horizontalAlignment) {\n case 'start':\n el.style.alignItems = 'flex-start';\n break;\n case 'end':\n el.style.alignItems = 'flex-end';\n break;\n case 'center_horizontally':\n el.style.alignItems = 'center';\n break;\n }\n }\n\n if (props?.canScroll) {\n el.style.overflowY = 'auto';\n }\n\n applyModifier(el, props?.modifier, theme);\n\n return el;\n}\n","import type { SduiComponent, RowUiProperties, Theme } from '../types';\nimport { applyModifier } from '../modifiers';\n\nexport function renderRow(component: SduiComponent, theme: Theme): HTMLElement {\n const props = component.properties as RowUiProperties | undefined;\n const el = document.createElement('div');\n\n el.style.display = 'flex';\n el.style.flexDirection = 'row';\n\n // horizontalArrangement → justify-content + gap\n if (props?.horizontalArrangement) {\n const arr = props.horizontalArrangement;\n switch (arr.type) {\n case 'start':\n el.style.justifyContent = 'flex-start';\n break;\n case 'center':\n el.style.justifyContent = 'center';\n break;\n case 'end':\n el.style.justifyContent = 'flex-end';\n break;\n case 'space_between':\n el.style.justifyContent = 'space-between';\n break;\n case 'space_evenly':\n el.style.justifyContent = 'space-evenly';\n break;\n case 'space_around':\n el.style.justifyContent = 'space-around';\n break;\n case 'spaced_by':\n if (arr.spacing != null) {\n el.style.gap = `${arr.spacing}px`;\n }\n break;\n }\n }\n\n // verticalAlignment → align-items\n if (props?.verticalAlignment) {\n switch (props.verticalAlignment) {\n case 'top':\n el.style.alignItems = 'flex-start';\n break;\n case 'bottom':\n el.style.alignItems = 'flex-end';\n break;\n case 'center_vertically':\n el.style.alignItems = 'center';\n break;\n }\n }\n\n if (props?.canScroll) {\n el.style.overflowX = 'auto';\n }\n\n applyModifier(el, props?.modifier, theme);\n\n return el;\n}\n","import type { SduiComponent, LazyColumnUiProperties, Theme } from '../types';\nimport { applyModifier } from '../modifiers';\n\nexport function renderLazyColumn(component: SduiComponent, theme: Theme): HTMLElement {\n const props = component.properties as LazyColumnUiProperties | undefined;\n const el = document.createElement('div');\n\n el.style.display = 'flex';\n el.style.flexDirection = 'column';\n el.style.overflowY = 'auto';\n\n if (props?.verticalArrangement) {\n const arr = props.verticalArrangement;\n switch (arr.type) {\n case 'top':\n el.style.justifyContent = 'flex-start';\n break;\n case 'center':\n el.style.justifyContent = 'center';\n break;\n case 'bottom':\n el.style.justifyContent = 'flex-end';\n break;\n case 'space_between':\n el.style.justifyContent = 'space-between';\n break;\n case 'space_evenly':\n el.style.justifyContent = 'space-evenly';\n break;\n case 'space_around':\n el.style.justifyContent = 'space-around';\n break;\n case 'spaced_by':\n if (arr.spacing != null) {\n el.style.gap = `${arr.spacing}px`;\n }\n break;\n }\n }\n\n applyModifier(el, props?.modifier, theme);\n\n return el;\n}\n","import type { SduiComponent, Theme } from '../types';\nimport { renderText } from './text';\nimport { renderImage } from './image';\nimport { renderBox } from './box';\nimport { renderColumn } from './column';\nimport { renderRow } from './row';\nimport { renderLazyColumn } from './lazy-column';\n\nexport type ComponentRenderer = (component: SduiComponent, theme: Theme) => HTMLElement;\n\nconst renderers: Record<string, ComponentRenderer> = {\n text: renderText,\n image: renderImage,\n box: renderBox,\n column: renderColumn,\n row: renderRow,\n lazy_column: renderLazyColumn,\n};\n\nexport function getRenderer(type: string): ComponentRenderer | undefined {\n return renderers[type];\n}\n","import type { SduiComponent, Theme } from './types';\nimport { getRenderer } from './components';\n\nexport function renderComponent(component: SduiComponent, theme: Theme): HTMLElement {\n const renderer = getRenderer(component.type);\n\n if (!renderer) {\n console.warn(`[sdui] Unknown component type: \"${component.type}\"`);\n const el = document.createElement('div');\n el.dataset.sduiUnknown = component.type;\n return el;\n }\n\n const el = renderer(component, theme);\n el.dataset.sduiType = component.type;\n\n // Recursively render children\n if (component.children && component.children.length > 0) {\n for (const child of component.children) {\n const childEl = renderComponent(child, theme);\n el.appendChild(childEl);\n }\n }\n\n return el;\n}\n","// ── Public types ──\n\nexport type PropertyType = 'string' | 'number' | 'boolean' | 'enum' | 'color' | 'object';\n\nexport interface PropertyDescriptor {\n name: string;\n label: string;\n type: PropertyType;\n required?: boolean;\n defaultValue?: unknown;\n enumValues?: string[];\n properties?: PropertyDescriptor[];\n isArray?: boolean;\n}\n\nexport interface ComponentMeta {\n type: string;\n label: string;\n acceptsChildren: boolean;\n properties: PropertyDescriptor[];\n}\n\n// ── Reusable sub-object property builders ──\n\nfunction sizeModelProperties(): PropertyDescriptor[] {\n return [\n { name: 'value', label: 'Value', type: 'number' },\n { name: 'unit', label: 'Unit', type: 'enum', enumValues: ['dp', 'match_parent', 'wrap_content'] },\n ];\n}\n\nfunction spacingModelProperties(): PropertyDescriptor[] {\n return [\n { name: 'top', label: 'Top', type: 'number' },\n { name: 'bottom', label: 'Bottom', type: 'number' },\n { name: 'start', label: 'Start', type: 'number' },\n { name: 'end', label: 'End', type: 'number' },\n ];\n}\n\nfunction colorModelProperties(): PropertyDescriptor[] {\n return [\n { name: 'light', label: 'Light', type: 'color' },\n { name: 'dark', label: 'Dark', type: 'color' },\n ];\n}\n\nfunction actionModelProperties(): PropertyDescriptor[] {\n return [\n { name: 'type', label: 'Action Type', type: 'enum', enumValues: ['navigate'] },\n {\n name: 'params',\n label: 'Params',\n type: 'object',\n properties: [\n { name: 'route', label: 'Route', type: 'string' },\n { name: 'args', label: 'Args', type: 'object' },\n ],\n },\n ];\n}\n\nfunction backgroundColorModelProperties(): PropertyDescriptor[] {\n return [\n {\n name: 'colors',\n label: 'Colors',\n type: 'object',\n isArray: true,\n properties: colorModelProperties(),\n },\n {\n name: 'type',\n label: 'Background Type',\n type: 'enum',\n enumValues: ['single', 'vertical_gradient', 'horizontal_gradient', 'linear_gradient'],\n },\n ];\n}\n\n// ── Modifier builders ──\n\nfunction modifierBaseProperties(): PropertyDescriptor[] {\n return [\n {\n name: 'alignment',\n label: 'Alignment',\n type: 'enum',\n enumValues: ['center', 'center_horizontally', 'center_vertically', 'start', 'top', 'top_start', 'end', 'bottom', 'bottom_end'],\n },\n { name: 'weight', label: 'Weight', type: 'number' },\n { name: 'action', label: 'Action', type: 'object', properties: actionModelProperties() },\n ];\n}\n\nfunction textModifierDescriptor(): PropertyDescriptor {\n return {\n name: 'modifier',\n label: 'Modifier',\n type: 'object',\n properties: [\n ...modifierBaseProperties(),\n { name: 'width', label: 'Width', type: 'object', properties: sizeModelProperties() },\n { name: 'margin', label: 'Margin', type: 'object', properties: spacingModelProperties() },\n ],\n };\n}\n\nfunction imageModifierDescriptor(): PropertyDescriptor {\n return {\n name: 'modifier',\n label: 'Modifier',\n type: 'object',\n properties: [\n ...modifierBaseProperties(),\n { name: 'width', label: 'Width', type: 'object', properties: sizeModelProperties() },\n { name: 'height', label: 'Height', type: 'object', properties: sizeModelProperties() },\n { name: 'padding', label: 'Padding', type: 'object', properties: spacingModelProperties() },\n { name: 'margin', label: 'Margin', type: 'object', properties: spacingModelProperties() },\n { name: 'aspectRatio', label: 'Aspect Ratio', type: 'number' },\n ],\n };\n}\n\nfunction containerModifierDescriptor(): PropertyDescriptor {\n return {\n name: 'modifier',\n label: 'Modifier',\n type: 'object',\n properties: [\n ...modifierBaseProperties(),\n { name: 'backgroundColor', label: 'Background Color', type: 'object', properties: backgroundColorModelProperties() },\n { name: 'width', label: 'Width', type: 'object', properties: sizeModelProperties() },\n { name: 'height', label: 'Height', type: 'object', properties: sizeModelProperties() },\n { name: 'padding', label: 'Padding', type: 'object', properties: spacingModelProperties() },\n { name: 'margin', label: 'Margin', type: 'object', properties: spacingModelProperties() },\n { name: 'aspectRatio', label: 'Aspect Ratio', type: 'number' },\n ],\n };\n}\n\n// ── Arrangement sub-object builders ──\n\nfunction verticalArrangementDescriptor(): PropertyDescriptor {\n return {\n name: 'verticalArrangement',\n label: 'Vertical Arrangement',\n type: 'object',\n properties: [\n {\n name: 'type',\n label: 'Type',\n type: 'enum',\n enumValues: ['top', 'center', 'bottom', 'space_evenly', 'space_between', 'space_around', 'spaced_by'],\n },\n { name: 'spacing', label: 'Spacing', type: 'number' },\n ],\n };\n}\n\nfunction horizontalArrangementDescriptor(): PropertyDescriptor {\n return {\n name: 'horizontalArrangement',\n label: 'Horizontal Arrangement',\n type: 'object',\n properties: [\n {\n name: 'type',\n label: 'Type',\n type: 'enum',\n enumValues: ['start', 'center', 'end', 'space_between', 'space_evenly', 'space_around', 'spaced_by'],\n },\n { name: 'spacing', label: 'Spacing', type: 'number' },\n ],\n };\n}\n\n// ── Component definitions ──\n\nconst COMPONENT_DEFINITIONS: ComponentMeta[] = [\n {\n type: 'text',\n label: 'Text',\n acceptsChildren: false,\n properties: [\n textModifierDescriptor(),\n { name: 'text', label: 'Text', type: 'string', required: true },\n { name: 'fontSize', label: 'Font Size', type: 'number' },\n { name: 'color', label: 'Color', type: 'object', properties: colorModelProperties() },\n {\n name: 'fontWeight',\n label: 'Font Weight',\n type: 'enum',\n enumValues: ['bold', 'medium', 'normal', 'semi_bold'],\n },\n {\n name: 'textAlign',\n label: 'Text Align',\n type: 'enum',\n enumValues: ['left', 'right', 'center', 'justify', 'start', 'end', 'unspecified'],\n },\n {\n name: 'overflow',\n label: 'Overflow',\n type: 'enum',\n enumValues: ['none', 'ellipsis'],\n },\n { name: 'maxLines', label: 'Max Lines', type: 'number' },\n { name: 'minLines', label: 'Min Lines', type: 'number' },\n ],\n },\n {\n type: 'image',\n label: 'Image',\n acceptsChildren: false,\n properties: [\n imageModifierDescriptor(),\n { name: 'image', label: 'Image URL', type: 'string', required: true },\n {\n name: 'scaleType',\n label: 'Scale Type',\n type: 'enum',\n enumValues: ['fit', 'crop', 'fill_height', 'fill_width', 'fill_bounds', 'inside', 'none'],\n },\n { name: 'contentDescription', label: 'Content Description', type: 'string' },\n { name: 'tintColor', label: 'Tint Color', type: 'object', properties: colorModelProperties() },\n ],\n },\n {\n type: 'box',\n label: 'Box',\n acceptsChildren: true,\n properties: [\n containerModifierDescriptor(),\n {\n name: 'alignment',\n label: 'Alignment',\n type: 'enum',\n enumValues: [\n 'top_start', 'top_center', 'top_end',\n 'center_start', 'center', 'center_end',\n 'bottom_start', 'bottom_center', 'bottom_end',\n ],\n },\n ],\n },\n {\n type: 'column',\n label: 'Column',\n acceptsChildren: true,\n properties: [\n containerModifierDescriptor(),\n verticalArrangementDescriptor(),\n {\n name: 'horizontalAlignment',\n label: 'Horizontal Alignment',\n type: 'enum',\n enumValues: ['start', 'end', 'center_horizontally'],\n },\n { name: 'canScroll', label: 'Can Scroll', type: 'boolean' },\n ],\n },\n {\n type: 'row',\n label: 'Row',\n acceptsChildren: true,\n properties: [\n containerModifierDescriptor(),\n {\n name: 'verticalAlignment',\n label: 'Vertical Alignment',\n type: 'enum',\n enumValues: ['top', 'bottom', 'center_vertically'],\n },\n horizontalArrangementDescriptor(),\n { name: 'canScroll', label: 'Can Scroll', type: 'boolean' },\n ],\n },\n {\n type: 'lazy_column',\n label: 'Lazy Column',\n acceptsChildren: true,\n properties: [\n containerModifierDescriptor(),\n verticalArrangementDescriptor(),\n ],\n },\n];\n\n// ── Public API ──\n\nexport function getComponents(): ComponentMeta[] {\n return JSON.parse(JSON.stringify(COMPONENT_DEFINITIONS));\n}\n","import type { SduiScreen, Theme } from './types';\nimport { renderComponent } from './render';\n\nexport type { SduiScreen, SduiComponent, Theme } from './types';\nexport type { PropertiesModel, TextUiProperties, ImageUiProperties, BoxUiProperties, ColumnUiProperties, RowUiProperties, LazyColumnUiProperties } from './types';\nexport type { ComponentMeta, PropertyDescriptor, PropertyType } from './component-meta';\nexport { getComponents } from './component-meta';\n\nexport interface RenderOptions {\n theme?: Theme;\n}\n\nexport function render(json: string, container: HTMLElement, options?: RenderOptions): void {\n const screen: SduiScreen = JSON.parse(json);\n const theme: Theme = options?.theme ?? 'light';\n\n const root = renderComponent(screen.root, theme);\n\n container.innerHTML = '';\n container.appendChild(root);\n}\n"],"mappings":"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","names":["el"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sdui-web",
3
- "version": "0.1.1",
3
+ "version": "0.2.0",
4
4
  "description": "Server-Driven UI renderer for the web — turns JSON component trees into DOM elements",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",