feat(ui): flex-shrink, text that wraps beside its siblings, calc(), order, and 0 as a size
- flex-shrink: a line whose children want more room than it has takes it back from those that shrink, in proportion to shrink times size and never below a min size, a fixed size or the content. A scroll box shrinks (and scrolls), and a box in a column shrinks as far as the scroll boxes inside it let it, so a list in a column takes the room its siblings leave with no height. `flex: grow shrink`, and `flex-shrink` by name. - A row wider than its room measures its texts (and boxes without a width) again in the room the rest leave them, so a line wraps beside an icon. - calc() with + - * / and brackets over px, %, em, rem, vw, vh, plain numbers and var(); a width or height keeps its percentage, taken of the room it is given. Lengths lists (padding, margin) keep a calc()'s spaces. - `order` places a box's children without touching the tree. - width: 0 and height: 0 are 0: an unset size is UI_AUTO now, not 0. - A component root that is itself a component takes each user's class, style and id in turn (the outermost's id wins), and the rules of all their sheets are weighed by specificity together; a user's rule wins a tie. The parent's sheet used to override the child's whatever its specificity, and a middle component's sheet was lost. - The default sheet lays .ui-track out as a row, so a range's fill is as tall as its track and a checked box's knob goes right; a range's thumb is centred on the fill's end. - ui_boxes.ludic. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
9ad6347044
commit
7d8f34de17
23 changed files with 609 additions and 94 deletions
53
packages/ludic.ui/cascade_merge.ludic
Normal file
53
packages/ludic.ui/cascade_merge.ludic
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
# cascade_merge.ludic - a component's root is styled by its own sheet and by the sheet of every user
|
||||
# that passed a class down to it, all at once: the rules that match, from all of them, ordered by
|
||||
# specificity as one sheet's are. On a tie the user's rule wins (the outermost user's last), as a
|
||||
# later rule does. Then `order`, which rearranges a flex box's children without touching the tree.
|
||||
function cs_merged(n: UiNode) -> void {
|
||||
let rules = new []UiRule
|
||||
let envs = new []UiEnv
|
||||
let seen = new []UiSheet
|
||||
if n.sheet != null { cs_gather(n, n.sheet, n.env, rules, envs, seen) }
|
||||
for i in 0 .. len(n.ups) {
|
||||
if n.ups[i].sheet != null { cs_gather(n, n.ups[i].sheet, n.ups[i].env, rules, envs, seen) }
|
||||
}
|
||||
for i in 0 .. len(rules) { cs_rule_in(n, rules[i], envs[i]) }
|
||||
}
|
||||
# a sheet's matching rules into the list, each after every rule at most as specific (stable)
|
||||
function cs_gather(n: UiNode, sh: UiSheet, e: UiEnv, rules: []UiRule, envs: []UiEnv, seen: []UiSheet) -> void {
|
||||
for i in 0 .. len(seen) {
|
||||
if seen[i] == sh { return }
|
||||
}
|
||||
push(seen, sh)
|
||||
for i in 0 .. len(sh.rules) {
|
||||
let r = sh.rules[i]
|
||||
if md_ok(r) and sel_match(r.sel, n) {
|
||||
push(rules, r)
|
||||
push(envs, e)
|
||||
var j = len(rules) - 1
|
||||
while j > 0 and rules[j - 1].spec > r.spec {
|
||||
rules[j] = rules[j - 1]
|
||||
envs[j] = envs[j - 1]
|
||||
j -= 1
|
||||
}
|
||||
rules[j] = r
|
||||
envs[j] = e
|
||||
}
|
||||
}
|
||||
}
|
||||
# CSS's order: the children placed by it, lowest first, the tree's order kept between equals
|
||||
function cs_order(n: UiNode) -> void {
|
||||
var any = false
|
||||
for i in 0 .. len(n.children) {
|
||||
if ly_order(n.children[i]) != 0 { any = true }
|
||||
}
|
||||
if not any { return }
|
||||
for i in 1 .. len(n.children) {
|
||||
let c = n.children[i]
|
||||
var j = i
|
||||
while j > 0 and ly_order(n.children[j - 1]) > ly_order(c) {
|
||||
n.children[j] = n.children[j - 1]
|
||||
j -= 1
|
||||
}
|
||||
n.children[j] = c
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue