@stina/extension-api 1.7.0 → 1.9.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.
@@ -30,6 +30,30 @@ describe('validateChatCard', () => {
30
30
  expect(result.ok).toBe(true)
31
31
  })
32
32
 
33
+ it('accepts a quotation with its attribution', () => {
34
+ const result = validateChatCard({
35
+ component: 'Quote',
36
+ text: 'Fyll gärna i del två i mallen innan vi ses.',
37
+ source: 'Maria Lind',
38
+ context: 'i morse 07:42',
39
+ footer: 'Ur mejlet om medarbetarsamtalet',
40
+ })
41
+
42
+ expect(result.ok).toBe(true)
43
+ })
44
+
45
+ it('rejects markup properties on a quotation', () => {
46
+ // Quoted text is printed as it arrived. A property that implied formatting
47
+ // would let someone else's words be dressed up as Stina's own.
48
+ const result = validateChatCard({
49
+ component: 'Quote',
50
+ text: 'Fyll gärna i del två.',
51
+ variant: 'accent',
52
+ })
53
+
54
+ expect(result.ok).toBe(false)
55
+ })
56
+
33
57
  it('accepts an icon beside every heading that has one', () => {
34
58
  for (const card of [
35
59
  { component: 'Chart', icon: 'temperature', series: [{ points: [1] }] },
@@ -333,6 +333,17 @@ const NoteCardSchema = z
333
333
  })
334
334
  .strict()
335
335
 
336
+ const QuoteCardSchema = z
337
+ .object({
338
+ component: z.literal('Quote'),
339
+ text: z.string(),
340
+ source: z.string().optional(),
341
+ context: z.string().optional(),
342
+ footer: z.string().optional(),
343
+ style,
344
+ })
345
+ .strict()
346
+
336
347
  const CalendarEventCardSchema = z
337
348
  .object({
338
349
  component: z.literal('CalendarEvent'),
@@ -373,6 +384,7 @@ export const CHAT_CARD_COMPONENTS = [
373
384
  'KeyValueList',
374
385
  'Timeline',
375
386
  'Note',
387
+ 'Quote',
376
388
  'CalendarEvent',
377
389
  ] as const
378
390
 
@@ -406,6 +418,7 @@ const CARD_MEMBERS = [
406
418
  KeyValueListCardSchema,
407
419
  TimelineCardSchema,
408
420
  NoteCardSchema,
421
+ QuoteCardSchema,
409
422
  CalendarEventCardSchema,
410
423
  ] as const
411
424
 
@@ -886,6 +886,33 @@ export interface NoteProps extends ExtensionComponentData {
886
886
  variant?: NoteVariant
887
887
  }
888
888
 
889
+ /**
890
+ * The extension API properties for the Quote component.
891
+ *
892
+ * Someone else's words, set apart and attributed. For the sentence out of a mail
893
+ * that actually answers the question, the line from a document worth reading as
894
+ * written, the message a colleague sent.
895
+ *
896
+ * The text is rendered as written and never as markdown, which is the whole
897
+ * point of it existing beside `Note`: a link or a heading inside quoted text
898
+ * would be formatted as though Stina had put it there. `Note` is for the user's
899
+ * own writing and for hers; this is for everyone else's.
900
+ *
901
+ * Quote what bears quoting, not the whole message. A card is a thing to glance
902
+ * at, and a page of pasted mail is a page nobody reads.
903
+ */
904
+ export interface QuoteProps extends ExtensionComponentData {
905
+ component: 'Quote'
906
+ /** The words themselves, verbatim. Rendered as written, never as markdown. */
907
+ text: string
908
+ /** Who wrote or said it, as they are known: a name, an address, a title. */
909
+ source?: string
910
+ /** When or where it came from: `i morse 07:42`, `i mötesanteckningarna`. */
911
+ context?: string
912
+ /** One quiet line under the quotation, for what is worth adding about it. */
913
+ footer?: string
914
+ }
915
+
889
916
  /** Whether an event is going ahead. */
890
917
  export type CalendarEventStatus = 'confirmed' | 'tentative' | 'cancelled'
891
918