@ponchia/ui 0.6.0 → 0.6.4

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.
Files changed (162) hide show
  1. package/CHANGELOG.md +82 -4
  2. package/README.md +1 -1
  3. package/annotations/index.d.ts.map +1 -1
  4. package/annotations/index.js +36 -33
  5. package/behaviors/carousel.d.ts +28 -0
  6. package/behaviors/carousel.d.ts.map +1 -0
  7. package/behaviors/carousel.js +3 -0
  8. package/behaviors/combobox.d.ts +40 -0
  9. package/behaviors/combobox.d.ts.map +1 -0
  10. package/behaviors/combobox.js +71 -20
  11. package/behaviors/command.d.ts +41 -0
  12. package/behaviors/command.d.ts.map +1 -0
  13. package/behaviors/command.js +9 -0
  14. package/behaviors/connectors.d.ts +17 -0
  15. package/behaviors/connectors.d.ts.map +1 -0
  16. package/behaviors/connectors.js +3 -0
  17. package/behaviors/crosshair.d.ts +42 -0
  18. package/behaviors/crosshair.d.ts.map +1 -0
  19. package/behaviors/crosshair.js +19 -1
  20. package/behaviors/dialog.d.ts +20 -0
  21. package/behaviors/dialog.d.ts.map +1 -0
  22. package/behaviors/dialog.js +3 -0
  23. package/behaviors/disclosure.d.ts +10 -0
  24. package/behaviors/disclosure.d.ts.map +1 -0
  25. package/behaviors/disclosure.js +3 -0
  26. package/behaviors/dismissible.d.ts +10 -0
  27. package/behaviors/dismissible.d.ts.map +1 -0
  28. package/behaviors/dismissible.js +3 -0
  29. package/behaviors/forms.d.ts +27 -0
  30. package/behaviors/forms.d.ts.map +1 -0
  31. package/behaviors/forms.js +18 -5
  32. package/behaviors/glyph.d.ts +21 -0
  33. package/behaviors/glyph.d.ts.map +1 -0
  34. package/behaviors/glyph.js +82 -4
  35. package/behaviors/index.d.ts +31 -237
  36. package/behaviors/index.d.ts.map +1 -0
  37. package/behaviors/index.js +17 -0
  38. package/behaviors/inert.d.ts +20 -0
  39. package/behaviors/inert.d.ts.map +1 -0
  40. package/behaviors/inert.js +46 -0
  41. package/behaviors/internal.d.ts +25 -0
  42. package/behaviors/internal.d.ts.map +1 -0
  43. package/behaviors/internal.js +30 -1
  44. package/behaviors/legend.d.ts +35 -0
  45. package/behaviors/legend.d.ts.map +1 -0
  46. package/behaviors/legend.js +9 -0
  47. package/behaviors/menu.d.ts +16 -0
  48. package/behaviors/menu.d.ts.map +1 -0
  49. package/behaviors/menu.js +3 -0
  50. package/behaviors/modal.d.ts +41 -0
  51. package/behaviors/modal.d.ts.map +1 -0
  52. package/behaviors/modal.js +124 -0
  53. package/behaviors/popover.d.ts +28 -0
  54. package/behaviors/popover.d.ts.map +1 -0
  55. package/behaviors/popover.js +17 -17
  56. package/behaviors/spotlight.d.ts +17 -0
  57. package/behaviors/spotlight.d.ts.map +1 -0
  58. package/behaviors/spotlight.js +3 -0
  59. package/behaviors/table.d.ts +36 -0
  60. package/behaviors/table.d.ts.map +1 -0
  61. package/behaviors/table.js +48 -8
  62. package/behaviors/tabs.d.ts +20 -0
  63. package/behaviors/tabs.d.ts.map +1 -0
  64. package/behaviors/tabs.js +3 -0
  65. package/behaviors/theme.d.ts +54 -0
  66. package/behaviors/theme.d.ts.map +1 -0
  67. package/behaviors/theme.js +17 -0
  68. package/behaviors/toast.d.ts +49 -0
  69. package/behaviors/toast.d.ts.map +1 -0
  70. package/behaviors/toast.js +34 -2
  71. package/classes/classes.json +747 -15
  72. package/classes/index.d.ts +118 -3
  73. package/classes/index.js +264 -66
  74. package/connectors/index.d.ts +12 -0
  75. package/connectors/index.d.ts.map +1 -1
  76. package/connectors/index.js +23 -2
  77. package/css/app.css +26 -0
  78. package/css/bullet.css +108 -0
  79. package/css/code.css +98 -0
  80. package/css/content.css +15 -2
  81. package/css/crosshair.css +7 -7
  82. package/css/diff.css +153 -0
  83. package/css/disclosure.css +18 -4
  84. package/css/dots.css +246 -9
  85. package/css/feedback.css +39 -7
  86. package/css/forms.css +71 -3
  87. package/css/legend.css +5 -2
  88. package/css/motion.css +79 -14
  89. package/css/overlay.css +59 -2
  90. package/css/primitives.css +67 -8
  91. package/css/report.css +43 -4
  92. package/css/sidenote.css +67 -0
  93. package/css/skins.css +9 -0
  94. package/css/spark.css +76 -0
  95. package/css/table.css +16 -3
  96. package/css/term.css +110 -0
  97. package/css/textref.css +63 -0
  98. package/css/toc.css +91 -0
  99. package/css/tokens.css +14 -1
  100. package/css/tree.css +134 -0
  101. package/dist/bronto.css +1 -1
  102. package/dist/css/analytical.css +1 -1
  103. package/dist/css/app.css +1 -1
  104. package/dist/css/bullet.css +1 -0
  105. package/dist/css/code.css +1 -0
  106. package/dist/css/content.css +1 -1
  107. package/dist/css/crosshair.css +1 -1
  108. package/dist/css/diff.css +1 -0
  109. package/dist/css/disclosure.css +1 -1
  110. package/dist/css/dots.css +1 -1
  111. package/dist/css/feedback.css +1 -1
  112. package/dist/css/forms.css +1 -1
  113. package/dist/css/legend.css +1 -1
  114. package/dist/css/motion.css +1 -1
  115. package/dist/css/overlay.css +1 -1
  116. package/dist/css/primitives.css +1 -1
  117. package/dist/css/report.css +1 -1
  118. package/dist/css/sidenote.css +1 -0
  119. package/dist/css/skins.css +1 -1
  120. package/dist/css/spark.css +1 -0
  121. package/dist/css/table.css +1 -1
  122. package/dist/css/term.css +1 -0
  123. package/dist/css/textref.css +1 -0
  124. package/dist/css/toc.css +1 -0
  125. package/dist/css/tokens.css +1 -1
  126. package/dist/css/tree.css +1 -0
  127. package/docs/annotations.md +39 -0
  128. package/docs/architecture.md +2 -3
  129. package/docs/bullet.md +78 -0
  130. package/docs/code.md +76 -0
  131. package/docs/d2.md +4 -3
  132. package/docs/diff.md +146 -0
  133. package/docs/dots.md +146 -0
  134. package/docs/glyphs.md +114 -0
  135. package/docs/legends.md +8 -4
  136. package/docs/mermaid.md +21 -4
  137. package/docs/reference.md +168 -8
  138. package/docs/reporting.md +49 -17
  139. package/docs/sidenote.md +64 -0
  140. package/docs/spark.md +78 -0
  141. package/docs/stability.md +1 -0
  142. package/docs/term.md +81 -0
  143. package/docs/textref.md +78 -0
  144. package/docs/theming.md +44 -5
  145. package/docs/toc.md +83 -0
  146. package/docs/tree.md +74 -0
  147. package/docs/usage.md +264 -23
  148. package/docs/vega.md +22 -3
  149. package/glyphs/glyphs.d.ts +61 -0
  150. package/glyphs/glyphs.js +600 -31
  151. package/llms.txt +169 -15
  152. package/package.json +51 -7
  153. package/qwik/index.d.ts +4 -2
  154. package/qwik/index.d.ts.map +1 -1
  155. package/qwik/index.js +10 -0
  156. package/react/index.d.ts +4 -2
  157. package/react/index.d.ts.map +1 -1
  158. package/react/index.js +6 -0
  159. package/solid/index.d.ts +6 -2
  160. package/solid/index.d.ts.map +1 -1
  161. package/solid/index.js +6 -0
  162. package/tokens/skins.js +22 -9
package/glyphs/glyphs.js CHANGED
@@ -22,8 +22,12 @@
22
22
  export const GLYPH_SIZE = 16;
23
23
 
24
24
  // Raw bitmaps. Each is GLYPH_SIZE rows of GLYPH_SIZE chars over [.#*]:
25
- // `.` off · `#` hot · `*` accent. Only `spark` uses accent dots — it is the
26
- // canonical two-tone demo; test/glyphs.test.mjs asserts the spark-only-* rule.
25
+ // `.` off · `#` hot · `*` accent. The curated two-tone glyphs (`spark`,
26
+ // `warning`, `info`) lift one feature onto the accent colour; every other
27
+ // glyph is monotone. test/glyphs.test.mjs pins that exact set.
28
+ //
29
+ // `digit-0`..`digit-9` + `colon`/`comma`/`period`/`percent` are the readout
30
+ // face — composed into multi-digit numerics by renderReadout().
27
31
  const RAW = {
28
32
  circle: [
29
33
  '................',
@@ -387,21 +391,21 @@ const RAW = {
387
391
  ],
388
392
  'eye-off': [
389
393
  '................',
390
- '................',
391
- '#...............',
392
- '.#..########....',
393
- '..####....####..',
394
- '.###.#####..###.',
395
- '.##..###.##..##.',
396
- '##..####.###..##',
397
- '.##..######.#.#.',
398
- '.###..####..###.',
399
- '..####....####.#',
400
- '....########.#..',
401
- '............#...',
402
- '...........#....',
403
- '................',
404
- '................',
394
+ '.#..............',
395
+ '.##.............',
396
+ '..##....###.....',
397
+ '...##.##...##...',
398
+ '..#.###.....##..',
399
+ '.##...##.##..##.',
400
+ '##.....####...#.',
401
+ '.##...##.##..##.',
402
+ '..##.##....###..',
403
+ '...##...###.##..',
404
+ '....##.....##...',
405
+ '.....##...##....',
406
+ '......##.##.....',
407
+ '.......###......',
408
+ '........##......',
405
409
  ],
406
410
  file: [
407
411
  '................',
@@ -513,10 +517,10 @@ const RAW = {
513
517
  ],
514
518
  info: [
515
519
  '................',
516
- '......####......',
517
- '.....######.....',
518
- '.....######.....',
519
- '......####......',
520
+ '......****......',
521
+ '.....******.....',
522
+ '.....******.....',
523
+ '......****......',
520
524
  '................',
521
525
  '....######......',
522
526
  '......####......',
@@ -874,19 +878,433 @@ const RAW = {
874
878
  warning: [
875
879
  '................',
876
880
  '.......##.......',
877
- '.......##.......',
878
881
  '......####......',
879
882
  '......####......',
883
+ '.....##**##.....',
884
+ '.....##**##.....',
885
+ '....###**###....',
886
+ '....###**###....',
887
+ '...####**####...',
888
+ '...####**####...',
889
+ '..#####**#####..',
890
+ '..#####..#####..',
891
+ '.######**######.',
892
+ '.##############.',
893
+ '.##############.',
894
+ '................',
895
+ ],
896
+ 'bar-chart': [
897
+ '................',
898
+ '................',
899
+ '............##..',
900
+ '............##..',
901
+ '.......##...##..',
902
+ '.......##...##..',
903
+ '.......##...##..',
904
+ '..##...##...##..',
905
+ '..##...##...##..',
906
+ '..##...##...##..',
907
+ '..##...##...##..',
908
+ '..##...##...##..',
909
+ '..############..',
910
+ '..############..',
911
+ '................',
912
+ '................',
913
+ ],
914
+ calendar: [
915
+ '................',
916
+ '...#......#.....',
917
+ '...#......#.....',
918
+ '..############..',
919
+ '..############..',
920
+ '..#..........#..',
921
+ '..#.##.##.##.#..',
922
+ '..#..........#..',
923
+ '..#.##.##.##.#..',
924
+ '..#..........#..',
925
+ '..#.##.##....#..',
926
+ '..############..',
927
+ '................',
928
+ '................',
929
+ '................',
930
+ '................',
931
+ ],
932
+ colon: [
933
+ '................',
934
+ '................',
935
+ '................',
936
+ '................',
937
+ '......####......',
938
+ '......####......',
939
+ '......####......',
940
+ '................',
941
+ '................',
942
+ '......####......',
943
+ '......####......',
944
+ '......####......',
945
+ '................',
946
+ '................',
947
+ '................',
948
+ '................',
949
+ ],
950
+ comma: [
951
+ '................',
952
+ '................',
953
+ '................',
954
+ '................',
955
+ '................',
956
+ '................',
957
+ '................',
958
+ '................',
959
+ '................',
960
+ '................',
961
+ '......####......',
962
+ '......####......',
963
+ '......####......',
964
+ '.......###......',
965
+ '......###.......',
966
+ '.....##.........',
967
+ ],
968
+ copy: [
969
+ '................',
970
+ '......#######...',
971
+ '......#.....#...',
972
+ '...#######..#...',
973
+ '...#.....#..#...',
974
+ '...#.....#..#...',
975
+ '...#.....####...',
976
+ '...#.....#......',
977
+ '...#.....#......',
978
+ '...#######......',
979
+ '................',
980
+ '................',
981
+ '................',
982
+ '................',
983
+ '................',
984
+ '................',
985
+ ],
986
+ database: [
987
+ '................',
988
+ '...########.....',
989
+ '..##########....',
990
+ '..#........#....',
991
+ '..##########....',
992
+ '...########.....',
993
+ '..#........#....',
994
+ '..##########....',
995
+ '...########.....',
996
+ '..#........#....',
997
+ '..##########....',
998
+ '...########.....',
999
+ '................',
1000
+ '................',
1001
+ '................',
1002
+ '................',
1003
+ ],
1004
+ 'digit-0': [
1005
+ '................',
1006
+ '.....######.....',
1007
+ '.....######.....',
1008
+ '...##......##...',
1009
+ '...##......##...',
1010
+ '...##....####...',
1011
+ '...##....####...',
1012
+ '...##..##..##...',
1013
+ '...##..##..##...',
1014
+ '...####....##...',
1015
+ '...####....##...',
1016
+ '...##......##...',
1017
+ '...##......##...',
1018
+ '.....######.....',
1019
+ '.....######.....',
1020
+ '................',
1021
+ ],
1022
+ 'digit-1': [
1023
+ '................',
1024
+ '.......##.......',
1025
+ '.......##.......',
1026
+ '.....####.......',
1027
+ '.....####.......',
1028
+ '.......##.......',
1029
+ '.......##.......',
1030
+ '.......##.......',
1031
+ '.......##.......',
1032
+ '.......##.......',
1033
+ '.......##.......',
1034
+ '.......##.......',
1035
+ '.......##.......',
1036
+ '.....######.....',
1037
+ '.....######.....',
1038
+ '................',
1039
+ ],
1040
+ 'digit-2': [
1041
+ '................',
1042
+ '.....######.....',
1043
+ '.....######.....',
1044
+ '...##......##...',
1045
+ '...##......##...',
1046
+ '...........##...',
1047
+ '...........##...',
1048
+ '.........##.....',
1049
+ '.........##.....',
1050
+ '.......##.......',
1051
+ '.......##.......',
1052
+ '.....##.........',
1053
+ '.....##.........',
1054
+ '...##########...',
1055
+ '...##########...',
1056
+ '................',
1057
+ ],
1058
+ 'digit-3': [
1059
+ '................',
1060
+ '...##########...',
1061
+ '...##########...',
1062
+ '.........##.....',
1063
+ '.........##.....',
1064
+ '.......##.......',
1065
+ '.......##.......',
1066
+ '.........##.....',
1067
+ '.........##.....',
1068
+ '...........##...',
1069
+ '...........##...',
1070
+ '...##......##...',
1071
+ '...##......##...',
1072
+ '.....######.....',
1073
+ '.....######.....',
1074
+ '................',
1075
+ ],
1076
+ 'digit-4': [
1077
+ '................',
1078
+ '.........##.....',
1079
+ '.........##.....',
1080
+ '.......####.....',
1081
+ '.......####.....',
880
1082
  '.....##..##.....',
881
1083
  '.....##..##.....',
882
- '....###..###....',
883
- '....##....##....',
884
- '...###....###...',
885
- '...##.####.##...',
886
- '..###.####.###..',
887
- '..##........##..',
888
- '.###############',
889
- '.###############',
1084
+ '...##....##.....',
1085
+ '...##....##.....',
1086
+ '...##########...',
1087
+ '...##########...',
1088
+ '.........##.....',
1089
+ '.........##.....',
1090
+ '.........##.....',
1091
+ '.........##.....',
1092
+ '................',
1093
+ ],
1094
+ 'digit-5': [
1095
+ '................',
1096
+ '...##########...',
1097
+ '...##########...',
1098
+ '...##...........',
1099
+ '...##...........',
1100
+ '...########.....',
1101
+ '...########.....',
1102
+ '...........##...',
1103
+ '...........##...',
1104
+ '...........##...',
1105
+ '...........##...',
1106
+ '...##......##...',
1107
+ '...##......##...',
1108
+ '.....######.....',
1109
+ '.....######.....',
1110
+ '................',
1111
+ ],
1112
+ 'digit-6': [
1113
+ '................',
1114
+ '.......####.....',
1115
+ '.......####.....',
1116
+ '.....##.........',
1117
+ '.....##.........',
1118
+ '...##...........',
1119
+ '...##...........',
1120
+ '...########.....',
1121
+ '...########.....',
1122
+ '...##......##...',
1123
+ '...##......##...',
1124
+ '...##......##...',
1125
+ '...##......##...',
1126
+ '.....######.....',
1127
+ '.....######.....',
1128
+ '................',
1129
+ ],
1130
+ 'digit-7': [
1131
+ '................',
1132
+ '...##########...',
1133
+ '...##########...',
1134
+ '...........##...',
1135
+ '...........##...',
1136
+ '.........##.....',
1137
+ '.........##.....',
1138
+ '.......##.......',
1139
+ '.......##.......',
1140
+ '.....##.........',
1141
+ '.....##.........',
1142
+ '.....##.........',
1143
+ '.....##.........',
1144
+ '.....##.........',
1145
+ '.....##.........',
1146
+ '................',
1147
+ ],
1148
+ 'digit-8': [
1149
+ '................',
1150
+ '.....######.....',
1151
+ '.....######.....',
1152
+ '...##......##...',
1153
+ '...##......##...',
1154
+ '...##......##...',
1155
+ '...##......##...',
1156
+ '.....######.....',
1157
+ '.....######.....',
1158
+ '...##......##...',
1159
+ '...##......##...',
1160
+ '...##......##...',
1161
+ '...##......##...',
1162
+ '.....######.....',
1163
+ '.....######.....',
1164
+ '................',
1165
+ ],
1166
+ 'digit-9': [
1167
+ '................',
1168
+ '.....######.....',
1169
+ '.....######.....',
1170
+ '...##......##...',
1171
+ '...##......##...',
1172
+ '...##......##...',
1173
+ '...##......##...',
1174
+ '.....########...',
1175
+ '.....########...',
1176
+ '...........##...',
1177
+ '...........##...',
1178
+ '.........##.....',
1179
+ '.........##.....',
1180
+ '.....####.......',
1181
+ '.....####.......',
1182
+ '................',
1183
+ ],
1184
+ filter: [
1185
+ '................',
1186
+ '..############..',
1187
+ '..############..',
1188
+ '...##########...',
1189
+ '....########....',
1190
+ '.....######.....',
1191
+ '......####......',
1192
+ '......####......',
1193
+ '......####......',
1194
+ '......####......',
1195
+ '......####......',
1196
+ '......####......',
1197
+ '................',
1198
+ '................',
1199
+ '................',
1200
+ '................',
1201
+ ],
1202
+ hash: [
1203
+ '................',
1204
+ '................',
1205
+ '....#...#.......',
1206
+ '....#...#.......',
1207
+ '..#########.....',
1208
+ '..#########.....',
1209
+ '....#...#.......',
1210
+ '....#...#.......',
1211
+ '..#########.....',
1212
+ '..#########.....',
1213
+ '....#...#.......',
1214
+ '....#...#.......',
1215
+ '................',
1216
+ '................',
1217
+ '................',
1218
+ '................',
1219
+ ],
1220
+ percent: [
1221
+ '................',
1222
+ '...###......#...',
1223
+ '..#...#....#....',
1224
+ '..#...#...#.....',
1225
+ '..#...#..#......',
1226
+ '...###..#.......',
1227
+ '.......#........',
1228
+ '......#.........',
1229
+ '.....#..###.....',
1230
+ '....#..#...#....',
1231
+ '...#...#...#....',
1232
+ '..#....#...#....',
1233
+ '.#......###.....',
1234
+ '................',
1235
+ '................',
1236
+ '................',
1237
+ ],
1238
+ period: [
1239
+ '................',
1240
+ '................',
1241
+ '................',
1242
+ '................',
1243
+ '................',
1244
+ '................',
1245
+ '................',
1246
+ '................',
1247
+ '................',
1248
+ '................',
1249
+ '................',
1250
+ '......####......',
1251
+ '......####......',
1252
+ '......####......',
1253
+ '................',
1254
+ '................',
1255
+ ],
1256
+ share: [
1257
+ '................',
1258
+ '...........###..',
1259
+ '..........#####.',
1260
+ '...........###..',
1261
+ '.........#.#....',
1262
+ '.......##.......',
1263
+ '...###.#........',
1264
+ '..#####.........',
1265
+ '...###.#........',
1266
+ '.......##.......',
1267
+ '.........#.#....',
1268
+ '...........###..',
1269
+ '..........#####.',
1270
+ '...........###..',
1271
+ '................',
1272
+ '................',
1273
+ ],
1274
+ sliders: [
1275
+ '................',
1276
+ '................',
1277
+ '....#...........',
1278
+ '...###..........',
1279
+ '..#####.########',
1280
+ '...###..........',
1281
+ '....#...........',
1282
+ '................',
1283
+ '...........#....',
1284
+ '..........###...',
1285
+ '########.#####..',
1286
+ '..........###...',
1287
+ '...........#....',
1288
+ '................',
1289
+ '................',
1290
+ '................',
1291
+ ],
1292
+ sort: [
1293
+ '................',
1294
+ '......#.........',
1295
+ '.....###........',
1296
+ '....#####.......',
1297
+ '...#######......',
1298
+ '......#.........',
1299
+ '......#.........',
1300
+ '......#.........',
1301
+ '......#.........',
1302
+ '......#.........',
1303
+ '...#######......',
1304
+ '....#####.......',
1305
+ '.....###........',
1306
+ '......#.........',
1307
+ '................',
890
1308
  '................',
891
1309
  ],
892
1310
  };
@@ -903,6 +1321,79 @@ export const GLYPHS = Object.freeze(
903
1321
  /** Every glyph name, frozen and sorted (mirrors GLYPHS keys). */
904
1322
  export const GLYPH_NAMES = Object.freeze(Object.keys(GLYPHS));
905
1323
 
1324
+ /**
1325
+ * Intent → glyph search aliases. A small hand-curated set so a name search can
1326
+ * resolve the *word a consumer thinks of* to the glyph that depicts it (the
1327
+ * "depict, don't name the purpose" convention: `delete` → `trash`, `settings`
1328
+ * → `gear`). Keys are real glyph names (gated by check-glyphs.mjs); values are
1329
+ * extra search terms beyond the name itself. Not every glyph needs an entry —
1330
+ * findGlyphs() always also matches the name substring.
1331
+ */
1332
+ export const GLYPH_TAGS = Object.freeze({
1333
+ trash: ['delete', 'remove', 'bin'],
1334
+ gear: ['settings', 'config', 'options', 'cog', 'preferences'],
1335
+ search: ['find', 'magnify', 'zoom', 'lookup'],
1336
+ 'bar-chart': ['analytics', 'graph', 'stats', 'report', 'metrics'],
1337
+ database: ['db', 'storage', 'data', 'server', 'table'],
1338
+ sliders: ['filter', 'settings', 'controls', 'adjust', 'tune'],
1339
+ filter: ['funnel', 'refine', 'facet'],
1340
+ sort: ['order', 'arrange', 'rank'],
1341
+ mail: ['email', 'envelope', 'message', 'inbox'],
1342
+ bell: ['notification', 'alert', 'remind'],
1343
+ user: ['person', 'account', 'profile', 'member'],
1344
+ home: ['house', 'dashboard', 'start'],
1345
+ file: ['document', 'page', 'doc'],
1346
+ folder: ['directory', 'group'],
1347
+ lock: ['secure', 'private', 'password', 'locked'],
1348
+ eye: ['view', 'show', 'visible', 'preview'],
1349
+ 'eye-off': ['hide', 'hidden', 'invisible', 'mask'],
1350
+ star: ['favorite', 'bookmark', 'rate'],
1351
+ heart: ['like', 'love', 'favorite'],
1352
+ refresh: ['reload', 'sync', 'update', 'retry'],
1353
+ close: ['cancel', 'dismiss', 'remove'],
1354
+ 'x-circle': ['cancel', 'error', 'fail', 'dismiss'],
1355
+ check: ['done', 'ok', 'complete', 'confirm', 'tick'],
1356
+ 'check-circle': ['done', 'success', 'ok', 'verified'],
1357
+ warning: ['caution', 'alert', 'attention'],
1358
+ info: ['about', 'help', 'note', 'details'],
1359
+ plus: ['add', 'new', 'create'],
1360
+ 'plus-circle': ['add', 'new', 'create'],
1361
+ minus: ['subtract', 'collapse'],
1362
+ link: ['url', 'hyperlink', 'external', 'chain'],
1363
+ download: ['save', 'export', 'fetch'],
1364
+ upload: ['import', 'send'],
1365
+ grid: ['layout', 'apps', 'dashboard', 'tiles'],
1366
+ menu: ['hamburger', 'nav', 'list'],
1367
+ clock: ['time', 'schedule', 'history', 'recent'],
1368
+ calendar: ['date', 'schedule', 'event', 'day'],
1369
+ copy: ['duplicate', 'clipboard', 'clone'],
1370
+ share: ['send', 'export', 'network', 'distribute'],
1371
+ hash: ['number', 'tag', 'pound', 'count'],
1372
+ moon: ['dark', 'night', 'theme'],
1373
+ sun: ['light', 'day', 'theme', 'bright'],
1374
+ edit: ['pencil', 'write', 'modify', 'rename'],
1375
+ });
1376
+
1377
+ /**
1378
+ * Glyph names whose name OR a search alias contains `query` (case-insensitive),
1379
+ * sorted. `findGlyphs('')` returns every name. For discovery — a CMS field, an
1380
+ * icon picker, an LLM resolving an intent word to a real glyph.
1381
+ *
1382
+ * @param {string} query
1383
+ * @returns {GlyphName[]}
1384
+ */
1385
+ export function findGlyphs(query) {
1386
+ const q = String(query ?? '')
1387
+ .trim()
1388
+ .toLowerCase();
1389
+ if (!q) return [...GLYPH_NAMES];
1390
+ return GLYPH_NAMES.filter(
1391
+ (name) =>
1392
+ name.toLowerCase().includes(q) ||
1393
+ (GLYPH_TAGS[name] ?? []).some((t) => t.toLowerCase().includes(q)),
1394
+ );
1395
+ }
1396
+
906
1397
  const TONE = { '#': 'hot', '*': 'accent' };
907
1398
 
908
1399
  /** The raw bitmap rows for a glyph, or `undefined` if the name is unknown. */
@@ -924,6 +1415,20 @@ export function glyphCells(name) {
924
1415
  return cells;
925
1416
  }
926
1417
 
1418
+ /**
1419
+ * The CSS `mask-image` `url()` for a glyph's lit cells — the value of
1420
+ * `--icon-mask` on a `.ui-icon` element (the one-node, currentColor,
1421
+ * scales-with-text icon path). `''` if the name is unknown. Single-tone:
1422
+ * accent `*` cells become opaque mask regions, like hot `#`.
1423
+ *
1424
+ * @param {GlyphNameInput} name
1425
+ * @returns {string}
1426
+ */
1427
+ export function glyphMask(name) {
1428
+ const rows = GLYPHS[name];
1429
+ return rows ? maskUrl(rows) : '';
1430
+ }
1431
+
927
1432
  const CELL = 'ui-dotmatrix__cell';
928
1433
 
929
1434
  function cellClass(cell) {
@@ -1027,7 +1532,13 @@ export function renderGlyph(name, options = {}) {
1027
1532
  const style = [`--dotmatrix-cols:${GLYPH_SIZE}`];
1028
1533
  const dotLen = dot && cssLen(dot);
1029
1534
  const gapLen = gap && cssLen(gap);
1030
- if (dotLen) style.push(`--dotmatrix-dot:${dotLen}`);
1535
+ // Default the dot track to an intrinsic icon scale when the author set no
1536
+ // (valid) `--dotmatrix-dot`. Without it the CSS grid falls back to
1537
+ // `minmax(0, 1fr)` and the 16×16 matrix balloons to fill its container
1538
+ // (full-bleed, ~1250px) — the string API would then render an icon-intent call
1539
+ // very differently from the DOM `initDotGlyph` path, which already defaults to
1540
+ // 0.08em. Mirror that default here so both paths render the same icon. (C7.)
1541
+ style.push(`--dotmatrix-dot:${dotLen || '0.08em'}`);
1031
1542
  // Solid mode fuses the dots into a crisp pixel glyph: square cells, no gap.
1032
1543
  if (solid) style.push('--dotmatrix-dot-radius:0', '--dotmatrix-gap:0');
1033
1544
  else if (gapLen) style.push(`--dotmatrix-gap:${gapLen}`);
@@ -1063,3 +1574,61 @@ export function renderGlyph(name, options = {}) {
1063
1574
  // inline-icon use. `.ui-dotmatrix`'s `display: grid` works on a span.
1064
1575
  return `<span class="${cls}" style="${style.join(';')}" ${a11y}>${inner}</span>`;
1065
1576
  }
1577
+
1578
+ // Character → glyph name for renderReadout. Punctuation reuses the readout face
1579
+ // (digit-0..9 + colon/comma/period/percent) plus the existing minus/plus.
1580
+ const READOUT_CHARS = {
1581
+ 0: 'digit-0',
1582
+ 1: 'digit-1',
1583
+ 2: 'digit-2',
1584
+ 3: 'digit-3',
1585
+ 4: 'digit-4',
1586
+ 5: 'digit-5',
1587
+ 6: 'digit-6',
1588
+ 7: 'digit-7',
1589
+ 8: 'digit-8',
1590
+ 9: 'digit-9',
1591
+ ':': 'colon',
1592
+ ',': 'comma',
1593
+ '.': 'period',
1594
+ '%': 'percent',
1595
+ '-': 'minus',
1596
+ '+': 'plus',
1597
+ };
1598
+
1599
+ /**
1600
+ * Compose a string of digits/punctuation into a row of dot-matrix glyphs — the
1601
+ * Nothing-style big numeric readout for a hero KPI, clock, countdown, or
1602
+ * percentage. Every character is a decorative glyph; the readout's *value* is
1603
+ * carried by the accessible name, so a `label` is STRONGLY recommended (it
1604
+ * defaults to the raw `text` when omitted — fine for "12:48", but pass a
1605
+ * fuller label like "Revenue: 12,480 USD" when the digits alone are ambiguous).
1606
+ *
1607
+ * Recognised characters: `0-9 : , . % - +` and space (a blank advance).
1608
+ * Anything else is skipped. The per-glyph options (`solid`, `render: 'mask'`,
1609
+ * `dot`, `gap`, `anim`) pass straight through to renderGlyph for each character,
1610
+ * so a mask-mode readout is one node per glyph (lightest) and a cell-mode one is
1611
+ * the full dot-display look. Returns `''` for empty input. Needs
1612
+ * `@ponchia/ui/css` (the `.ui-readout` + `.ui-dotmatrix`/`.ui-icon` rules).
1613
+ *
1614
+ * @param {string} text
1615
+ * @param {RenderReadoutOptions} [options]
1616
+ * @returns {string}
1617
+ */
1618
+ export function renderReadout(text, options = {}) {
1619
+ const str = String(text ?? '');
1620
+ if (!str) return '';
1621
+ const { label, gap, ...glyphOpts } = options;
1622
+ const a11y = `role="img" aria-label="${esc(label ?? str)}"`;
1623
+ // The glyphs inside are always decorative — the wrapper carries the name.
1624
+ const inner = [...str]
1625
+ .map((ch) => {
1626
+ if (ch === ' ') return '<span class="ui-readout__spacer" aria-hidden="true"></span>';
1627
+ const name = READOUT_CHARS[ch];
1628
+ if (!name) return '';
1629
+ return renderGlyph(name, glyphOpts);
1630
+ })
1631
+ .join('');
1632
+ const style = gap && cssLen(gap) ? ` style="--readout-gap:${cssLen(gap)}"` : '';
1633
+ return `<span class="ui-readout"${style} ${a11y}>${inner}</span>`;
1634
+ }