refactor: migrate examples to the canonical Ebox DSL
This commit is contained in:
parent
f571c89d70
commit
94bac1c7c7
@ -41,7 +41,7 @@
|
||||
- Imagery/iconography: Text-only.
|
||||
|
||||
## Components
|
||||
- Existing components to reuse: `ebox-create`, `ebox-column`, `ebox-row`, `ebox-flex`, `ebox-grid`, and `ebox-spacer`.
|
||||
- Author forms to reuse: String, `text`, `box`, `row`, `column`, `flex`, and `grid`. Empty `box` nodes express spacing directly without another public form.
|
||||
- New/changed components: Header band, property section bands, track-function cards, implicit-track/flow cards, gap/placement cards, alignment cards, and public-contract footer.
|
||||
- Variants and states: Static semantic color families only.
|
||||
- Token/component ownership: Palette values and example composition live in `.ebox` fixtures; the runner owns only parsing and rendering. The migrated references remain data files, so adding a layout does not add a fixture-specific Elisp branch.
|
||||
|
||||
@ -41,7 +41,7 @@
|
||||
- 图像与图标:纯文本。
|
||||
|
||||
## 组件
|
||||
- 复用的现有组件:`ebox-create`、`ebox-column`、`ebox-row`、`ebox-flex`、`ebox-grid` 和 `ebox-spacer`。
|
||||
- 复用的作者 form:String、`text`、`box`、`row`、`column`、`flex` 和 `grid`。空 `box` 直接表达间距,不再引入另一个公共 form。
|
||||
- 新增/调整的组件:标题带、能力分区标题带、固定/分数轨道卡片、放置卡片和公开契约页脚。
|
||||
- 变体与状态:仅使用静态语义色组。
|
||||
- Token/组件归属:配色值和示例组合放在 `.ebox` fixture 中;运行器只负责解析和渲染。迁移来的参考仍然是数据文件,新增布局不需要在 Elisp 中增加针对 fixture 的分支。
|
||||
|
||||
@ -167,7 +167,9 @@ CANVAS-BACKGROUND fills display space outside generated root lines."
|
||||
(prog1
|
||||
(progn
|
||||
(ebox-playground--apply-preview-display-settings
|
||||
(and (consp node) (plist-get node :bgcolor)))
|
||||
(and (consp node)
|
||||
(ebox-style-node-specified-value
|
||||
node :background-color)))
|
||||
(ebox-render-to-buffer buffer node))
|
||||
(setq published-p t))
|
||||
(unless published-p
|
||||
|
||||
@ -1,7 +1,3 @@
|
||||
(box :content "Playground file"
|
||||
:box-sizing 'border-box
|
||||
:padding '(1 (12))
|
||||
:border t
|
||||
:border-color "#2563EB"
|
||||
:bgcolor "#EFF6FF"
|
||||
:color "#1E3A8A")
|
||||
(box :box-sizing 'border-box :padding '(1 (12)) :border t
|
||||
:border-color "#2563EB" :bgcolor "#EFF6FF" :color "#1E3A8A"
|
||||
"Playground file")
|
||||
|
||||
@ -1,41 +1,29 @@
|
||||
(box :layout 'column
|
||||
(box :content "Ebox comprehensive DSL showcase\nThe outer sections omit :width so Playground viewport sizing drives the layout."
|
||||
:padding '(1 (16)) :border "#334155"
|
||||
:bgcolor "#F8FAFC" :color "#0F172A" :text-align 'center)
|
||||
|
||||
(column
|
||||
(box :padding '(1 (16)) :border "#334155" :bgcolor "#F8FAFC" :color
|
||||
"#0F172A" :text-align 'center
|
||||
"Ebox comprehensive DSL showcase\nThe outer sections omit :width so Playground viewport sizing drives the layout.")
|
||||
(box :width '(viewport) :height 1 :bgcolor "#F8FAFC")
|
||||
|
||||
(box :content "Width rule in this file\nContainer sections use auto width. Fixed widths remain only where the example demonstrates exact item sizing, basis, min-width, or max-width."
|
||||
:padding '(0 (14)) :border "#64748B"
|
||||
:bgcolor "#F8FAFC" :color "#111827" :wrap-mode 'word)
|
||||
|
||||
(box :padding '(0 (14)) :border "#64748B" :bgcolor "#F8FAFC" :color
|
||||
"#111827" :wrap-mode 'word
|
||||
"Width rule in this file\nContainer sections use auto width. Fixed widths remain only where the example demonstrates exact item sizing, basis, min-width, or max-width.")
|
||||
(box :width '(viewport) :height 1 :bgcolor "#F8FAFC")
|
||||
|
||||
(box :layout 'flex
|
||||
:margin '(1 0 0 1) :padding '(1 (8))
|
||||
:border "#475569" :bgcolor "#F8FAFC"
|
||||
:flex-flow '(row wrap)
|
||||
:justify-content 'space-between :align-items 'center
|
||||
:align-content 'flex-start :row-gap 1 :column-gap '(12)
|
||||
(item
|
||||
:order -1 :flex-basis '(270) :align-self 'flex-start
|
||||
(box :content "item order -1\n:flex-basis 270\nalign-self start"
|
||||
:width '(270) :padding '(0 (8))
|
||||
:border "#BE185D" :bgcolor "#FCE7F3" :color "#831843"
|
||||
:wrap-mode 'word))
|
||||
(box :flex '(1 1 (220))
|
||||
:content "Box :flex (1 1 220)\ngrow shrink basis"
|
||||
:width '(220) :height 4
|
||||
:padding '(0 (8)) :border "#1D4ED8"
|
||||
:bgcolor "#DBEAFE" :color "#111827" :wrap-mode 'word)
|
||||
(box :flex-grow 2 :flex-shrink 1 :flex-basis '(240)
|
||||
:align-self 'center
|
||||
:content "Box grow 2\nshrink 1\nbasis 240"
|
||||
:width '(240) :height 4 :padding '(0 (8))
|
||||
:border "#B45309" :bgcolor "#FEF3C7" :color "#78350F"
|
||||
:wrap-mode 'word)
|
||||
(box :flex-shrink 3 :flex-basis '(190) :align-self 'flex-end
|
||||
:content "Box shrink 3\nbasis 190\nalign-self flex-end"
|
||||
:width '(190) :height 4 :padding '(0 (8))
|
||||
:border "#15803D" :bgcolor "#DCFCE7" :color "#14532D"
|
||||
:wrap-mode 'word)))
|
||||
(flex :margin '(1 0 0 1) :padding '(1 (8)) :border "#475569" :bgcolor
|
||||
"#F8FAFC" :flex-flow '(row wrap) :justify-content
|
||||
'space-between :align-items 'center :align-content 'flex-start
|
||||
:row-gap 1 :column-gap '(12)
|
||||
(box :order -1 :flex-basis '(270) :align-self 'flex-start
|
||||
:width '(270) :padding '(0 (8)) :border "#BE185D"
|
||||
:bgcolor "#FCE7F3" :color "#831843" :wrap-mode 'word
|
||||
"Box order -1\n:flex-basis 270\nalign-self start")
|
||||
(box :flex '(1 1 (220)) :width '(220) :height 4 :padding
|
||||
'(0 (8)) :border "#1D4ED8" :bgcolor "#DBEAFE" :color
|
||||
"#111827" :wrap-mode 'word
|
||||
"Box :flex (1 1 220)\ngrow shrink basis")
|
||||
(box :flex-grow 2 :flex-shrink 1 :flex-basis '(240) :align-self
|
||||
'center :width '(240) :height 4 :padding '(0 (8)) :border
|
||||
"#B45309" :bgcolor "#FEF3C7" :color "#78350F" :wrap-mode
|
||||
'word "Box grow 2\nshrink 1\nbasis 240")
|
||||
(box :flex-shrink 3 :flex-basis '(190) :align-self 'flex-end
|
||||
:width '(190) :height 4 :padding '(0 (8)) :border
|
||||
"#15803D" :bgcolor "#DCFCE7" :color "#14532D" :wrap-mode
|
||||
'word "Box shrink 3\nbasis 190\nalign-self flex-end")))
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,98 +1,61 @@
|
||||
(box :layout 'column
|
||||
(box :content "Ebox Playground\nPixel-precise layout, composed only from public nodes."
|
||||
:width '(720)
|
||||
:padding '(1 (18))
|
||||
:border "#8F432F"
|
||||
:color "#252A2E"
|
||||
:bgcolor "#FFFDF8"
|
||||
:face 'bold
|
||||
:text-align 'center)
|
||||
(column
|
||||
(box :width '(720) :padding '(1 (18)) :border "#8F432F" :color
|
||||
"#252A2E" :bgcolor "#FFFDF8" :font-weight 'bold :text-align 'center
|
||||
"Ebox Playground\nPixel-precise layout, composed only from public nodes.")
|
||||
(box :width '(720) :height 1 :bgcolor "#FAF7F0")
|
||||
(box :content "01 FIXED + FRACTIONAL\nA definite Grid width divides into one exact track and one flexible track."
|
||||
:width '(720)
|
||||
:padding '(0 (16))
|
||||
:border "#C97252"
|
||||
:border-bottom 'none
|
||||
:color "#252A2E"
|
||||
:bgcolor "#F1D4C9"
|
||||
:wrap-mode 'word)
|
||||
(box :layout 'grid
|
||||
:width '(720)
|
||||
:grid-template-columns '((220) 1fr)
|
||||
:gap '(1 (12))
|
||||
:border "#C97252"
|
||||
:bgcolor "#FFF9F5"
|
||||
(box :content "FIXED TRACK\n220 px stays exact"
|
||||
:width '(220) :padding '(1 0) :text-align 'center
|
||||
:color "#252A2E" :bgcolor "#F1D4C9")
|
||||
(box :content "FRACTIONAL TRACK\n1fr receives the remaining width"
|
||||
:width '(486) :padding '(1 0) :text-align 'center
|
||||
:color "#252A2E" :bgcolor "#F9E8E0")
|
||||
(box :content "The Grid owns one definite width; its tracks divide that space without competing viewport calculations."
|
||||
:grid-column '(1 :span 2) :width '(718) :padding '(1 0)
|
||||
:color "#663322" :bgcolor "#FFFDF8"
|
||||
:text-align 'center :wrap-mode 'word))
|
||||
(box :width '(720) :padding '(0 (16)) :border "#C97252"
|
||||
:border-bottom 'none :color "#252A2E" :bgcolor "#F1D4C9"
|
||||
:wrap-mode 'word
|
||||
"01 FIXED + FRACTIONAL\nA definite Grid width divides into one exact track and one flexible track.")
|
||||
(grid :width '(720) :grid-template-columns '((220) 1fr) :gap
|
||||
'(1 (12)) :border "#C97252" :bgcolor "#FFF9F5"
|
||||
(box :width '(220) :padding '(1 0) :text-align 'center :color
|
||||
"#252A2E" :bgcolor "#F1D4C9"
|
||||
"FIXED TRACK\n220 px stays exact")
|
||||
(box :width '(486) :padding '(1 0) :text-align 'center :color
|
||||
"#252A2E" :bgcolor "#F9E8E0"
|
||||
"FRACTIONAL TRACK\n1fr receives the remaining width")
|
||||
(box :grid-column '(1 :span 2) :width '(718) :padding '(1 0)
|
||||
:color "#663322" :bgcolor "#FFFDF8" :text-align 'center
|
||||
:wrap-mode 'word
|
||||
"The Grid owns one definite width; its tracks divide that space without competing viewport calculations."))
|
||||
(box :width '(720) :height 1 :bgcolor "#FAF7F0")
|
||||
(box :content "02 EXPLICIT PLACEMENT\nSpan columns, target cells, and leave the remaining nodes to auto placement."
|
||||
:width '(720)
|
||||
:padding '(0 (16))
|
||||
:border "#6D8A73"
|
||||
:border-bottom 'none
|
||||
:color "#252A2E"
|
||||
:bgcolor "#DCEBDD"
|
||||
:wrap-mode 'word)
|
||||
(box :layout 'grid
|
||||
:width '(720)
|
||||
:grid-template-columns '((210) (210) 1fr)
|
||||
:gap '(1 (10))
|
||||
:border "#6D8A73"
|
||||
:bgcolor "#F7FBF7"
|
||||
(box :content "SPAN 1 → 3" :grid-column '(1 :span 2)
|
||||
:width '(430) :padding '(1 0) :text-align 'center
|
||||
:color "#24422D" :bgcolor "#DCEBDD")
|
||||
(box :content "COLUMN 3" :grid-column 3 :grid-row 1
|
||||
:width '(278) :padding '(1 0) :text-align 'center
|
||||
:color "#24422D" :bgcolor "#C8DDCB")
|
||||
(box :content "ROW 2 / COL 1" :grid-column 1 :grid-row 2
|
||||
:width '(210) :padding '(1 0) :text-align 'center
|
||||
:color "#24422D" :bgcolor "#EDF5EE")
|
||||
(box :content "AUTO PLACED" :width '(210) :padding '(1 0)
|
||||
:text-align 'center :color "#24422D" :bgcolor "#E3F0E5")
|
||||
(box :content "STABLE CELLS" :width '(278) :padding '(1 0)
|
||||
:text-align 'center :color "#24422D" :bgcolor "#D4E6D7"))
|
||||
(box :width '(720) :padding '(0 (16)) :border "#6D8A73"
|
||||
:border-bottom 'none :color "#252A2E" :bgcolor "#DCEBDD"
|
||||
:wrap-mode 'word
|
||||
"02 EXPLICIT PLACEMENT\nSpan columns, target cells, and leave the remaining nodes to auto placement.")
|
||||
(grid :width '(720) :grid-template-columns '((210) (210) 1fr) :gap
|
||||
'(1 (10)) :border "#6D8A73" :bgcolor "#F7FBF7"
|
||||
(box :grid-column '(1 :span 2) :width '(430) :padding '(1 0)
|
||||
:text-align 'center :color "#24422D" :bgcolor "#DCEBDD"
|
||||
"SPAN 1 → 3")
|
||||
(box :grid-column 3 :grid-row 1 :width '(278) :padding '(1 0)
|
||||
:text-align 'center :color "#24422D" :bgcolor "#C8DDCB"
|
||||
"COLUMN 3")
|
||||
(box :grid-column 1 :grid-row 2 :width '(210) :padding '(1 0)
|
||||
:text-align 'center :color "#24422D" :bgcolor "#EDF5EE"
|
||||
"ROW 2 / COL 1")
|
||||
(box :width '(210) :padding '(1 0) :text-align 'center :color
|
||||
"#24422D" :bgcolor "#E3F0E5" "AUTO PLACED")
|
||||
(box :width '(278) :padding '(1 0) :text-align 'center :color
|
||||
"#24422D" :bgcolor "#D4E6D7" "STABLE CELLS"))
|
||||
(box :width '(720) :height 1 :bgcolor "#FAF7F0")
|
||||
(box :content "03 PUBLIC COMPOSITION\nColumn, Flex, and Grid share the same public node contract."
|
||||
:width '(720)
|
||||
:padding '(0 (16))
|
||||
:border "#4E7890"
|
||||
:border-bottom 'none
|
||||
:color "#252A2E"
|
||||
:bgcolor "#D9EAF2"
|
||||
:wrap-mode 'word)
|
||||
(box :layout 'flex
|
||||
:width '(720)
|
||||
:flex-flow '(row wrap)
|
||||
:gap '(1 (12))
|
||||
:padding '(1 (12))
|
||||
:border "#4E7890"
|
||||
:bgcolor "#F7FAFC"
|
||||
(box :content "COLUMN\nvertical composition"
|
||||
:flex-grow 1 :flex-shrink 1 :flex-basis '(200)
|
||||
:min-width '(180) :padding '(1 (12))
|
||||
:color "#193846" :bgcolor "#D9EAF2")
|
||||
(box :content "FLEX\nwrap and distribute"
|
||||
:flex-grow 1 :flex-shrink 1 :flex-basis '(200)
|
||||
:min-width '(180) :padding '(1 (12))
|
||||
:color "#3F3655" :bgcolor "#E7E2F1")
|
||||
(box :content "GRID\nplace in two dimensions"
|
||||
:flex-grow 1 :flex-shrink 1 :flex-basis '(200)
|
||||
:min-width '(180) :padding '(1 (12))
|
||||
:color "#6B3020" :bgcolor "#F1D4C9"))
|
||||
(box :width '(720) :padding '(0 (16)) :border "#4E7890"
|
||||
:border-bottom 'none :color "#252A2E" :bgcolor "#D9EAF2"
|
||||
:wrap-mode 'word
|
||||
"03 PUBLIC COMPOSITION\nColumn, Flex, and Grid share the same public node contract.")
|
||||
(flex :width '(720) :flex-flow '(row wrap) :gap '(1 (12)) :padding
|
||||
'(1 (12)) :border "#4E7890" :bgcolor "#F7FAFC"
|
||||
(box :flex-grow 1 :flex-shrink 1 :flex-basis '(200) :min-width
|
||||
'(180) :padding '(1 (12)) :color "#193846" :bgcolor
|
||||
"#D9EAF2" "COLUMN\nvertical composition")
|
||||
(box :flex-grow 1 :flex-shrink 1 :flex-basis '(200) :min-width
|
||||
'(180) :padding '(1 (12)) :color "#3F3655" :bgcolor
|
||||
"#E7E2F1" "FLEX\nwrap and distribute")
|
||||
(box :flex-grow 1 :flex-shrink 1 :flex-basis '(200) :min-width
|
||||
'(180) :padding '(1 (12)) :color "#6B3020" :bgcolor
|
||||
"#F1D4C9" "GRID\nplace in two dimensions"))
|
||||
(box :width '(720) :height 1 :bgcolor "#FAF7F0")
|
||||
(box :content "PUBLIC CONTRACT ebox-create · ebox-column · ebox-flex · ebox-grid · ebox-spacer"
|
||||
:width '(720)
|
||||
:padding '(0 (16))
|
||||
:border "#8D887F"
|
||||
:color "#4D5651"
|
||||
:bgcolor "#EEEAE2"
|
||||
:wrap-mode 'word))
|
||||
(box :width '(720) :padding '(0 (16)) :border "#8D887F" :color
|
||||
"#4D5651" :bgcolor "#EEEAE2" :wrap-mode 'word
|
||||
"AUTHOR FORMS String · text · box · row · column · flex · grid"))
|
||||
|
||||
@ -1,65 +1,57 @@
|
||||
(box :layout 'column
|
||||
:margin-left 1 :margin-top 1 :padding '(1 2 1 2) :bgcolor "linen"
|
||||
(box :content "Ebox Responsive Layout\nDrag the preview window: sections stretch to the current viewport, cards reflow, and text wraps without changing the window layout."
|
||||
:padding '(1 (18)) :border "#334155" :text-align 'center
|
||||
:color "#000" :bgcolor "ghost white")
|
||||
(box :height 1)
|
||||
|
||||
(box :content "No explicit viewport width here\nThis page mostly omits :width. The Playground binds the current preview width while rendering, so auto width behaves like a responsive container."
|
||||
:padding '(0 (16)) :border "#0F766E"
|
||||
:bgcolor "#F0FDFA" :color "#134E4A" :wrap-mode 'word)
|
||||
(box :height 1)
|
||||
|
||||
(box :content "Adaptive toolbar\nButtons below keep stable sizes. The row packs as many as fit and then wraps."
|
||||
:padding '(0 (16)) :border "#EA580C" :border-bottom 'none
|
||||
:bgcolor "#FFF7ED" :color "#431407" :wrap-mode 'word)
|
||||
(box :layout 'flex :flex-flow '(row wrap) :column-gap '(8) :row-gap 1
|
||||
:padding '(1 (8)) :border "#FDBA74" :bgcolor "#FFFBF5"
|
||||
(box :content "Render" :width '(96) :padding '(0 (8))
|
||||
:border "#EA580C" :bgcolor "#FED7AA" :color "#111827"
|
||||
:text-align 'center)
|
||||
(box :content "Save" :width '(88) :padding '(0 (8))
|
||||
:border "#D97706" :bgcolor "#FEF3C7" :color "#111827"
|
||||
:text-align 'center)
|
||||
(box :content "Format" :width '(96) :padding '(0 (8))
|
||||
:border "#16A34A" :bgcolor "#DCFCE7" :color "#14532D"
|
||||
:text-align 'center)
|
||||
(box :content "Sample" :width '(104) :padding '(0 (8))
|
||||
:border "#0284C7" :bgcolor "#E0F2FE" :color "#0C4A6E"
|
||||
:text-align 'center)
|
||||
(box :content "Write" :width '(88) :padding '(0 (8))
|
||||
:border "#9333EA" :bgcolor "#F3E8FF" :color "#3B0764"
|
||||
:text-align 'center))
|
||||
(box :height 1)
|
||||
|
||||
(box :content "Responsive cards\nEach card starts from a flex-basis, grows when space is available, and wraps to new rows when the preview becomes narrow."
|
||||
:padding '(0 (16)) :border "#2563EB" :border-bottom 'none
|
||||
:bgcolor "#EFF6FF" :color "#1E3A8A" :wrap-mode 'word)
|
||||
(box :layout 'flex :flex-flow '(row wrap) :column-gap '(12) :row-gap 1
|
||||
:padding '(1 (8)) :border "#93C5FD" :bgcolor "#F8FBFF"
|
||||
:justify-content 'center
|
||||
(box :flex '(1 1 (210))
|
||||
:content "Overview\nThe row uses the current preview width automatically."
|
||||
:min-width '(180) :max-width '(280)
|
||||
:padding '(0 (10)) ;; :border "#2563EB"
|
||||
:bgcolor "#DBEAFE" :color "#111827" :wrap-mode 'word)
|
||||
(box :flex '(1 1 (210))
|
||||
:content "Editor\nDrag slowly or quickly; resize rendering follows the viewport."
|
||||
:min-width '(180) :max-width '(300)
|
||||
:padding '(0 (10)) ;; :border "#4F46E5"
|
||||
:bgcolor "#E0E7FF" :color "#111827" :wrap-mode 'word)
|
||||
(box :flex '(1 1 (210))
|
||||
:content "Preview\nThe preview updates from the current viewport width."
|
||||
:min-width '(180) :max-width '(320)
|
||||
:padding '(0 (10)) ;; :border "#7C3AED"
|
||||
:bgcolor "#EDE9FE" :color "#111827" :wrap-mode 'word)
|
||||
(box :flex '(1 1 (210))
|
||||
:content "Flow\nCards keep readable widths instead of overflowing."
|
||||
:min-width '(180) :max-width '(280)
|
||||
:padding '(0 (10)) ;; :border "#0891B2"
|
||||
:bgcolor "#CFFAFE" :color "#164E63" :wrap-mode 'word))
|
||||
(box :height 1)
|
||||
|
||||
(box :content "What to watch\nNarrow preview: cards stack and text wraps. Wide preview: cards share a row and expand up to max-width. The source/preview split is preserved."
|
||||
:padding '(0 (16)) :border "#475569"
|
||||
:bgcolor "#F8FAFC" :color "#0F172A" :wrap-mode 'word))
|
||||
(column :margin-left 1 :margin-top 1 :padding '(1 2 1 2) :bgcolor
|
||||
"linen"
|
||||
(box :padding '(1 (18)) :border "#334155" :text-align 'center
|
||||
:color "#000" :bgcolor "ghost white"
|
||||
"Ebox Responsive Layout\nDrag the preview window: sections stretch to the current viewport, cards reflow, and text wraps without changing the window layout.")
|
||||
(box :height 1)
|
||||
(box :padding '(0 (16)) :border "#0F766E" :bgcolor "#F0FDFA"
|
||||
:color "#134E4A" :wrap-mode 'word
|
||||
"No explicit viewport width here\nThis page mostly omits :width. The Playground binds the current preview width while rendering, so auto width behaves like a responsive container.")
|
||||
(box :height 1)
|
||||
(box :padding '(0 (16)) :border "#EA580C" :border-bottom 'none
|
||||
:bgcolor "#FFF7ED" :color "#431407" :wrap-mode 'word
|
||||
"Adaptive toolbar\nButtons below keep stable sizes. The row packs as many as fit and then wraps.")
|
||||
(flex :flex-flow '(row wrap) :column-gap '(8) :row-gap 1
|
||||
:padding '(1 (8)) :border "#FDBA74" :bgcolor "#FFFBF5"
|
||||
(box :width '(96) :padding '(0 (8)) :border "#EA580C"
|
||||
:bgcolor "#FED7AA" :color "#111827" :text-align
|
||||
'center "Render")
|
||||
(box :width '(88) :padding '(0 (8)) :border "#D97706"
|
||||
:bgcolor "#FEF3C7" :color "#111827" :text-align
|
||||
'center "Save")
|
||||
(box :width '(96) :padding '(0 (8)) :border "#16A34A"
|
||||
:bgcolor "#DCFCE7" :color "#14532D" :text-align
|
||||
'center "Format")
|
||||
(box :width '(104) :padding '(0 (8)) :border "#0284C7"
|
||||
:bgcolor "#E0F2FE" :color "#0C4A6E" :text-align
|
||||
'center "Sample")
|
||||
(box :width '(88) :padding '(0 (8)) :border "#9333EA"
|
||||
:bgcolor "#F3E8FF" :color "#3B0764" :text-align
|
||||
'center "Write"))
|
||||
(box :height 1)
|
||||
(box :padding '(0 (16)) :border "#2563EB" :border-bottom 'none
|
||||
:bgcolor "#EFF6FF" :color "#1E3A8A" :wrap-mode 'word
|
||||
"Responsive cards\nEach card starts from a flex-basis, grows when space is available, and wraps to new rows when the preview becomes narrow.")
|
||||
(flex :flex-flow '(row wrap) :column-gap '(12) :row-gap 1
|
||||
:padding '(1 (8)) :border "#93C5FD" :bgcolor "#F8FBFF"
|
||||
:justify-content 'center
|
||||
(box :flex '(1 1 (210)) :min-width '(180) :max-width
|
||||
'(280) :padding '(0 (10)) :bgcolor "#DBEAFE" :color
|
||||
"#111827" :wrap-mode 'word
|
||||
"Overview\nThe row uses the current preview width automatically.")
|
||||
(box :flex '(1 1 (210)) :min-width '(180) :max-width
|
||||
'(300) :padding '(0 (10)) :bgcolor "#E0E7FF" :color
|
||||
"#111827" :wrap-mode 'word
|
||||
"Editor\nDrag slowly or quickly; resize rendering follows the viewport.")
|
||||
(box :flex '(1 1 (210)) :min-width '(180) :max-width
|
||||
'(320) :padding '(0 (10)) :bgcolor "#EDE9FE" :color
|
||||
"#111827" :wrap-mode 'word
|
||||
"Preview\nThe preview updates from the current viewport width.")
|
||||
(box :flex '(1 1 (210)) :min-width '(180) :max-width
|
||||
'(280) :padding '(0 (10)) :bgcolor "#CFFAFE" :color
|
||||
"#164E63" :wrap-mode 'word
|
||||
"Flow\nCards keep readable widths instead of overflowing."))
|
||||
(box :height 1)
|
||||
(box :padding '(0 (16)) :border "#475569" :bgcolor "#F8FAFC"
|
||||
:color "#0F172A" :wrap-mode 'word
|
||||
"What to watch\nNarrow preview: cards stack and text wraps. Wide preview: cards share a row and expand up to max-width. The source/preview split is preserved."))
|
||||
|
||||
@ -120,7 +120,7 @@ concurrent cache warming CPU work."
|
||||
(completed-without-error nil)
|
||||
(ebox-playground-flex-resize-evaluator--output-lines nil)
|
||||
(checks nil))
|
||||
(condition-case error-data
|
||||
(condition-case-unless-debug error-data
|
||||
(progn
|
||||
(delete-other-windows)
|
||||
(setq source
|
||||
|
||||
@ -33,6 +33,13 @@
|
||||
(ebox-playground-test--forms-named name child))
|
||||
form))))
|
||||
|
||||
(defun ebox-playground-test--form-children (form)
|
||||
"Return canonical author children from DSL FORM."
|
||||
(let ((items (cdr form)))
|
||||
(while (keywordp (car items))
|
||||
(setq items (cddr items)))
|
||||
items))
|
||||
|
||||
(defun ebox-playground-test--line-widths (text)
|
||||
"Return rendered pixel widths for every line in TEXT."
|
||||
(mapcar #'ebox-string-pixel-width
|
||||
@ -115,15 +122,17 @@
|
||||
ebox-playground-directory))))
|
||||
(dolist (box (ebox-playground-test--boxes form))
|
||||
(let ((properties (cdr box)))
|
||||
(when (and (memq :content properties)
|
||||
(when (and (cl-some #'stringp
|
||||
(ebox-playground-test--form-children box))
|
||||
(memq :bgcolor properties))
|
||||
(should (memq :color properties))))))))
|
||||
|
||||
(ert-deftest ebox-playground-uses-only-public-layout-apis ()
|
||||
"The example should build and render through the public Ebox entry point."
|
||||
(let* ((node (ebox-playground-view))
|
||||
(let* ((source (ebox-playground--read-file ebox-playground-default-file))
|
||||
(node (ebox-playground-view))
|
||||
(rendered (substring-no-properties (ebox-render node))))
|
||||
(should (eq (plist-get node :ebox-type) 'stack))
|
||||
(should (eq (car source) 'column))
|
||||
(dolist (label '("Ebox Playground" "FIXED + FRACTIONAL"
|
||||
"EXPLICIT PLACEMENT" "PUBLIC COMPOSITION"))
|
||||
(should (string-match-p (regexp-quote label) rendered)))))
|
||||
@ -234,7 +243,7 @@
|
||||
(lambda (&optional _frame) 8)))
|
||||
(with-temp-buffer
|
||||
(setq buffer-file-name "/tmp/ebox-playground-viewport-render.ebox")
|
||||
(insert "(box :content \"viewport\" :width '(viewport) :height 1)")
|
||||
(insert "(box :width '(viewport) :height 1 \"viewport\")")
|
||||
(ebox-dsl-mode)
|
||||
(ebox-dsl-render)
|
||||
(with-current-buffer preview
|
||||
@ -281,7 +290,7 @@
|
||||
(with-temp-buffer
|
||||
(setq source (current-buffer)
|
||||
buffer-file-name "/tmp/ebox-playground-two-window.ebox")
|
||||
(insert "(box :content \"two windows\" :width '(viewport) :height 1)")
|
||||
(insert "(box :width '(viewport) :height 1 \"two windows\")")
|
||||
(ebox-dsl-mode)
|
||||
(cl-letf (((symbol-function 'window-body-width)
|
||||
(lambda (&optional _window _pixelwise) 987))
|
||||
@ -313,7 +322,7 @@
|
||||
(lambda (&optional _frame) 8)))
|
||||
(with-temp-buffer
|
||||
(setq buffer-file-name "/tmp/ebox-playground-viewport-resize.ebox")
|
||||
(insert "(box :content \"viewport\" :width '(viewport) :height 1)")
|
||||
(insert "(box :width '(viewport) :height 1 \"viewport\")")
|
||||
(ebox-dsl-mode)
|
||||
(ebox-dsl-render)
|
||||
(setq window-width 1234)
|
||||
@ -417,7 +426,7 @@
|
||||
(error "Injected preview render failure"))))
|
||||
(should-error
|
||||
(ebox-playground--render-to-preview-buffer
|
||||
preview (ebox-create :content "rollback"))))
|
||||
preview (ebox-build '(box "rollback")))))
|
||||
(with-current-buffer preview
|
||||
(should-not truncate-lines)
|
||||
(should (equal face-remapping-alist
|
||||
@ -481,21 +490,21 @@
|
||||
(let* ((ebox-viewport-width viewport)
|
||||
(lines (ebox-string-lines
|
||||
(ebox-render (ebox-playground-view path viewport))))
|
||||
(spacer-lines
|
||||
(separator-lines
|
||||
(cl-remove-if-not
|
||||
(lambda (line)
|
||||
(equal (get-text-property 0 'display line)
|
||||
`(space :width (,viewport))))
|
||||
lines)))
|
||||
(should (= (length spacer-lines) 11))
|
||||
(dolist (line spacer-lines)
|
||||
(should (= (length separator-lines) 11))
|
||||
(dolist (line separator-lines)
|
||||
(should (equal (get-text-property 0 'display line)
|
||||
`(space :width (,viewport))))
|
||||
(should (= (ebox-string-pixel-width line) viewport))
|
||||
(should (equal (get-text-property 0 'face line)
|
||||
'(:background "#FAF7F0"))))))))
|
||||
|
||||
(ert-deftest ebox-playground-public-layout-gallery-fixed-spacers-paint-the-canvas ()
|
||||
(ert-deftest ebox-playground-public-layout-gallery-fixed-separators-paint-the-canvas ()
|
||||
"The default public gallery fixed separators should keep canvas coverage."
|
||||
(let* ((path (expand-file-name "examples/public-layout-gallery.ebox"
|
||||
ebox-playground-directory))
|
||||
@ -512,11 +521,11 @@
|
||||
|
||||
(ert-deftest ebox-playground-grid-reference-covers-public-properties ()
|
||||
"The Grid reference should cover every public property and supported value form."
|
||||
(let ((source (with-temp-buffer
|
||||
(insert-file-contents
|
||||
(expand-file-name "examples/grid-reference.ebox"
|
||||
ebox-playground-directory))
|
||||
(buffer-string))))
|
||||
(let ((source
|
||||
(prin1-to-string
|
||||
(ebox-playground--read-file
|
||||
(expand-file-name "examples/grid-reference.ebox"
|
||||
ebox-playground-directory)))))
|
||||
(dolist (property '(:grid-template-columns :grid-template-rows
|
||||
:grid-auto-columns :grid-auto-rows :grid-auto-flow
|
||||
:grid-row-gap :grid-column-gap :gap :row-gap
|
||||
@ -565,7 +574,7 @@
|
||||
(unwind-protect
|
||||
(with-temp-buffer
|
||||
(setq buffer-file-name "/tmp/ebox-playground-render-test.ebox")
|
||||
(insert "(box :content \"Rendered from .ebox\" :width '(240))")
|
||||
(insert "(box :width '(240) \"Rendered from .ebox\")")
|
||||
(ebox-dsl-mode)
|
||||
(ebox-dsl-render)
|
||||
(should (eq (window-buffer (selected-window)) (current-buffer)))
|
||||
@ -578,16 +587,19 @@
|
||||
(ert-deftest ebox-playground-evaluates-property-expressions ()
|
||||
"Evaluate executable property values while preserving quoted constants."
|
||||
(let* ((form (ebox-playground--evaluate-form
|
||||
'(box :content "Dynamic property values"
|
||||
:width (ebox-playground-test--dynamic-width)
|
||||
'(box :width (ebox-playground-test--dynamic-width)
|
||||
:color (ebox-playground-test--dynamic-color)
|
||||
:padding '(0 (4))
|
||||
:text-align 'center)))
|
||||
:text-align 'center
|
||||
"Dynamic property values")))
|
||||
(node (ebox-build form)))
|
||||
(should (equal (plist-get node :width) 240))
|
||||
(should (equal (plist-get node :color) "#123456"))
|
||||
(should (equal (plist-get node :padding-left-pixel) 4))
|
||||
(should (eq (plist-get node :text-align) 'center))))
|
||||
(should (equal (ebox-style-node-specified-value node :width) '(240)))
|
||||
(should (equal (ebox-style-node-specified-value node :color) "#123456"))
|
||||
(should (equal
|
||||
(ebox-style-node-specified-value node :padding-left)
|
||||
'(4)))
|
||||
(should (eq (ebox-style-node-specified-value node :text-align)
|
||||
'center))))
|
||||
|
||||
(provide 'ebox-playground-tests)
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user