@gntik-ai/templates 0.10.0 → 0.11.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.ts CHANGED
@@ -648,6 +648,17 @@ declare function ResetPasswordPage({ onSubmit, onContinue, error, minPasswordLen
648
648
  //#region src/reset-password/template.meta.d.ts
649
649
  declare const meta$29: TemplateMeta;
650
650
  //#endregion
651
+ //#region src/resource-detail/CustomTabs.d.ts
652
+ interface CustomTabsProps {
653
+ tabs: {
654
+ value: string;
655
+ label: string;
656
+ content: ReactNode;
657
+ }[];
658
+ defaultTab?: string;
659
+ onTabChange?: (tab: string) => void;
660
+ }
661
+ //#endregion
651
662
  //#region src/resource-detail/data.d.ts
652
663
  /** The editable part of the resource (Settings tab). */
653
664
  interface ResourceSettings {
@@ -663,11 +674,11 @@ interface ResourceDetailLabels {
663
674
  settings: string;
664
675
  sections: string;
665
676
  }
666
- interface ResourceDetailProps {
677
+ interface ResourceDetailBaseProps {
667
678
  /** Per-key copy overrides; explicit props take precedence, then labels, then the active catalog. */
668
679
  labels?: Partial<ResourceDetailLabels>;
669
680
  /**
670
- * Optional boolean, default false. Shows only the keyboard-accessible Overview tab in
681
+ * Optional boolean, default false. With built-in tabs, shows only the keyboard-accessible Overview tab in
671
682
  * the "Resource sections" tablist, using explicit resource props without sample defaults.
672
683
  * Ignores activity, events, dangerActions, defaultTab, onSaveSettings and onDangerAction.
673
684
  * Explicit actions and onEditDetails are still honored. ConsoleShell defaults are unchanged.
@@ -696,16 +707,31 @@ interface ResourceDetailProps {
696
707
  events: readonly StatusEvent[];
697
708
  activity: readonly ActivityItem[];
698
709
  dangerActions: DangerZoneAction[];
699
- defaultTab: ResourceDetailTab;
700
- onTabChange: (tab: ResourceDetailTab) => void;
701
710
  onEditDetails: () => void;
702
711
  onSaveSettings: (settings: ResourceSettings) => void;
703
712
  /** Confirmed Danger zone action id (e.g. `pause`, `delete`). */
704
713
  onDangerAction: (actionId: string) => void | Promise<void>;
705
- shell: Omit<ConsoleShellProps, 'children'>;
706
- }
707
- /** Resource detail: editable tabs by default, or explicit-only Overview when readOnly is true. */
708
- declare function ResourceDetailPage(props: Partial<ResourceDetailProps>): import("react").JSX.Element;
714
+ /** null omits ConsoleShell; undefined or an object preserves the default frame. */
715
+ shell: Omit<ConsoleShellProps, 'children'> | null;
716
+ }
717
+ type ResourceDetailTabsProps = {
718
+ tabs?: undefined;
719
+ defaultTab?: ResourceDetailTab;
720
+ onTabChange?: (tab: ResourceDetailTab) => void;
721
+ } |
722
+ /** Replaces the built-in tabs, including in read-only mode; [] hides the tab set. */
723
+ CustomTabsProps;
724
+ type ResourceDetailProps = ResourceDetailBaseProps & ResourceDetailTabsProps;
725
+ /**
726
+ * Resource detail: editable tabs by default, or explicit-only Overview when readOnly is true.
727
+ * Pass tabs to replace the built-in sections with caller labels, values and content; readOnly
728
+ * does not filter custom tabs. An omitted or unknown defaultTab selects the first custom tab.
729
+ * shell={null} renders only Page and its header. The host owns the main landmark and must
730
+ * provide ChartLocaleProvider when its custom chart content needs a locale. Breadcrumbs
731
+ * render in the header in this mode: pass a trail or [] to avoid the editable sample trail.
732
+ * Omitted or object shells and omitted tabs preserve the existing default output.
733
+ */
734
+ declare function ResourceDetailPage(props: Partial<ResourceDetailBaseProps> & ResourceDetailTabsProps): import("react").JSX.Element;
709
735
  //#endregion
710
736
  //#region src/resource-detail/template.meta.d.ts
711
737
  declare const meta$30: TemplateMeta;
package/dist/index.js CHANGED
@@ -3003,6 +3003,33 @@ const meta$29 = {
3003
3003
  blocks: ["reset-password-form"]
3004
3004
  };
3005
3005
  //#endregion
3006
+ //#region src/resource-detail/CustomTabs.tsx
3007
+ function CustomTabs({ tabs, defaultTab, onTabChange, label }) {
3008
+ const [selected, setSelected] = useState(defaultTab);
3009
+ const value = tabs.find((tab) => tab.value === selected)?.value ?? tabs[0]?.value ?? null;
3010
+ if (tabs.length === 0) return null;
3011
+ return /* @__PURE__ */ jsxs(Tabs, {
3012
+ value,
3013
+ onValueChange: (next) => {
3014
+ const tab = tabs.find((tab) => tab.value === next);
3015
+ if (tab) {
3016
+ setSelected(tab.value);
3017
+ onTabChange?.(tab.value);
3018
+ }
3019
+ },
3020
+ children: [/* @__PURE__ */ jsx(TabsList, {
3021
+ "aria-label": label,
3022
+ children: tabs.map((tab) => /* @__PURE__ */ jsx(TabsTab, {
3023
+ value: tab.value,
3024
+ children: tab.label
3025
+ }, tab.value))
3026
+ }), tabs.map((tab) => /* @__PURE__ */ jsx(TabsPanel, {
3027
+ value: tab.value,
3028
+ children: tab.content
3029
+ }, tab.value))]
3030
+ });
3031
+ }
3032
+ //#endregion
3006
3033
  //#region src/resource-detail/data.ts
3007
3034
  const detailResource = {
3008
3035
  name: "orders-api",
@@ -3058,11 +3085,19 @@ const TABS = [
3058
3085
  "activity",
3059
3086
  "settings"
3060
3087
  ];
3061
- /** Resource detail: editable tabs by default, or explicit-only Overview when readOnly is true. */
3088
+ /**
3089
+ * Resource detail: editable tabs by default, or explicit-only Overview when readOnly is true.
3090
+ * Pass tabs to replace the built-in sections with caller labels, values and content; readOnly
3091
+ * does not filter custom tabs. An omitted or unknown defaultTab selects the first custom tab.
3092
+ * shell={null} renders only Page and its header. The host owns the main landmark and must
3093
+ * provide ChartLocaleProvider when its custom chart content needs a locale. Breadcrumbs
3094
+ * render in the header in this mode: pass a trail or [] to avoid the editable sample trail.
3095
+ * Omitted or object shells and omitted tabs preserve the existing default output.
3096
+ */
3062
3097
  function ResourceDetailPage(props) {
3063
3098
  const { t } = useI18n();
3064
3099
  const readOnly = props.readOnly ?? false;
3065
- const { name = readOnly ? "" : detailResource.name, description = readOnly ? "" : detailResource.description, status = readOnly ? "" : detailResource.status, breadcrumbs = readOnly ? [] : detailBreadcrumbs, meta: metaProp, actions: actionsProp, details: detailsProp, overviewTitle = "Configuration", overviewDescription = readOnly ? "" : "Settings of this resource.", historyTitle = "Status history", events = readOnly ? [] : detailEvents, activity = readOnly ? [] : detailActivity, dangerActions = readOnly ? [] : detailDangerActions, defaultTab = "overview", onTabChange, onEditDetails, onSaveSettings, onDangerAction, shell, labels } = props;
3100
+ const { name = readOnly ? "" : detailResource.name, description = readOnly ? "" : detailResource.description, status = readOnly ? "" : detailResource.status, breadcrumbs = readOnly ? [] : detailBreadcrumbs, meta: metaProp, actions: actionsProp, details: detailsProp, overviewTitle = "Configuration", overviewDescription = readOnly ? "" : "Settings of this resource.", historyTitle = "Status history", events = readOnly ? [] : detailEvents, activity = readOnly ? [] : detailActivity, dangerActions = readOnly ? [] : detailDangerActions, defaultTab = "overview", onEditDetails, onSaveSettings, onDangerAction, shell, labels } = props;
3066
3101
  const meta = metaProp ?? (readOnly ? [] : detailMeta);
3067
3102
  const actions = actionsProp ?? (readOnly ? [] : [{
3068
3103
  label: "View logs",
@@ -3089,139 +3124,146 @@ function ResourceDetailPage(props) {
3089
3124
  value,
3090
3125
  label: labels?.[value] ?? t(`resourceDetail.${value}`)
3091
3126
  }));
3092
- return /* @__PURE__ */ jsx(ConsoleShell, {
3093
- currentHref: "/deployments",
3094
- breadcrumbs,
3095
- ...shell,
3096
- children: /* @__PURE__ */ jsx(Page, {
3097
- width: "wide",
3098
- header: /* @__PURE__ */ jsx(PageHeader, {
3099
- breadcrumbs: null,
3100
- title: name,
3101
- description,
3102
- status,
3103
- meta,
3104
- actions,
3105
- tabs: null
3106
- }),
3107
- children: /* @__PURE__ */ jsxs(Tabs, {
3108
- value: readOnly ? "overview" : tab,
3109
- onValueChange: (v) => {
3110
- const next = tabs.find((t) => t.value === v)?.value ?? "overview";
3111
- setTab(next);
3112
- onTabChange?.(next);
3113
- },
3114
- children: [
3115
- /* @__PURE__ */ jsx(TabsList, {
3116
- "aria-label": labels?.sections ?? t("resourceDetail.sections"),
3117
- children: tabs.map((t) => /* @__PURE__ */ jsx(TabsTab, {
3118
- value: t.value,
3119
- children: t.label
3120
- }, t.value))
3121
- }),
3122
- /* @__PURE__ */ jsx(TabsPanel, {
3123
- value: "overview",
3124
- children: /* @__PURE__ */ jsxs(Grid, {
3125
- cols: historyEvents === void 0 ? 1 : {
3126
- base: 1,
3127
- lg: 5
3128
- },
3129
- gap: 6,
3130
- align: "start",
3131
- children: [/* @__PURE__ */ jsx(DescriptionListCard, {
3132
- className: historyEvents === void 0 ? void 0 : "lg:col-span-3",
3133
- titleAs: "h2",
3134
- title: overviewTitle,
3135
- description: overviewDescription,
3136
- items: details,
3137
- onEdit: onEditDetails
3138
- }), historyEvents !== void 0 && /* @__PURE__ */ jsx(Section, {
3139
- role: readOnly ? "group" : void 0,
3140
- variant: "card",
3141
- padding: "md",
3142
- title: historyTitle,
3143
- className: "lg:col-span-2",
3144
- children: /* @__PURE__ */ jsx(StatusTimeline, {
3145
- events: historyEvents,
3146
- maxVisible: readOnly ? void 0 : 4
3147
- })
3148
- })]
3149
- })
3150
- }),
3151
- !readOnly && /* @__PURE__ */ jsx(TabsPanel, {
3152
- value: "activity",
3153
- children: /* @__PURE__ */ jsx(Section, {
3127
+ const content = /* @__PURE__ */ jsx(Page, {
3128
+ width: "wide",
3129
+ header: /* @__PURE__ */ jsx(PageHeader, {
3130
+ as: shell === null ? "div" : void 0,
3131
+ breadcrumbs: shell === null ? breadcrumbs : null,
3132
+ title: name,
3133
+ description,
3134
+ status,
3135
+ meta,
3136
+ actions,
3137
+ tabs: null
3138
+ }),
3139
+ children: props.tabs !== void 0 ? /* @__PURE__ */ jsx(CustomTabs, {
3140
+ tabs: props.tabs,
3141
+ defaultTab: props.defaultTab,
3142
+ onTabChange: props.onTabChange,
3143
+ label: labels?.sections ?? t("resourceDetail.sections")
3144
+ }) : /* @__PURE__ */ jsxs(Tabs, {
3145
+ value: readOnly ? "overview" : tab,
3146
+ onValueChange: (v) => {
3147
+ const next = tabs.find((t) => t.value === v)?.value ?? "overview";
3148
+ setTab(next);
3149
+ if (props.tabs === void 0) props.onTabChange?.(next);
3150
+ },
3151
+ children: [
3152
+ /* @__PURE__ */ jsx(TabsList, {
3153
+ "aria-label": labels?.sections ?? t("resourceDetail.sections"),
3154
+ children: tabs.map((t) => /* @__PURE__ */ jsx(TabsTab, {
3155
+ value: t.value,
3156
+ children: t.label
3157
+ }, t.value))
3158
+ }),
3159
+ /* @__PURE__ */ jsx(TabsPanel, {
3160
+ value: "overview",
3161
+ children: /* @__PURE__ */ jsxs(Grid, {
3162
+ cols: historyEvents === void 0 ? 1 : {
3163
+ base: 1,
3164
+ lg: 5
3165
+ },
3166
+ gap: 6,
3167
+ align: "start",
3168
+ children: [/* @__PURE__ */ jsx(DescriptionListCard, {
3169
+ className: historyEvents === void 0 ? void 0 : "lg:col-span-3",
3170
+ titleAs: "h2",
3171
+ title: overviewTitle,
3172
+ description: overviewDescription,
3173
+ items: details,
3174
+ onEdit: onEditDetails
3175
+ }), historyEvents !== void 0 && /* @__PURE__ */ jsx(Section, {
3176
+ role: readOnly ? "group" : void 0,
3154
3177
  variant: "card",
3155
3178
  padding: "md",
3156
- title: "Activity",
3157
- description: "Changes made to this resource by people and automations.",
3158
- children: /* @__PURE__ */ jsx(ActivityFeed, {
3159
- items: activity,
3160
- label: "Activity, newest first"
3179
+ title: historyTitle,
3180
+ className: "lg:col-span-2",
3181
+ children: /* @__PURE__ */ jsx(StatusTimeline, {
3182
+ events: historyEvents,
3183
+ maxVisible: readOnly ? void 0 : 4
3161
3184
  })
3185
+ })]
3186
+ })
3187
+ }),
3188
+ !readOnly && /* @__PURE__ */ jsx(TabsPanel, {
3189
+ value: "activity",
3190
+ children: /* @__PURE__ */ jsx(Section, {
3191
+ variant: "card",
3192
+ padding: "md",
3193
+ title: "Activity",
3194
+ description: "Changes made to this resource by people and automations.",
3195
+ children: /* @__PURE__ */ jsx(ActivityFeed, {
3196
+ items: activity,
3197
+ label: "Activity, newest first"
3162
3198
  })
3163
- }),
3164
- !readOnly && /* @__PURE__ */ jsx(TabsPanel, {
3165
- value: "settings",
3166
- children: /* @__PURE__ */ jsxs(Stack, {
3167
- gap: 8,
3168
- children: [/* @__PURE__ */ jsx("form", {
3169
- noValidate: true,
3170
- onSubmit: (e) => {
3171
- e.preventDefault();
3172
- setSaved(settings);
3173
- onSaveSettings?.(settings);
3174
- },
3175
- children: /* @__PURE__ */ jsx(FormSection, {
3176
- title: "General",
3177
- description: "Name and description shown across the console.",
3178
- actions: /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(Button, {
3179
- variant: "ghost",
3180
- disabled: !dirty,
3181
- onClick: () => setSettings(saved),
3182
- children: "Discard"
3183
- }), /* @__PURE__ */ jsx(Button, {
3184
- type: "submit",
3185
- disabled: !dirty,
3186
- children: "Save changes"
3187
- })] }),
3188
- children: /* @__PURE__ */ jsxs(Stack, {
3189
- gap: 4,
3190
- children: [/* @__PURE__ */ jsxs(Field, { children: [
3191
- /* @__PURE__ */ jsx(FieldLabel, {
3192
- required: true,
3193
- children: "Name"
3194
- }),
3195
- /* @__PURE__ */ jsx(Input, {
3196
- required: true,
3197
- value: settings.name,
3198
- onValueChange: (v) => setSettings((s) => ({
3199
- ...s,
3200
- name: v
3201
- }))
3202
- }),
3203
- /* @__PURE__ */ jsx(FieldDescription, { children: "Lowercase letters, numbers and dashes." })
3204
- ] }), /* @__PURE__ */ jsxs(Field, { children: [/* @__PURE__ */ jsx(FieldLabel, { children: "Description" }), /* @__PURE__ */ jsx(Textarea, {
3205
- rows: 3,
3206
- value: settings.description,
3199
+ })
3200
+ }),
3201
+ !readOnly && /* @__PURE__ */ jsx(TabsPanel, {
3202
+ value: "settings",
3203
+ children: /* @__PURE__ */ jsxs(Stack, {
3204
+ gap: 8,
3205
+ children: [/* @__PURE__ */ jsx("form", {
3206
+ noValidate: true,
3207
+ onSubmit: (e) => {
3208
+ e.preventDefault();
3209
+ setSaved(settings);
3210
+ onSaveSettings?.(settings);
3211
+ },
3212
+ children: /* @__PURE__ */ jsx(FormSection, {
3213
+ title: "General",
3214
+ description: "Name and description shown across the console.",
3215
+ actions: /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(Button, {
3216
+ variant: "ghost",
3217
+ disabled: !dirty,
3218
+ onClick: () => setSettings(saved),
3219
+ children: "Discard"
3220
+ }), /* @__PURE__ */ jsx(Button, {
3221
+ type: "submit",
3222
+ disabled: !dirty,
3223
+ children: "Save changes"
3224
+ })] }),
3225
+ children: /* @__PURE__ */ jsxs(Stack, {
3226
+ gap: 4,
3227
+ children: [/* @__PURE__ */ jsxs(Field, { children: [
3228
+ /* @__PURE__ */ jsx(FieldLabel, {
3229
+ required: true,
3230
+ children: "Name"
3231
+ }),
3232
+ /* @__PURE__ */ jsx(Input, {
3233
+ required: true,
3234
+ value: settings.name,
3207
3235
  onValueChange: (v) => setSettings((s) => ({
3208
3236
  ...s,
3209
- description: v
3237
+ name: v
3210
3238
  }))
3211
- })] })]
3212
- })
3239
+ }),
3240
+ /* @__PURE__ */ jsx(FieldDescription, { children: "Lowercase letters, numbers and dashes." })
3241
+ ] }), /* @__PURE__ */ jsxs(Field, { children: [/* @__PURE__ */ jsx(FieldLabel, { children: "Description" }), /* @__PURE__ */ jsx(Textarea, {
3242
+ rows: 3,
3243
+ value: settings.description,
3244
+ onValueChange: (v) => setSettings((s) => ({
3245
+ ...s,
3246
+ description: v
3247
+ }))
3248
+ })] })]
3213
3249
  })
3214
- }), /* @__PURE__ */ jsx(DangerZone, {
3215
- description: "These actions affect everyone who uses this resource.",
3216
- actions: dangerActions,
3217
- onConfirm: onDangerAction
3218
- })]
3219
- })
3250
+ })
3251
+ }), /* @__PURE__ */ jsx(DangerZone, {
3252
+ description: "These actions affect everyone who uses this resource.",
3253
+ actions: dangerActions,
3254
+ onConfirm: onDangerAction
3255
+ })]
3220
3256
  })
3221
- ]
3222
- })
3257
+ })
3258
+ ]
3223
3259
  })
3224
3260
  });
3261
+ return shell === null ? content : /* @__PURE__ */ jsx(ConsoleShell, {
3262
+ currentHref: "/deployments",
3263
+ breadcrumbs,
3264
+ ...shell,
3265
+ children: content
3266
+ });
3225
3267
  }
3226
3268
  //#endregion
3227
3269
  //#region src/resource-detail/template.meta.ts
@@ -3230,7 +3272,7 @@ const meta$30 = {
3230
3272
  family: "Resources",
3231
3273
  priority: "P1",
3232
3274
  status: "beta",
3233
- description: "Resource detail with editable Overview, Activity and Settings tabs by default; optional readOnly (boolean, default false) uses only explicit header and detail props and one Overview tab, with optional history (readonly StatusEvent[], default undefined): omitted hides the history card, [] shows the named empty state, and events render exactly as supplied without invented actors. Read-only ignores activity, events, dangerActions, defaultTab, onSaveSettings and onDangerAction; explicit actions and onEditDetails are honored. The Resource sections tablist retains Tab, arrow, Home/End and Enter/Space keyboard navigation; history is a named group containing the Status history list or empty-state region. Uses token styling in dark (default), light and high_contrast. Examples: runtime-with-transition maps state and lastTransitionAt to one actor-free event, runtime-without-transition maps null to [], and realtime-configuration and postgres-table-detail omit history. Optional labels?: Partial<ResourceDetailLabels> overrides overview, activity, settings and sections (all strings). Unset keys use I18nProvider (en/es); no provider keeps English. Only the tabs and tablist are localized by this template; fixtures and other section text are unchanged. readOnly keeps only the localized overview tab. See the Catalog labels live preview. ConsoleShell retains sample frame defaults unless explicit shell props are supplied, as in the examples.",
3275
+ description: "Resource detail with editable Overview, Activity and Settings tabs by default; optional readOnly (boolean, default false) uses only explicit header and detail props and one Overview tab, with optional history (readonly StatusEvent[], default undefined): omitted hides the history card, [] shows the named empty state, and events render exactly as supplied without invented actors. Read-only ignores activity, events, dangerActions, defaultTab, onSaveSettings and onDangerAction; explicit actions and onEditDetails are honored. The Resource sections tablist retains Tab, arrow, Home/End and Enter/Space keyboard navigation; history is a named group containing the Status history list or empty-state region. Uses token styling in dark (default), light and high_contrast. Examples: runtime-with-transition maps state and lastTransitionAt to one actor-free event, runtime-without-transition maps null to [], and realtime-configuration and postgres-table-detail omit history. Optional labels?: Partial<ResourceDetailLabels> overrides overview, activity, settings and sections (all strings). Unset keys use I18nProvider (en/es); no provider keeps English. Only the tabs and tablist are localized by this template; fixtures and other section text are unchanged. readOnly keeps only the localized overview tab. See the Catalog labels live preview. ConsoleShell retains sample frame defaults when shell is omitted or an object. shell={null} renders only Page and PageHeader, with breadcrumbs in the header; pass breadcrumbs or [] to avoid the editable sample trail. The host owns main and provides ChartLocaleProvider for custom chart locales. Optional tabs?: { value: string; label: string; content: ReactNode }[] replaces the built-in tabs in caller order, even with readOnly; [] hides the tab set. With custom tabs, defaultTab and onTabChange use string values; an omitted or unknown defaultTab selects the first tab. Without tabs they retain ResourceDetailTab values. Custom tabs use the same Base UI keyboard navigation and panel mounting. See the embedded-custom-tabs live preview for shell-less composition inside a host main.",
3234
3276
  layout: "SidebarLayout + Page",
3235
3277
  blocks: [
3236
3278
  "app-sidebar",