@tomako/tools-runtime 0.1.1 → 0.1.2

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 (33) hide show
  1. package/package.json +13 -4
  2. package/src/components/tools/workspace/tool-workspace-layout.tsx +1 -1
  3. package/src/constants/related-tools.ts +4 -0
  4. package/src/features/tools/app-icon-resizer/app-icon-resizer.container.tsx +15 -2
  5. package/src/features/tools/app-icon-resizer/app-icon-resizer.spec.ts +1 -1
  6. package/src/features/tools/app-icon-resizer/widget/app-icon-resizer.tsx +54 -11
  7. package/src/features/tools/app-icon-resizer/widget/platform-icons.tsx +2 -5
  8. package/src/features/tools/mrr-calculator/mrr-calculator.container.tsx +23 -0
  9. package/src/features/tools/mrr-calculator/mrr-calculator.spec.ts +15 -0
  10. package/src/features/tools/mrr-calculator/widget/calculations.ts +74 -0
  11. package/src/features/tools/mrr-calculator/widget/index.ts +1 -0
  12. package/src/features/tools/mrr-calculator/widget/mrr-calculator.tsx +581 -0
  13. package/src/features/tools/registry.ts +6 -0
  14. package/src/features/tools/runtime-registry.ts +4 -0
  15. package/src/features/tools/shared/create-standard-landing-container.tsx +35 -5
  16. package/src/features/tools/shared/tool-page-shell.tsx +4 -4
  17. package/src/features/tools/shared/tool-standard-landing-sections.tsx +262 -52
  18. package/src/features/tools/spec-registry.ts +2 -0
  19. package/src/features/tools/widget-registry.ts +2 -0
  20. package/src/i18n/messages/en/tools/app-icon-resizer.ts +90 -62
  21. package/src/i18n/messages/en/tools/index.ts +2 -0
  22. package/src/i18n/messages/en/tools/mrr-calculator.ts +202 -0
  23. package/src/i18n/messages/en/tools-ui.ts +3 -2
  24. package/src/i18n/messages/zh/page/tools.ts +2 -3
  25. package/src/i18n/messages/zh/tools/app-icon-resizer.ts +90 -62
  26. package/src/i18n/messages/zh/tools/index.ts +2 -0
  27. package/src/i18n/messages/zh/tools/mrr-calculator.ts +112 -0
  28. package/src/i18n/messages/zh/tools-ui.ts +3 -2
  29. package/src/i18n/messages/zh-tw/tools/app-icon-resizer.ts +90 -62
  30. package/src/i18n/messages/zh-tw/tools/index.ts +2 -0
  31. package/src/i18n/messages/zh-tw/tools/mrr-calculator.ts +52 -0
  32. package/src/i18n/messages/zh-tw/tools-ui.ts +3 -2
  33. package/src/lib/tools/resolve-tool-locale-copy.ts +7 -1
@@ -3,9 +3,11 @@ import type { ComponentType } from "react";
3
3
 
4
4
  import type {
5
5
  ToolStandardFaqItem,
6
+ ToolStandardEditorialSection,
6
7
  ToolStandardGenerationStep,
7
8
  ToolStandardImageTextSection,
8
9
  ToolStandardNarrativeSection,
10
+ ToolStandardReferenceTable,
9
11
  ToolStandardReportPreview,
10
12
  ToolStandardSectionId,
11
13
  } from "../../../features/tools/shared/tool-standard-landing-sections";
@@ -33,6 +35,10 @@ export type StandardLandingCopyKeys = {
33
35
  reportPreview?: string;
34
36
  /** Optional answer-first sections for decision and strategy tools. */
35
37
  narrativeSections?: string;
38
+ /** Optional structured reading sections for rules, limits, and next actions. */
39
+ editorialSections?: string;
40
+ /** Optional searchable specifications table. */
41
+ referenceTable?: string;
36
42
  };
37
43
 
38
44
  export type StandardLandingContainerConfig = {
@@ -50,6 +56,14 @@ export type StandardLandingContainerConfig = {
50
56
  passFaqToShell?: boolean;
51
57
  /** A content CTA may navigate to a real, cost-free action. */
52
58
  contentCtaHref?: string;
59
+ /** Hide repeated content CTAs when the primary action is already the workspace above. */
60
+ showContentCtas?: boolean;
61
+ /** Some tools have a useful step list but no extra illustration to repeat it. */
62
+ showGenerationImage?: boolean;
63
+ /** Only render a standalone guide when the tool has a real sequential workflow. */
64
+ showGeneration?: boolean;
65
+ /** Use less vertical padding and a grouped benefit list below mobile breakpoints. */
66
+ compactMobileSections?: boolean;
53
67
  /** Override the default section sequence when the tool archetype needs a different reading flow. */
54
68
  sectionOrder?: readonly ToolStandardSectionId[];
55
69
  };
@@ -73,6 +87,10 @@ export function createStandardLandingContainer(
73
87
  workspaceHeadingLevel = "h1",
74
88
  passFaqToShell = true,
75
89
  contentCtaHref,
90
+ showContentCtas = true,
91
+ showGenerationImage = true,
92
+ showGeneration = true,
93
+ compactMobileSections = false,
76
94
  sectionOrder,
77
95
  } = config;
78
96
 
@@ -96,9 +114,12 @@ export function createStandardLandingContainer(
96
114
  const narrativeSections = copyKeys?.narrativeSections
97
115
  ? (t.raw(copyKeys.narrativeSections) as readonly ToolStandardNarrativeSection[])
98
116
  : [];
99
- const generationSteps = t.raw(
100
- "standard.generation.steps",
101
- ) as readonly ToolStandardGenerationStep[];
117
+ const editorialSections = copyKeys?.editorialSections
118
+ ? (t.raw(copyKeys.editorialSections) as readonly ToolStandardEditorialSection[])
119
+ : [];
120
+ const generationSteps = showGeneration
121
+ ? (t.raw("standard.generation.steps") as readonly ToolStandardGenerationStep[])
122
+ : [];
102
123
  const faqRaw = t.raw("faqItems");
103
124
  const faqItems = (
104
125
  Array.isArray(faqRaw) ? faqRaw : []
@@ -106,6 +127,9 @@ export function createStandardLandingContainer(
106
127
  const reportPreview = copyKeys?.reportPreview
107
128
  ? (t.raw(copyKeys.reportPreview) as ToolStandardReportPreview)
108
129
  : undefined;
130
+ const referenceTable = copyKeys?.referenceTable
131
+ ? (t.raw(copyKeys.referenceTable) as ToolStandardReferenceTable)
132
+ : undefined;
109
133
  const shellFaq = faqItems.filter(
110
134
  (item): item is { question: string; answer: string } =>
111
135
  typeof item.answer === "string",
@@ -137,7 +161,8 @@ export function createStandardLandingContainer(
137
161
  }}
138
162
  imageTextSections={imageTextSections}
139
163
  narrativeSections={narrativeSections}
140
- generation={{
164
+ editorialSections={editorialSections}
165
+ generation={showGeneration ? {
141
166
  title: t("standard.generation.title"),
142
167
  image: {
143
168
  src: generationImageSrc,
@@ -146,15 +171,20 @@ export function createStandardLandingContainer(
146
171
  steps: generationSteps,
147
172
  ctaLabel: t("standard.generation.ctaLabel"),
148
173
  ctaHref: contentCtaHref,
149
- }}
174
+ showCta: showContentCtas,
175
+ showImage: showGenerationImage,
176
+ } : undefined}
150
177
  reportPreview={reportPreview}
178
+ referenceTable={referenceTable}
151
179
  faq={{
152
180
  title: t(faqTitleKey),
153
181
  intro: t("standard.faqIntro"),
154
182
  ctaLabel: t("standard.faqCtaLabel"),
155
183
  ctaHref: contentCtaHref,
184
+ showCta: showContentCtas,
156
185
  items: faqItems,
157
186
  }}
187
+ mobileDensity={compactMobileSections ? "compact" : "default"}
158
188
  sectionOrder={sectionOrder}
159
189
  />
160
190
  </ToolPageShell>
@@ -104,7 +104,7 @@ export async function ToolPageShell({
104
104
  ) : null}
105
105
 
106
106
  <div className="relative z-10 flex min-h-[min(72svh,680px)] flex-col">
107
- <div className="mx-auto flex w-full max-w-screen-2xl flex-1 flex-col justify-center gap-10 px-5 pb-8 pt-8 sm:px-8 md:px-12 lg:px-16 lg:pt-12">
107
+ <div className="mx-auto flex w-full max-w-[76rem] flex-1 flex-col justify-center gap-10 px-4 pb-8 pt-8 sm:px-8 lg:pt-12">
108
108
  <div className="grid flex-1 gap-10 lg:grid-cols-[0.9fr_1.1fr] lg:items-center">
109
109
  <div className="max-w-4xl">
110
110
  <p className="inline-flex items-center gap-2 rounded-full border border-[#2B211A]/14 bg-[#FFF8EA]/45 px-4 py-2 text-sm font-semibold text-[#4C3C31] shadow-[0_12px_36px_rgba(83,48,28,0.08)] backdrop-blur">
@@ -136,13 +136,13 @@ export async function ToolPageShell({
136
136
  </div>
137
137
  </section>
138
138
 
139
- <div className="mx-auto flex max-w-screen-2xl flex-col gap-16 px-5 py-16 sm:px-8 md:gap-20 md:py-24">
139
+ <div className="mx-auto flex max-w-[76rem] flex-col gap-16 px-4 py-16 sm:px-8 md:gap-20 md:py-24">
140
140
  {children}
141
141
  </div>
142
142
  </>
143
143
  ) : (
144
144
  <>
145
- <div className="mx-auto max-w-screen-2xl px-5 py-5 sm:px-8">
145
+ <div className="mx-auto max-w-[76rem] px-4 py-5 sm:px-8">
146
146
  {heroVariant === "showcase" && heroVisual ? (
147
147
  <section className="pb-14 pt-14 md:pb-16 md:pt-16">
148
148
  <div className="mx-auto max-w-4xl text-center">
@@ -211,7 +211,7 @@ export async function ToolPageShell({
211
211
  </>
212
212
  )}
213
213
  {relatedToolSlugs?.length ? (
214
- <div className="mx-auto w-full max-w-screen-2xl px-5 pb-16 sm:px-8 md:pb-20">
214
+ <div className="mx-auto w-full max-w-[76rem] px-4 pb-16 sm:px-8 md:pb-20">
215
215
  <RelatedTools locale={locale} currentToolSlug={spec.slug} slugs={relatedToolSlugs} />
216
216
  </div>
217
217
  ) : null}