@citolab/qti-components 8.0.2 → 8.1.0

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 (53) hide show
  1. package/cdn/index.global.js +1 -1
  2. package/cdn/index.js +647 -815
  3. package/dist/base.d.ts +58 -1
  4. package/dist/base.js +7 -1
  5. package/dist/{chunk-NJQHUUTN.js → chunk-3IACYIU2.js} +2 -2
  6. package/dist/{chunk-TWPXES3S.js → chunk-4XR2JHCP.js} +6 -6
  7. package/dist/chunk-4XR2JHCP.js.map +1 -0
  8. package/dist/{chunk-7V4HJFHW.js → chunk-6ITD55QE.js} +2 -2
  9. package/dist/{chunk-ZII6M3SN.js → chunk-6V3A7NQP.js} +2 -2
  10. package/dist/{chunk-7AVWRQIS.js → chunk-6XJUP55A.js} +62 -76
  11. package/dist/{chunk-7AVWRQIS.js.map → chunk-6XJUP55A.js.map} +1 -1
  12. package/dist/{chunk-J5SQLKNP.js → chunk-CF3DXJWM.js} +6 -6
  13. package/dist/{chunk-HQESINXH.js → chunk-EKXZI26R.js} +84 -1
  14. package/dist/chunk-EKXZI26R.js.map +1 -0
  15. package/dist/{chunk-IJD53WY6.js → chunk-HDEG6BAZ.js} +15 -15
  16. package/dist/{chunk-IJD53WY6.js.map → chunk-HDEG6BAZ.js.map} +1 -1
  17. package/dist/{chunk-CK7AV2UJ.js → chunk-IXPDMYKH.js} +3 -3
  18. package/dist/chunk-IYC7LZV6.js +7 -0
  19. package/dist/chunk-IYC7LZV6.js.map +1 -0
  20. package/dist/{chunk-VAE6HBKR.js → chunk-MK2I3MQB.js} +86 -59
  21. package/dist/chunk-MK2I3MQB.js.map +1 -0
  22. package/dist/{chunk-BQFWCZFH.js → chunk-NZLW6EX7.js} +2 -2
  23. package/dist/{chunk-HBSWJC3B.js → chunk-Q52IJELT.js} +5 -5
  24. package/dist/{chunk-RSVRS5AK.js → chunk-TXIB3SKC.js} +4 -4
  25. package/dist/corrections.js +8 -8
  26. package/dist/elements.d.ts +0 -1
  27. package/dist/elements.js +4 -4
  28. package/dist/index.d.ts +2 -2
  29. package/dist/index.js +28 -14
  30. package/dist/interactions.js +3 -3
  31. package/dist/item.css +370 -532
  32. package/dist/item.js +5 -5
  33. package/dist/loader.js +2 -2
  34. package/dist/processing.d.ts +61 -11
  35. package/dist/processing.js +10 -2
  36. package/dist/qti-components-jsx.d.ts +756 -552
  37. package/dist/test.js +6 -6
  38. package/dist/transformers.d.ts +1 -1
  39. package/dist/transformers.js +1 -1
  40. package/package.json +8 -8
  41. package/dist/chunk-G6GFQDVN.js +0 -7
  42. package/dist/chunk-G6GFQDVN.js.map +0 -1
  43. package/dist/chunk-HQESINXH.js.map +0 -1
  44. package/dist/chunk-TWPXES3S.js.map +0 -1
  45. package/dist/chunk-VAE6HBKR.js.map +0 -1
  46. /package/dist/{chunk-NJQHUUTN.js.map → chunk-3IACYIU2.js.map} +0 -0
  47. /package/dist/{chunk-7V4HJFHW.js.map → chunk-6ITD55QE.js.map} +0 -0
  48. /package/dist/{chunk-ZII6M3SN.js.map → chunk-6V3A7NQP.js.map} +0 -0
  49. /package/dist/{chunk-J5SQLKNP.js.map → chunk-CF3DXJWM.js.map} +0 -0
  50. /package/dist/{chunk-CK7AV2UJ.js.map → chunk-IXPDMYKH.js.map} +0 -0
  51. /package/dist/{chunk-BQFWCZFH.js.map → chunk-NZLW6EX7.js.map} +0 -0
  52. /package/dist/{chunk-HBSWJC3B.js.map → chunk-Q52IJELT.js.map} +0 -0
  53. /package/dist/{chunk-RSVRS5AK.js.map → chunk-TXIB3SKC.js.map} +0 -0
package/dist/base.d.ts CHANGED
@@ -102,6 +102,63 @@ declare const dropRegion: lit.CSSResult;
102
102
  */
103
103
  declare const validationMessage: lit.CSSResult;
104
104
 
105
+ /**
106
+ * Custom-state support shim for browsers this library cannot use natively.
107
+ *
108
+ * Interactions track selection and correct/incorrect marking through
109
+ * `internals.states`, with bare state names (`checked`, `radio`,
110
+ * `correct-response`, …). Two browser profiles cannot service that:
111
+ *
112
+ * - Safari 16.4–17.3 implement `ElementInternals` but not `CustomStateSet`, so
113
+ * `internals.states` is `undefined` and reading it throws — "undefined is not
114
+ * an object (evaluating 'internals.states.has')".
115
+ * - Chrome and Edge before the CSS custom-state spec change expose `states` but
116
+ * reject names that do not start with `--`, so `states.add('radio')` throws
117
+ * "The specified value 'radio' must start with '--'".
118
+ *
119
+ * On both, picking a choice throws rather than registering. `attachInternals`
120
+ * itself is unguarded throughout the interaction base classes, which puts the
121
+ * hard support floor at Safari 16.4 — inside the range that breaks.
122
+ *
123
+ * The shim replaces `states` with a permissive `Set` and mirrors its contents to
124
+ * a space-separated `data-state` attribute on the host, because these browsers'
125
+ * CSS parsers also drop any selector list containing `:state()`. The theme's
126
+ * built stylesheets pair every `:state(x)` with a `[data-state~='x']` arm (see
127
+ * `tools/postcss/custom-state-fallback.mjs`), so styling survives too.
128
+ *
129
+ * Support is classified by behaviour rather than by browser version, and the
130
+ * shim is not installed at all where `states` works.
131
+ */
132
+ /** A permissive `CustomStateSet` that mirrors its contents to `data-state`. */
133
+ declare class CustomStateSetShim extends Set<string> {
134
+ #private;
135
+ constructor(host: HTMLElement);
136
+ add(state: string): this;
137
+ delete(state: string): boolean;
138
+ clear(): void;
139
+ }
140
+ type CustomStateSupport = 'missing' | 'legacy' | 'modern';
141
+ /**
142
+ * Classify native custom-state support by behaviour:
143
+ *
144
+ * - `missing`: `ElementInternals` carries no `states` at all.
145
+ * - `legacy`: `states` exists but rejects a bare name.
146
+ * - `modern`: `states` exists and accepts a bare name — no shim wanted.
147
+ *
148
+ * `attachInternals` only works on a custom element, so the probe registers a
149
+ * throwaway one. That happens solely when `states` is present, so the `missing`
150
+ * path never defines anything.
151
+ */
152
+ declare function classifyCustomStateSupport(attachInternals: (this: HTMLElement) => ElementInternals): CustomStateSupport;
153
+ /**
154
+ * Patch `HTMLElement.prototype.attachInternals` so every element's `states` is
155
+ * the shim, on the two profiles that need it. Idempotent, and a no-op where
156
+ * native support is usable.
157
+ *
158
+ * Returns the classification that was acted on, which is what the tests assert.
159
+ */
160
+ declare function installCustomStateSetFallback(): CustomStateSupport | 'already-installed';
161
+
105
162
  declare class ScoringHelper {
106
163
  /**
107
164
  * Checks if a given point is within a specified area.
@@ -132,4 +189,4 @@ declare const convertNumberToUniversalFormat: (number: number | string) => strin
132
189
  declare function IsNullOrUndefined(value: unknown): boolean;
133
190
  declare function removeDoubleSlashes(str: string): string;
134
191
 
135
- export { BaseType, ComputedContext, ComputedItemContext, IsNullOrUndefined, ItemContext, ScoringHelper, boxSizing, computedContext, computedItemContext, convertNumberToUniversalFormat, decimalSeparator, dropRegion, itemContext, removeDoubleSlashes, validationMessage };
192
+ export { BaseType, ComputedContext, ComputedItemContext, CustomStateSetShim, type CustomStateSupport, IsNullOrUndefined, ItemContext, ScoringHelper, boxSizing, classifyCustomStateSupport, computedContext, computedItemContext, convertNumberToUniversalFormat, decimalSeparator, dropRegion, installCustomStateSetFallback, itemContext, removeDoubleSlashes, validationMessage };
package/dist/base.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import {
2
+ CustomStateSetShim,
2
3
  INITIAL_SESSION_CONTEXT,
3
4
  INITIAL_TEST_CONTEXT,
4
5
  Interaction,
@@ -11,12 +12,14 @@ import {
11
12
  ScoringHelper,
12
13
  asSeed,
13
14
  boxSizing,
15
+ classifyCustomStateSupport,
14
16
  computedContext,
15
17
  computedItemContext,
16
18
  configContext,
17
19
  convertNumberToUniversalFormat,
18
20
  decimalSeparator,
19
21
  dropRegion,
22
+ installCustomStateSetFallback,
20
23
  interactionContext,
21
24
  isSeed,
22
25
  itemContext,
@@ -34,8 +37,9 @@ import {
34
37
  sessionContext,
35
38
  testContext,
36
39
  validationMessage
37
- } from "./chunk-HQESINXH.js";
40
+ } from "./chunk-EKXZI26R.js";
38
41
  export {
42
+ CustomStateSetShim,
39
43
  INITIAL_SESSION_CONTEXT,
40
44
  INITIAL_TEST_CONTEXT,
41
45
  Interaction,
@@ -48,12 +52,14 @@ export {
48
52
  ScoringHelper,
49
53
  asSeed,
50
54
  boxSizing,
55
+ classifyCustomStateSupport,
51
56
  computedContext,
52
57
  computedItemContext,
53
58
  configContext,
54
59
  convertNumberToUniversalFormat,
55
60
  decimalSeparator,
56
61
  dropRegion,
62
+ installCustomStateSetFallback,
57
63
  interactionContext,
58
64
  isSeed,
59
65
  itemContext,
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  qtiContentElements
3
- } from "./chunk-7AVWRQIS.js";
3
+ } from "./chunk-6XJUP55A.js";
4
4
 
5
5
  // ../qti-elements/dist/register.js
6
6
  for (const { tag, ctor } of qtiContentElements) {
@@ -8,4 +8,4 @@ for (const { tag, ctor } of qtiContentElements) {
8
8
  customElements.define(tag, ctor);
9
9
  }
10
10
  }
11
- //# sourceMappingURL=chunk-NJQHUUTN.js.map
11
+ //# sourceMappingURL=chunk-3IACYIU2.js.map
@@ -14,7 +14,7 @@ import {
14
14
  responseAttributeConverter,
15
15
  serializeResponseAttribute,
16
16
  validationMessage
17
- } from "./chunk-HQESINXH.js";
17
+ } from "./chunk-EKXZI26R.js";
18
18
 
19
19
  // ../interactions/core/dist/elements/qti-gap-text/qti-gap-text.js
20
20
  import { html as html2, LitElement } from "lit";
@@ -383,7 +383,7 @@ var qti_simple_associable_choice_styles_default = [
383
383
  * that observer, so the state is the form that works everywhere and the [qti-droppable]
384
384
  * attribute that used to accompany it is gone. Positive opt-in, so tabular headers are untouched.
385
385
  */
386
- :host(:state(droppable)) {
386
+ :host(:is(:state(droppable), [data-state~='droppable'])) {
387
387
  /*
388
388
  * The CARD token, not the slot one. This element is a droppable only in match, and match
389
389
  * publishes no measurement — so reading --qti-dropzone-min-height here meant reading a name
@@ -409,7 +409,7 @@ var qti_simple_associable_choice_styles_default = [
409
409
  justify-content: space-between;
410
410
  }
411
411
 
412
- :host(:state(droppable)) [part~='drop'] {
412
+ :host(:is(:state(droppable), [data-state~='droppable'])) [part~='drop'] {
413
413
  /*
414
414
  * Match's dropzones are NOT auto-sized from the chips: a match target is a category, and
415
415
  * should look able to hold several answers rather than hugging the widest one. So this reads
@@ -449,7 +449,7 @@ var qti_simple_associable_choice_styles_default = [
449
449
  }
450
450
 
451
451
  /* The label sits against the drop region below it. */
452
- :host(:state(droppable)) [part~='label'] {
452
+ :host(:is(:state(droppable), [data-state~='droppable'])) [part~='label'] {
453
453
  align-content: flex-end;
454
454
  }
455
455
 
@@ -463,7 +463,7 @@ var qti_simple_associable_choice_styles_default = [
463
463
  * [part~='drag'] a chip a drop target renders, where that selector cannot reach it — match's
464
464
  * selector names a light-DOM ancestry the placed clone no longer has
465
465
  */
466
- :host(:state(drag)) [part~='drop'],
466
+ :host(:is(:state(drag), [data-state~='drag'])) [part~='drop'],
467
467
  :host([part~='drag']) [part~='drop'] {
468
468
  display: none;
469
469
  }
@@ -10329,4 +10329,4 @@ export {
10329
10329
  QtiTextEntryInteraction,
10330
10330
  elements16
10331
10331
  };
10332
- //# sourceMappingURL=chunk-TWPXES3S.js.map
10332
+ //# sourceMappingURL=chunk-4XR2JHCP.js.map