@pure-ds/storybook 0.7.46 → 0.7.53

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 (45) hide show
  1. package/.storybook/preview.js +14 -14
  2. package/dist/pds-reference.json +271 -41
  3. package/package.json +2 -2
  4. package/public/assets/js/app.js +8 -6
  5. package/public/assets/js/pds-ask.js +6 -6
  6. package/public/assets/js/pds-enhancers.js +1 -1
  7. package/public/assets/js/pds-manager.js +511 -291
  8. package/public/assets/js/pds.js +2 -2
  9. package/public/assets/pds/components/pds-live-edit.js +1 -1
  10. package/public/assets/pds/components/pds-toaster.js +55 -11
  11. package/public/assets/pds/core/pds-ask.js +6 -6
  12. package/public/assets/pds/core/pds-enhancers.js +1 -1
  13. package/public/assets/pds/core/pds-manager.js +511 -291
  14. package/public/assets/pds/core.js +2 -2
  15. package/public/assets/pds/pds-css-complete.json +544 -55
  16. package/public/assets/pds/pds.css-data.json +154 -0
  17. package/public/assets/pds/styles/pds-components.css +12 -11
  18. package/public/assets/pds/styles/pds-components.css.js +24 -22
  19. package/public/assets/pds/styles/pds-styles.css +12 -11
  20. package/public/assets/pds/styles/pds-styles.css.js +24 -22
  21. package/public/assets/pds/vscode-custom-data.json +30 -0
  22. package/src/js/app.js +7 -4
  23. package/src/js/common/common.js +120 -23
  24. package/src/js/common/toast.js +8 -0
  25. package/src/js/pds-core/pds-config.js +63 -10
  26. package/src/js/pds-core/pds-enhancers.js +6 -1
  27. package/src/js/pds-core/pds-generator.js +823 -217
  28. package/src/js/pds-core/pds-live.js +3 -4
  29. package/src/js/pds.d.ts +19 -6
  30. package/src/js/pds.js +11 -6
  31. package/stories/components/PdsFab.stories.js +2 -2
  32. package/stories/components/PdsForm.stories.js +3 -3
  33. package/stories/components/PdsIcon.stories.js +2 -2
  34. package/stories/components/PdsRating.stories.js +1 -1
  35. package/stories/components/PdsScrollrow.stories.js +10 -10
  36. package/stories/components/PdsSplitpanel.stories.js +8 -8
  37. package/stories/foundations/Colors.stories.js +1289 -187
  38. package/stories/foundations/HTMLDefaults.stories.js +3 -3
  39. package/stories/foundations/Icons.stories.js +20 -20
  40. package/stories/foundations/SmartSurfaces.stories.js +11 -14
  41. package/stories/patterns/InteractiveStates.stories.js +5 -5
  42. package/stories/primitives/Badges.stories.js +1 -0
  43. package/stories/primitives/Cards.stories.js +3 -3
  44. package/stories/reference/pds-object-docs.js +7 -2
  45. package/stories/utils/PdsToast.stories.js +62 -1
@@ -1167,6 +1167,160 @@
1167
1167
  }
1168
1168
  ]
1169
1169
  },
1170
+ {
1171
+ "name": "--color-accentInteractive-light",
1172
+ "description": "accentInteractive color scale - shade light",
1173
+ "syntax": "<color>",
1174
+ "references": [
1175
+ {
1176
+ "name": "Value",
1177
+ "url": "data:text/plain,%5Bobject%20Object%5D"
1178
+ }
1179
+ ]
1180
+ },
1181
+ {
1182
+ "name": "--color-accentInteractive-dark",
1183
+ "description": "accentInteractive color scale - shade dark",
1184
+ "syntax": "<color>",
1185
+ "references": [
1186
+ {
1187
+ "name": "Value",
1188
+ "url": "data:text/plain,%5Bobject%20Object%5D"
1189
+ }
1190
+ ]
1191
+ },
1192
+ {
1193
+ "name": "--color-surfaceAccent-light",
1194
+ "description": "surfaceAccent color scale - shade light",
1195
+ "syntax": "<color>",
1196
+ "references": [
1197
+ {
1198
+ "name": "Value",
1199
+ "url": "data:text/plain,%5Bobject%20Object%5D"
1200
+ }
1201
+ ]
1202
+ },
1203
+ {
1204
+ "name": "--color-surfaceAccent-dark",
1205
+ "description": "surfaceAccent color scale - shade dark",
1206
+ "syntax": "<color>",
1207
+ "references": [
1208
+ {
1209
+ "name": "Value",
1210
+ "url": "data:text/plain,%5Bobject%20Object%5D"
1211
+ }
1212
+ ]
1213
+ },
1214
+ {
1215
+ "name": "--color-dangerInteractive-light",
1216
+ "description": "dangerInteractive color scale - shade light",
1217
+ "syntax": "<color>",
1218
+ "references": [
1219
+ {
1220
+ "name": "Value",
1221
+ "url": "data:text/plain,%5Bobject%20Object%5D"
1222
+ }
1223
+ ]
1224
+ },
1225
+ {
1226
+ "name": "--color-dangerInteractive-dark",
1227
+ "description": "dangerInteractive color scale - shade dark",
1228
+ "syntax": "<color>",
1229
+ "references": [
1230
+ {
1231
+ "name": "Value",
1232
+ "url": "data:text/plain,%5Bobject%20Object%5D"
1233
+ }
1234
+ ]
1235
+ },
1236
+ {
1237
+ "name": "--color-successInteractive-light",
1238
+ "description": "successInteractive color scale - shade light",
1239
+ "syntax": "<color>",
1240
+ "references": [
1241
+ {
1242
+ "name": "Value",
1243
+ "url": "data:text/plain,%5Bobject%20Object%5D"
1244
+ }
1245
+ ]
1246
+ },
1247
+ {
1248
+ "name": "--color-successInteractive-dark",
1249
+ "description": "successInteractive color scale - shade dark",
1250
+ "syntax": "<color>",
1251
+ "references": [
1252
+ {
1253
+ "name": "Value",
1254
+ "url": "data:text/plain,%5Bobject%20Object%5D"
1255
+ }
1256
+ ]
1257
+ },
1258
+ {
1259
+ "name": "--color-warningInteractive-light",
1260
+ "description": "warningInteractive color scale - shade light",
1261
+ "syntax": "<color>",
1262
+ "references": [
1263
+ {
1264
+ "name": "Value",
1265
+ "url": "data:text/plain,%5Bobject%20Object%5D"
1266
+ }
1267
+ ]
1268
+ },
1269
+ {
1270
+ "name": "--color-warningInteractive-dark",
1271
+ "description": "warningInteractive color scale - shade dark",
1272
+ "syntax": "<color>",
1273
+ "references": [
1274
+ {
1275
+ "name": "Value",
1276
+ "url": "data:text/plain,%5Bobject%20Object%5D"
1277
+ }
1278
+ ]
1279
+ },
1280
+ {
1281
+ "name": "--color-infoInteractive-light",
1282
+ "description": "infoInteractive color scale - shade light",
1283
+ "syntax": "<color>",
1284
+ "references": [
1285
+ {
1286
+ "name": "Value",
1287
+ "url": "data:text/plain,%5Bobject%20Object%5D"
1288
+ }
1289
+ ]
1290
+ },
1291
+ {
1292
+ "name": "--color-infoInteractive-dark",
1293
+ "description": "infoInteractive color scale - shade dark",
1294
+ "syntax": "<color>",
1295
+ "references": [
1296
+ {
1297
+ "name": "Value",
1298
+ "url": "data:text/plain,%5Bobject%20Object%5D"
1299
+ }
1300
+ ]
1301
+ },
1302
+ {
1303
+ "name": "--color-surfaceStatus-light",
1304
+ "description": "surfaceStatus color scale - shade light",
1305
+ "syntax": "<color>",
1306
+ "references": [
1307
+ {
1308
+ "name": "Value",
1309
+ "url": "data:text/plain,%5Bobject%20Object%5D"
1310
+ }
1311
+ ]
1312
+ },
1313
+ {
1314
+ "name": "--color-surfaceStatus-dark",
1315
+ "description": "surfaceStatus color scale - shade dark",
1316
+ "syntax": "<color>",
1317
+ "references": [
1318
+ {
1319
+ "name": "Value",
1320
+ "url": "data:text/plain,%5Bobject%20Object%5D"
1321
+ }
1322
+ ]
1323
+ },
1170
1324
  {
1171
1325
  "name": "--spacing-0",
1172
1326
  "description": "Spacing scale value 0",
@@ -1405,22 +1405,23 @@ a.btn-working {
1405
1405
  }
1406
1406
 
1407
1407
  .badge-primary, .badge-secondary, .badge-success, .badge-info, .badge-warning, .badge-danger { color: white; }
1408
- .badge-primary { background-color: var(--color-primary-600); }
1408
+ .badge-primary { background-color: var(--color-primary-fill); }
1409
1409
  .badge-secondary { background-color: var(--color-secondary-600); }
1410
- .badge-success { background-color: var(--color-success-600); }
1411
- .badge-info { background-color: var(--color-info-600); }
1412
- .badge-warning { background-color: var(--color-warning-600); }
1413
- .badge-danger { background-color: var(--color-danger-600); }
1410
+ .badge-success { background-color: var(--color-success-fill); }
1411
+ .badge-info { background-color: var(--color-info-fill); }
1412
+ .badge-warning { background-color: var(--color-warning-fill); }
1413
+ .badge-danger { background-color: var(--color-danger-fill); }
1414
1414
 
1415
1415
  .badge-outline {
1416
1416
  background-color: transparent;
1417
+ color: var(--color-text-secondary);
1417
1418
  border: var(--border-width-thin) solid currentColor;
1418
- &.badge-primary { color: var(--color-text-primary); }
1419
- &.badge-secondary { color: var(--color-secondary-600); }
1420
- &.badge-success { color: var(--color-success-600); }
1421
- &.badge-info { color: var(--color-info-600); }
1422
- &.badge-warning { color: var(--color-warning-600); }
1423
- &.badge-danger { color: var(--color-danger-600); }
1419
+ &.badge-primary { color: var(--color-primary-text); }
1420
+ &.badge-secondary { color: var(--color-text-secondary); }
1421
+ &.badge-success { color: var(--color-success-text); }
1422
+ &.badge-info { color: var(--color-info-text); }
1423
+ &.badge-warning { color: var(--color-warning-text); }
1424
+ &.badge-danger { color: var(--color-danger-text); }
1424
1425
  }
1425
1426
 
1426
1427
  .badge-sm { padding: 2px var(--spacing-1); font-size: 10px; }
@@ -1409,22 +1409,23 @@ a.btn-working {
1409
1409
  }
1410
1410
 
1411
1411
  .badge-primary, .badge-secondary, .badge-success, .badge-info, .badge-warning, .badge-danger { color: white; }
1412
- .badge-primary { background-color: var(--color-primary-600); }
1412
+ .badge-primary { background-color: var(--color-primary-fill); }
1413
1413
  .badge-secondary { background-color: var(--color-secondary-600); }
1414
- .badge-success { background-color: var(--color-success-600); }
1415
- .badge-info { background-color: var(--color-info-600); }
1416
- .badge-warning { background-color: var(--color-warning-600); }
1417
- .badge-danger { background-color: var(--color-danger-600); }
1414
+ .badge-success { background-color: var(--color-success-fill); }
1415
+ .badge-info { background-color: var(--color-info-fill); }
1416
+ .badge-warning { background-color: var(--color-warning-fill); }
1417
+ .badge-danger { background-color: var(--color-danger-fill); }
1418
1418
 
1419
1419
  .badge-outline {
1420
1420
  background-color: transparent;
1421
+ color: var(--color-text-secondary);
1421
1422
  border: var(--border-width-thin) solid currentColor;
1422
- &.badge-primary { color: var(--color-text-primary); }
1423
- &.badge-secondary { color: var(--color-secondary-600); }
1424
- &.badge-success { color: var(--color-success-600); }
1425
- &.badge-info { color: var(--color-info-600); }
1426
- &.badge-warning { color: var(--color-warning-600); }
1427
- &.badge-danger { color: var(--color-danger-600); }
1423
+ &.badge-primary { color: var(--color-primary-text); }
1424
+ &.badge-secondary { color: var(--color-text-secondary); }
1425
+ &.badge-success { color: var(--color-success-text); }
1426
+ &.badge-info { color: var(--color-info-text); }
1427
+ &.badge-warning { color: var(--color-warning-text); }
1428
+ &.badge-danger { color: var(--color-danger-text); }
1428
1429
  }
1429
1430
 
1430
1431
  .badge-sm { padding: 2px var(--spacing-1); font-size: 10px; }
@@ -3624,22 +3625,23 @@ a.btn-working {
3624
3625
  }
3625
3626
 
3626
3627
  .badge-primary, .badge-secondary, .badge-success, .badge-info, .badge-warning, .badge-danger { color: white; }
3627
- .badge-primary { background-color: var(--color-primary-600); }
3628
+ .badge-primary { background-color: var(--color-primary-fill); }
3628
3629
  .badge-secondary { background-color: var(--color-secondary-600); }
3629
- .badge-success { background-color: var(--color-success-600); }
3630
- .badge-info { background-color: var(--color-info-600); }
3631
- .badge-warning { background-color: var(--color-warning-600); }
3632
- .badge-danger { background-color: var(--color-danger-600); }
3630
+ .badge-success { background-color: var(--color-success-fill); }
3631
+ .badge-info { background-color: var(--color-info-fill); }
3632
+ .badge-warning { background-color: var(--color-warning-fill); }
3633
+ .badge-danger { background-color: var(--color-danger-fill); }
3633
3634
 
3634
3635
  .badge-outline {
3635
3636
  background-color: transparent;
3637
+ color: var(--color-text-secondary);
3636
3638
  border: var(--border-width-thin) solid currentColor;
3637
- &.badge-primary { color: var(--color-text-primary); }
3638
- &.badge-secondary { color: var(--color-secondary-600); }
3639
- &.badge-success { color: var(--color-success-600); }
3640
- &.badge-info { color: var(--color-info-600); }
3641
- &.badge-warning { color: var(--color-warning-600); }
3642
- &.badge-danger { color: var(--color-danger-600); }
3639
+ &.badge-primary { color: var(--color-primary-text); }
3640
+ &.badge-secondary { color: var(--color-text-secondary); }
3641
+ &.badge-success { color: var(--color-success-text); }
3642
+ &.badge-info { color: var(--color-info-text); }
3643
+ &.badge-warning { color: var(--color-warning-text); }
3644
+ &.badge-danger { color: var(--color-danger-text); }
3643
3645
  }
3644
3646
 
3645
3647
  .badge-sm { padding: 2px var(--spacing-1); font-size: 10px; }
@@ -2469,22 +2469,23 @@ a.btn-working {
2469
2469
  }
2470
2470
 
2471
2471
  .badge-primary, .badge-secondary, .badge-success, .badge-info, .badge-warning, .badge-danger { color: white; }
2472
- .badge-primary { background-color: var(--color-primary-600); }
2472
+ .badge-primary { background-color: var(--color-primary-fill); }
2473
2473
  .badge-secondary { background-color: var(--color-secondary-600); }
2474
- .badge-success { background-color: var(--color-success-600); }
2475
- .badge-info { background-color: var(--color-info-600); }
2476
- .badge-warning { background-color: var(--color-warning-600); }
2477
- .badge-danger { background-color: var(--color-danger-600); }
2474
+ .badge-success { background-color: var(--color-success-fill); }
2475
+ .badge-info { background-color: var(--color-info-fill); }
2476
+ .badge-warning { background-color: var(--color-warning-fill); }
2477
+ .badge-danger { background-color: var(--color-danger-fill); }
2478
2478
 
2479
2479
  .badge-outline {
2480
2480
  background-color: transparent;
2481
+ color: var(--color-text-secondary);
2481
2482
  border: var(--border-width-thin) solid currentColor;
2482
- &.badge-primary { color: var(--color-text-primary); }
2483
- &.badge-secondary { color: var(--color-secondary-600); }
2484
- &.badge-success { color: var(--color-success-600); }
2485
- &.badge-info { color: var(--color-info-600); }
2486
- &.badge-warning { color: var(--color-warning-600); }
2487
- &.badge-danger { color: var(--color-danger-600); }
2483
+ &.badge-primary { color: var(--color-primary-text); }
2484
+ &.badge-secondary { color: var(--color-text-secondary); }
2485
+ &.badge-success { color: var(--color-success-text); }
2486
+ &.badge-info { color: var(--color-info-text); }
2487
+ &.badge-warning { color: var(--color-warning-text); }
2488
+ &.badge-danger { color: var(--color-danger-text); }
2488
2489
  }
2489
2490
 
2490
2491
  .badge-sm { padding: 2px var(--spacing-1); font-size: 10px; }
@@ -2473,22 +2473,23 @@ a.btn-working {
2473
2473
  }
2474
2474
 
2475
2475
  .badge-primary, .badge-secondary, .badge-success, .badge-info, .badge-warning, .badge-danger { color: white; }
2476
- .badge-primary { background-color: var(--color-primary-600); }
2476
+ .badge-primary { background-color: var(--color-primary-fill); }
2477
2477
  .badge-secondary { background-color: var(--color-secondary-600); }
2478
- .badge-success { background-color: var(--color-success-600); }
2479
- .badge-info { background-color: var(--color-info-600); }
2480
- .badge-warning { background-color: var(--color-warning-600); }
2481
- .badge-danger { background-color: var(--color-danger-600); }
2478
+ .badge-success { background-color: var(--color-success-fill); }
2479
+ .badge-info { background-color: var(--color-info-fill); }
2480
+ .badge-warning { background-color: var(--color-warning-fill); }
2481
+ .badge-danger { background-color: var(--color-danger-fill); }
2482
2482
 
2483
2483
  .badge-outline {
2484
2484
  background-color: transparent;
2485
+ color: var(--color-text-secondary);
2485
2486
  border: var(--border-width-thin) solid currentColor;
2486
- &.badge-primary { color: var(--color-text-primary); }
2487
- &.badge-secondary { color: var(--color-secondary-600); }
2488
- &.badge-success { color: var(--color-success-600); }
2489
- &.badge-info { color: var(--color-info-600); }
2490
- &.badge-warning { color: var(--color-warning-600); }
2491
- &.badge-danger { color: var(--color-danger-600); }
2487
+ &.badge-primary { color: var(--color-primary-text); }
2488
+ &.badge-secondary { color: var(--color-text-secondary); }
2489
+ &.badge-success { color: var(--color-success-text); }
2490
+ &.badge-info { color: var(--color-info-text); }
2491
+ &.badge-warning { color: var(--color-warning-text); }
2492
+ &.badge-danger { color: var(--color-danger-text); }
2492
2493
  }
2493
2494
 
2494
2495
  .badge-sm { padding: 2px var(--spacing-1); font-size: 10px; }
@@ -6469,22 +6470,23 @@ a.btn-working {
6469
6470
  }
6470
6471
 
6471
6472
  .badge-primary, .badge-secondary, .badge-success, .badge-info, .badge-warning, .badge-danger { color: white; }
6472
- .badge-primary { background-color: var(--color-primary-600); }
6473
+ .badge-primary { background-color: var(--color-primary-fill); }
6473
6474
  .badge-secondary { background-color: var(--color-secondary-600); }
6474
- .badge-success { background-color: var(--color-success-600); }
6475
- .badge-info { background-color: var(--color-info-600); }
6476
- .badge-warning { background-color: var(--color-warning-600); }
6477
- .badge-danger { background-color: var(--color-danger-600); }
6475
+ .badge-success { background-color: var(--color-success-fill); }
6476
+ .badge-info { background-color: var(--color-info-fill); }
6477
+ .badge-warning { background-color: var(--color-warning-fill); }
6478
+ .badge-danger { background-color: var(--color-danger-fill); }
6478
6479
 
6479
6480
  .badge-outline {
6480
6481
  background-color: transparent;
6482
+ color: var(--color-text-secondary);
6481
6483
  border: var(--border-width-thin) solid currentColor;
6482
- &.badge-primary { color: var(--color-text-primary); }
6483
- &.badge-secondary { color: var(--color-secondary-600); }
6484
- &.badge-success { color: var(--color-success-600); }
6485
- &.badge-info { color: var(--color-info-600); }
6486
- &.badge-warning { color: var(--color-warning-600); }
6487
- &.badge-danger { color: var(--color-danger-600); }
6484
+ &.badge-primary { color: var(--color-primary-text); }
6485
+ &.badge-secondary { color: var(--color-text-secondary); }
6486
+ &.badge-success { color: var(--color-success-text); }
6487
+ &.badge-info { color: var(--color-info-text); }
6488
+ &.badge-warning { color: var(--color-warning-text); }
6489
+ &.badge-danger { color: var(--color-danger-text); }
6488
6490
  }
6489
6491
 
6490
6492
  .badge-sm { padding: 2px var(--spacing-1); font-size: 10px; }
@@ -769,6 +769,36 @@
769
769
  "name": "pds-locale",
770
770
  "description": "Locale switcher component.\r\n\r\nThe component only persists canonical 5-letter locale tags (`xx-YY`),\r\nfor example `en-US` and `nl-NL`.",
771
771
  "attributes": [
772
+ {
773
+ "name": "name",
774
+ "description": "Form field name used during submit."
775
+ },
776
+ {
777
+ "name": "value",
778
+ "description": "Selected canonical locale tag (`xx-YY`)."
779
+ },
780
+ {
781
+ "name": "required",
782
+ "description": "Requires a locale value for validity.",
783
+ "valueSet": "v"
784
+ },
785
+ {
786
+ "name": "disabled",
787
+ "description": "Disables interaction and omits form value.",
788
+ "valueSet": "v"
789
+ },
790
+ {
791
+ "name": "mode",
792
+ "description": "Label display mode. In `compact`, the UI shows 2-letter aliases and puts the full Intl language name in the `title` attribute. In `full`, it renders the full Intl language name as the visible label.",
793
+ "values": [
794
+ {
795
+ "name": "compact"
796
+ },
797
+ {
798
+ "name": "full"
799
+ }
800
+ ]
801
+ },
772
802
  {
773
803
  "name": "data-label",
774
804
  "description": "Accessible label for the locale radio group."
package/src/js/app.js CHANGED
@@ -1,4 +1,4 @@
1
- import { PDS, msg, str } from "./pds";
1
+ import { PDS, html, msg, str } from "./pds";
2
2
  import { config } from "../../pds.config.js";
3
3
  import pkg from "../../package.json";
4
4
 
@@ -15,12 +15,15 @@ const repoUrl = rawRepoUrl
15
15
  const homepageUrl = pkg.homepage || repoUrl;
16
16
  const issuesUrl = pkg.bugs?.url || "";
17
17
 
18
- document.body.innerHTML = /*html*/ `
18
+ // Lit-like ergonomics: appendChild(DocumentFragment) with bindings
19
+ document.body.appendChild(html`
19
20
  <div class="container text-center">
20
21
  <img src="/assets/img/pds-logo.svg" alt="PDS Logo" title="${msg("PDS Logo")}" width="64" height="64" />
21
22
  <header class="container section">
22
- <h1>${pkg.name} ${msg(str`version ${pkg.version}`)}</h1>
23
+ <h1 @click=${() => PDS.toast("Hallo")}>
24
+ ${pkg.name} ${msg(str`version ${pkg.version}`)}
25
+ </h1>
23
26
  <small class="text-muted">${msg(pkg.description)}</small>
24
27
  </header>
25
28
  </div>
26
- `;
29
+ `);
@@ -31,20 +31,48 @@ export function fragmentFromTemplateLike(templateLike) {
31
31
  const htmlParts = [];
32
32
 
33
33
  const propBindingPattern = /(\s)(\.[\w-]+)=\s*$/;
34
+ const eventBindingPattern = /(\s)(@[\w-]+)=\s*$/;
35
+ const booleanBindingPattern = /(\s)(\?[\w-]+)=\s*$/;
36
+ const attrBindingPattern = /(\s)([\w:-]+)=\s*$/;
34
37
 
35
38
  for (let i = 0; i < strings.length; i += 1) {
36
39
  let chunk = strings[i] ?? "";
37
- const match = chunk.match(propBindingPattern);
38
-
39
- if (match && i < values.length) {
40
- const propToken = match[2];
41
- const propName = propToken.slice(1);
40
+ if (i < values.length) {
42
41
  const marker = `pds-val-${i}`;
43
- chunk = chunk.replace(
44
- propBindingPattern,
45
- `$1data-pds-prop="${propName}:${marker}"`
46
- );
47
- consumedValues.add(i);
42
+ const propMatch = chunk.match(propBindingPattern);
43
+ const eventMatch = chunk.match(eventBindingPattern);
44
+ const boolMatch = chunk.match(booleanBindingPattern);
45
+ const attrMatch = chunk.match(attrBindingPattern);
46
+
47
+ if (propMatch) {
48
+ const propName = propMatch[2].slice(1);
49
+ chunk = chunk.replace(
50
+ propBindingPattern,
51
+ `$1data-pds-bind-${i}="prop:${propName}:${marker}"`
52
+ );
53
+ consumedValues.add(i);
54
+ } else if (eventMatch) {
55
+ const eventName = eventMatch[2].slice(1);
56
+ chunk = chunk.replace(
57
+ eventBindingPattern,
58
+ `$1data-pds-bind-${i}="event:${eventName}:${marker}"`
59
+ );
60
+ consumedValues.add(i);
61
+ } else if (boolMatch) {
62
+ const attrName = boolMatch[2].slice(1);
63
+ chunk = chunk.replace(
64
+ booleanBindingPattern,
65
+ `$1data-pds-bind-${i}="boolean:${attrName}:${marker}"`
66
+ );
67
+ consumedValues.add(i);
68
+ } else if (attrMatch) {
69
+ const attrName = attrMatch[2];
70
+ chunk = chunk.replace(
71
+ attrBindingPattern,
72
+ `$1data-pds-bind-${i}="attr:${attrName}:${marker}"`
73
+ );
74
+ consumedValues.add(i);
75
+ }
48
76
  }
49
77
 
50
78
  htmlParts.push(chunk);
@@ -99,24 +127,93 @@ export function fragmentFromTemplateLike(templateLike) {
99
127
 
100
128
  const elements = tpl.content.querySelectorAll("*");
101
129
  elements.forEach((el) => {
102
- const propAttr = el.getAttribute("data-pds-prop");
103
- if (!propAttr) return;
104
- const [propName, markerValue] = propAttr.split(":");
105
- const index = Number(String(markerValue).replace("pds-val-", ""));
106
- if (propName && Number.isInteger(index)) {
107
- el[propName] = values[index];
108
- }
109
- el.removeAttribute("data-pds-prop");
130
+ [...el.attributes].forEach((attr) => {
131
+ if (!attr.name.startsWith("data-pds-bind-")) return;
132
+
133
+ const firstColon = attr.value.indexOf(":");
134
+ const lastColon = attr.value.lastIndexOf(":");
135
+ if (firstColon <= 0 || lastColon <= firstColon) {
136
+ el.removeAttribute(attr.name);
137
+ return;
138
+ }
139
+
140
+ const kind = attr.value.slice(0, firstColon);
141
+ const bindingName = attr.value.slice(firstColon + 1, lastColon);
142
+ const markerValue = attr.value.slice(lastColon + 1);
143
+ const index = Number(String(markerValue).replace("pds-val-", ""));
144
+ const value = values[index];
145
+
146
+ if (!bindingName || !Number.isInteger(index)) {
147
+ el.removeAttribute(attr.name);
148
+ return;
149
+ }
150
+
151
+ if (kind === "prop") {
152
+ el[bindingName] = value;
153
+ } else if (kind === "event") {
154
+ if (typeof value === "function" || (value && typeof value.handleEvent === "function")) {
155
+ el.addEventListener(bindingName, value);
156
+ }
157
+ } else if (kind === "boolean") {
158
+ if (value) {
159
+ el.setAttribute(bindingName, "");
160
+ } else {
161
+ el.removeAttribute(bindingName);
162
+ }
163
+ } else if (kind === "attr") {
164
+ if (value == null || value === false) {
165
+ el.removeAttribute(bindingName);
166
+ } else {
167
+ el.setAttribute(bindingName, String(value));
168
+ }
169
+ }
170
+
171
+ el.removeAttribute(attr.name);
172
+ });
110
173
  });
111
174
 
112
175
  return tpl.content;
113
176
  }
114
177
 
115
178
  /**
116
- * Parses an HTML string into a NodeList
117
- * @param {String} html
179
+ * Parses either an HTML string or tagged template into a DocumentFragment.
180
+ * Useful when you want direct appendChild(fragment) ergonomics.
181
+ * @param {string | TemplateStringsArray | {strings: string[], values: unknown[]}} html
182
+ * @param {...unknown} values
183
+ * @returns {DocumentFragment}
184
+ */
185
+ export function parseFragment(html, ...values) {
186
+ const isTaggedTemplate =
187
+ Array.isArray(html) && Object.prototype.hasOwnProperty.call(html, "raw");
188
+
189
+ if (isTaggedTemplate) {
190
+ return fragmentFromTemplateLike({ strings: Array.from(html), values });
191
+ }
192
+
193
+ if (Array.isArray(html?.strings) && Array.isArray(html?.values)) {
194
+ return fragmentFromTemplateLike({ strings: html.strings, values: html.values });
195
+ }
196
+
197
+ const tpl = document.createElement("template");
198
+ tpl.innerHTML = String(html ?? "");
199
+ return tpl.content;
200
+ }
201
+
202
+ /**
203
+ * Parses either an HTML string or a tagged template into DOM nodes.
204
+ *
205
+ * Supports two modes:
206
+ * 1. String mode: PDS.parse(htmlString) - returns NodeList, no binding support
207
+ * Example: PDS.parse(`<button class="btn">Click</button>`)
208
+ *
209
+ * 2. Tagged template mode: PDS.parse`...` - supports Lit-like bindings
210
+ * Bindings: `.prop=${value}`, `@event=${handler}`, `?boolean=${flag}`, `attr=${value}`
211
+ * Example: PDS.parse`<h1 @click=${handler}>...</h1>`
212
+ *
213
+ * @param {string | TemplateStringsArray | {strings: string[], values: unknown[]}} html
214
+ * @param {...unknown} values
118
215
  * @returns {NodeListOf<ChildNode>}
119
216
  */
120
- export function parseHTML(html) {
121
- return new DOMParser().parseFromString(html, "text/html").body.childNodes;
122
- }
217
+ export function parseHTML(html, ...values) {
218
+ return parseFragment(html, ...values).childNodes;
219
+ }
@@ -28,6 +28,7 @@ async function ensureToaster() {
28
28
  * @param {string} message - The message to display
29
29
  * @param {Object} [options={}] - Toast configuration
30
30
  * @param {"information"|"success"|"warning"|"error"} [options.type="information"] - Toast type/severity
31
+ * @param {string} [options.title] - Optional heading override (falls back to type label when empty)
31
32
  * @param {number} [options.duration] - Duration in milliseconds (auto-calculated if not provided based on message length)
32
33
  * @param {boolean} [options.closable=true] - Whether the toast can be manually closed
33
34
  * @param {boolean} [options.persistent=false] - If true, toast won't auto-dismiss (requires manual close)
@@ -47,6 +48,13 @@ async function ensureToaster() {
47
48
  * });
48
49
  *
49
50
  * @example
51
+ * // Custom title overrides type-derived heading
52
+ * await PDS.toast('Feature coming soon...', {
53
+ * type: 'information',
54
+ * title: 'Qogni'
55
+ * });
56
+ *
57
+ * @example
50
58
  * // Persistent warning (must be manually closed)
51
59
  * await PDS.toast('This action cannot be undone', {
52
60
  * type: 'warning',