Repository navigation
REDZ.UI 0.19.0
Added
-
A banner for a state of the whole system,
app-bannerwith the tonesapp-banner-info(the default),
app-banner-success,app-banner-warningandapp-banner-danger: the first row ofapp, above its header, across
the window and sticky with the header under it; first in the body of a page without the shell; off paper.
REDZ.ui.banner({tone, text})shows the one banner or replaces it, and answers a function that removes it;
REDZ.ui.banner(null)removes it. The same tone and words again change nothing and say nothing, so a page may call it
on every answer of its server. The words are said once, politely, at once fordanger. Its height goes to
--redz-app-banner-heighton the root, which the header, the side navigation,--redz-sticky-topand the scroll
padding add. -
redz-ui-tools-<version>.zipin every release: the tools a project runs on its own server and never serves, each
the very file the release was built and checked with -floor.php, the browser floor checker, with its list
floor.json, andmin.php, the minifier -, PHP 8.4 or newer with no extension, no network, and their passport
redz-ui-tools.json: the PHP they need, the file of each tool and the sha256 of every file.tools/dist/of the tag,
written byphp tools/build.php; the Check workflow runs both on PHP 8.4 with no extension loaded. -
The floor checker for a project:
php floor.php check [--allow=FILE] [--json] FILE…, a finding a line on standard
output and the summary on standard error, exit 0 clean, 1 findings, 2 for anything else;--jsonprints the findings
as objects. An exception of a project's own carries its reason:/* floor-allow NAME[, NAME…] -- reason */covers its
lines and the next one,--allow=FILEa set of files; one that allows nothing is a finding. It applies the release's
exceptions of scopeanyonly. -
The minifier for a project:
MIN__JsBlocks([$label => $js, …])joins classic scripts, each in a block of its own, for
one ES module, and refuses what reads otherwise there - a staticimportorexport, avaror a function declared
outside any function,thisoutside any function but an arrow,with, an HTML-like comment, a legacy octal number or
escape;MIN__SelfTest()gives the samples it proves itself on that misfire. A class's private names#nameare read. -
Outside judges of the minifier on every commit,
php tools/judge.php: Lightning CSS reprints every stylesheet it
squeezes, the library's and the css-tokenizer-tests corpus, as written and as squeezed, which must read the same;
esbuild parses every script it writes for the browser floor; a watch on the size of the two main files against esbuild
--minify. Both are native binaries from npm, pinned by version and sha512. -
The passport names the arguments of every text:
argsbesidetextsandplurals, andeditor.argsbeside
editor.texts, give each key the{names}the library fills in it,[]for none,["count"]for a count. They
are read from the scripts' calls, and the build fails when two calls of one key pass different names or the
library's own English text of a key uses other names than its calls pass. -
A combination that a button's or a link's
aria-keyshortcutsnames is the page's even while none of them can be
pressed: disabled, busy, hidden, inert or outside the open modal, it never reaches the browser, so a page's save keeps
Ctrl Sfrom the browser's own save while it saves or has nothing to save. The first that can be pressed is pressed. -
A password field tells the page each time its text is shown or hidden, by the person or on its form's submit or the
page's return from the history:redz:revealbubbles from it,detail.revealedtrue or false. -
data-ago="short"on a tickingtimesays how long ago it was in the short words of the page's language ("42 min.
ago", "42 мин. назад") for a narrow place such as a stat tile;data-agoalone keeps the long words. -
Filter buttons: a button with
command="--filter"andaria-controlsnaming a region shows only the items whose
data-NAMEholds a word of itsvalue-NAMEis the button'sname,statewithout one. The buttons of one name
are one choice,value=""shows all, and pressing the pressed one again shows all; names narrow together and with the
search field.data-filter-countcounts: in a button its items, in adata-filter-groupthe group's, with a region's
id the page's textfilter.count. Adata-filter-grouphides while none of its items shows. A press says the count;
the region firesredz:filterwith{count, total}; items the page puts in or changes are filtered again.
REDZ.ui.filter(region, {name: value})chooses from code and answers the count,nullclears. Any element with a
data-searchis an item, and a table row matches its band's label too. -
A search on the server: a field with
data-filter-serverfiresredz:searchwith{query, form, signal}on the
field 600 ms after the typing pauses, at once on Enter and Escape and when another control of its<search>or form
changes; answered with a promise, the region isaria-busyand a field in aform-adornshows a ring, a newer
question aborts the one before and a late answer is dropped, and the count is said - the answer'scount, else the
items there are. -
Show more: a button with
command="--more"andaria-controlsnaming a list firesredz:morewith{shown, signal}on the list; answered with a promise, the button is busy, then the focus goes to the first new item and the
page's textmore.loadedsays how many came. The answer may say{total}or{done: true};data-more-totalis a
total known from the start,data-more-maxa cap whosedata-more-capsentence takes the button's place, and a
data-more-countreadsmore.count("10 of 23") ormore.some("10+").list-moreis the row under a list that
holds them. A server search over the list starts it again. -
Selection: an element with
data-selectholds a selection; a check withdata-select-allheads its checks (or those
of the scopes itsaria-controlsnames) - checked, mixed or clear, and pressed it checks or clears them all. Only
enabled checks in items a filter shows count: a checked row a filter hides leaves the count while hidden and is
checked again when shown. Aselection-barinside hides at zero, adata-select-countsays the page's text
selected, and the scope firesredz:selectionwith{count, total, values}.data-select="rows"checks a row
clicked anywhere but on its controls; adata-selectinside another is a group;command="--select-all"and
"--select-none"buttons do what a head does. -
Sorting in place: a
table-sortbutton with avaluesorts its table's rows by each row'sdata-sort-VALUE, else
the cell'sdata-sort-value, else its text - numbers as numbers, words in the page's language, an empty value last
both ways, ties in the drawn order, a band's rows under it with its subtotal last.data-sort-first="descending"
starts the other way;data-sort-reseton the table makes a third press bring back the drawn order. The page's texts
sort.ascending,sort.descendingandsort.nonesay it. The table fires the cancelableredz:sortwith{key, direction}first, for a page that sorts itself; rows the page puts in are sorted the same, andREDZ.ui.sort(table)
sorts again. -
A question that waits for the server:
REDZ.ui.confirm({..., run})carries the answer out before the dialog closes -
run({choice, phrase, signal})answers a promise; meanwhile OK is busy, the other buttons unavailable, the body inert,
Escape and a click outside held. Refused with words, a danger alert with them stands right above the footer, said at
once, the buttons wake and the focus stays on OK. A dialog closed by code meanwhile aborts the signal, and a later
refusal is a danger toast.choice: {label, items: [{value, text, hint}], value}puts radios above the phrase, and
the answer is then the chosen value. A dialog of the page's own waits the same way: aform[method="dialog"]fires
the cancelableredz:savewith{form, data, submitter, signal}on its submit. -
A third answer:
REDZ.ui.confirm({..., alt: {text, tone, value}})puts a button at the footer's start - Discard
beside Stay and Save - that answers its value;focus: 'ok'or'alt'starts the focus there instead of on Cancel.
dialog-footer-startis that place in any footer, and a footer of three buttons in a dialog narrower than 368 px
stacks them full width, the confirming one on top. -
REDZ.ui.alert(box, {tone, text})fills a box with an alert of the tone, its icon and the words, and says them -
politely, at once fordanger, the same words again said again;nullempties it; a promise shows the page's text
busypast 400 ms, then what it answers or its rejection. No live role on the box. -
REDZ.ui.status(line, {tone, text, keep: true})keeps a success or an info in the line. -
A text download:
command="--download"naming a field, a textarea or any element downloads its value or its text,
data-file,data-type; atext/csvfile starts with a UTF-8 byte order mark unlessdata-bom="false".
REDZ.ui.download({text, file, type, bom})or({blob, file})does it from code. Each download is said, in the
page's textdownloaded. -
busy()on an item of a menu holds the button that opened the menu busy too, the outermost one for a menu inside a
menu. A region'sdata-busyshows its words under the spinner and says them instead ofbusy. Any other element - a
cell that checks - shows a small ring after 400 ms and, for a screen reader, the words of itsdata-busyorbusy,
saying nothing aloud. -
Contents loaded the first time they show:
data-lazyon adetailsor itsaccordion-body, a region a--toggle
button opens, a tab panel or a tree's group firesredz:loadwith{region}when it first shows - open at load, put
in open later, or opened by a person, never for the paper. Answered with a promise, an empty region shows three
placeholder lines; a refusal shows its words in the region, which stays open, and the next opening tries again.
data-lazywritten again on a region that shows loads it again. -
Uploads:
data-paste="page", or an element's id, takes files pasted anywhere on the page or in that element - a paste
of words into a text field stays words, the one in the open modal or the one that shows takes them.
REDZ.ui.upload.clear(upload), and the form's reset, takes away the files not yet stored, their sending aborted;
REDZ.ui.upload.settled(upload)answers once nothing sends.redz:changeaddspendingandfailed, and while a
file sends the file field is invalid with the page's textfile.pending. -
data-followon any element that scrolls keeps its end in view while its contents come in or grow, a ResizeObserver
on it and its children;data-follow="current"keeps its child witharia-currentin view at the nearest edge with a
step's room beside it. Acommand="--follow"button naming it shows while the reader is away and something new came
in, and brings the end back;follow-dockfloats it at the middle of the box's bottom. -
action-bar, a sticky bar at the bottom of the window on the page's tinted floor, withaction-bar-text: across its
region, clear of a phone's home bar, aside on a touch screen while a field has the focus, off paper. -
A list group's item whose title is a
stretched-linkis a link as a whole by script, as a table's row: its words stay
selectable, and Ctrl, Cmd or the middle button open a new tab.list-group-actionsholds its buttons, dimmed until the
item is pointed at or focused. -
The package
redz-ui-qr,js/redz-ui-qr.min.jsinpackages.qr: draws the QR code of a text into aqrtile as one
SVG path that traces each dark region, so no seam shows on paper or at any zoom -data-qr,data-qr-level(L,
Mby default,Q,H) anddata-qr-quiet(4) in the markup, orREDZ.ui.qr(tile, text, {level, quiet})for a
text such as a secret that should sit in no attribute,nullto empty it. Byte mode UTF-8, versions 1 to 40, the
level raised for free when the same version holds more; the tile isrole="img", named by the page; a text too long
empties the tile, marks itdata-qr-errorand hides it. Built withoutinnerHTMLor astyleattribute, so a
strict CSP with Trusted Types passes. A module never falls under 3 px (--redz-qr-module-min): the tile grows. -
logo, a white mat for someone else's logo in both themes, with a border: 32 px high,logo-sm28 andlogo-lg40,
anh-*utility for a banner (h-88added), and as wide as its logo asks -data-ratio, its width by its height,
widens it by the ratio to the power 0.75, from square to four times as wide, and the picture fills 90 by 80 % of it.
data-colorgrounds a logo drawn on a solid color,logo-fadesoftens its sides into it, and animg.logo-groundis
a blurred copy behind a photo;choice-mediatakes the same, a logo there as high as the banner over the fourth root
of its ratio, so a 4:1 wordmark gets 70 % of the height and stays readable. -
Share links for X (
share-x), Viber (share-viber, its letters drawn as VK's are) and WeChat (share-wechat, a plain
button for the page's popover with a QR code);data-share-urlanddata-share-titleon any element write the
share links and copies inside it - a row of buttons without a menu. -
A text token per tone,
--redz-TONE-text: where a tone is text - a subtle badge, an outline or subtle button,
text-TONE, an alert's icon, a form's and a log's tone - it reads it. It is the tone itself, and underdata-brand
the brand darkened in the light theme, its hue kept, to a luminance of 0.13 at most, so it reads at 4.5:1 on white
and on its subtle fill.data-brand-secondary,-success,-info,-warningand-dangerderive their tones the
same way, each with its-subtle,-contrastand-text. -
meter meter-stacked, a meter of several parts on adiv role="meter": each child'sdata-vits share of the scale,
data-toneits color, 2 px apart; a part withdata-overis hatched red, readable without its color. -
Charts:
chart chart-linedraws one series as an SVG line with its area under it, behind the rows that keep their
tooltips and mark their point under the pointer;spark-linedraws a sparkline as a line;spark-stripin astrip
fills its box with a cell a day in its state's tone - 90 days, 60 below 560 px, 30 below 360 px, the oldest going
first - and thestrip-headcaption with thedata-daysshown is the one that shows. -
command-line, a command to copy in one frame: one line that scrolls under a fade at its cut edge, never under the
copy button in its own column, left to right on any page, selected whole by a click; avaris an amber chip of a
part the person puts in.command-stepsnumbers commands run one after another in circles; a--copynaming the
list copies them all, a line each, and one inside acommand-linewithout a target copies its command.
Changed
card-img-overlaylays its words in white on a shade that rises from the bottom of the picture, and its links turn
white with them: the words kept the text's color, so on a phone dark words stood on dark water. Acard-imgunder an
overlay fills its card, so a card a grid stretches stays a picture instead of a picture over a white end.- A table row whose
table-checkbox is checked is tinted, as a row witharia-selected="true"is. - A tree's group with
data-lazyasks the page byredz:load, as every region that loads, instead ofredz:expand
(no page listened for it); a refusal now leaves the group open with the page's words instead of closing it. - A list group's item follows
data-density: 12 px by default, 8 compact, 16 comfortable, 20 spacious. data-followis read byjs/follow.js, which replacesjs/log.js.- The link follows the primary tone's text token: under a light
data-brandit stays readable. - A chart's first and last day labels are found by type, so a line drawn among the rows does not move them.
- The budgets: the main stylesheet at most 38 KB and the main script 42 KB, gzipped.
floor.jsoncarries, for each name that falls short at the floor, its BCD key, and for each vendor form the browsers
that take it; its exceptions carry their scope and, for a key, the names under it. The verdictprefix -webkit-gives
way to the browsers of"-webkit-".- Every exception of
tools/floor/rules.jsonhas a scope:anyfor an engine's own fact,librarywhere the library's
own code stands in -js/menu-place.jsplaces only the library's menus and tooltips. - The library's floor gate,
tools/floor.php, judges through the checker each release ships and byfloor.json, and
runs that checker on its command line on every commit. - A refusal of the minifier names the byte and the line of the text it was given, with the code around it, and has the
byte as its code; a fault of its own proof is aLogicException. - The floor gate and the minifier read bytes without the ctype and mbstring extensions: on macOS ctype read bytes by the
locale, so a byte such as 0xA0 counted as a space there and not on Linux.
Fixed
- The minifier no longer hangs on a stylesheet that ends in a
\; it refuses it (since 0.4.0). - The minifier refuses a script with a string, a pattern, a template or a comment that runs to its end, and a string or
a pattern that runs past its line, instead of failing in its own proof. - A
table's head sticks at the top of a page without the shell, or under a page's own bar by--redz-sticky-top. It held the shell header's
height everywhere, so a table at the top of such a page had its head over its first row. - A
menu,popoverordialoginside athtakes the size, weight and color of the page's text, not the head's. - A group's end slot
table-group-endin a table wider than itstable-scroll, as on a phone, stays at the scroller's
visible end, over a label that runs under it. It stood at the far end of the band, out of sight until scrolled there. - A
table-groupband in atable-scroll-firstortable-scroll-lastkeeps its own background and no line: it took
the held column's background, line and stickiness. - A search field over a table with groups keeps a group's
table-groupband andtable-subtotalwhile a row of the
group matches, and hides them with the group's last row. It matched each band and subtotal against its own words, so
a search hid the band of every row it found. - A search field's
data-filter-emptynote shows only while words are typed: in a region with no items, a search typed
and cleared left the note that nothing matches. - A white label's
--redz-primary-contrastis black or white by the luminance of--redz-brand, so its words read at
4.5:1 or more on any colour. It went by the colour's lightness and turned white below 0.62, which gave 3.7 to 4.5:1 on
many mid tones, such as#4f9453and#7a7a7a. - A tablist with
data-hashtakes a new address as a person's choice, throughredz:select: a page that refuses it,
with unsaved edits, keeps its tab and gets the address back. A link to a panel or the back button selected the tab
past the page's question. The panel the address names comes into view, as at load. - A
stretched-linkin alist-group-itemmakes that item its link, and the item's other links and buttons stay their
own. The item was not the link's box, so the link covered the first screen of the page, wherever the list stood. - A button
REDZ.ui.busy()marks keeps its own fill and edge while it waits, as the states table shows it. The
aria-disabledit is given turned it to the disabled look, which on the page floor of a dialog's footer left only the
spinner to see. A busy outline button without an icon keeps its edge too. - A logo in a
choice-mediawithoutwidthandheightfits the banner: its height went unbounded, so a wide logo
drew at its own size, 236 by 68 where the banner holds 40. - On a phone, a shell without an
app-sidebarlays its main region edge to edge, as one with a sidebar does; it kept
an 8 px margin at the start. The same holds in print. - A shortcut leaves alone a button inside an
inertregion, which it pressed, and keeps a held combination's repeats
from the browser: holding the keys of a page's save let the browser's own "Save page" through after the first press. - A
list-group-flushright in acard, under its header, gives its rows the card's 16 px at the sides, as Bootstrap
does: its rows' words stood against the card's edge (since 0.2.0). Inside acard-body, which has its own room, the
rows stay flush. - An
alertkeeps its icon beside its words in a narrow box, such as a dialog on a phone: below about 320 px its words
wrapped under the icon, which stood alone on a line above them. - A
selection-barin a narrow box with more than one action keeps its clear button on the line of its count, at the
end, and its buttons wrap below them: the clear button, last, wrapped onto a line of its own at the start. - A busy region's words stand on a ground of the region's color, as wide as they are: they spanned the region over the
dimmed words under them, which on a narrow region read through them. - A row header,
th scope="row", in atable-scrollkeeps its words on one line, as the scroller is there to give the
table its width: on a phone "Boat A" broke onto two lines.text-wraplets a long one wrap again. - A tooltip hides on a scroll only when the scroll moves its element: any box scrolling anywhere hid it, so a log with
data-followtaking a line, or a page nudged by a pixel, closed the tooltip a reader was on.
Files. redz-ui-0.19.0.zip - the folder a project serves, as it is: css/, js/, LICENSE, LICENSE-editor, NOTICE and redz-ui.json, the passport (the version, the floor, the files to link, the vocabulary and the sha256 of every file). This release needs the icon pack redz-ui-icons 1.13.2, a release of its own. redz-ui-tools-0.19.0.zip - the tools a project runs on its own server, never serves: floor.php, the browser floor checker, with its list floor.json, and min.php, the minifier, each the file this release was built and checked with; PHP 8.4 or newer with no extension, no network; redz-ui-tools.json is their passport. checks.zip - the sheet of the probes this release passed in every engine, also at https://redz-tech.github.io/REDZ.UI/0.19.0/checks/.
Check the archives: gh release verify-asset v0.19.0 redz-ui-0.19.0.zip --repo redz-tech/REDZ.UI, and the same for redz-ui-tools-0.19.0.zip.