@fonderie/react-courier-admin-screens 0.6.0 → 0.7.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.
package/dist/index.d.cts CHANGED
@@ -6,13 +6,45 @@ interface ITemplateEditorScreenProps {
6
6
  type: string;
7
7
  locale?: string | null;
8
8
  onSaved?: () => void;
9
+ /**
10
+ * A built-in email's default-locale row (the list's `system` flag): it can
11
+ * be edited and rolled back, never deleted — Delete is not offered.
12
+ */
13
+ system?: boolean;
14
+ /** Called after a delete; the template no longer exists. */
15
+ onDeleted?: () => void;
16
+ /** Shows "Add locale": create a translation of this template. */
17
+ onAddLocale?: (type: string) => void;
9
18
  }
10
- declare function TemplateEditorScreen({ client, type, locale, onSaved, }: ITemplateEditorScreenProps): react.JSX.Element;
19
+ declare function TemplateEditorScreen({ client, type, locale, onSaved, system, onDeleted, onAddLocale, }: ITemplateEditorScreenProps): react.JSX.Element;
11
20
 
12
21
  interface ITemplateListScreenProps {
13
22
  client: CourierAdminClient;
23
+ /** Receives the whole row — type AND locale, and whether it is built-in. */
14
24
  onSelectTemplate?: (template: ITemplateEntry) => void;
25
+ /** Shows a "New template" button. Receives the locales in use, to suggest. */
26
+ onCreateTemplate?: (context: {
27
+ locales: string[];
28
+ }) => void;
15
29
  }
16
- declare function TemplateListScreen({ client, onSelectTemplate }: ITemplateListScreenProps): react.JSX.Element;
30
+ declare function TemplateListScreen({ client, onSelectTemplate, onCreateTemplate, }: ITemplateListScreenProps): react.JSX.Element;
17
31
 
18
- export { type ITemplateEditorScreenProps, type ITemplateListScreenProps, TemplateEditorScreen, TemplateListScreen };
32
+ interface ITemplateCreateScreenProps {
33
+ client: CourierAdminClient;
34
+ /**
35
+ * Given ⇒ add a LOCALE of this existing template: the type is fixed and the
36
+ * form starts from its default-locale copy. Omitted ⇒ a brand-new template
37
+ * type (one the app sends that has no stored copy yet).
38
+ */
39
+ type?: string;
40
+ /** Locales already in use, offered as suggestions. */
41
+ locales?: string[];
42
+ /** Called with what was created, so the caller can open it in the editor. */
43
+ onCreated?: (created: {
44
+ type: string;
45
+ locale: string | null;
46
+ }) => void;
47
+ }
48
+ declare function TemplateCreateScreen({ client, type, locales, onCreated, }: ITemplateCreateScreenProps): react.JSX.Element;
49
+
50
+ export { type ITemplateCreateScreenProps, type ITemplateEditorScreenProps, type ITemplateListScreenProps, TemplateCreateScreen, TemplateEditorScreen, TemplateListScreen };
package/dist/index.d.ts CHANGED
@@ -6,13 +6,45 @@ interface ITemplateEditorScreenProps {
6
6
  type: string;
7
7
  locale?: string | null;
8
8
  onSaved?: () => void;
9
+ /**
10
+ * A built-in email's default-locale row (the list's `system` flag): it can
11
+ * be edited and rolled back, never deleted — Delete is not offered.
12
+ */
13
+ system?: boolean;
14
+ /** Called after a delete; the template no longer exists. */
15
+ onDeleted?: () => void;
16
+ /** Shows "Add locale": create a translation of this template. */
17
+ onAddLocale?: (type: string) => void;
9
18
  }
10
- declare function TemplateEditorScreen({ client, type, locale, onSaved, }: ITemplateEditorScreenProps): react.JSX.Element;
19
+ declare function TemplateEditorScreen({ client, type, locale, onSaved, system, onDeleted, onAddLocale, }: ITemplateEditorScreenProps): react.JSX.Element;
11
20
 
12
21
  interface ITemplateListScreenProps {
13
22
  client: CourierAdminClient;
23
+ /** Receives the whole row — type AND locale, and whether it is built-in. */
14
24
  onSelectTemplate?: (template: ITemplateEntry) => void;
25
+ /** Shows a "New template" button. Receives the locales in use, to suggest. */
26
+ onCreateTemplate?: (context: {
27
+ locales: string[];
28
+ }) => void;
15
29
  }
16
- declare function TemplateListScreen({ client, onSelectTemplate }: ITemplateListScreenProps): react.JSX.Element;
30
+ declare function TemplateListScreen({ client, onSelectTemplate, onCreateTemplate, }: ITemplateListScreenProps): react.JSX.Element;
17
31
 
18
- export { type ITemplateEditorScreenProps, type ITemplateListScreenProps, TemplateEditorScreen, TemplateListScreen };
32
+ interface ITemplateCreateScreenProps {
33
+ client: CourierAdminClient;
34
+ /**
35
+ * Given ⇒ add a LOCALE of this existing template: the type is fixed and the
36
+ * form starts from its default-locale copy. Omitted ⇒ a brand-new template
37
+ * type (one the app sends that has no stored copy yet).
38
+ */
39
+ type?: string;
40
+ /** Locales already in use, offered as suggestions. */
41
+ locales?: string[];
42
+ /** Called with what was created, so the caller can open it in the editor. */
43
+ onCreated?: (created: {
44
+ type: string;
45
+ locale: string | null;
46
+ }) => void;
47
+ }
48
+ declare function TemplateCreateScreen({ client, type, locales, onCreated, }: ITemplateCreateScreenProps): react.JSX.Element;
49
+
50
+ export { type ITemplateCreateScreenProps, type ITemplateEditorScreenProps, type ITemplateListScreenProps, TemplateCreateScreen, TemplateEditorScreen, TemplateListScreen };
package/dist/index.js CHANGED
@@ -13,10 +13,14 @@ function TemplateEditorScreen({
13
13
  client,
14
14
  type,
15
15
  locale,
16
- onSaved
16
+ onSaved,
17
+ system = false,
18
+ onDeleted,
19
+ onAddLocale
17
20
  }) {
18
21
  const { template, isLoading, error, refresh } = useTemplate(client, type, locale);
19
- const { saveTemplate } = useTemplates(client);
22
+ const { saveTemplate, removeTemplate } = useTemplates(client);
23
+ const [isDeleting, setIsDeleting] = useState(false);
20
24
  const { revisions, rollback } = useTemplateRevisions(client, type, locale);
21
25
  const [isSaving, setIsSaving] = useState(false);
22
26
  const [saveError, setSaveError] = useState(null);
@@ -86,15 +90,42 @@ function TemplateEditorScreen({
86
90
  setIsSaving(false);
87
91
  }
88
92
  };
93
+ const handleDelete = async () => {
94
+ const which = locale ? `the ${locale} version of "${type}"` : `"${type}"`;
95
+ const fallback = locale ? " People in that locale will receive the default version." : "";
96
+ if (!window.confirm(`Delete ${which}?${fallback}`)) return;
97
+ setIsDeleting(true);
98
+ setSaveError(null);
99
+ try {
100
+ await removeTemplate(type, locale);
101
+ onDeleted?.();
102
+ } catch (err) {
103
+ setSaveError(err);
104
+ } finally {
105
+ setIsDeleting(false);
106
+ }
107
+ };
89
108
  if (isLoading) return /* @__PURE__ */ jsx("p", { style: styles.status, children: "Loading template\u2026" });
90
109
  if (error)
91
110
  return /* @__PURE__ */ jsx("p", { style: styles.error, role: "alert", children: error.explanation });
92
111
  return /* @__PURE__ */ jsxs("div", { style: styles.container, children: [
93
- /* @__PURE__ */ jsx("h1", { style: styles.title, children: type }),
112
+ /* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: 12, flexWrap: "wrap" }, children: [
113
+ /* @__PURE__ */ jsx("h1", { style: styles.title, children: type }),
114
+ onAddLocale && !locale ? /* @__PURE__ */ jsx(
115
+ "button",
116
+ {
117
+ type: "button",
118
+ style: { ...styles.rollbackButton, marginLeft: "auto" },
119
+ onClick: () => onAddLocale(type),
120
+ children: "+ Add locale"
121
+ }
122
+ ) : null
123
+ ] }),
94
124
  /* @__PURE__ */ jsxs("p", { style: styles.meta, children: [
95
- locale ?? "base",
125
+ /* @__PURE__ */ jsx("strong", { children: locale ?? "default locale" }),
96
126
  " \xB7 v",
97
- template?.version ?? 1
127
+ template?.version ?? 1,
128
+ system ? " \xB7 built-in email: edit or roll back, it cannot be deleted" : ""
98
129
  ] }),
99
130
  /* @__PURE__ */ jsxs("div", { style: styles.split, children: [
100
131
  /* @__PURE__ */ jsxs("div", { style: styles.column, children: [
@@ -143,7 +174,22 @@ function TemplateEditorScreen({
143
174
  ),
144
175
  "Active"
145
176
  ] }),
146
- saveError && /* @__PURE__ */ jsx("p", { style: styles.error, role: "alert", children: saveError.explanation }),
177
+ saveError?.reason === "VERSION_CONFLICT" ? /* @__PURE__ */ jsxs("p", { style: styles.error, role: "alert", children: [
178
+ "Someone changed this template since you opened it. Reload to see their change, then edit again.",
179
+ " ",
180
+ /* @__PURE__ */ jsx(
181
+ "button",
182
+ {
183
+ type: "button",
184
+ style: styles.rollbackButton,
185
+ onClick: () => {
186
+ setSaveError(null);
187
+ void refresh();
188
+ },
189
+ children: "Reload"
190
+ }
191
+ )
192
+ ] }) : saveError ? /* @__PURE__ */ jsx("p", { style: styles.error, role: "alert", children: saveError.explanation }) : null,
147
193
  /* @__PURE__ */ jsxs("div", { style: styles.saveRow, children: [
148
194
  /* @__PURE__ */ jsx(
149
195
  "button",
@@ -154,7 +200,23 @@ function TemplateEditorScreen({
154
200
  children: isSaving ? "Saving\u2026" : "Save"
155
201
  }
156
202
  ),
157
- !dirty && !isSaving && /* @__PURE__ */ jsx("span", { style: styles.meta, children: "No changes to save" })
203
+ !dirty && !isSaving && /* @__PURE__ */ jsx("span", { style: styles.meta, children: "No changes to save" }),
204
+ !system ? /* @__PURE__ */ jsx(
205
+ "button",
206
+ {
207
+ type: "button",
208
+ disabled: isDeleting,
209
+ onClick: () => void handleDelete(),
210
+ style: {
211
+ ...styles.rollbackButton,
212
+ height: 36,
213
+ marginLeft: "auto",
214
+ color: "var(--fonderie-danger,#e00)",
215
+ borderColor: "color-mix(in srgb, var(--fonderie-danger,#e00) 40%, transparent)"
216
+ },
217
+ children: isDeleting ? "Deleting\u2026" : "Delete"
218
+ }
219
+ ) : null
158
220
  ] })
159
221
  ] }),
160
222
  /* @__PURE__ */ jsx("label", { style: styles.label, htmlFor: "template-sample", children: "Sample data" }),
@@ -390,10 +452,35 @@ var styles = {
390
452
  // src/screens/TemplateListScreen.tsx
391
453
  import { useTemplates as useTemplates2 } from "@fonderie/react-courier-admin";
392
454
  import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
393
- function TemplateListScreen({ client, onSelectTemplate }) {
455
+ function TemplateListScreen({
456
+ client,
457
+ onSelectTemplate,
458
+ onCreateTemplate
459
+ }) {
394
460
  const { templates, isLoading, error } = useTemplates2(client);
395
461
  return /* @__PURE__ */ jsxs2("div", { style: styles2.container, children: [
396
- /* @__PURE__ */ jsx2("h1", { style: styles2.title, children: "Templates" }),
462
+ /* @__PURE__ */ jsxs2(
463
+ "div",
464
+ {
465
+ style: { display: "flex", alignItems: "center", justifyContent: "space-between", gap: 16 },
466
+ children: [
467
+ /* @__PURE__ */ jsx2("h1", { style: styles2.title, children: "Templates" }),
468
+ onCreateTemplate ? /* @__PURE__ */ jsx2(
469
+ "button",
470
+ {
471
+ type: "button",
472
+ onClick: () => onCreateTemplate({
473
+ locales: [
474
+ ...new Set(templates.map((t) => t.locale).filter((l) => !!l))
475
+ ]
476
+ }),
477
+ style: styles2.newButton,
478
+ children: "New template"
479
+ }
480
+ ) : null
481
+ ]
482
+ }
483
+ ),
397
484
  /* @__PURE__ */ jsx2("p", { style: styles2.hint, children: "Every email the app sends. Open one to edit its copy and preview it live." }),
398
485
  isLoading ? /* @__PURE__ */ jsx2("p", { style: styles2.status, children: "Loading templates\u2026" }) : error ? /* @__PURE__ */ jsx2("p", { style: styles2.error, role: "alert", children: error.explanation }) : /* @__PURE__ */ jsx2("ul", { style: styles2.list, children: templates.map((template) => /* @__PURE__ */ jsx2("li", { style: styles2.row, children: /* @__PURE__ */ jsxs2(
399
486
  "button",
@@ -404,6 +491,7 @@ function TemplateListScreen({ client, onSelectTemplate }) {
404
491
  children: [
405
492
  /* @__PURE__ */ jsx2("span", { style: styles2.type, children: template.type }),
406
493
  /* @__PURE__ */ jsx2("span", { style: styles2.locale, children: template.locale ?? "default locale" }),
494
+ template.system ? /* @__PURE__ */ jsx2("span", { style: styles2.builtIn, children: "built-in" }) : null,
407
495
  /* @__PURE__ */ jsxs2("span", { style: template.active ? styles2.active : styles2.inactive, children: [
408
496
  /* @__PURE__ */ jsx2("span", { style: styles2.dot }),
409
497
  template.active ? "active" : "inactive"
@@ -469,6 +557,29 @@ var styles2 = {
469
557
  },
470
558
  locale: { fontSize: 12.5, color: "var(--fonderie-text-muted,#5c5c5c)" },
471
559
  dot: { width: 6, height: 6, borderRadius: 999, background: "currentColor" },
560
+ builtIn: {
561
+ fontSize: 11,
562
+ fontWeight: 500,
563
+ padding: "1px 7px",
564
+ borderRadius: 999,
565
+ border: "1px solid var(--fonderie-border,#e0e0e0)",
566
+ color: "var(--fonderie-text-muted,#5c5c5c)"
567
+ },
568
+ newButton: {
569
+ display: "inline-flex",
570
+ alignItems: "center",
571
+ height: 32,
572
+ boxSizing: "border-box",
573
+ borderRadius: 6,
574
+ padding: "0 12px",
575
+ fontSize: 13,
576
+ fontWeight: 500,
577
+ fontFamily: "inherit",
578
+ cursor: "pointer",
579
+ backgroundColor: "var(--fonderie-text,#171717)",
580
+ color: "var(--fonderie-surface,#fff)",
581
+ border: "1px solid var(--fonderie-text,#171717)"
582
+ },
472
583
  active: {
473
584
  ...pill,
474
585
  color: "var(--fonderie-accent-strong,#009767)",
@@ -480,7 +591,214 @@ var styles2 = {
480
591
  background: "color-mix(in srgb, var(--fonderie-text-muted,#5c5c5c) 10%, transparent)"
481
592
  }
482
593
  };
594
+
595
+ // src/screens/TemplateCreateScreen.tsx
596
+ import { FonderieApiError } from "@fonderie/client";
597
+ import { useEffect as useEffect2, useState as useState2 } from "react";
598
+ import { Fragment, jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
599
+ var TYPE_RE = /^[a-z0-9][a-z0-9_-]{0,80}$/;
600
+ var LOCALE_RE = /^[a-z]{2,3}(-[A-Za-z0-9]{2,8})*$/;
601
+ function TemplateCreateScreen({
602
+ client,
603
+ type,
604
+ locales = [],
605
+ onCreated
606
+ }) {
607
+ const addingLocale = type !== void 0;
608
+ const [newType, setNewType] = useState2("");
609
+ const [locale, setLocale] = useState2("");
610
+ const [subject, setSubject] = useState2("");
611
+ const [html, setHtml] = useState2("");
612
+ const [text, setText] = useState2("");
613
+ const [error, setError] = useState2(null);
614
+ const [busy, setBusy] = useState2(false);
615
+ useEffect2(() => {
616
+ if (!type) return;
617
+ client.getTemplate(type, null).then(({ result }) => {
618
+ setSubject(result.subject ?? "");
619
+ setHtml(result.html ?? "");
620
+ setText(result.text);
621
+ }).catch(() => void 0);
622
+ }, [client, type]);
623
+ const submit = async (e) => {
624
+ e.preventDefault();
625
+ setError(null);
626
+ const t = addingLocale ? type : newType.trim();
627
+ const l = locale.trim() || null;
628
+ if (!TYPE_RE.test(t))
629
+ return setError("Type: lowercase letters, digits, - and _ (e.g. weekly-digest).");
630
+ if (addingLocale && !l) return setError("Choose the locale to add, e.g. fr or fr-CA.");
631
+ if (l && !LOCALE_RE.test(l)) return setError("Locale: a language tag such as fr, es or fr-CA.");
632
+ if (!text.trim())
633
+ return setError("The plain-text body is required \u2014 it is what every email client can show.");
634
+ setBusy(true);
635
+ try {
636
+ const exists = await client.getTemplate(t, l).then(
637
+ () => true,
638
+ (err) => !(err instanceof FonderieApiError && err.status === 404)
639
+ );
640
+ if (exists) {
641
+ setError(`"${t}"${l ? ` (${l})` : ""} already exists \u2014 open it from the list to edit.`);
642
+ return;
643
+ }
644
+ const input = { text, active: true };
645
+ if (subject) input.subject = subject;
646
+ if (html) input.html = html;
647
+ await client.setTemplate(t, input, l);
648
+ onCreated?.({ type: t, locale: l });
649
+ } catch (err) {
650
+ setError(err instanceof FonderieApiError ? err.explanation : String(err));
651
+ } finally {
652
+ setBusy(false);
653
+ }
654
+ };
655
+ return /* @__PURE__ */ jsxs3("div", { style: styles3.container, children: [
656
+ /* @__PURE__ */ jsx3("h1", { style: styles3.title, children: addingLocale ? `Add a locale to ${type}` : "New template" }),
657
+ /* @__PURE__ */ jsx3("p", { style: styles3.meta, children: addingLocale ? "Starts from the default copy. People whose locale matches receive this version; everyone else keeps the default." : "For an email your app sends that has no stored copy yet. The type must match what the app sends." }),
658
+ /* @__PURE__ */ jsxs3("form", { style: styles3.form, onSubmit: (e) => void submit(e), children: [
659
+ !addingLocale ? /* @__PURE__ */ jsxs3(Fragment, { children: [
660
+ /* @__PURE__ */ jsx3("label", { style: styles3.label, htmlFor: "new-template-type", children: "Type" }),
661
+ /* @__PURE__ */ jsx3(
662
+ "input",
663
+ {
664
+ id: "new-template-type",
665
+ style: styles3.input,
666
+ value: newType,
667
+ placeholder: "weekly-digest",
668
+ autoComplete: "off",
669
+ spellCheck: false,
670
+ onChange: (e) => setNewType(e.target.value)
671
+ }
672
+ )
673
+ ] }) : null,
674
+ /* @__PURE__ */ jsxs3("label", { style: styles3.label, htmlFor: "new-template-locale", children: [
675
+ "Locale ",
676
+ addingLocale ? "" : "(optional \u2014 empty is the default)"
677
+ ] }),
678
+ /* @__PURE__ */ jsx3(
679
+ "input",
680
+ {
681
+ id: "new-template-locale",
682
+ style: styles3.input,
683
+ value: locale,
684
+ placeholder: "fr",
685
+ list: "new-template-locales",
686
+ autoComplete: "off",
687
+ spellCheck: false,
688
+ onChange: (e) => setLocale(e.target.value)
689
+ }
690
+ ),
691
+ /* @__PURE__ */ jsx3("datalist", { id: "new-template-locales", children: [...new Set(locales)].map((l) => /* @__PURE__ */ jsx3("option", { value: l }, l)) }),
692
+ /* @__PURE__ */ jsx3("label", { style: styles3.label, htmlFor: "new-template-subject", children: "Subject" }),
693
+ /* @__PURE__ */ jsx3(
694
+ "input",
695
+ {
696
+ id: "new-template-subject",
697
+ style: styles3.input,
698
+ value: subject,
699
+ onChange: (e) => setSubject(e.target.value)
700
+ }
701
+ ),
702
+ /* @__PURE__ */ jsx3("label", { style: styles3.label, htmlFor: "new-template-html", children: "HTML body" }),
703
+ /* @__PURE__ */ jsx3(
704
+ "textarea",
705
+ {
706
+ id: "new-template-html",
707
+ style: { ...styles3.textarea, minHeight: 160 },
708
+ value: html,
709
+ onChange: (e) => setHtml(e.target.value)
710
+ }
711
+ ),
712
+ /* @__PURE__ */ jsx3("label", { style: styles3.label, htmlFor: "new-template-text", children: "Plain-text body" }),
713
+ /* @__PURE__ */ jsx3(
714
+ "textarea",
715
+ {
716
+ id: "new-template-text",
717
+ style: { ...styles3.textarea, minHeight: 100 },
718
+ value: text,
719
+ onChange: (e) => setText(e.target.value)
720
+ }
721
+ ),
722
+ error ? /* @__PURE__ */ jsx3("p", { style: styles3.error, role: "alert", children: error }) : null,
723
+ /* @__PURE__ */ jsx3("button", { type: "submit", disabled: busy, style: styles3.button, children: busy ? "Creating\u2026" : addingLocale ? "Add locale" : "Create template" })
724
+ ] })
725
+ ] });
726
+ }
727
+ var MONO = 'var(--fonderie-mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace)';
728
+ var styles3 = {
729
+ container: { padding: "8px 40px 64px", maxWidth: 760, boxSizing: "border-box" },
730
+ title: {
731
+ fontSize: 22,
732
+ fontWeight: 600,
733
+ margin: "8px 0 4px",
734
+ letterSpacing: "var(--fonderie-tracking-display,-0.05em)",
735
+ lineHeight: 1.25
736
+ },
737
+ meta: {
738
+ fontSize: 13,
739
+ color: "var(--fonderie-text-muted,#5c5c5c)",
740
+ marginBottom: 20,
741
+ lineHeight: 1.5
742
+ },
743
+ form: {
744
+ display: "flex",
745
+ flexDirection: "column",
746
+ gap: 4,
747
+ background: "var(--fonderie-surface,#fff)",
748
+ border: "1px solid var(--fonderie-border,#e0e0e0)",
749
+ borderRadius: "var(--fonderie-radius-lg,8px)",
750
+ padding: "6px 20px 20px"
751
+ },
752
+ label: { fontSize: 13, fontWeight: 500, marginTop: 14, marginBottom: 2 },
753
+ input: {
754
+ height: 36,
755
+ boxSizing: "border-box",
756
+ border: "1px solid var(--fonderie-border,#e0e0e0)",
757
+ borderRadius: 6,
758
+ padding: "0 10px",
759
+ fontSize: 13.5,
760
+ fontFamily: "inherit",
761
+ background: "var(--fonderie-surface,#fff)",
762
+ color: "var(--fonderie-text,#171717)"
763
+ },
764
+ textarea: {
765
+ border: "1px solid var(--fonderie-border,#e0e0e0)",
766
+ borderRadius: 6,
767
+ padding: 10,
768
+ fontSize: 13,
769
+ lineHeight: 1.55,
770
+ background: "var(--fonderie-surface,#fff)",
771
+ color: "var(--fonderie-text,#171717)",
772
+ fontFamily: MONO
773
+ },
774
+ error: {
775
+ color: "var(--fonderie-danger,#e00)",
776
+ background: "color-mix(in srgb, var(--fonderie-danger,#e00) 8%, transparent)",
777
+ borderRadius: 6,
778
+ padding: "8px 12px",
779
+ margin: "8px 0",
780
+ fontSize: 13.5
781
+ },
782
+ button: {
783
+ display: "inline-flex",
784
+ alignItems: "center",
785
+ height: 36,
786
+ boxSizing: "border-box",
787
+ backgroundColor: "var(--fonderie-text,#171717)",
788
+ color: "var(--fonderie-surface,#fff)",
789
+ padding: "0 16px",
790
+ borderRadius: 6,
791
+ border: "1px solid var(--fonderie-text,#171717)",
792
+ fontSize: 13.5,
793
+ fontWeight: 600,
794
+ fontFamily: "inherit",
795
+ cursor: "pointer",
796
+ alignSelf: "flex-start",
797
+ marginTop: 16
798
+ }
799
+ };
483
800
  export {
801
+ TemplateCreateScreen,
484
802
  TemplateEditorScreen,
485
803
  TemplateListScreen
486
804
  };