@webwriter/quiz 1.0.5 → 1.0.6

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