@remit/ui 0.0.158 → 0.0.159

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@remit/ui",
3
- "version": "0.0.158",
3
+ "version": "0.0.159",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "src"
@@ -136,6 +136,7 @@ export function AgendaComposer({
136
136
  onCancel={onCancel}
137
137
  saveLabel={saveLabel}
138
138
  repeatEditable={repeatEditable}
139
+ guestsEditable
139
140
  onCustomRepeat={onCustomRepeat}
140
141
  touch={touch}
141
142
  header={
@@ -78,11 +78,27 @@ describe("EventEditor", () => {
78
78
  it("reveals the rest on request", () => {
79
79
  const html = render({ expanded: true });
80
80
  assert.match(html, /aria-label="Location"/);
81
- assert.match(html, /aria-label="Guests"/);
82
81
  assert.match(html, /aria-label="Repeat"/);
83
82
  assert.match(html, /Fewer details/);
84
83
  });
85
84
 
85
+ it("takes no guests until a surface says it can store them", () => {
86
+ assert.doesNotMatch(render({ expanded: true }), /aria-label="Guests"/);
87
+ assert.match(
88
+ render({ expanded: true, guestsEditable: true }),
89
+ /aria-label="Guests"/,
90
+ );
91
+ });
92
+
93
+ it("drops the calendar picker where the event cannot be moved", () => {
94
+ assert.match(render({}), /Northwind/);
95
+ assert.doesNotMatch(render({ calendarEditable: false }), /Northwind/);
96
+ assert.doesNotMatch(
97
+ render({ expanded: true, calendarEditable: false }),
98
+ /Northwind/,
99
+ );
100
+ });
101
+
86
102
  it("drops the clock fields for an all-day entry", () => {
87
103
  const html = render({ draft: { ...draft, allDay: true } });
88
104
  assert.doesNotMatch(html, /aria-label="Start time"/);
@@ -64,9 +64,13 @@ const backwards: EventDraft = {
64
64
  function Live({
65
65
  startExpanded,
66
66
  seed: initial = seed,
67
+ guestsEditable,
68
+ calendarEditable,
67
69
  }: {
68
70
  startExpanded: boolean;
69
71
  seed?: EventDraft;
72
+ guestsEditable?: boolean;
73
+ calendarEditable?: boolean;
70
74
  }) {
71
75
  const [draft, setDraft] = useState(initial);
72
76
  const [expanded, setExpanded] = useState(startExpanded);
@@ -78,6 +82,8 @@ function Live({
78
82
  calendars={calendars}
79
83
  expanded={expanded}
80
84
  onToggleExpanded={() => setExpanded((open) => !open)}
85
+ guestsEditable={guestsEditable}
86
+ calendarEditable={calendarEditable}
81
87
  onSave={() => {}}
82
88
  onCancel={() => {}}
83
89
  />
@@ -99,6 +105,24 @@ export const EndBeforeStart: Story = {
99
105
  render: () => <Live startExpanded={false} seed={backwards} />,
100
106
  };
101
107
 
108
+ /**
109
+ * Guests are opt-in. A store with nowhere to put them leaves the field out, so
110
+ * the default form has none: a box that takes names and drops them is worse
111
+ * than no box, because the reader only finds out later.
112
+ */
113
+ export const WithGuests: Story = {
114
+ render: () => <Live startExpanded guestsEditable />,
115
+ };
116
+
117
+ /**
118
+ * Editing an event that already exists. The collection a resource lives in is
119
+ * part of its address, so the calendar is read-only here rather than a picker
120
+ * that changes nothing.
121
+ */
122
+ export const WithoutTheCalendarPicker: Story = {
123
+ render: () => <Live startExpanded calendarEditable={false} />,
124
+ };
125
+
102
126
  /** All day takes the clock fields away, so there is no range left to reject. */
103
127
  export const AllDay: Story = {
104
128
  render: () => (
@@ -276,6 +276,18 @@ export interface EventEditorProps {
276
276
  * a single instance reads the rule back instead of offering to change it.
277
277
  */
278
278
  repeatEditable?: boolean;
279
+ /**
280
+ * Whether guests can be written here. Off unless a surface says otherwise: a
281
+ * box that takes names and drops them is worse than no box, because the
282
+ * reader only finds out later, from an event with nobody on it.
283
+ */
284
+ guestsEditable?: boolean;
285
+ /**
286
+ * Whether the event can be moved to another calendar. An edit cannot: the
287
+ * collection a resource lives in is part of its address, so a picker that
288
+ * changes it and saves nothing is a control that lies.
289
+ */
290
+ calendarEditable?: boolean;
279
291
  /** Opens the custom-rule editor. Absent leaves the derived choices alone. */
280
292
  onCustomRepeat?: () => void;
281
293
  /** Grows the controls for a rail. */
@@ -302,6 +314,8 @@ export function EventEditor({
302
314
  saveLabel = "Add",
303
315
  header,
304
316
  repeatEditable = true,
317
+ guestsEditable = false,
318
+ calendarEditable = true,
305
319
  onCustomRepeat,
306
320
  touch,
307
321
  className,
@@ -363,10 +377,12 @@ export function EventEditor({
363
377
  {header}
364
378
  <EventField label="Title">{title}</EventField>
365
379
  <EventField label="When">{when}</EventField>
366
- <EventField label="Calendar">{calendarPicker}</EventField>
380
+ {calendarEditable && (
381
+ <EventField label="Calendar">{calendarPicker}</EventField>
382
+ )}
367
383
  <EventField label="Repeat">{repeat}</EventField>
368
384
  <EventField label="Location">{location}</EventField>
369
- <EventField label="Guests">{guests}</EventField>
385
+ {guestsEditable && <EventField label="Guests">{guests}</EventField>}
370
386
  <EventField label="Notes">{notes}</EventField>
371
387
  {actions}
372
388
  </div>
@@ -381,7 +397,7 @@ export function EventEditor({
381
397
 
382
398
  {title}
383
399
  {when}
384
- {calendarPicker}
400
+ {calendarEditable && calendarPicker}
385
401
 
386
402
  {onToggleExpanded && (
387
403
  <button
@@ -405,7 +421,7 @@ export function EventEditor({
405
421
  {!folded && (
406
422
  <div className="flex flex-col gap-2 border-t border-line pt-3">
407
423
  {location}
408
- {guests}
424
+ {guestsEditable && guests}
409
425
  {repeat}
410
426
  {notes}
411
427
  </div>