@qti-components/order-interaction 2.0.1-next.3 → 3.0.0-next.5
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.
|
@@ -27,11 +27,16 @@ declare const QtiOrderInteraction_base: (abstract new (...args: any[]) => import
|
|
|
27
27
|
* @slot prompt - The prompt shown above the interaction.
|
|
28
28
|
* @slot drags - The draggable choice sources.
|
|
29
29
|
*
|
|
30
|
-
* @csspart container - The outer container wrapping
|
|
31
|
-
* @csspart
|
|
30
|
+
* @csspart container - The outer container wrapping the bank and the drops.
|
|
31
|
+
* @csspart bank - The slot holding the unplaced chips (was `drags`).
|
|
32
32
|
* @csspart drops - The drop-target region.
|
|
33
|
-
* @csspart drop - Each individual drop target.
|
|
34
|
-
*
|
|
33
|
+
* @csspart drop - Each individual drop target. Tokens: `filled`, `full`, `drag-active`, `drag-over`
|
|
34
|
+
* (a plain div cannot carry `:state()`, so the state names are part tokens here).
|
|
35
|
+
* @csspart chip - A choice placed into a drop target (was `drag`).
|
|
36
|
+
* @csspart message - Live validation message region (role="alert").
|
|
37
|
+
* @cssstate disabled - The interaction is switched off.
|
|
38
|
+
* @cssstate readonly - The interaction is frozen: it shows its value and takes no input.
|
|
39
|
+
* @cssstate drag-active - A drag is in progress (was `dragzone-active`, `dragzone-enabled`).
|
|
35
40
|
*/
|
|
36
41
|
export declare class QtiOrderInteraction extends QtiOrderInteraction_base {
|
|
37
42
|
static styles: import("lit").CSSResult[];
|
|
@@ -38,13 +38,18 @@ const SlottedBase = DragDropSlottedMixin(Interaction, `qti-simple-choice`, `[par
|
|
|
38
38
|
* @slot prompt - The prompt shown above the interaction.
|
|
39
39
|
* @slot drags - The draggable choice sources.
|
|
40
40
|
*
|
|
41
|
-
* @csspart container - The outer container wrapping
|
|
42
|
-
* @csspart
|
|
41
|
+
* @csspart container - The outer container wrapping the bank and the drops.
|
|
42
|
+
* @csspart bank - The slot holding the unplaced chips (was `drags`).
|
|
43
43
|
* @csspart drops - The drop-target region.
|
|
44
|
-
* @csspart drop - Each individual drop target.
|
|
45
|
-
*
|
|
44
|
+
* @csspart drop - Each individual drop target. Tokens: `filled`, `full`, `drag-active`, `drag-over`
|
|
45
|
+
* (a plain div cannot carry `:state()`, so the state names are part tokens here).
|
|
46
|
+
* @csspart chip - A choice placed into a drop target (was `drag`).
|
|
47
|
+
* @csspart message - Live validation message region (role="alert").
|
|
48
|
+
* @cssstate disabled - The interaction is switched off.
|
|
49
|
+
* @cssstate readonly - The interaction is frozen: it shows its value and takes no input.
|
|
50
|
+
* @cssstate drag-active - A drag is in progress (was `dragzone-active`, `dragzone-enabled`).
|
|
46
51
|
*/
|
|
47
|
-
export class QtiOrderInteraction extends DragDropSlottedSortableMixin(SlottedBase, '[
|
|
52
|
+
export class QtiOrderInteraction extends DragDropSlottedSortableMixin(SlottedBase, '[data-draggable="true"]') {
|
|
48
53
|
constructor() {
|
|
49
54
|
super(...arguments);
|
|
50
55
|
this.nrChoices = 0;
|
|
@@ -57,7 +62,7 @@ export class QtiOrderInteraction extends DragDropSlottedSortableMixin(SlottedBas
|
|
|
57
62
|
}
|
|
58
63
|
return html ` <slot name="prompt"> </slot>
|
|
59
64
|
<div part="container">
|
|
60
|
-
<slot part="drags"> </slot>
|
|
65
|
+
<slot part="bank drags"> </slot>
|
|
61
66
|
<div part="drops">
|
|
62
67
|
${[...Array(this.nrChoices)].map((_, i) => {
|
|
63
68
|
const identifier = `droplist${i}`;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"qti-order-interaction.js","sourceRoot":"","sources":["../src/qti-order-interaction.ts"],"names":[],"mappings":";;;;;;AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAC3B,OAAO,EAAE,MAAM,EAAE,MAAM,0BAA0B,CAAC;AAClD,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAEpD,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACnD,OAAO,EACL,oBAAoB,EACpB,4BAA4B,EAC7B,MAAM,gEAAgE,CAAC;AAExE,OAAO,MAAM,MAAM,gCAAgC,CAAC;AAIpD,MAAM,WAAW,GAAG,oBAAoB,CAAC,WAAW,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,qBAAqB,CAAC,CAAC;AAEpH
|
|
1
|
+
{"version":3,"file":"qti-order-interaction.js","sourceRoot":"","sources":["../src/qti-order-interaction.ts"],"names":[],"mappings":"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","sourcesContent":["import { html } from 'lit';\nimport { repeat } from 'lit/directives/repeat.js';\nimport { property, state } from 'lit/decorators.js';\n\nimport { Interaction } from '@qti-components/base';\nimport {\n DragDropSlottedMixin,\n DragDropSlottedSortableMixin\n} from '@qti-components/interactions-core/mixins/drag-drop-observables';\n\nimport styles from './qti-order-interaction.styles';\n\nimport type { PropertyValueMap } from 'lit';\n\nconst SlottedBase = DragDropSlottedMixin(Interaction, `qti-simple-choice`, `[part~='drop']`, `slot[part~='drags']`);\n\n/**\n * Order interaction: candidates arrange choices into a target sequence.\n *\n * @customElement qti-order-interaction\n *\n * @attr {string} response-identifier - Required. Identifier of the bound response variable.\n * @attr {'horizontal'|'vertical'} [orientation=vertical] - Layout direction of the drop\n * sequence. Unlike on `qti-choice-interaction`, QTI does not deprecate this for order.\n * @attr {boolean} [shuffle=false] - Requests choice shuffling. Applied by the transform\n * pipeline (`qti-transformers`), not by this element.\n * @attr {number} [min-associations=1] - Non-QTI vocabulary inherited from the drag-drop\n * mixin; currently the only way to set the lower bound. QTI spells this `min-choices`.\n * @attr {number} [max-associations=0] - Non-QTI vocabulary inherited from the drag-drop\n * mixin; currently the only way to set the upper bound. QTI spells this `max-choices`.\n * @attr {number} min-choices - Not implemented. The QTI-correct spelling of the lower bound.\n * See plans/interaction-attribute-spec-conformance.md.\n * @attr {number} max-choices - Not implemented. The QTI-correct spelling of the upper bound.\n * See plans/interaction-attribute-spec-conformance.md.\n * @attr {boolean} [auto-size-dropzones=true] - Extension, not QTI. Sizes every drop target to\n * the widest chip so placement does not reflow the layout. On by default: an order slot is a\n * socket cut to one chip, and both axes are measured (see DROP-SIZING.md).\n * @attr {boolean} [disable-animations=false] - Extension, not QTI. Disables the FLIP move\n * animation.\n *\n * @slot prompt - The prompt shown above the interaction.\n * @slot drags - The draggable choice sources.\n *\n * @csspart container - The outer container wrapping the bank and the drops.\n * @csspart bank - The slot holding the unplaced chips (was `drags`).\n * @csspart drops - The drop-target region.\n * @csspart drop - Each individual drop target. Tokens: `filled`, `full`, `drag-active`, `drag-over`\n * (a plain div cannot carry `:state()`, so the state names are part tokens here).\n * @csspart chip - A choice placed into a drop target (was `drag`).\n * @csspart message - Live validation message region (role=\"alert\").\n * @cssstate disabled - The interaction is switched off.\n * @cssstate readonly - The interaction is frozen: it shows its value and takes no input.\n * @cssstate drag-active - A drag is in progress (was `dragzone-active`, `dragzone-enabled`).\n */\nexport class QtiOrderInteraction extends DragDropSlottedSortableMixin(SlottedBase, '[data-draggable=\"true\"]') {\n static override styles = styles;\n protected childrenMap: Element[];\n\n @state() protected nrChoices: number = 0;\n\n /** orientation of choices */\n @property({ type: String })\n public orientation: 'horizontal' | 'vertical';\n\n override render() {\n const choices = Array.from(this.querySelectorAll('qti-simple-choice'));\n if (this.nrChoices < choices.length) {\n this.nrChoices = choices.length;\n }\n\n return html` <slot name=\"prompt\"> </slot>\n <div part=\"container\">\n <slot part=\"bank drags\"> </slot>\n <div part=\"drops\">\n ${[...Array(this.nrChoices)].map((_, i) => {\n const identifier = `droplist${i}`;\n // The chips are rendered here, from the interaction's placement map, rather than being\n // appended into this div by handleDrop. `data-declarative-drops` is what tells the\n // mixin to keep them in the map and leave this element's children alone.\n const drags = this._dragDrop?.nodesByTarget?.[identifier] ?? [];\n return html`<div role=\"region\" part=\"drop\" data-declarative-drops identifier=${identifier}>\n ${repeat(\n drags,\n node => node.getAttribute('identifier'),\n node => node\n )}\n </div>`;\n })}\n </div>\n <div id=\"validation-message\" part=\"message\" role=\"alert\" style=\"display:none;\"></div>\n </div>`;\n }\n\n // some interactions have a different way of getting the response\n // this is called from the drag and drop mixin class\n // you have to implement your own getResponse method in the superclass\n // cause they are different for some interactions.\n getValue(val: string[]) {\n return val?.map((v, i) => `${v} droplist${i}`) || [];\n }\n\n // some interactions have a different way of getting the response\n // this is called from the drag and drop mixin class\n // you have to implement your own getResponse method in the superclass\n // cause they are different for some interactions.\n // MH: is this function called? Shouldn't we use getValue?\n protected getResponse(): string[] {\n const droppables = Array.from<HTMLElement>(this.shadowRoot.querySelectorAll(`[part~='drop']`));\n\n // Read placement, not the DOM. The DOM is rendered *from* placement now, so querying it back\n // out would be asking the same question twice and hoping for the same answer.\n return droppables.map(droppable =>\n this.chipsIn(droppable)\n .map(chip => chip.getAttribute('identifier'))\n .join(' ')\n );\n }\n\n public override shouldTreatBlockedMaxAsInvalid(): boolean {\n return false;\n }\n\n override async firstUpdated() {\n super.firstUpdated();\n this.childrenMap = Array.from(this.querySelectorAll('qti-simple-choice'));\n // `part=\"drag\"` used to be stamped on the light-DOM originals here, purely so the clone would\n // inherit it — a slotted chip's own `part` is unreachable. The mixin stamps the clone directly\n // now, at the moment it makes it.\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'qti-order-interaction': QtiOrderInteraction;\n }\n}\n"]}
|
|
@@ -27,11 +27,19 @@ export default [
|
|
|
27
27
|
display: block;
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
-
[part
|
|
30
|
+
[part~='bank'] {
|
|
31
|
+
/* The bank, the same in every drag-drop interaction: flush with the container (no padding, no
|
|
32
|
+
margin, no edge of its own), chips a --qti-gap apart. Its lit and ringed looks while a chip is
|
|
33
|
+
in flight are the theme's ('::part(bank drag-active)', '::part(bank drag-over)'). */
|
|
31
34
|
display: flex;
|
|
35
|
+
flex-wrap: wrap;
|
|
32
36
|
align-items: flex-start;
|
|
33
37
|
flex: 1;
|
|
34
|
-
|
|
38
|
+
gap: var(--qti-gap, 0.5rem);
|
|
39
|
+
padding: 0;
|
|
40
|
+
margin: 0;
|
|
41
|
+
border: 0;
|
|
42
|
+
border-radius: var(--qti-radius-box, 0.2rem);
|
|
35
43
|
}
|
|
36
44
|
|
|
37
45
|
[part='drops'] {
|
|
@@ -58,8 +66,8 @@ export default [
|
|
|
58
66
|
gap: 0.5rem;
|
|
59
67
|
}
|
|
60
68
|
|
|
61
|
-
:host([orientation='horizontal']) [part
|
|
62
|
-
:host(.qti-orientation-horizontal) [part
|
|
69
|
+
:host([orientation='horizontal']) [part~='bank'],
|
|
70
|
+
:host(.qti-orientation-horizontal) [part~='bank'] {
|
|
63
71
|
flex-direction: row;
|
|
64
72
|
}
|
|
65
73
|
/*
|
|
@@ -72,8 +80,8 @@ export default [
|
|
|
72
80
|
* wrapped and the '.qti-orientation-horizontal' class did not. The theme's rule is gone and so
|
|
73
81
|
* is this one; both spellings now wrap, which is what the attribute already did.
|
|
74
82
|
*/
|
|
75
|
-
:host([orientation='vertical']) [part
|
|
76
|
-
:host(.qti-orientation-vertical) [part
|
|
83
|
+
:host([orientation='vertical']) [part~='bank'],
|
|
84
|
+
:host(.qti-orientation-vertical) [part~='bank'] {
|
|
77
85
|
flex-direction: column;
|
|
78
86
|
}
|
|
79
87
|
:host([orientation='vertical']) [part='drops'],
|
|
@@ -125,7 +133,7 @@ export default [
|
|
|
125
133
|
* never done anything; it is left in the theme rather than deleted here, since removing it is a
|
|
126
134
|
* decision about how a long label should behave, not a relocation.
|
|
127
135
|
*/
|
|
128
|
-
[part~='
|
|
136
|
+
[part~='chip'] {
|
|
129
137
|
display: flex;
|
|
130
138
|
align-items: center;
|
|
131
139
|
overflow: visible;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"qti-order-interaction.styles.js","sourceRoot":"","sources":["../src/qti-order-interaction.styles.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAE1B,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAEhF;;;;;;;;;;;;;;;;GAgBG;AACH,eAAe;IACb,SAAS;IACT,iBAAiB;IACjB,UAAU;IACV,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkNF;CACF,CAAC","sourcesContent":["import { css } from 'lit';\n\nimport { boxSizing, dropRegion, validationMessage } from '@qti-components/base';\n\n/**\n * Layout and sizing only. Paint and state live in the theme.\n *\n * What left, and where it went — `styles/qti-theme/interactions/qti-order-interaction.css` and\n * `styles/overrides/kennisnet/qti/order-interaction.scss`:\n *\n * [part~='drop'][active] / [enabled] -> ::part(active) / ::part(enabled)\n * [part~='drop']:has([part='drag']) -> ::part(filled)\n *\n * They had to be rewritten, not relocated: an attribute selector and `:has()` cannot follow\n * `::part()`, so the drop's flags became part tokens (verified in Chromium, see setDropFlag).\n *\n * Two rules were deleted rather than moved, because neither did anything:\n * - `background-color: var(--qti-background-color-active-droplist)` — that property is never\n * defined anywhere in the repo, so the declaration was invalid at computed-value time.\n * - `[part~='drop'][data-cross-slot-target]` — nothing has ever set that attribute.\n */\nexport default [\n boxSizing,\n validationMessage,\n dropRegion,\n css`\n /* The box this element already had. See the note in qti-match-interaction.styles.ts. */\n :host {\n display: block;\n }\n\n [part='drags'] {\n display: flex;\n align-items: flex-start;\n flex: 1;\n flex-wrap: wrap;\n }\n\n [part='drops'] {\n flex: 1;\n display: grid;\n grid-auto-flow: row;\n /*\n * A column floor and a drop's own min-width are two jobs, and this asks for both by name\n * rather than letting one token mean both. --qti-drop-track-min-width is the policy: a column\n * stays usable however narrow the chips are. --qti-dropzone-min-width is the measurement: a\n * column is never narrower than the chip it holds. max() of the two is what the grid wants,\n * and the 0px fallback is what makes this correct for an interaction that never measures.\n *\n * One name did both until --qti-drop-min-width was deleted for exactly that (it meant the\n * track floor here and a drop's own min-width in the match target). Folding the track back\n * onto --qti-dropzone-min-width brought the conflation back: a theme setting it to give\n * unmeasured drops a floor also set every column, and a code path that stopped publishing a\n * measured width stopped meaning \"no floor\".\n */\n grid-template-columns: repeat(\n auto-fit,\n minmax(max(var(--qti-drop-track-min-width, 120px), var(--qti-dropzone-min-width, 0px)), 1fr)\n );\n gap: 0.5rem;\n }\n\n :host([orientation='horizontal']) [part='drags'],\n :host(.qti-orientation-horizontal) [part='drags'] {\n flex-direction: row;\n }\n /*\n * Horizontal adds nothing to [part='drops']: the base rule above is already the horizontal\n * layout — auto-fit columns that wrap. Only 'vertical' overrides it, to a single column.\n *\n * There used to be a 'grid-auto-flow: column' here, which forced every drop onto one\n * non-wrapping line. The theme cancelled it by restating the base rule at\n * qti-order-interaction.css, but only for '[orientation='horizontal']' — so the attribute\n * wrapped and the '.qti-orientation-horizontal' class did not. The theme's rule is gone and so\n * is this one; both spellings now wrap, which is what the attribute already did.\n */\n :host([orientation='vertical']) [part='drags'],\n :host(.qti-orientation-vertical) [part='drags'] {\n flex-direction: column;\n }\n :host([orientation='vertical']) [part='drops'],\n :host(.qti-orientation-vertical) [part='drops'] {\n grid-template-columns: 1fr;\n }\n\n /* Drop target. The interaction measures its chips and publishes the result as a custom\n property on its host; the property itself lives here, not in a style attribute. */\n [part~='drop'] {\n display: flex;\n flex: 1;\n min-height: var(--qti-dropzone-min-height, 0);\n\n /*\n * Both axes, not just the height.\n *\n * The width was measured and published all along and then thrown away: the drop is a grid item\n * and stretched to its track, which is 1fr, so a slot in the vertical layout came out 669px\n * wide for a 149px chip. justify-self: start stops the stretch and the measured minimum then\n * decides, so a slot is exactly as wide as the widest chip — the same rule the height has\n * always followed.\n *\n * The grid is untouched: the tracks still lay the slots out and still wrap in the horizontal\n * layout. Only the slot inside the track stops filling it.\n */\n min-width: var(--qti-dropzone-min-width, 0);\n justify-self: start;\n\n /* A chip's drop shadow hangs outside its column. */\n overflow: visible;\n }\n\n [part='drops'] {\n overflow: visible;\n }\n\n /* Once a drop holds a chip it stops stretching to the row and sits at the top of it. */\n :host(:has(qti-simple-choice)) [part~='drop'] {\n align-self: flex-start;\n }\n\n /*\n * The chip a drop renders.\n *\n * 'overflow: visible', not 'hidden'. The theme declared both, in two '::part(drag)' blocks at\n * equal specificity in the same layer, so the later one won and the chip has always been\n * unclipped. The 'text-overflow: ellipsis' still sitting beside the first one has therefore\n * never done anything; it is left in the theme rather than deleted here, since removing it is a\n * decision about how a long label should behave, not a relocation.\n */\n [part~='drag'] {\n display: flex;\n align-items: center;\n overflow: visible;\n }\n\n [part='container'] {\n display: grid;\n grid-template-areas:\n 'drags drops'\n 'message message';\n grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);\n align-items: start;\n gap: 0.5rem;\n }\n\n slot[part~='drags'] {\n grid-area: drags;\n }\n\n [part='drops'] {\n grid-area: drops;\n }\n\n [part='message'] {\n grid-area: message;\n width: 100%;\n justify-self: start;\n }\n\n /*\n * The PLATFORM DEFAULT for container positioning, when the orientation is horizontal.\n *\n * Read that carefully, because the two things are separate axes in QTI 3 and this rule does not\n * merge them. Vocabulary §1.2.9.3 defines qti-choices-* as where the choices container sits\n * relative to the order-target container; orientation is how items flow WITHIN a container.\n * They compose: §1.2.9.2 Figure 73 is orientation=\"vertical\" class=\"qti-choices-left\" and\n * renders two COLUMNS SIDE BY SIDE — vertical does not stack the containers, and horizontal does\n * not imply that it should.\n *\n * What makes this rule legitimate is that §1.2.9.3 declines to specify the positioning at all\n * when no class is given: \"In the absence of choices | order target container positioning,\n * delivery systems should render platform defaults.\" That default is ours, and for a horizontal\n * flow the useful one is stacked, because a row needs the width. An author who wants something\n * else says so with qti-choices-*, which is exactly what the spec provides it for — and those\n * rules below still win (see the source-order note).\n *\n * Side by side used to work here anyway, but only because a slot could be narrower\n * than the chip standing in it: the theme gave a placed chip width: 100%, so a 218px chip was\n * squeezed into a 184px track and three of them fitted in half the width. That squeeze is gone\n * (DROP-SIZING.md §5), and without it \"van links naar rechts\" collapsed to a single column,\n * because 384px cannot hold two 218px chips.\n *\n * Measured on ITEM013: side by side gives the slots 384px and one 384px track; stacked gives them\n * 800px and three 256px tracks, each wider than the chip. Vertical is untouched — one column is\n * what it wants, and the split suits it.\n *\n * Deliberately BEFORE the qti-choices-* rules below, not after. Those tie on specificity, so\n * source order decides: an author who writes qti-choices-left still gets it, and this is only the\n * default for an orientation that has no such class.\n */\n :host([orientation='horizontal']) [part='container'],\n :host(.qti-orientation-horizontal) [part='container'] {\n grid-template-areas:\n 'drags'\n 'drops'\n 'message';\n grid-template-columns: minmax(0, 1fr);\n }\n\n :host(.qti-choices-top) [part='container'] {\n grid-template-areas:\n 'drags'\n 'drops'\n 'message';\n grid-template-columns: minmax(0, 1fr);\n }\n\n :host(.qti-choices-bottom) [part='container'] {\n grid-template-areas:\n 'drops'\n 'drags'\n 'message';\n grid-template-columns: minmax(0, 1fr);\n }\n\n :host(.qti-choices-left) [part='container'] {\n grid-template-areas:\n 'drags drops'\n 'message message';\n grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);\n }\n\n :host(.qti-choices-right) [part='container'] {\n grid-template-areas:\n 'drops drags'\n 'message message';\n grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);\n }\n\n /* An answer key shows the answer, not the bank you would have dragged it from. The attribute is\n set on the clone by the correct-response mixin; the theme used to do this with a\n '.full-correct-response' descendant selector, from the document. */\n :host([answer-key]) [part~='drags'] {\n display: none;\n }\n `\n];\n"]}
|
|
1
|
+
{"version":3,"file":"qti-order-interaction.styles.js","sourceRoot":"","sources":["../src/qti-order-interaction.styles.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAE1B,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAEhF;;;;;;;;;;;;;;;;GAgBG;AACH,eAAe;IACb,SAAS;IACT,iBAAiB;IACjB,UAAU;IACV,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0NF;CACF,CAAC","sourcesContent":["import { css } from 'lit';\n\nimport { boxSizing, dropRegion, validationMessage } from '@qti-components/base';\n\n/**\n * Layout and sizing only. Paint and state live in the theme.\n *\n * What left, and where it went — `styles/qti-theme/interactions/qti-order-interaction.css` and\n * `styles/overrides/kennisnet/qti/order-interaction.scss`:\n *\n * [part~='drop'][active] / [enabled] -> ::part(active) / ::part(enabled)\n * [part~='drop']:has([part='drag']) -> ::part(filled)\n *\n * They had to be rewritten, not relocated: an attribute selector and `:has()` cannot follow\n * `::part()`, so the drop's flags became part tokens (verified in Chromium, see setDropFlag).\n *\n * Two rules were deleted rather than moved, because neither did anything:\n * - `background-color: var(--qti-background-color-active-droplist)` — that property is never\n * defined anywhere in the repo, so the declaration was invalid at computed-value time.\n * - `[part~='drop'][data-cross-slot-target]` — nothing has ever set that attribute.\n */\nexport default [\n boxSizing,\n validationMessage,\n dropRegion,\n css`\n /* The box this element already had. See the note in qti-match-interaction.styles.ts. */\n :host {\n display: block;\n }\n\n [part~='bank'] {\n /* The bank, the same in every drag-drop interaction: flush with the container (no padding, no\n margin, no edge of its own), chips a --qti-gap apart. Its lit and ringed looks while a chip is\n in flight are the theme's ('::part(bank drag-active)', '::part(bank drag-over)'). */\n display: flex;\n flex-wrap: wrap;\n align-items: flex-start;\n flex: 1;\n gap: var(--qti-gap, 0.5rem);\n padding: 0;\n margin: 0;\n border: 0;\n border-radius: var(--qti-radius-box, 0.2rem);\n }\n\n [part='drops'] {\n flex: 1;\n display: grid;\n grid-auto-flow: row;\n /*\n * A column floor and a drop's own min-width are two jobs, and this asks for both by name\n * rather than letting one token mean both. --qti-drop-track-min-width is the policy: a column\n * stays usable however narrow the chips are. --qti-dropzone-min-width is the measurement: a\n * column is never narrower than the chip it holds. max() of the two is what the grid wants,\n * and the 0px fallback is what makes this correct for an interaction that never measures.\n *\n * One name did both until --qti-drop-min-width was deleted for exactly that (it meant the\n * track floor here and a drop's own min-width in the match target). Folding the track back\n * onto --qti-dropzone-min-width brought the conflation back: a theme setting it to give\n * unmeasured drops a floor also set every column, and a code path that stopped publishing a\n * measured width stopped meaning \"no floor\".\n */\n grid-template-columns: repeat(\n auto-fit,\n minmax(max(var(--qti-drop-track-min-width, 120px), var(--qti-dropzone-min-width, 0px)), 1fr)\n );\n gap: 0.5rem;\n }\n\n :host([orientation='horizontal']) [part~='bank'],\n :host(.qti-orientation-horizontal) [part~='bank'] {\n flex-direction: row;\n }\n /*\n * Horizontal adds nothing to [part='drops']: the base rule above is already the horizontal\n * layout — auto-fit columns that wrap. Only 'vertical' overrides it, to a single column.\n *\n * There used to be a 'grid-auto-flow: column' here, which forced every drop onto one\n * non-wrapping line. The theme cancelled it by restating the base rule at\n * qti-order-interaction.css, but only for '[orientation='horizontal']' — so the attribute\n * wrapped and the '.qti-orientation-horizontal' class did not. The theme's rule is gone and so\n * is this one; both spellings now wrap, which is what the attribute already did.\n */\n :host([orientation='vertical']) [part~='bank'],\n :host(.qti-orientation-vertical) [part~='bank'] {\n flex-direction: column;\n }\n :host([orientation='vertical']) [part='drops'],\n :host(.qti-orientation-vertical) [part='drops'] {\n grid-template-columns: 1fr;\n }\n\n /* Drop target. The interaction measures its chips and publishes the result as a custom\n property on its host; the property itself lives here, not in a style attribute. */\n [part~='drop'] {\n display: flex;\n flex: 1;\n min-height: var(--qti-dropzone-min-height, 0);\n\n /*\n * Both axes, not just the height.\n *\n * The width was measured and published all along and then thrown away: the drop is a grid item\n * and stretched to its track, which is 1fr, so a slot in the vertical layout came out 669px\n * wide for a 149px chip. justify-self: start stops the stretch and the measured minimum then\n * decides, so a slot is exactly as wide as the widest chip — the same rule the height has\n * always followed.\n *\n * The grid is untouched: the tracks still lay the slots out and still wrap in the horizontal\n * layout. Only the slot inside the track stops filling it.\n */\n min-width: var(--qti-dropzone-min-width, 0);\n justify-self: start;\n\n /* A chip's drop shadow hangs outside its column. */\n overflow: visible;\n }\n\n [part='drops'] {\n overflow: visible;\n }\n\n /* Once a drop holds a chip it stops stretching to the row and sits at the top of it. */\n :host(:has(qti-simple-choice)) [part~='drop'] {\n align-self: flex-start;\n }\n\n /*\n * The chip a drop renders.\n *\n * 'overflow: visible', not 'hidden'. The theme declared both, in two '::part(drag)' blocks at\n * equal specificity in the same layer, so the later one won and the chip has always been\n * unclipped. The 'text-overflow: ellipsis' still sitting beside the first one has therefore\n * never done anything; it is left in the theme rather than deleted here, since removing it is a\n * decision about how a long label should behave, not a relocation.\n */\n [part~='chip'] {\n display: flex;\n align-items: center;\n overflow: visible;\n }\n\n [part='container'] {\n display: grid;\n grid-template-areas:\n 'drags drops'\n 'message message';\n grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);\n align-items: start;\n gap: 0.5rem;\n }\n\n slot[part~='drags'] {\n grid-area: drags;\n }\n\n [part='drops'] {\n grid-area: drops;\n }\n\n [part='message'] {\n grid-area: message;\n width: 100%;\n justify-self: start;\n }\n\n /*\n * The PLATFORM DEFAULT for container positioning, when the orientation is horizontal.\n *\n * Read that carefully, because the two things are separate axes in QTI 3 and this rule does not\n * merge them. Vocabulary §1.2.9.3 defines qti-choices-* as where the choices container sits\n * relative to the order-target container; orientation is how items flow WITHIN a container.\n * They compose: §1.2.9.2 Figure 73 is orientation=\"vertical\" class=\"qti-choices-left\" and\n * renders two COLUMNS SIDE BY SIDE — vertical does not stack the containers, and horizontal does\n * not imply that it should.\n *\n * What makes this rule legitimate is that §1.2.9.3 declines to specify the positioning at all\n * when no class is given: \"In the absence of choices | order target container positioning,\n * delivery systems should render platform defaults.\" That default is ours, and for a horizontal\n * flow the useful one is stacked, because a row needs the width. An author who wants something\n * else says so with qti-choices-*, which is exactly what the spec provides it for — and those\n * rules below still win (see the source-order note).\n *\n * Side by side used to work here anyway, but only because a slot could be narrower\n * than the chip standing in it: the theme gave a placed chip width: 100%, so a 218px chip was\n * squeezed into a 184px track and three of them fitted in half the width. That squeeze is gone\n * (DROP-SIZING.md §5), and without it \"van links naar rechts\" collapsed to a single column,\n * because 384px cannot hold two 218px chips.\n *\n * Measured on ITEM013: side by side gives the slots 384px and one 384px track; stacked gives them\n * 800px and three 256px tracks, each wider than the chip. Vertical is untouched — one column is\n * what it wants, and the split suits it.\n *\n * Deliberately BEFORE the qti-choices-* rules below, not after. Those tie on specificity, so\n * source order decides: an author who writes qti-choices-left still gets it, and this is only the\n * default for an orientation that has no such class.\n */\n :host([orientation='horizontal']) [part='container'],\n :host(.qti-orientation-horizontal) [part='container'] {\n grid-template-areas:\n 'drags'\n 'drops'\n 'message';\n grid-template-columns: minmax(0, 1fr);\n }\n\n :host(.qti-choices-top) [part='container'] {\n grid-template-areas:\n 'drags'\n 'drops'\n 'message';\n grid-template-columns: minmax(0, 1fr);\n }\n\n :host(.qti-choices-bottom) [part='container'] {\n grid-template-areas:\n 'drops'\n 'drags'\n 'message';\n grid-template-columns: minmax(0, 1fr);\n }\n\n :host(.qti-choices-left) [part='container'] {\n grid-template-areas:\n 'drags drops'\n 'message message';\n grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);\n }\n\n :host(.qti-choices-right) [part='container'] {\n grid-template-areas:\n 'drops drags'\n 'message message';\n grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);\n }\n\n /* An answer key shows the answer, not the bank you would have dragged it from. The attribute is\n set on the clone by the correct-response mixin; the theme used to do this with a\n '.full-correct-response' descendant selector, from the document. */\n :host([answer-key]) [part~='drags'] {\n display: none;\n }\n `\n];\n"]}
|
package/package.json
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@qti-components/order-interaction",
|
|
3
3
|
"description": "QTI order-interaction interaction",
|
|
4
|
-
"version": "
|
|
4
|
+
"version": "3.0.0-next.5",
|
|
5
5
|
"author": "",
|
|
6
6
|
"dependencies": {
|
|
7
|
-
"@qti-components/base": "^3.0.0-next.
|
|
8
|
-
"@qti-components/interactions-core": "^
|
|
7
|
+
"@qti-components/base": "^3.0.0-next.6",
|
|
8
|
+
"@qti-components/interactions-core": "^3.0.0-next.7",
|
|
9
9
|
"@qti-components/utilities": "^1.3.3"
|
|
10
10
|
},
|
|
11
11
|
"devDependencies": {
|