@intellectif/lk-react 2.0.0 → 2.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 (47) hide show
  1. package/dist/{chunk-32WWQOG3.js → chunk-3X7MYAFT.js} +99 -26
  2. package/dist/chunk-3X7MYAFT.js.map +1 -0
  3. package/dist/{chunk-KJNQLAB5.cjs → chunk-7BT6OXAR.cjs} +84 -17
  4. package/dist/chunk-7BT6OXAR.cjs.map +1 -0
  5. package/dist/{chunk-SH7BRP4M.cjs → chunk-STLRKR2I.cjs} +5 -5
  6. package/dist/{chunk-SH7BRP4M.cjs.map → chunk-STLRKR2I.cjs.map} +1 -1
  7. package/dist/{chunk-OS7MO2OW.js → chunk-UASXUWHH.js} +4 -4
  8. package/dist/{chunk-OS7MO2OW.js.map → chunk-UASXUWHH.js.map} +1 -1
  9. package/dist/{chunk-73XCWYKD.cjs → chunk-UXO6KYSZ.cjs} +97 -24
  10. package/dist/chunk-UXO6KYSZ.cjs.map +1 -0
  11. package/dist/{chunk-MKH5THDR.cjs → chunk-W6BH2YMZ.cjs} +119 -36
  12. package/dist/chunk-W6BH2YMZ.cjs.map +1 -0
  13. package/dist/{chunk-V5EN3ESV.js → chunk-XTJ22JAP.js} +85 -18
  14. package/dist/chunk-XTJ22JAP.js.map +1 -0
  15. package/dist/{chunk-G5ZEWJRA.js → chunk-ZVFWJTT4.js} +119 -36
  16. package/dist/chunk-ZVFWJTT4.js.map +1 -0
  17. package/dist/components/ActivitySequence.cjs +4 -4
  18. package/dist/components/ActivitySequence.js +3 -3
  19. package/dist/components/FillInTheBlanks.cjs +2 -2
  20. package/dist/components/FillInTheBlanks.d.cts +7 -1
  21. package/dist/components/FillInTheBlanks.d.ts +7 -1
  22. package/dist/components/FillInTheBlanks.js +1 -1
  23. package/dist/components/MultipleChoice.cjs +2 -2
  24. package/dist/components/MultipleChoice.d.cts +14 -3
  25. package/dist/components/MultipleChoice.d.ts +14 -3
  26. package/dist/components/MultipleChoice.js +1 -1
  27. package/dist/components/WrittenResponse.cjs +2 -2
  28. package/dist/components/WrittenResponse.d.cts +53 -5
  29. package/dist/components/WrittenResponse.d.ts +53 -5
  30. package/dist/components/WrittenResponse.js +1 -1
  31. package/dist/index.cjs +13 -9
  32. package/dist/index.cjs.map +1 -1
  33. package/dist/index.d.cts +2 -2
  34. package/dist/index.d.ts +2 -2
  35. package/dist/index.js +11 -4
  36. package/dist/index.js.map +1 -1
  37. package/dist/types-CNmjqD6M.d.cts +108 -0
  38. package/dist/types-CNmjqD6M.d.ts +108 -0
  39. package/package.json +3 -3
  40. package/dist/chunk-32WWQOG3.js.map +0 -1
  41. package/dist/chunk-73XCWYKD.cjs.map +0 -1
  42. package/dist/chunk-G5ZEWJRA.js.map +0 -1
  43. package/dist/chunk-KJNQLAB5.cjs.map +0 -1
  44. package/dist/chunk-MKH5THDR.cjs.map +0 -1
  45. package/dist/chunk-V5EN3ESV.js.map +0 -1
  46. package/dist/types-iknDq5tf.d.cts +0 -17
  47. package/dist/types-iknDq5tf.d.ts +0 -17
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/components/WrittenResponse/WrittenResponse.tsx","../src/components/WrittenResponse/index.tsx"],"names":["WrittenResponse","jsx"],"mappings":"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","file":"chunk-V5EN3ESV.js","sourcesContent":["'use client';\n\nimport {\n ActivitySchemaError,\n countWords,\n evaluate,\n type InteractionEvent,\n type ThemeTokens,\n validateActivity,\n type WrittenResponseData,\n type XAPIStatement,\n xAPIBuilder,\n} from '@intellectif/lk-core';\nimport { type CSSProperties, useEffect, useMemo, useState } from 'react';\nimport { useActivityState } from '../../hooks/useActivityState.js';\nimport { ANONYMOUS_ACTOR, isDevelopment, objectIdFor } from '../_internal.js';\nimport { ActivityMedia } from '../shared/ActivityMedia.js';\nimport { FeedbackRegion } from '../shared/FeedbackRegion.js';\n\n/**\n * Payload delivered when the learner submits a written response. Grading is\n * DEFERRED (asynchronous AI/human grading), so there is no score here — and\n * deliberately no fake one: an ungraded submission must never be shown or\n * stored as a 0. The consumer persists `text` and grades it out-of-band.\n */\nexport interface WrittenResponseSubmission {\n /** The submitted text, verbatim. */\n text: string;\n /** Word count of `text`, recomputed with the canonical `countWords()`. */\n wordCount: number;\n /** Whether `wordCount` falls within the activity's `[minWords, maxWords]`. */\n withinWordBounds: boolean;\n /** Time in milliseconds from first interaction to submission. */\n timeSpent: number;\n /** The SUBMITTED-verb xAPI statement built for this submission (no score fields). */\n xapiStatement: XAPIStatement;\n}\n\n/**\n * Props for {@link WrittenResponse}. Mirrors `ActivityProps` except for the\n * completion callback: a deferred-grading activity completes with a\n * {@link WrittenResponseSubmission} (`onSubmitted`), not a scored\n * `ActivityResult` (`onComplete`) — deviation from Req 22.8 recorded in the\n * roadmap (§3.1): fabricating a score of 0 for ungraded work is the exact\n * bug this type exists to fix.\n */\nexport interface WrittenResponseProps {\n data: WrittenResponseData;\n onSubmitted: (submission: WrittenResponseSubmission) => void;\n onInteraction?: (event: InteractionEvent) => void;\n /** Per-instance token overrides, applied as inline CSS vars on the root. */\n theme?: Partial<ThemeTokens>;\n locale?: string;\n disabled?: boolean;\n}\n\nexport function WrittenResponse({\n data,\n onSubmitted,\n onInteraction,\n theme,\n locale,\n disabled,\n}: WrittenResponseProps) {\n // Dev-only boundary validation (Req 2.3), same convention as MC/FIB.\n const devError = useMemo(() => {\n if (!isDevelopment()) {\n return null;\n }\n const result = validateActivity('written-response', data);\n return result.success ? null : new ActivitySchemaError('written-response', result.errors);\n }, [data]);\n\n const { state, start, complete, getTimeSpent, reset } = useActivityState();\n const [text, setText] = useState('');\n const [summary, setSummary] = useState<string | null>(null);\n\n // Reset on data-prop change (Req 3.7).\n // biome-ignore lint/correctness/useExhaustiveDependencies: data is the reset trigger (Req 3.7)\n useEffect(() => {\n setText('');\n setSummary(null);\n reset();\n }, [data, reset]);\n\n if (devError) {\n throw devError;\n }\n\n const submitted = state === 'completed';\n const inactive = disabled === true || submitted;\n const wordCount = countWords(text);\n const withinBounds = wordCount >= data.minWords && wordCount <= data.maxWords;\n\n const handleChange = (value: string): void => {\n if (inactive) {\n return;\n }\n if (state === 'idle') {\n start();\n }\n setText(value);\n onInteraction?.({\n type: 'text-changed',\n activityId: data.id,\n timestamp: Date.now(),\n payload: { wordCount: countWords(value) },\n });\n };\n\n const handleSubmit = (event: React.FormEvent): void => {\n event.preventDefault();\n if (inactive || text.trim().length === 0) {\n return;\n }\n const outcome = evaluate(data, { type: 'written-response', text, wordCount });\n complete();\n const timeSpent = getTimeSpent();\n const partial = outcome.status === 'deferred' ? outcome.partial : undefined;\n const finalWordCount = typeof partial?.wordCount === 'number' ? partial.wordCount : wordCount;\n const finalWithinBounds =\n typeof partial?.withinWordBounds === 'boolean' ? partial.withinWordBounds : withinBounds;\n const xapiStatement = xAPIBuilder.buildSubmittedStatement({\n actor: ANONYMOUS_ACTOR,\n object: {\n id: objectIdFor(data.id),\n name: { [data.locale ?? 'en-US']: data.title },\n type: 'http://adlnet.gov/expapi/activities/cmi.interaction',\n interactionType: 'long-fill-in',\n },\n timeSpentMs: timeSpent,\n response: text,\n resultExtensions: {\n 'urn:learning-kit:extension:word-count': finalWordCount,\n 'urn:learning-kit:extension:within-word-bounds': finalWithinBounds,\n },\n });\n onSubmitted({\n text,\n wordCount: finalWordCount,\n withinWordBounds: finalWithinBounds,\n timeSpent,\n xapiStatement,\n });\n setSummary('Response submitted. It will be graded and your result will appear here later.');\n onInteraction?.({\n type: 'submitted',\n activityId: data.id,\n timestamp: Date.now(),\n payload: { wordCount: finalWordCount, withinWordBounds: finalWithinBounds },\n });\n };\n\n const promptId = `${data.id}-prompt`;\n const counterId = `${data.id}-counter`;\n const boundsLabel =\n data.minWords > 0 ? `${data.minWords}–${data.maxWords} words` : `up to ${data.maxWords} words`;\n\n return (\n <form\n className=\"lk-wr\"\n aria-label={data.title}\n lang={locale}\n style={theme as CSSProperties | undefined}\n onSubmit={handleSubmit}\n >\n {data.media ? <ActivityMedia media={data.media} /> : null}\n <p className=\"lk-wr-prompt\" id={promptId}>\n {data.prompt}\n </p>\n <textarea\n className=\"lk-wr-textarea\"\n aria-labelledby={promptId}\n aria-describedby={counterId}\n value={text}\n onChange={(event) => handleChange(event.target.value)}\n disabled={inactive}\n rows={8}\n />\n <div\n className=\"lk-wr-counter\"\n id={counterId}\n aria-live=\"polite\"\n data-within-bounds={withinBounds}\n >\n {wordCount} {wordCount === 1 ? 'word' : 'words'} ({boundsLabel})\n </div>\n <button\n type=\"submit\"\n className=\"lk-wr-submit\"\n disabled={inactive || text.trim().length === 0}\n >\n Submit\n </button>\n <FeedbackRegion id={`${data.id}-feedback`}>{summary}</FeedbackRegion>\n </form>\n );\n}\n","'use client';\n\nimport { ActivityErrorBoundary } from '../ActivityErrorBoundary.js';\nimport {\n WrittenResponse as WrittenResponseCore,\n type WrittenResponseProps,\n} from './WrittenResponse.js';\n\nexport type { WrittenResponseProps, WrittenResponseSubmission } from './WrittenResponse.js';\n\n/**\n * Public Written Response activity: a labelled textarea with a live word\n * counter for free-text writing graded asynchronously (AI or human). The core\n * is wrapped in `ActivityErrorBoundary` so a render failure (incl. the dev\n * schema-validation throw) degrades to an accessible fallback.\n */\nexport function WrittenResponse(props: WrittenResponseProps) {\n return (\n <ActivityErrorBoundary activityTitle={props.data?.title}>\n <WrittenResponseCore {...props} />\n </ActivityErrorBoundary>\n );\n}\n"]}
@@ -1,17 +0,0 @@
1
- import { ActivityData, ActivityResult, InteractionEvent, ThemeTokens } from '@intellectif/lk-core';
2
-
3
- /**
4
- * The consistent prop contract shared by every activity component (Req 3.1).
5
- * Defined here (React-specific) rather than in lk-core, which is React-free.
6
- */
7
- interface ActivityProps<TData extends ActivityData = ActivityData> {
8
- data: TData;
9
- onComplete: (result: ActivityResult) => void;
10
- onInteraction?: (event: InteractionEvent) => void;
11
- /** Per-instance token overrides, applied as inline CSS vars on the root. */
12
- theme?: Partial<ThemeTokens>;
13
- locale?: string;
14
- disabled?: boolean;
15
- }
16
-
17
- export type { ActivityProps as A };
@@ -1,17 +0,0 @@
1
- import { ActivityData, ActivityResult, InteractionEvent, ThemeTokens } from '@intellectif/lk-core';
2
-
3
- /**
4
- * The consistent prop contract shared by every activity component (Req 3.1).
5
- * Defined here (React-specific) rather than in lk-core, which is React-free.
6
- */
7
- interface ActivityProps<TData extends ActivityData = ActivityData> {
8
- data: TData;
9
- onComplete: (result: ActivityResult) => void;
10
- onInteraction?: (event: InteractionEvent) => void;
11
- /** Per-instance token overrides, applied as inline CSS vars on the root. */
12
- theme?: Partial<ThemeTokens>;
13
- locale?: string;
14
- disabled?: boolean;
15
- }
16
-
17
- export type { ActivityProps as A };