@webwriter/quiz 1.0.10 → 1.1.1

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 (103) hide show
  1. package/LICENSE +6 -6
  2. package/custom.d.ts +175 -175
  3. package/dist/widgets/webwriter-choice-item.js +10 -7
  4. package/dist/widgets/webwriter-choice.js +39 -6
  5. package/dist/widgets/webwriter-order-item.js +14 -11
  6. package/dist/widgets/webwriter-order.js +30 -4
  7. package/dist/widgets/webwriter-quiz.js +2 -1
  8. package/dist/widgets/webwriter-text.js +26 -9
  9. package/lit-localize.json +14 -14
  10. package/localization/bg.xlf +69 -69
  11. package/localization/cs.xlf +69 -69
  12. package/localization/da.xlf +69 -69
  13. package/localization/de.xlf +74 -74
  14. package/localization/el.xlf +69 -69
  15. package/localization/es.xlf +69 -69
  16. package/localization/et.xlf +69 -69
  17. package/localization/fi.xlf +69 -69
  18. package/localization/fr.xlf +69 -69
  19. package/localization/generated/bg.ts +29 -29
  20. package/localization/generated/cs.ts +29 -29
  21. package/localization/generated/da.ts +29 -29
  22. package/localization/generated/de.ts +29 -29
  23. package/localization/generated/el.ts +29 -29
  24. package/localization/generated/es.ts +29 -29
  25. package/localization/generated/et.ts +29 -29
  26. package/localization/generated/fi.ts +29 -29
  27. package/localization/generated/fr.ts +29 -29
  28. package/localization/generated/hu.ts +29 -29
  29. package/localization/generated/id.ts +29 -29
  30. package/localization/generated/index.js +2 -2
  31. package/localization/generated/it.ts +29 -29
  32. package/localization/generated/ja.ts +29 -29
  33. package/localization/generated/ko.ts +29 -29
  34. package/localization/generated/locale-codes.js +79 -79
  35. package/localization/generated/lt.ts +29 -29
  36. package/localization/generated/lv.ts +29 -29
  37. package/localization/generated/nb.ts +29 -29
  38. package/localization/generated/nl.ts +29 -29
  39. package/localization/generated/pl.ts +29 -29
  40. package/localization/generated/pt-BR.ts +29 -29
  41. package/localization/generated/pt-PT.ts +29 -29
  42. package/localization/generated/ro.ts +29 -29
  43. package/localization/generated/ru.ts +29 -29
  44. package/localization/generated/sk.ts +29 -29
  45. package/localization/generated/sl.ts +29 -29
  46. package/localization/generated/sv.ts +29 -29
  47. package/localization/generated/tr.ts +29 -29
  48. package/localization/generated/uk.ts +29 -29
  49. package/localization/generated/zh-hans.ts +29 -29
  50. package/localization/hu.xlf +69 -69
  51. package/localization/id.xlf +69 -69
  52. package/localization/it.xlf +69 -69
  53. package/localization/ja.xlf +69 -69
  54. package/localization/ko.xlf +69 -69
  55. package/localization/lt.xlf +69 -69
  56. package/localization/lv.xlf +69 -69
  57. package/localization/nb.xlf +69 -69
  58. package/localization/nl.xlf +69 -69
  59. package/localization/pl.xlf +69 -69
  60. package/localization/pt-BR.xlf +69 -69
  61. package/localization/pt-PT.xlf +69 -69
  62. package/localization/ro.xlf +69 -69
  63. package/localization/ru.xlf +69 -69
  64. package/localization/sk.xlf +69 -69
  65. package/localization/sl.xlf +69 -69
  66. package/localization/sv.xlf +69 -69
  67. package/localization/tr.xlf +69 -69
  68. package/localization/uk.xlf +69 -69
  69. package/localization/zh-hans.xlf +69 -69
  70. package/package.json +7 -2
  71. package/src/lib/combobox.ts +455 -455
  72. package/src/lib/highlighter-fill.svg +5 -5
  73. package/src/snippets/Beispiel-Choice.html +57 -57
  74. package/src/snippets/Beispiel-Mark.html +13 -13
  75. package/src/snippets/Beispiel-Order.html +52 -52
  76. package/src/snippets/Beispiel-Text.html +20 -20
  77. package/src/snippets/blank.html +1 -0
  78. package/src/snippets/choice.html +7 -7
  79. package/src/snippets/cloze.html +3 -3
  80. package/src/snippets/mark.html +3 -3
  81. package/src/snippets/order.html +7 -7
  82. package/src/snippets/pairing.html +9 -9
  83. package/src/snippets/speech.html +3 -3
  84. package/src/snippets/text.html +3 -3
  85. package/src/snippets/wordsearch.html +3 -3
  86. package/src/widgets/webwriter-choice-item.ts +253 -250
  87. package/src/widgets/webwriter-choice.ts +339 -314
  88. package/src/widgets/webwriter-cloze-gap.ts +215 -215
  89. package/src/widgets/webwriter-cloze.ts +135 -135
  90. package/src/widgets/webwriter-mark.ts +431 -431
  91. package/src/widgets/webwriter-order-item.ts +440 -437
  92. package/src/widgets/webwriter-order.ts +311 -284
  93. package/src/widgets/webwriter-pairing-item.ts +160 -160
  94. package/src/widgets/webwriter-pairing.ts +192 -192
  95. package/src/widgets/webwriter-quiz.ts +282 -281
  96. package/src/widgets/webwriter-speech.ts +272 -272
  97. package/src/widgets/webwriter-task-explainer.ts +42 -42
  98. package/src/widgets/webwriter-task-hint.ts +22 -22
  99. package/src/widgets/webwriter-task-prompt.ts +23 -23
  100. package/src/widgets/webwriter-task.ts +546 -546
  101. package/src/widgets/webwriter-text.ts +155 -135
  102. package/tsconfig.json +6 -6
  103. package/.env +0 -1
@@ -1,216 +1,216 @@
1
- import {LitElement, html, css, RenderOptions} from "lit"
2
- import {LitElementWw} from "@webwriter/lit"
3
- import {customElement, query} from "lit/decorators.js"
4
-
5
- import SlIconButton from "@shoelace-style/shoelace/dist/components/icon-button/icon-button.component.js"
6
- import SlOption from "@shoelace-style/shoelace/dist/components/option/option.component.js"
7
- import IconPlus from "bootstrap-icons/icons/plus.svg"
8
- import IconSlashCircle from "bootstrap-icons/icons/slash-circle.svg"
9
- import IconCheckCircle from "bootstrap-icons/icons/check-circle.svg"
10
- import IconX from "bootstrap-icons/icons/x.svg"
11
-
12
- import { Combobox } from "../lib/combobox"
13
- import { property } from "lit/decorators/property.js"
14
- import { queryAsync } from "lit/decorators/query-async.js"
15
- import "@shoelace-style/shoelace/dist/themes/light.css"
16
-
17
- import LOCALIZE from "../../localization/generated"
18
- import {msg} from "@lit/localize"
19
-
20
- declare global {interface HTMLElementTagNameMap {
21
- "webwriter-cloze-gap": WebwriterClozeGap;
22
- }}
23
-
24
- @customElement("webwriter-cloze-gap")
25
- export class WebwriterClozeGap extends LitElementWw {
26
-
27
- localize = LOCALIZE
28
-
29
- @property({type: Array, attribute: true, reflect: true})
30
- accessor solution: string[]
31
-
32
- @property({type: String, attribute: true, reflect: true})
33
- accessor value: string
34
-
35
- @property({type: Array, attribute: true, reflect: true})
36
- accessor distraction: string[] = []
37
-
38
- @property({type: Boolean, attribute: true, reflect: true})
39
- accessor showOptions = false
40
-
41
- static scopedElements = {
42
- "ww-combobox": Combobox,
43
- "sl-icon-button": SlIconButton,
44
- "sl-option": SlOption
45
- }
46
-
47
- static styles = css`
48
- :host {
49
- display: inline-block !important;
50
- vertical-align: top;
51
- margin: 0 1ch;
52
- max-width: calc(100% - 2ch);
53
- max-height: 1lh;
54
- }
55
-
56
- :host(::after) {
57
- content: " ";
58
- display: block;
59
- }
60
-
61
- sl-icon-button[data-hidden] {
62
- visibility: hidden;
63
- }
64
-
65
- sl-icon-button::part(base) {
66
- padding: 0;
67
- }
68
-
69
- :host(:not(:focus-within)) #add {
70
- visibility: hidden;
71
- }
72
-
73
- sl-icon-button {
74
- overflow: visible;
75
- margin-right: 0;
76
- }
77
-
78
- ww-combobox::part(base) {
79
- min-height: unset;
80
- padding: 2px 2px;
81
- }
82
-
83
- :host(:is([contenteditable=true], [contenteditable=""])) ww-combobox::part(input) {
84
- color: var(--sl-color-success-700);
85
- }
86
-
87
- sl-option::part(base) {
88
- padding: 0;
89
- font-size: var(--sl-input-font-size-small);
90
- }
91
-
92
- sl-option::part(label) {
93
- padding: var(--sl-spacing-2x-small) 0;
94
- }
95
-
96
- sl-option::part(label):hover {
97
- color: var(--sl-color-primary-600);
98
- }
99
-
100
- sl-option::part(checked-icon) {
101
- display: none;
102
- }
103
-
104
- .remove::part(base):hover {
105
- color: var(--sl-color-danger-600) !important;
106
- }
107
-
108
- .remove::part(base):active {
109
- color: var(--sl-color-danger-800) !important;
110
- }
111
-
112
- :is(.toggle, .remove)::part(base) {
113
- padding: var(--sl-spacing-2x-small);
114
- }
115
-
116
- .solution::part(base) {
117
- color: var(--sl-color-success-700);
118
- }
119
-
120
- .toggle {
121
- color: inherit;
122
- }
123
-
124
-
125
- `
126
- @query("ww-combobox")
127
- accessor input: Combobox
128
-
129
- async focus() {
130
- (await this.input).focus()
131
- }
132
-
133
- handleChange = (e: CustomEvent) => {
134
- e.preventDefault()
135
- if(!this.isContentEditable) {
136
- this.value = this.input.value as string
137
- }
138
- }
139
-
140
- addSolution(value: string) {
141
- this.solution = Array.from(new Set([...(this.solution ?? []), value]))
142
- }
143
-
144
- toggleOptionType(value: string) {
145
- if(this.solution.includes(value)) {
146
- this.solution = this.solution.filter(v => v !== value)
147
- this.distraction = Array.from(new Set([...(this.distraction ?? []), value]))
148
- }
149
- else if(this.distraction.includes(value)) {
150
- this.distraction = this.distraction.filter(v => v !== value)
151
- this.solution = Array.from(new Set([...(this.solution ?? []), value]))
152
- }
153
- }
154
-
155
- removeOption(value: string) {
156
- this.solution = this.solution.filter(v => v !== value)
157
- this.distraction = this.distraction.filter(v => v !== value)
158
- if(this.allOptions.length === 0) {
159
- this.isAdding = false
160
- }
161
- }
162
-
163
- handleAddClick = (e: MouseEvent) => {
164
- e.stopImmediatePropagation()
165
- e.preventDefault()
166
- this.addSolution(this.input.value as string)
167
- this.isAdding = true
168
- this.input.value = ""
169
- this.input.open = true
170
- }
171
-
172
- handleToggleClick = (e: MouseEvent, value: string) => {
173
- e.stopImmediatePropagation()
174
- e.preventDefault()
175
- this.toggleOptionType(value)
176
- }
177
-
178
- handleRemoveClick = (e: MouseEvent, value: string) => {
179
- e.stopImmediatePropagation()
180
- e.preventDefault()
181
- this.removeOption(value)
182
- }
183
-
184
- handleKeydown = (e: KeyboardEvent) => {
185
- if(e.key === "Enter") {
186
- this.handleAddClick(e as any)
187
- }
188
- }
189
-
190
- handleBlur = (e: FocusEvent) => {
191
- this.isAdding = false
192
- if(this.solution.length === 1) {
193
- this.input.value = this.solution[0]
194
- }
195
- }
196
-
197
- get allOptions() {
198
- return [...(this.solution ?? []), ...this.distraction]
199
- }
200
-
201
- @property({type: Boolean, attribute: false})
202
- accessor isAdding = false
203
-
204
- render() {
205
- return html`<ww-combobox @blur=${this.handleBlur} ?suggestions=${this.allOptions.length > 1 || this.isAdding || this.distraction.length > 0} size="small" autosize .value=${this.value} @sl-change=${this.handleChange} @sl-input=${() => this.requestUpdate()} @keydown=${this.handleKeydown} >
206
- <sl-icon-button id="add" title="Add another solution" ?disabled=${this.allOptions.includes(this.input?.value as string)} ?data-hidden=${!this.input?.value} src=${IconPlus} size="small" slot="prefix" @click=${this.handleAddClick} @mousedown=${(e: Event) => {e.stopPropagation(); e.preventDefault()}} @focus=${e => e.stopPropagation()} ></sl-icon-button>
207
- ${this.allOptions.sort().map(value => html`
208
- <sl-option size="small" value=${value} class=${this.solution.includes(value)? "solution": "distraction"} >
209
- <sl-icon-button title=${this.solution.includes(value)? "Change to a distraction": "Change to a solution"} class="toggle" slot="prefix" src=${this.solution.includes(value)? IconCheckCircle: IconSlashCircle} @click=${(e: any) => this.handleToggleClick(e, value)} @mousedown=${(e: Event) => {e.stopPropagation(); e.preventDefault()}}></sl-icon-button>
210
- <span title=${this.solution.includes(value)? "Solution": "Distraction"}>${value}</span>
211
- <sl-icon-button title="Remove" class="remove" slot="suffix" src=${IconX} @click=${(e: any) => this.handleRemoveClick(e, value)} @mousedown=${(e: Event) => {e.stopPropagation(); e.preventDefault()}}></sl-icon-button>
212
- </sl-option>
213
- `)}
214
- </ww-combobox>`
215
- }
1
+ import {LitElement, html, css, RenderOptions} from "lit"
2
+ import {LitElementWw} from "@webwriter/lit"
3
+ import {customElement, query} from "lit/decorators.js"
4
+
5
+ import SlIconButton from "@shoelace-style/shoelace/dist/components/icon-button/icon-button.component.js"
6
+ import SlOption from "@shoelace-style/shoelace/dist/components/option/option.component.js"
7
+ import IconPlus from "bootstrap-icons/icons/plus.svg"
8
+ import IconSlashCircle from "bootstrap-icons/icons/slash-circle.svg"
9
+ import IconCheckCircle from "bootstrap-icons/icons/check-circle.svg"
10
+ import IconX from "bootstrap-icons/icons/x.svg"
11
+
12
+ import { Combobox } from "../lib/combobox"
13
+ import { property } from "lit/decorators/property.js"
14
+ import { queryAsync } from "lit/decorators/query-async.js"
15
+ import "@shoelace-style/shoelace/dist/themes/light.css"
16
+
17
+ import LOCALIZE from "../../localization/generated"
18
+ import {msg} from "@lit/localize"
19
+
20
+ declare global {interface HTMLElementTagNameMap {
21
+ "webwriter-cloze-gap": WebwriterClozeGap;
22
+ }}
23
+
24
+ @customElement("webwriter-cloze-gap")
25
+ export class WebwriterClozeGap extends LitElementWw {
26
+
27
+ localize = LOCALIZE
28
+
29
+ @property({type: Array, attribute: true, reflect: true})
30
+ accessor solution: string[]
31
+
32
+ @property({type: String, attribute: true, reflect: true})
33
+ accessor value: string
34
+
35
+ @property({type: Array, attribute: true, reflect: true})
36
+ accessor distraction: string[] = []
37
+
38
+ @property({type: Boolean, attribute: true, reflect: true})
39
+ accessor showOptions = false
40
+
41
+ static scopedElements = {
42
+ "ww-combobox": Combobox,
43
+ "sl-icon-button": SlIconButton,
44
+ "sl-option": SlOption
45
+ }
46
+
47
+ static styles = css`
48
+ :host {
49
+ display: inline-block !important;
50
+ vertical-align: top;
51
+ margin: 0 1ch;
52
+ max-width: calc(100% - 2ch);
53
+ max-height: 1lh;
54
+ }
55
+
56
+ :host(::after) {
57
+ content: " ";
58
+ display: block;
59
+ }
60
+
61
+ sl-icon-button[data-hidden] {
62
+ visibility: hidden;
63
+ }
64
+
65
+ sl-icon-button::part(base) {
66
+ padding: 0;
67
+ }
68
+
69
+ :host(:not(:focus-within)) #add {
70
+ visibility: hidden;
71
+ }
72
+
73
+ sl-icon-button {
74
+ overflow: visible;
75
+ margin-right: 0;
76
+ }
77
+
78
+ ww-combobox::part(base) {
79
+ min-height: unset;
80
+ padding: 2px 2px;
81
+ }
82
+
83
+ :host(:is([contenteditable=true], [contenteditable=""])) ww-combobox::part(input) {
84
+ color: var(--sl-color-success-700);
85
+ }
86
+
87
+ sl-option::part(base) {
88
+ padding: 0;
89
+ font-size: var(--sl-input-font-size-small);
90
+ }
91
+
92
+ sl-option::part(label) {
93
+ padding: var(--sl-spacing-2x-small) 0;
94
+ }
95
+
96
+ sl-option::part(label):hover {
97
+ color: var(--sl-color-primary-600);
98
+ }
99
+
100
+ sl-option::part(checked-icon) {
101
+ display: none;
102
+ }
103
+
104
+ .remove::part(base):hover {
105
+ color: var(--sl-color-danger-600) !important;
106
+ }
107
+
108
+ .remove::part(base):active {
109
+ color: var(--sl-color-danger-800) !important;
110
+ }
111
+
112
+ :is(.toggle, .remove)::part(base) {
113
+ padding: var(--sl-spacing-2x-small);
114
+ }
115
+
116
+ .solution::part(base) {
117
+ color: var(--sl-color-success-700);
118
+ }
119
+
120
+ .toggle {
121
+ color: inherit;
122
+ }
123
+
124
+
125
+ `
126
+ @query("ww-combobox")
127
+ accessor input: Combobox
128
+
129
+ async focus() {
130
+ (await this.input).focus()
131
+ }
132
+
133
+ handleChange = (e: CustomEvent) => {
134
+ e.preventDefault()
135
+ if(!this.isContentEditable) {
136
+ this.value = this.input.value as string
137
+ }
138
+ }
139
+
140
+ addSolution(value: string) {
141
+ this.solution = Array.from(new Set([...(this.solution ?? []), value]))
142
+ }
143
+
144
+ toggleOptionType(value: string) {
145
+ if(this.solution.includes(value)) {
146
+ this.solution = this.solution.filter(v => v !== value)
147
+ this.distraction = Array.from(new Set([...(this.distraction ?? []), value]))
148
+ }
149
+ else if(this.distraction.includes(value)) {
150
+ this.distraction = this.distraction.filter(v => v !== value)
151
+ this.solution = Array.from(new Set([...(this.solution ?? []), value]))
152
+ }
153
+ }
154
+
155
+ removeOption(value: string) {
156
+ this.solution = this.solution.filter(v => v !== value)
157
+ this.distraction = this.distraction.filter(v => v !== value)
158
+ if(this.allOptions.length === 0) {
159
+ this.isAdding = false
160
+ }
161
+ }
162
+
163
+ handleAddClick = (e: MouseEvent) => {
164
+ e.stopImmediatePropagation()
165
+ e.preventDefault()
166
+ this.addSolution(this.input.value as string)
167
+ this.isAdding = true
168
+ this.input.value = ""
169
+ this.input.open = true
170
+ }
171
+
172
+ handleToggleClick = (e: MouseEvent, value: string) => {
173
+ e.stopImmediatePropagation()
174
+ e.preventDefault()
175
+ this.toggleOptionType(value)
176
+ }
177
+
178
+ handleRemoveClick = (e: MouseEvent, value: string) => {
179
+ e.stopImmediatePropagation()
180
+ e.preventDefault()
181
+ this.removeOption(value)
182
+ }
183
+
184
+ handleKeydown = (e: KeyboardEvent) => {
185
+ if(e.key === "Enter") {
186
+ this.handleAddClick(e as any)
187
+ }
188
+ }
189
+
190
+ handleBlur = (e: FocusEvent) => {
191
+ this.isAdding = false
192
+ if(this.solution.length === 1) {
193
+ this.input.value = this.solution[0]
194
+ }
195
+ }
196
+
197
+ get allOptions() {
198
+ return [...(this.solution ?? []), ...this.distraction]
199
+ }
200
+
201
+ @property({type: Boolean, attribute: false})
202
+ accessor isAdding = false
203
+
204
+ render() {
205
+ return html`<ww-combobox @blur=${this.handleBlur} ?suggestions=${this.allOptions.length > 1 || this.isAdding || this.distraction.length > 0} size="small" autosize .value=${this.value} @sl-change=${this.handleChange} @sl-input=${() => this.requestUpdate()} @keydown=${this.handleKeydown} >
206
+ <sl-icon-button id="add" title="Add another solution" ?disabled=${this.allOptions.includes(this.input?.value as string)} ?data-hidden=${!this.input?.value} src=${IconPlus} size="small" slot="prefix" @click=${this.handleAddClick} @mousedown=${(e: Event) => {e.stopPropagation(); e.preventDefault()}} @focus=${e => e.stopPropagation()} ></sl-icon-button>
207
+ ${this.allOptions.sort().map(value => html`
208
+ <sl-option size="small" value=${value} class=${this.solution.includes(value)? "solution": "distraction"} >
209
+ <sl-icon-button title=${this.solution.includes(value)? "Change to a distraction": "Change to a solution"} class="toggle" slot="prefix" src=${this.solution.includes(value)? IconCheckCircle: IconSlashCircle} @click=${(e: any) => this.handleToggleClick(e, value)} @mousedown=${(e: Event) => {e.stopPropagation(); e.preventDefault()}}></sl-icon-button>
210
+ <span title=${this.solution.includes(value)? "Solution": "Distraction"}>${value}</span>
211
+ <sl-icon-button title="Remove" class="remove" slot="suffix" src=${IconX} @click=${(e: any) => this.handleRemoveClick(e, value)} @mousedown=${(e: Event) => {e.stopPropagation(); e.preventDefault()}}></sl-icon-button>
212
+ </sl-option>
213
+ `)}
214
+ </ww-combobox>`
215
+ }
216
216
  }