@terrafirmagreg-team/recipe 0.1.0 → 1.2.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/package.json +16 -16
- package/src/components/button-copy.tsx +1 -0
- package/src/components/cards/card/index.tsx +5 -3
- package/src/components/cards/card/scene.tsx +4 -2
- package/src/components/cards/card/strip.tsx +4 -2
- package/src/components/cards/card/text.tsx +2 -1
- package/src/components/cards/card/tips.tsx +1 -0
- package/src/components/cards/default-item.tsx +6 -2
- package/src/components/cards/glare-filter.tsx +1 -0
- package/src/components/cards/paged-card.tsx +1 -0
- package/src/components/cards/slot-hitbox.tsx +4 -2
- package/src/components/cards/strip-card/buttons.tsx +7 -2
- package/src/components/cards/strip-card/index.tsx +3 -1
- package/src/components/cards/strip-card/member-cell.tsx +4 -2
- package/src/components/cards/strip-card/sprite.tsx +1 -0
- package/src/components/embed-card.tsx +44 -0
- package/src/components/mdx/recipe.tsx +34 -16
- package/src/components/tool-list.tsx +1 -0
- package/src/{lib/tree.ts → components/tree.tsx} +20 -12
- package/src/components/views/alloy/index.tsx +14 -7
- package/src/components/views/alloy/list.tsx +3 -2
- package/src/components/views/alloy/mix/index.tsx +1 -0
- package/src/components/views/alloy/mix/ratio.tsx +7 -6
- package/src/components/views/alloy/mix/rows.tsx +6 -7
- package/src/components/views/alloy/mix/status.tsx +8 -7
- package/src/components/views/alloy/mix/total.tsx +13 -12
- package/src/components/views/alloy/range-bar.tsx +2 -1
- package/src/components/views/alloy/stack-bar.tsx +4 -2
- package/src/components/views/browser/axis-switcher.tsx +13 -12
- package/src/components/views/browser/card-grid.tsx +2 -1
- package/src/components/views/browser/favorite-button.tsx +2 -1
- package/src/components/views/browser/frame.tsx +3 -2
- package/src/components/views/browser/index.tsx +20 -2
- package/src/components/views/browser/item-panel/index.tsx +11 -9
- package/src/components/views/browser/item-panel/skeleton.tsx +1 -0
- package/src/components/views/browser/item-panel-grid/cell.tsx +5 -3
- package/src/components/views/browser/item-panel-grid/favorite-cell.tsx +4 -2
- package/src/components/views/browser/item-panel-grid/index.tsx +4 -2
- package/src/components/views/browser/item-view/index.tsx +7 -12
- package/src/components/views/browser/item-view/tags.tsx +7 -5
- package/src/components/views/browser/item-view-header.tsx +10 -9
- package/src/components/views/browser/pane-tabs.tsx +1 -0
- package/src/components/views/browser/place-header.tsx +4 -3
- package/src/components/views/browser/query-controls.tsx +3 -1
- package/src/components/views/browser/recipe-item-header.tsx +5 -4
- package/src/components/views/browser/settings.tsx +4 -3
- package/src/components/views/browser/toolbar.tsx +3 -2
- package/src/components/views/browser/type-tabs.tsx +5 -3
- package/src/components/views/browser/type-view.tsx +7 -12
- package/src/components/views/browser/workstation-rail.tsx +4 -3
- package/src/components/views/calc/calculator/actions.tsx +4 -14
- package/src/components/views/calc/calculator/help.tsx +69 -28
- package/src/components/views/calc/calculator/index.tsx +34 -82
- package/src/components/views/calc/dot-overlay.tsx +1 -0
- package/src/components/views/calc/edge.tsx +134 -32
- package/src/components/views/calc/flow/index.tsx +92 -54
- package/src/components/views/calc/flow/picker-dialogs.tsx +84 -6
- package/src/components/views/calc/flow/toolbar.tsx +9 -21
- package/src/components/views/calc/flow/view-menu.tsx +16 -120
- package/src/components/views/calc/member-picker.tsx +8 -6
- package/src/components/views/calc/node-card/actions.tsx +28 -106
- package/src/components/views/calc/node-card/badges.tsx +10 -28
- package/src/components/views/calc/node-card/chips.tsx +8 -40
- package/src/components/views/calc/node-card/far.tsx +13 -65
- package/src/components/views/calc/node-card/full.tsx +133 -83
- package/src/components/views/calc/node-card/index.tsx +1 -0
- package/src/components/views/calc/node-card/menu.tsx +93 -22
- package/src/components/views/calc/node-card/port-cells.tsx +186 -0
- package/src/components/views/calc/node-card/port-rails.tsx +251 -0
- package/src/components/views/calc/node-card/ports.tsx +86 -0
- package/src/components/views/calc/recipe-picker/body.tsx +17 -14
- package/src/components/views/calc/recipe-picker/footer.tsx +5 -3
- package/src/components/views/calc/recipe-picker/index.tsx +5 -0
- package/src/components/views/calc/sidebar.tsx +19 -10
- package/src/components/views/calc/trees/icon-picker.tsx +3 -2
- package/src/components/views/calc/trees/index.tsx +5 -4
- package/src/components/views/calc/trees/label.tsx +6 -4
- package/src/components/views/calc/trees/rows.tsx +6 -5
- package/src/components/views/forge/gui.tsx +2 -1
- package/src/components/views/forge/index.tsx +14 -7
- package/src/components/views/forge/list.tsx +3 -2
- package/src/components/views/forge/workbench/controls.tsx +13 -6
- package/src/components/views/forge/workbench/index.tsx +3 -2
- package/src/components/views/forge/workbench/panel.tsx +1 -0
- package/src/components/views/forge/workbench/ruler.tsx +5 -4
- package/src/components/views/forge/workbench/status.tsx +6 -5
- package/src/components/views/forge/workbench/tape.tsx +5 -4
- package/src/hooks/alloy/use-fluid-colors.ts +12 -9
- package/src/hooks/alloy/use-mix-state.ts +3 -2
- package/src/hooks/calc/flow/use-engage.ts +129 -0
- package/src/hooks/calc/flow/use-handlers.ts +192 -0
- package/src/hooks/calc/flow/use-layout.ts +105 -0
- package/src/hooks/calc/flow/{mount.ts → use-mount.ts} +1 -0
- package/src/hooks/calc/flow/{nodes.ts → use-nodes.ts} +46 -37
- package/src/hooks/calc/flow/use-pickers.ts +57 -0
- package/src/hooks/calc/flow/{viewport.ts → use-viewport.ts} +13 -26
- package/src/hooks/calc/flow/{window.ts → use-window.ts} +1 -0
- package/src/hooks/calc/use-actions.ts +208 -229
- package/src/hooks/calc/use-amounts.ts +23 -60
- package/src/hooks/calc/use-data.ts +106 -192
- package/src/hooks/calc/use-defaults.ts +4 -2
- package/src/hooks/calc/use-far-mode.ts +1 -0
- package/src/hooks/calc/use-focus.ts +8 -7
- package/src/hooks/calc/use-maps.ts +1 -0
- package/src/hooks/calc/use-reset.ts +1 -0
- package/src/hooks/calc/use-resolver.ts +32 -196
- package/src/hooks/calc/use-session.ts +1 -0
- package/src/hooks/calc/use-share.ts +5 -2
- package/src/hooks/calc/use-storage.ts +5 -4
- package/src/hooks/calc/use-tier.ts +1 -0
- package/src/hooks/calc/use-view-mode.ts +1 -0
- package/src/hooks/calc/use-worker.ts +56 -121
- package/src/hooks/forge/use-anvil-gui.ts +4 -2
- package/src/hooks/forge/use-forge-state.ts +1 -0
- package/src/hooks/forge/use-ruler.ts +1 -0
- package/src/hooks/use-add-to-calc.ts +23 -19
- package/src/hooks/use-categories-by-id.ts +18 -0
- package/src/hooks/use-favorite-hotkey.ts +1 -0
- package/src/hooks/use-favorites.ts +1 -0
- package/src/hooks/use-group-outlines.ts +1 -0
- package/src/hooks/use-hide-unused.ts +2 -1
- package/src/hooks/use-index.ts +6 -2
- package/src/hooks/use-item-feeds.ts +3 -1
- package/src/hooks/use-item-pane.ts +6 -4
- package/src/hooks/use-item-press.ts +27 -23
- package/src/hooks/use-item-tag-groups.ts +4 -2
- package/src/hooks/use-item-tooltips.ts +3 -1
- package/src/hooks/use-left-sidebar-tree.ts +11 -3
- package/src/hooks/use-mod-names.ts +4 -2
- package/src/hooks/use-mount-limit.ts +1 -0
- package/src/hooks/use-panel-cells.ts +3 -1
- package/src/hooks/use-panel-page.ts +9 -6
- package/src/hooks/use-panel-tabs.ts +2 -1
- package/src/hooks/use-query.ts +8 -6
- package/src/hooks/use-session.ts +6 -2
- package/src/hooks/use-sidebar-group.ts +3 -7
- package/src/hooks/use-tag-members.ts +3 -1
- package/src/hooks/use-tool-recipes.ts +1 -0
- package/src/hooks/use-type-filter.ts +1 -0
- package/src/lib/alloy/mix.ts +1 -0
- package/src/lib/alloy/parse.ts +1 -0
- package/src/lib/calc/defaults.ts +6 -4
- package/src/lib/calc/flow.ts +143 -107
- package/src/lib/calc/focus.ts +1 -0
- package/src/lib/calc/meta.ts +3 -1
- package/src/lib/calc/pack.ts +47 -154
- package/src/lib/calc/ports.ts +43 -0
- package/src/lib/calc/resolve.ts +6 -38
- package/src/lib/calc/route/buckets.ts +1 -0
- package/src/lib/calc/route/geometry.ts +13 -24
- package/src/lib/calc/route/index.ts +1 -0
- package/src/lib/calc/route/polyline.ts +3 -3
- package/src/lib/calc/route/router.ts +181 -57
- package/src/lib/calc/scheme.ts +226 -0
- package/src/lib/calc/storage/entry.ts +27 -19
- package/src/lib/calc/storage/index.ts +2 -0
- package/src/lib/calc/storage/keys.ts +4 -8
- package/src/lib/calc/storage/store.ts +11 -36
- package/src/lib/calc/tree/index.ts +2 -16
- package/src/lib/calc/tree/materials.ts +1 -0
- package/src/lib/calc/tree/recipe.ts +1 -0
- package/src/lib/calc/tree/share.ts +86 -149
- package/src/lib/calc/worker/api.ts +3 -11
- package/src/lib/calc/worker/fetch.ts +1 -0
- package/src/lib/calc/worker/flush.ts +7 -20
- package/src/lib/calc/worker/index.ts +1 -1
- package/src/lib/calc/worker/protocol.ts +16 -13
- package/src/lib/calc/worker/resolve.ts +32 -84
- package/src/lib/calc/worker/state.ts +5 -6
- package/src/{components/cards/card/model.ts → lib/card-model.ts} +1 -0
- package/src/lib/client/recipe-categories.ts +11 -93
- package/src/lib/client/recipe.ts +13 -11
- package/src/lib/client-index/catalog.ts +33 -27
- package/src/lib/client-index/chrome.ts +30 -30
- package/src/lib/client-index/index.ts +1 -0
- package/src/lib/client-index/registry.ts +70 -59
- package/src/lib/client-index/rows.ts +63 -57
- package/src/lib/client-index/tooltips.ts +28 -34
- package/src/lib/config.ts +2 -1
- package/src/lib/data/category/dto.ts +4 -3
- package/src/lib/data/category/load.ts +9 -8
- package/src/lib/data/category/parse.ts +4 -3
- package/src/lib/data/dto.ts +4 -3
- package/src/lib/data/grid.ts +2 -1
- package/src/lib/data/parse/entry.ts +3 -2
- package/src/lib/data/parse/index.ts +1 -0
- package/src/lib/data/parse/layout.ts +5 -2
- package/src/lib/data/parse/slots.ts +3 -2
- package/src/lib/data/parse/widgets.ts +3 -2
- package/src/lib/data/scene.ts +1 -1
- package/src/lib/data/slot-io.ts +1 -0
- package/src/lib/dump.ts +4 -3
- package/src/lib/embed.ts +22 -0
- package/src/lib/favorite-hover.ts +1 -0
- package/src/lib/fluid-outputs.ts +10 -12
- package/src/lib/forge/actions.ts +2 -1
- package/src/lib/forge/data.ts +2 -1
- package/src/lib/forge/solve.ts +1 -0
- package/src/lib/group.ts +1 -0
- package/src/lib/index-store.ts +15 -9
- package/src/lib/links.ts +15 -9
- package/src/lib/lookup.ts +10 -8
- package/src/lib/panel-outline.ts +1 -0
- package/src/lib/panel.ts +3 -2
- package/src/lib/preview.ts +12 -8
- package/src/lib/recipe-slots.ts +1 -0
- package/src/lib/search.ts +1 -0
- package/src/lib/sidebar.ts +1 -0
- package/src/lib/used-items.ts +1 -0
- package/src/locales/en_us.json +170 -226
- package/src/locales/ru_ru.json +170 -226
- package/src/locales.ts +1 -0
- package/src/types/alloy.ts +1 -0
- package/src/{hooks/calc/flow/props.ts → types/calc-flow-props.ts} +18 -14
- package/src/types/calc.ts +41 -44
- package/src/types/forge.ts +1 -0
- package/src/types/index.ts +4 -2
- package/styles/calc.css +308 -47
- package/src/components/cards/fit-card.tsx +0 -26
- package/src/components/views/calc/target.tsx +0 -271
- package/src/hooks/calc/flow/engage.ts +0 -89
- package/src/hooks/calc/flow/handlers.ts +0 -115
- package/src/hooks/calc/flow/layout.ts +0 -149
- package/src/hooks/calc/flow/pickers.ts +0 -50
- package/src/hooks/calc/use-calc-fill.ts +0 -91
- package/src/hooks/calc/use-density.ts +0 -28
- package/src/hooks/calc/use-derived.ts +0 -258
- package/src/hooks/calc/use-direction.ts +0 -23
- package/src/hooks/calc/use-edge-style.ts +0 -40
- package/src/hooks/calc/use-fill.ts +0 -213
- package/src/lib/alloy/alloy.test.ts +0 -186
- package/src/lib/calc/tree/build.ts +0 -196
- package/src/lib/calc/tree/context.ts +0 -42
- package/src/lib/calc/tree/goal.ts +0 -64
- package/src/lib/calc/tree/ideal.ts +0 -36
- package/src/lib/calc/tree/pick.ts +0 -68
- package/src/lib/calc/tree/tree.test.ts +0 -169
- package/src/lib/calc/worker/fill.ts +0 -123
- package/src/lib/client-index/cache.ts +0 -13
- package/src/lib/forge/forge.test.ts +0 -123
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
'use client';
|
|
2
|
+
import type { DatasetRef } from '@terrafirmagreg-team/sites/location';
|
|
2
3
|
|
|
3
4
|
import { useTranslations } from '@terrafirmagreg-team/translate/hooks/use-translations';
|
|
4
5
|
import { EmptyState } from '@terrafirmagreg-team/ui/components/blocks/page/empty-state';
|
|
5
6
|
import { LinkPreview } from '@terrafirmagreg-team/ui/components/blocks/link/link-preview';
|
|
6
7
|
import { recipeItemName } from '@terrafirmagreg-team/recipe/lib/client-index';
|
|
7
|
-
import { tagPseudoId } from '@terrafirmagreg-team/
|
|
8
|
+
import { tagPseudoId } from '@terrafirmagreg-team/dump/lib/dump/paths';
|
|
8
9
|
import { recipeHref } from '@terrafirmagreg-team/recipe/lib/links';
|
|
9
10
|
import { replaceUrlState } from '@terrafirmagreg-team/ui/lib/utils/history';
|
|
10
11
|
import type { Lang } from '@terrafirmagreg-team/translate/types/locale';
|
|
@@ -19,7 +20,7 @@ export function ItemTagGroups({
|
|
|
19
20
|
nav,
|
|
20
21
|
}: {
|
|
21
22
|
groups: [string, string[]][];
|
|
22
|
-
dataset:
|
|
23
|
+
dataset: DatasetRef;
|
|
23
24
|
lang: Lang;
|
|
24
25
|
names: Record<string, Record<string, string>>;
|
|
25
26
|
query: string;
|
|
@@ -27,7 +28,7 @@ export function ItemTagGroups({
|
|
|
27
28
|
}) {
|
|
28
29
|
const t = useTranslations();
|
|
29
30
|
if (!groups.length) {
|
|
30
|
-
return <EmptyState variant="empty">{t('recipe.empty_tags')}</EmptyState>;
|
|
31
|
+
return <EmptyState variant="empty">{t('No tags for this item.', { note: 'recipe.empty_tags' })}</EmptyState>;
|
|
31
32
|
}
|
|
32
33
|
return (
|
|
33
34
|
<div className="flex flex-col gap-3 pt-1">
|
|
@@ -36,8 +37,8 @@ export function ItemTagGroups({
|
|
|
36
37
|
{groups.length > 1 && (
|
|
37
38
|
<p className="text-xs font-medium text-muted-foreground">
|
|
38
39
|
{tagKind === 'block'
|
|
39
|
-
? t('recipe.tags_block')
|
|
40
|
-
: t('recipe.tags_item')}
|
|
40
|
+
? t('Blocks', { note: 'recipe.tags_block' })
|
|
41
|
+
: t('Items', { note: 'recipe.tags_item' })}
|
|
41
42
|
</p>
|
|
42
43
|
)}
|
|
43
44
|
<div className="flex flex-wrap gap-1">
|
|
@@ -81,3 +82,4 @@ export function ItemTagGroups({
|
|
|
81
82
|
</div>
|
|
82
83
|
);
|
|
83
84
|
}
|
|
85
|
+
|
|
@@ -15,9 +15,9 @@ import {
|
|
|
15
15
|
PopoverTitle,
|
|
16
16
|
PopoverTrigger,
|
|
17
17
|
} from '@terrafirmagreg-team/ui/components/ui/popover';
|
|
18
|
-
import { formatNbt, formatNbtPretty } from '@terrafirmagreg-team/
|
|
19
|
-
import type { ParsedStackId } from '@terrafirmagreg-team/
|
|
20
|
-
import type { ReferenceKind } from '@terrafirmagreg-team/
|
|
18
|
+
import { formatNbt, formatNbtPretty } from '@terrafirmagreg-team/dump/lib/snbt';
|
|
19
|
+
import type { ParsedStackId } from '@terrafirmagreg-team/dump/lib/dump/contract/ref';
|
|
20
|
+
import type { ReferenceKind } from '@terrafirmagreg-team/dump/lib/dump/contract/ref';
|
|
21
21
|
|
|
22
22
|
export function ItemViewHeader({
|
|
23
23
|
item,
|
|
@@ -42,7 +42,7 @@ export function ItemViewHeader({
|
|
|
42
42
|
const pretty =
|
|
43
43
|
parsed.nbt !== undefined ? formatNbtPretty(parsed.nbt) : undefined;
|
|
44
44
|
const copyId = held.shift && nbt ? `${parsed.id}${nbt}` : parsed.id;
|
|
45
|
-
const copyTitle = held.shift ? t('recipe.copy_stack') : t('recipe.copy');
|
|
45
|
+
const copyTitle = held.shift ? t('Copy stack id', { note: 'recipe.copy_stack' }) : t('Copy id', { note: 'recipe.copy' });
|
|
46
46
|
return (
|
|
47
47
|
<>
|
|
48
48
|
<ItemRow
|
|
@@ -82,7 +82,7 @@ export function ItemViewHeader({
|
|
|
82
82
|
<IconButton
|
|
83
83
|
variant="ghost"
|
|
84
84
|
tooltip={false}
|
|
85
|
-
label={t('recipe.nbt')}
|
|
85
|
+
label={t('NBT', { note: 'recipe.nbt' })}
|
|
86
86
|
className="size-7 rounded-lg text-muted-foreground hover:text-foreground [&_svg]:size-3.5"
|
|
87
87
|
>
|
|
88
88
|
<Braces />
|
|
@@ -95,12 +95,12 @@ export function ItemViewHeader({
|
|
|
95
95
|
>
|
|
96
96
|
<div className="flex items-center justify-between">
|
|
97
97
|
<PopoverTitle className="text-xs font-medium tracking-wider text-muted-foreground uppercase">
|
|
98
|
-
{t('recipe.nbt')}
|
|
98
|
+
{t('NBT', { note: 'recipe.nbt' })}
|
|
99
99
|
</PopoverTitle>
|
|
100
100
|
<ButtonCopy
|
|
101
101
|
value={nbt}
|
|
102
|
-
title={t('recipe.copy_nbt')}
|
|
103
|
-
aria-label={t('recipe.copy_nbt')}
|
|
102
|
+
title={t('Copy NBT', { note: 'recipe.copy_nbt' })}
|
|
103
|
+
aria-label={t('Copy NBT', { note: 'recipe.copy_nbt' })}
|
|
104
104
|
copy={<Copy className="size-3" />}
|
|
105
105
|
copied={<Check className="size-3" />}
|
|
106
106
|
/>
|
|
@@ -114,7 +114,7 @@ export function ItemViewHeader({
|
|
|
114
114
|
{onAddToCalc ? (
|
|
115
115
|
<IconButton
|
|
116
116
|
variant="ghost"
|
|
117
|
-
label={t('recipe.calc.add.title')}
|
|
117
|
+
label={t('Add to calculator', { note: 'recipe.calc.add.title' })}
|
|
118
118
|
className="size-7 rounded-lg text-muted-foreground hover:text-foreground [&_svg]:size-3.5"
|
|
119
119
|
onClick={onAddToCalc}
|
|
120
120
|
>
|
|
@@ -128,3 +128,4 @@ export function ItemViewHeader({
|
|
|
128
128
|
</>
|
|
129
129
|
);
|
|
130
130
|
}
|
|
131
|
+
|
|
@@ -25,7 +25,7 @@ export function PlaceHeader({
|
|
|
25
25
|
? index?.categories?.find((row) => row.id === placeId)
|
|
26
26
|
: undefined;
|
|
27
27
|
const title = isCalc
|
|
28
|
-
? t('recipe.calculator')
|
|
28
|
+
? t('Calculator', { note: 'recipe.calculator' })
|
|
29
29
|
: placeId
|
|
30
30
|
? recipeItemName(names, lang, placeId)
|
|
31
31
|
: '';
|
|
@@ -58,8 +58,8 @@ export function PlaceHeader({
|
|
|
58
58
|
<span className="truncate">{placeId}</span>
|
|
59
59
|
<ButtonCopy
|
|
60
60
|
value={placeId}
|
|
61
|
-
title={t('recipe.copy')}
|
|
62
|
-
aria-label={t('recipe.copy')}
|
|
61
|
+
title={t('Copy id', { note: 'recipe.copy' })}
|
|
62
|
+
aria-label={t('Copy id', { note: 'recipe.copy' })}
|
|
63
63
|
copy={<Copy className="size-3" />}
|
|
64
64
|
copied={<Check className="size-3" />}
|
|
65
65
|
/>
|
|
@@ -69,3 +69,4 @@ export function PlaceHeader({
|
|
|
69
69
|
/>
|
|
70
70
|
);
|
|
71
71
|
}
|
|
72
|
+
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
'use client';
|
|
2
|
+
import type { DatasetRef } from '@terrafirmagreg-team/sites/location';
|
|
2
3
|
|
|
3
4
|
import type { ReactNode } from 'react';
|
|
4
5
|
import { Search } from 'lucide-react';
|
|
@@ -15,7 +16,7 @@ import type { Lang } from '@terrafirmagreg-team/translate/types/locale';
|
|
|
15
16
|
import type { RecipeHrefOpts } from '@terrafirmagreg-team/recipe/types';
|
|
16
17
|
|
|
17
18
|
type QueryNav = {
|
|
18
|
-
dataset:
|
|
19
|
+
dataset: DatasetRef;
|
|
19
20
|
lang: Lang;
|
|
20
21
|
params?: RecipeHrefOpts;
|
|
21
22
|
};
|
|
@@ -101,3 +102,4 @@ export function QueryPager({
|
|
|
101
102
|
/>
|
|
102
103
|
);
|
|
103
104
|
}
|
|
105
|
+
|
|
@@ -7,8 +7,8 @@ import { Entry } from '@terrafirmagreg-team/game/components/entry/entry';
|
|
|
7
7
|
import { CopyIdMenu } from '@terrafirmagreg-team/game/components/entry/copy-id-menu';
|
|
8
8
|
import { ButtonCopy } from '@terrafirmagreg-team/recipe/components/button-copy';
|
|
9
9
|
import { recipeItemName } from '@terrafirmagreg-team/recipe/lib/client-index';
|
|
10
|
-
import { parseStackId } from '@terrafirmagreg-team/
|
|
11
|
-
import { formatNbt } from '@terrafirmagreg-team/
|
|
10
|
+
import { parseStackId } from '@terrafirmagreg-team/dump/lib/dump/contract/ref';
|
|
11
|
+
import { formatNbt } from '@terrafirmagreg-team/dump/lib/snbt';
|
|
12
12
|
import type { Recipe } from '@terrafirmagreg-team/recipe/lib/data/dto';
|
|
13
13
|
import type { RecipeSession } from '@terrafirmagreg-team/recipe/types';
|
|
14
14
|
|
|
@@ -47,8 +47,8 @@ export function RecipeItemHeader({
|
|
|
47
47
|
<span className="truncate">{recipe.id}</span>
|
|
48
48
|
<ButtonCopy
|
|
49
49
|
value={recipe.id}
|
|
50
|
-
title={t('recipe.copy_recipe_id')}
|
|
51
|
-
aria-label={t('recipe.copy_recipe_id')}
|
|
50
|
+
title={t('Copy recipe id', { note: 'recipe.copy_recipe_id' })}
|
|
51
|
+
aria-label={t('Copy recipe id', { note: 'recipe.copy_recipe_id' })}
|
|
52
52
|
copy={<Copy className="size-3" />}
|
|
53
53
|
copied={<Check className="size-3" />}
|
|
54
54
|
/>
|
|
@@ -57,3 +57,4 @@ export function RecipeItemHeader({
|
|
|
57
57
|
/>
|
|
58
58
|
);
|
|
59
59
|
}
|
|
60
|
+
|
|
@@ -25,7 +25,7 @@ export function RecipeSettings() {
|
|
|
25
25
|
<Button
|
|
26
26
|
variant="outline"
|
|
27
27
|
size="icon-sm"
|
|
28
|
-
aria-label={t('recipe.settings')}
|
|
28
|
+
aria-label={t('Settings', { note: 'recipe.settings' })}
|
|
29
29
|
className="rounded-lg"
|
|
30
30
|
/>
|
|
31
31
|
}
|
|
@@ -35,7 +35,7 @@ export function RecipeSettings() {
|
|
|
35
35
|
<PopoverContent align="start" className="flex w-56 flex-col gap-2">
|
|
36
36
|
<Label className="gap-1.5 text-sm font-normal">
|
|
37
37
|
<Switch size="sm" checked={hideUnused} onCheckedChange={setHideUnused} />
|
|
38
|
-
{t('recipe.hide_unused')}
|
|
38
|
+
{t('Hide unused', { note: 'recipe.hide_unused' })}
|
|
39
39
|
</Label>
|
|
40
40
|
<Label className="gap-1.5 text-sm font-normal">
|
|
41
41
|
<Switch
|
|
@@ -43,9 +43,10 @@ export function RecipeSettings() {
|
|
|
43
43
|
checked={sidebarGroup === 'mod'}
|
|
44
44
|
onCheckedChange={(value) => setSidebarGroup(value ? 'mod' : 'flat')}
|
|
45
45
|
/>
|
|
46
|
-
{t('recipe.sidebar_group_mod')}
|
|
46
|
+
{t('Group sidebar by mod', { note: 'recipe.sidebar_group_mod' })}
|
|
47
47
|
</Label>
|
|
48
48
|
</PopoverContent>
|
|
49
49
|
</Popover>
|
|
50
50
|
);
|
|
51
51
|
}
|
|
52
|
+
|
|
@@ -26,12 +26,12 @@ export function RecipeToolbar({ session }: { session: RecipeSession }) {
|
|
|
26
26
|
onClick={() => setItemsOpen(true)}
|
|
27
27
|
>
|
|
28
28
|
<LayoutGrid className="size-3.5" />
|
|
29
|
-
{t('recipe.items')}
|
|
29
|
+
{t('Items', { note: 'recipe.items' })}
|
|
30
30
|
</Button>
|
|
31
31
|
<Sheet open={itemsOpen} onOpenChange={setItemsOpen}>
|
|
32
32
|
<SheetContent side="right" className="w-full gap-3 sm:max-w-md">
|
|
33
33
|
<SheetHeader>
|
|
34
|
-
<SheetTitle>{t('recipe.items')}</SheetTitle>
|
|
34
|
+
<SheetTitle>{t('Items', { note: 'recipe.items' })}</SheetTitle>
|
|
35
35
|
</SheetHeader>
|
|
36
36
|
<ItemPanel
|
|
37
37
|
dataset={session.dataset}
|
|
@@ -51,3 +51,4 @@ export function RecipeToolbar({ session }: { session: RecipeSession }) {
|
|
|
51
51
|
</div>
|
|
52
52
|
);
|
|
53
53
|
}
|
|
54
|
+
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
'use client';
|
|
2
|
+
import type { DatasetRef } from '@terrafirmagreg-team/sites/location';
|
|
2
3
|
|
|
3
4
|
import { useMemo } from 'react';
|
|
4
5
|
import { Shapes } from 'lucide-react';
|
|
5
6
|
import { Entry } from '@terrafirmagreg-team/game/components/entry/entry';
|
|
6
7
|
import { recipeItemName } from '@terrafirmagreg-team/recipe/lib/client-index';
|
|
7
|
-
import {
|
|
8
|
+
import { IconPager } from '@terrafirmagreg-team/ui/components/blocks/page/pager';
|
|
8
9
|
import type { RecipeCategory, RecipeSession } from '@terrafirmagreg-team/recipe/types';
|
|
9
10
|
|
|
10
11
|
function CategoryGlyph({
|
|
@@ -12,7 +13,7 @@ function CategoryGlyph({
|
|
|
12
13
|
dataset,
|
|
13
14
|
}: {
|
|
14
15
|
category?: RecipeCategory;
|
|
15
|
-
dataset:
|
|
16
|
+
dataset: DatasetRef;
|
|
16
17
|
}) {
|
|
17
18
|
return category?.icon ? (
|
|
18
19
|
<Entry
|
|
@@ -59,7 +60,7 @@ export function RecipeTypeTabs({
|
|
|
59
60
|
}, [index, ids, lang, names, dataset]);
|
|
60
61
|
|
|
61
62
|
return (
|
|
62
|
-
<
|
|
63
|
+
<IconPager
|
|
63
64
|
value={value}
|
|
64
65
|
options={options}
|
|
65
66
|
onChange={onChange ?? (() => {})}
|
|
@@ -67,3 +68,4 @@ export function RecipeTypeTabs({
|
|
|
67
68
|
/>
|
|
68
69
|
);
|
|
69
70
|
}
|
|
71
|
+
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
|
-
import { useEffect,
|
|
3
|
+
import { useEffect, useRef } from 'react';
|
|
4
4
|
import { useTranslations } from '@terrafirmagreg-team/translate/hooks/use-translations';
|
|
5
5
|
import { useAsyncResult, useAsyncValue } from '@terrafirmagreg-team/ui/hooks/use-async-value';
|
|
6
6
|
import { RecipeFrame } from '@terrafirmagreg-team/recipe/components/views/browser/frame';
|
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
recipeCardDim,
|
|
10
10
|
} from '@terrafirmagreg-team/recipe/components/views/browser/card-grid';
|
|
11
11
|
import { PlaceHeader } from '@terrafirmagreg-team/recipe/components/views/browser/place-header';
|
|
12
|
+
import { useCategoriesById } from '@terrafirmagreg-team/recipe/hooks/use-categories-by-id';
|
|
12
13
|
import { useFitPages } from '@terrafirmagreg-team/ui/hooks/page/use-fit-pages';
|
|
13
14
|
import {
|
|
14
15
|
loadTypeRows,
|
|
@@ -20,7 +21,6 @@ import { RecipeTypeTabs } from '@terrafirmagreg-team/recipe/components/views/bro
|
|
|
20
21
|
import { WorkstationRail } from '@terrafirmagreg-team/recipe/components/views/browser/workstation-rail';
|
|
21
22
|
import { replaceUrlState } from '@terrafirmagreg-team/ui/lib/utils/history';
|
|
22
23
|
import type {
|
|
23
|
-
RecipeCategory,
|
|
24
24
|
RecipeCompactRow,
|
|
25
25
|
RecipeSession,
|
|
26
26
|
} from '@terrafirmagreg-team/recipe/types';
|
|
@@ -43,13 +43,7 @@ export function TypeView({ session }: { session: RecipeSession }) {
|
|
|
43
43
|
|
|
44
44
|
const placeId = place?.kind === 'type' ? place.id : RECIPE_ALL_TYPE;
|
|
45
45
|
|
|
46
|
-
const categoriesById =
|
|
47
|
-
() =>
|
|
48
|
-
new Map<string, RecipeCategory>(
|
|
49
|
-
(index?.categories ?? []).map((row) => [row.id, row]),
|
|
50
|
-
),
|
|
51
|
-
[index],
|
|
52
|
-
);
|
|
46
|
+
const categoriesById = useCategoriesById(index);
|
|
53
47
|
const nonEmptyIds = nonEmptyCategoryIds(index);
|
|
54
48
|
|
|
55
49
|
const shown =
|
|
@@ -133,7 +127,7 @@ export function TypeView({ session }: { session: RecipeSession }) {
|
|
|
133
127
|
session={session}
|
|
134
128
|
rows={EMPTY_ROWS}
|
|
135
129
|
boxRef={boxRef}
|
|
136
|
-
empty={t('recipe.no_dump')}
|
|
130
|
+
empty={t('No recipe dump for this dataset. Run export to generate data.', { note: 'recipe.no_dump' })}
|
|
137
131
|
/>
|
|
138
132
|
) : (
|
|
139
133
|
<RecipeCardGrid
|
|
@@ -143,7 +137,7 @@ export function TypeView({ session }: { session: RecipeSession }) {
|
|
|
143
137
|
maxH={list.box.h}
|
|
144
138
|
maxW={list.box.w}
|
|
145
139
|
loading={index == null || (shown != null && rows === undefined)}
|
|
146
|
-
empty={t('recipe.empty_type')}
|
|
140
|
+
empty={t('No recipes of this type.', { note: 'recipe.empty_type' })}
|
|
147
141
|
onSwipe={onSwipe}
|
|
148
142
|
/>
|
|
149
143
|
);
|
|
@@ -172,7 +166,7 @@ export function TypeView({ session }: { session: RecipeSession }) {
|
|
|
172
166
|
/>
|
|
173
167
|
}
|
|
174
168
|
header={
|
|
175
|
-
<PlaceHeader session={session} overline={t('recipe.axis_type')} />
|
|
169
|
+
<PlaceHeader session={session} overline={t('Categories', { note: 'recipe.axis_type' })} />
|
|
176
170
|
}
|
|
177
171
|
rail={
|
|
178
172
|
<WorkstationRail
|
|
@@ -187,3 +181,4 @@ export function TypeView({ session }: { session: RecipeSession }) {
|
|
|
187
181
|
</RecipeFrame>
|
|
188
182
|
);
|
|
189
183
|
}
|
|
184
|
+
|
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
import { Factory } from 'lucide-react';
|
|
4
4
|
import { Entry } from '@terrafirmagreg-team/game/components/entry/entry';
|
|
5
5
|
import { recipeItemName } from '@terrafirmagreg-team/recipe/lib/client-index';
|
|
6
|
-
import { stackIdFromRef } from '@terrafirmagreg-team/
|
|
7
|
-
import type { TaggedReference } from '@terrafirmagreg-team/
|
|
6
|
+
import { stackIdFromRef } from '@terrafirmagreg-team/dump/lib/dump/contract/ref';
|
|
7
|
+
import type { TaggedReference } from '@terrafirmagreg-team/dump/lib/dump/contract/ref';
|
|
8
8
|
import type { RecipeSession } from '@terrafirmagreg-team/recipe/types';
|
|
9
9
|
|
|
10
10
|
export function WorkstationRail({
|
|
@@ -17,7 +17,7 @@ export function WorkstationRail({
|
|
|
17
17
|
if (!workstations?.length) return null;
|
|
18
18
|
const { lang, names, nav } = session;
|
|
19
19
|
return (
|
|
20
|
-
<div className="flex max-h-full
|
|
20
|
+
<div className="scrollbar-thin flex max-h-full flex-col items-center gap-1 self-start overflow-y-auto overflow-x-hidden rounded-lg border border-border bg-muted/60 p-1">
|
|
21
21
|
<Factory
|
|
22
22
|
className="m-1 size-3.5 shrink-0 text-muted-foreground"
|
|
23
23
|
aria-hidden
|
|
@@ -40,3 +40,4 @@ export function WorkstationRail({
|
|
|
40
40
|
</div>
|
|
41
41
|
);
|
|
42
42
|
}
|
|
43
|
+
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import { Share2, Trash2 } from 'lucide-react';
|
|
4
4
|
import { IconButton } from '@terrafirmagreg-team/ui/components/blocks/button/icon-button';
|
|
5
5
|
import { useTranslations } from '@terrafirmagreg-team/translate/hooks/use-translations';
|
|
6
6
|
import { RecipeToolbar } from '@terrafirmagreg-team/recipe/components/views/browser/toolbar';
|
|
@@ -12,14 +12,12 @@ export function CalcActions({
|
|
|
12
12
|
shared,
|
|
13
13
|
onShare,
|
|
14
14
|
hasTargets,
|
|
15
|
-
onAutoBuild,
|
|
16
15
|
onClear,
|
|
17
16
|
}: {
|
|
18
17
|
session: RecipeSession;
|
|
19
18
|
shared: boolean;
|
|
20
19
|
onShare: () => void;
|
|
21
20
|
hasTargets: boolean;
|
|
22
|
-
onAutoBuild: () => void;
|
|
23
21
|
onClear: () => void;
|
|
24
22
|
}) {
|
|
25
23
|
const t = useTranslations();
|
|
@@ -28,7 +26,7 @@ export function CalcActions({
|
|
|
28
26
|
<RecipeToolbar session={session} />
|
|
29
27
|
<IconButton
|
|
30
28
|
overlay
|
|
31
|
-
label={shared ? t('recipe.copied') : t('recipe.calc.share')}
|
|
29
|
+
label={shared ? t('Copied', { note: 'recipe.copied' }) : t('Share', { note: 'recipe.calc.share' })}
|
|
32
30
|
onClick={onShare}
|
|
33
31
|
>
|
|
34
32
|
<Share2 className="size-3.5" />
|
|
@@ -37,16 +35,7 @@ export function CalcActions({
|
|
|
37
35
|
{hasTargets ? (
|
|
38
36
|
<IconButton
|
|
39
37
|
overlay
|
|
40
|
-
label={t('recipe.calc.
|
|
41
|
-
onClick={onAutoBuild}
|
|
42
|
-
>
|
|
43
|
-
<Play className="size-3.5" />
|
|
44
|
-
</IconButton>
|
|
45
|
-
) : null}
|
|
46
|
-
{hasTargets ? (
|
|
47
|
-
<IconButton
|
|
48
|
-
overlay
|
|
49
|
-
label={t('recipe.calc.clear.title')}
|
|
38
|
+
label={t('Clear', { note: 'recipe.calc.clear.title' })}
|
|
50
39
|
onClick={onClear}
|
|
51
40
|
>
|
|
52
41
|
<Trash2 className="size-3.5" />
|
|
@@ -55,3 +44,4 @@ export function CalcActions({
|
|
|
55
44
|
</>
|
|
56
45
|
);
|
|
57
46
|
}
|
|
47
|
+
|
|
@@ -2,10 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
import {
|
|
4
4
|
ArrowUp,
|
|
5
|
+
ChevronUp,
|
|
5
6
|
ChevronsUpDown,
|
|
6
7
|
Eye,
|
|
7
8
|
Info,
|
|
9
|
+
Mountain,
|
|
8
10
|
Move,
|
|
11
|
+
Scissors,
|
|
9
12
|
Settings2,
|
|
10
13
|
SquareMousePointer,
|
|
11
14
|
} from 'lucide-react';
|
|
@@ -22,39 +25,33 @@ export function CalcHelp() {
|
|
|
22
25
|
return (
|
|
23
26
|
<Popover>
|
|
24
27
|
<PopoverTrigger
|
|
25
|
-
render={<IconButton overlay label={t('recipe.calc.help.title')} />}
|
|
28
|
+
render={<IconButton overlay label={t('Calculator help', { note: 'recipe.calc.help.title' })} />}
|
|
26
29
|
>
|
|
27
30
|
<Info className="size-3.5" />
|
|
28
31
|
</PopoverTrigger>
|
|
29
32
|
<PopoverContent side="bottom" align="end" className="w-80 space-y-3 p-3">
|
|
30
33
|
<section className="space-y-1.5">
|
|
31
34
|
<h4 className="text-[10px] font-semibold uppercase tracking-wider text-muted-foreground/70">
|
|
32
|
-
{t('recipe.calc.help.sec_nodes')}
|
|
35
|
+
{t('Nodes', { note: 'recipe.calc.help.sec_nodes' })}
|
|
33
36
|
</h4>
|
|
34
37
|
<ul className="space-y-1.5 text-xs text-muted-foreground">
|
|
35
38
|
<li className="flex items-center gap-2">
|
|
36
39
|
<span className="flex w-5 shrink-0 items-center justify-center">
|
|
37
40
|
<span className="size-4 rounded border border-primary/60" />
|
|
38
41
|
</span>
|
|
39
|
-
{t('recipe.calc.help.recipe')}
|
|
40
|
-
</li>
|
|
41
|
-
<li className="flex items-center gap-2">
|
|
42
|
-
<span className="flex w-5 shrink-0 items-center justify-center">
|
|
43
|
-
<span className="size-4 rounded border border-dashed border-muted-foreground/50" />
|
|
44
|
-
</span>
|
|
45
|
-
{t('recipe.calc.help.catalyst')}
|
|
42
|
+
{t('Resolved with a recipe', { note: 'recipe.calc.help.recipe' })}
|
|
46
43
|
</li>
|
|
47
44
|
<li className="flex items-center gap-2">
|
|
48
45
|
<span className="flex w-5 shrink-0 items-center justify-center">
|
|
49
46
|
<span className="size-4 rounded border border-red-500/70" />
|
|
50
47
|
</span>
|
|
51
|
-
{t('recipe.calc.help.cycle')}
|
|
48
|
+
{t('Recipe cycle', { note: 'recipe.calc.help.cycle' })}
|
|
52
49
|
</li>
|
|
53
50
|
<li className="flex items-center gap-2">
|
|
54
51
|
<span className="flex w-5 shrink-0 items-center justify-center">
|
|
55
52
|
<span className="size-3.5 rounded ring-2 ring-primary/70" />
|
|
56
53
|
</span>
|
|
57
|
-
{t('recipe.calc.help.focus')}
|
|
54
|
+
{t('Focused node', { note: 'recipe.calc.help.focus' })}
|
|
58
55
|
</li>
|
|
59
56
|
<li className="flex items-center gap-2">
|
|
60
57
|
<span className="flex w-5 shrink-0 items-center justify-center">
|
|
@@ -62,83 +59,126 @@ export function CalcHelp() {
|
|
|
62
59
|
+N
|
|
63
60
|
</span>
|
|
64
61
|
</span>
|
|
65
|
-
{t('recipe.calc.help.satisfied')}
|
|
62
|
+
{t('Covered by another card output', { note: 'recipe.calc.help.satisfied' })}
|
|
66
63
|
</li>
|
|
67
64
|
<li className="flex items-center gap-2">
|
|
68
65
|
<span className="flex w-5 shrink-0 items-center justify-center">
|
|
69
|
-
<
|
|
70
|
-
S
|
|
71
|
-
</span>
|
|
66
|
+
<Mountain className="size-3.5 text-muted-foreground" />
|
|
72
67
|
</span>
|
|
73
|
-
{t('recipe.calc.help.source')}
|
|
68
|
+
{t('No recipe; raw material', { note: 'recipe.calc.help.source' })}
|
|
74
69
|
</li>
|
|
75
70
|
</ul>
|
|
76
71
|
</section>
|
|
77
72
|
<section className="space-y-1.5">
|
|
78
73
|
<h4 className="text-[10px] font-semibold uppercase tracking-wider text-muted-foreground/70">
|
|
79
|
-
{t('recipe.calc.help.
|
|
74
|
+
{t('Ports', { note: 'recipe.calc.help.sec_ports' })}
|
|
75
|
+
</h4>
|
|
76
|
+
<ul className="space-y-1.5 text-xs text-muted-foreground">
|
|
77
|
+
<li className="flex items-center gap-2">
|
|
78
|
+
<span className="flex w-5 shrink-0 items-center justify-center">
|
|
79
|
+
<span className="size-3.5 rounded-sm border border-emerald-500" />
|
|
80
|
+
</span>
|
|
81
|
+
{t('Input port: click to pick a supplier or drag a wire', { note: 'recipe.calc.help.port_in' })}
|
|
82
|
+
</li>
|
|
83
|
+
<li className="flex items-center gap-2">
|
|
84
|
+
<span className="flex w-5 shrink-0 items-center justify-center">
|
|
85
|
+
<span className="size-3.5 rounded-sm border border-red-400" />
|
|
86
|
+
</span>
|
|
87
|
+
{t('Output port: click to pick a recipe or drag a wire', { note: 'recipe.calc.help.port_out' })}
|
|
88
|
+
</li>
|
|
89
|
+
<li className="flex items-center gap-2">
|
|
90
|
+
<span className="flex w-5 shrink-0 items-center justify-center">
|
|
91
|
+
<span className="size-3.5 rounded-sm border border-dotted border-emerald-500" />
|
|
92
|
+
</span>
|
|
93
|
+
{t('Catalyst: needed but not consumed; wire it or click to pick a supplier', { note: 'recipe.calc.help.port_cat' })}
|
|
94
|
+
</li>
|
|
95
|
+
<li className="flex items-center gap-2">
|
|
96
|
+
<span className="flex w-5 shrink-0 items-center justify-center">
|
|
97
|
+
<ChevronUp className="size-3.5 text-muted-foreground" />
|
|
98
|
+
</span>
|
|
99
|
+
{t('Hidden ports - scroll the rail or click the arrow', { note: 'recipe.calc.help.port_more' })}
|
|
100
|
+
</li>
|
|
101
|
+
</ul>
|
|
102
|
+
</section>
|
|
103
|
+
<section className="space-y-1.5">
|
|
104
|
+
<h4 className="text-[10px] font-semibold uppercase tracking-wider text-muted-foreground/70">
|
|
105
|
+
{t('Edges', { note: 'recipe.calc.help.sec_edges' })}
|
|
80
106
|
</h4>
|
|
81
107
|
<ul className="space-y-1.5 text-xs text-muted-foreground">
|
|
82
108
|
<li className="flex items-center gap-2">
|
|
83
109
|
<span className="flex w-5 shrink-0 items-center justify-center">
|
|
84
110
|
<ArrowUp className="size-3.5 text-muted-foreground" />
|
|
85
111
|
</span>
|
|
86
|
-
{t('recipe.calc.help.edges')}
|
|
112
|
+
{t('Arrows flow from ingredient to product', { note: 'recipe.calc.help.edges' })}
|
|
87
113
|
</li>
|
|
88
114
|
<li className="flex items-center gap-2">
|
|
89
115
|
<span className="flex w-5 shrink-0 items-center justify-center">
|
|
90
116
|
<span className="h-0.5 w-4 rounded bg-teal-500" />
|
|
91
117
|
</span>
|
|
92
|
-
{t('recipe.calc.help.edge_out')}
|
|
118
|
+
{t('Outgoing edges', { note: 'recipe.calc.help.edge_out' })}
|
|
93
119
|
</li>
|
|
94
120
|
<li className="flex items-center gap-2">
|
|
95
121
|
<span className="flex w-5 shrink-0 items-center justify-center">
|
|
96
122
|
<span className="h-0.5 w-4 rounded bg-yellow-500" />
|
|
97
123
|
</span>
|
|
98
|
-
{t('recipe.calc.help.edge_in')}
|
|
124
|
+
{t('Incoming edges', { note: 'recipe.calc.help.edge_in' })}
|
|
125
|
+
</li>
|
|
126
|
+
<li className="flex items-center gap-2">
|
|
127
|
+
<span className="flex w-5 shrink-0 items-center justify-center">
|
|
128
|
+
<span className="h-0 w-4 border-t border-dashed border-primary/70" />
|
|
129
|
+
</span>
|
|
130
|
+
{t('Drag port to port to link; drag a wire end to retarget', { note: 'recipe.calc.help.edge_link' })}
|
|
99
131
|
</li>
|
|
100
132
|
<li className="flex items-center gap-2">
|
|
101
133
|
<span className="flex w-5 shrink-0 items-center justify-center">
|
|
102
|
-
<span className="
|
|
134
|
+
<span className="rounded border border-border bg-background px-0.5 text-[9px] leading-3 tabular-nums">
|
|
135
|
+
16
|
|
136
|
+
</span>
|
|
103
137
|
</span>
|
|
104
|
-
{t('recipe.calc.help.
|
|
138
|
+
{t('Flow on a wire - shows on hover; click to cap the amount', { note: 'recipe.calc.help.edge_flow' })}
|
|
139
|
+
</li>
|
|
140
|
+
<li className="flex items-center gap-2">
|
|
141
|
+
<span className="flex w-5 shrink-0 items-center justify-center">
|
|
142
|
+
<Scissors className="size-3.5 text-muted-foreground" />
|
|
143
|
+
</span>
|
|
144
|
+
{t('Shift + hover a wire shows x - click to delete it', { note: 'recipe.calc.help.edge_cut' })}
|
|
105
145
|
</li>
|
|
106
146
|
</ul>
|
|
107
147
|
</section>
|
|
108
148
|
<section className="space-y-1.5">
|
|
109
149
|
<h4 className="text-[10px] font-semibold uppercase tracking-wider text-muted-foreground/70">
|
|
110
|
-
{t('recipe.calc.help.sec_actions')}
|
|
150
|
+
{t('Actions', { note: 'recipe.calc.help.sec_actions' })}
|
|
111
151
|
</h4>
|
|
112
152
|
<ul className="space-y-1.5 text-xs text-muted-foreground">
|
|
113
153
|
<li className="flex items-center gap-2">
|
|
114
154
|
<span className="flex w-5 shrink-0 items-center justify-center">
|
|
115
155
|
<ChevronsUpDown className="size-3.5 text-muted-foreground" />
|
|
116
156
|
</span>
|
|
117
|
-
{t('recipe.calc.help.chip')}
|
|
157
|
+
{t('Recipe/tag member: open picker', { note: 'recipe.calc.help.chip' })}
|
|
118
158
|
</li>
|
|
119
159
|
<li className="flex items-center gap-2">
|
|
120
160
|
<span className="flex w-5 shrink-0 items-center justify-center">
|
|
121
161
|
<Eye className="size-3.5 text-muted-foreground" />
|
|
122
162
|
</span>
|
|
123
|
-
{t('recipe.calc.help.hover')}
|
|
163
|
+
{t('Recipe preview', { note: 'recipe.calc.help.hover' })}
|
|
124
164
|
</li>
|
|
125
165
|
<li className="flex items-center gap-2">
|
|
126
166
|
<span className="flex w-5 shrink-0 items-center justify-center">
|
|
127
167
|
<SquareMousePointer className="size-3.5 text-muted-foreground" />
|
|
128
168
|
</span>
|
|
129
|
-
{t('recipe.calc.help.ctx')}
|
|
169
|
+
{t('Node context menu', { note: 'recipe.calc.help.ctx' })}
|
|
130
170
|
</li>
|
|
131
171
|
<li className="flex items-center gap-2">
|
|
132
172
|
<span className="flex w-5 shrink-0 items-center justify-center">
|
|
133
173
|
<Settings2 className="size-3.5 text-muted-foreground" />
|
|
134
174
|
</span>
|
|
135
|
-
{t('recipe.calc.help.modes')}
|
|
175
|
+
{t('View modes', { note: 'recipe.calc.help.modes' })}
|
|
136
176
|
</li>
|
|
137
177
|
<li className="flex items-center gap-2">
|
|
138
178
|
<span className="flex w-5 shrink-0 items-center justify-center">
|
|
139
179
|
<Move className="size-3.5 text-muted-foreground" />
|
|
140
180
|
</span>
|
|
141
|
-
{t('recipe.calc.help.nav')}
|
|
181
|
+
{t('Pan and zoom', { note: 'recipe.calc.help.nav' })}
|
|
142
182
|
</li>
|
|
143
183
|
</ul>
|
|
144
184
|
</section>
|
|
@@ -146,3 +186,4 @@ export function CalcHelp() {
|
|
|
146
186
|
</Popover>
|
|
147
187
|
);
|
|
148
188
|
}
|
|
189
|
+
|