@gravitee/graphene-core 2.57.0 → 2.58.0-renovate-react.1323345

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.
@@ -118,6 +118,8 @@
118
118
 
119
119
  /* ── Layout ─────────────────────────────────────── */
120
120
  --container-content: var(--content-max-width);
121
+ --max-width-content: var(--content-max-width);
122
+ --max-width-focused: var(--content-focused-width);
121
123
 
122
124
  /* ── Radius ──────────────────────────────────────── */
123
125
  --radius-sm: calc(var(--radius) - 0.125rem);
@@ -23,7 +23,8 @@
23
23
 
24
24
  /* ── Content area ────────────────────────────────── */
25
25
  --content-padding: var(--graphene-spacing-6);
26
- --content-max-width: 80rem;
26
+ --content-max-width: 100rem;
27
+ --content-focused-width: 56rem;
27
28
 
28
29
  /* ── Derived layout ────────────────────────────── */
29
30
  --sidebar-height: 100svh;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gravitee/graphene-core",
3
- "version": "2.57.0",
3
+ "version": "2.58.0-renovate-react.1323345",
4
4
  "type": "module",
5
5
  "description": "Gravitee's Graphene design system: accessible React components, design tokens, icons, and shared ESLint/TypeScript configs. Built on shadcn/ui and Tailwind.",
6
6
  "keywords": [
@@ -95,6 +95,7 @@
95
95
  },
96
96
  "peerDependencies": {
97
97
  "@fontsource/dm-sans": ">=5.0.0",
98
+ "@gravitee/graphene-core": "2.58.0-renovate-react.1323345",
98
99
  "@monaco-editor/react": "^4.7.0",
99
100
  "@tanstack/react-table": "^8.0.0",
100
101
  "@testing-library/dom": ">=10.0.0",
@@ -77,11 +77,25 @@ export function ResourceDetailPage({
77
77
  );
78
78
  }
79
79
 
80
- // 3. With LayoutSlots (module federation):
80
+ // 3. Content width:
81
+ // Detail pages use the default container. No layout configuration needed.
82
+ // Do NOT set max-w-* classes on page wrappers.
83
+ //
84
+ // Use contentVariant: 'full-bleed' only for tool layouts (Policy Studio),
85
+ // observability dashboards, or log/trace explorers.
86
+
87
+ // 4. With LayoutSlots (module federation):
81
88
  // If using useLayoutConfig instead of direct props, push the sidebar from
82
89
  // inside your module component. The host owns appContext in ContentHeader;
83
90
  // modules only set breadcrumbs, leading, and contextSidebar.
84
91
  //
92
+ // Use the `banner` slot to show a full-width status bar above the content
93
+ // area. Common on resource detail pages where changes must be deployed.
94
+ // The banner spans edge-to-edge regardless of contentVariant.
95
+ // Add role="status" and a descriptive aria-label on the banner root element.
96
+ // On unmount or when status clears, set banner: null (useLayoutConfig resets
97
+ // owned keys automatically on unmount).
98
+ //
85
99
  // // appContext lives in the host shell's ContentHeader — modules do not set it.
86
100
  // useLayoutConfig(
87
101
  // {
@@ -89,9 +103,13 @@ export function ResourceDetailPage({
89
103
  // contextExpanded,
90
104
  // contextSidebar: <ContextSidebar header={...} groups={...} ... />,
91
105
  // leading: <ContextToggleButton expanded={contextExpanded} onToggle={...} />,
106
+ // banner: needsDeploy
107
+ // ? <DeployStrip onDeploy={handleDeploy} role="status" aria-label="Deployment status" />
108
+ // : null,
109
+ // bannerSticky: true,
92
110
  // breadcrumbs: [...],
93
111
  // },
94
- // [section, contextExpanded],
112
+ // [section, contextExpanded, needsDeploy, handleDeploy],
95
113
  // );
96
114
  //
97
115
  // Child pages can call useLayoutConfig for non-overlapping keys without
@@ -104,23 +122,3 @@ export function ResourceDetailPage({
104
122
  //
105
123
  // See Storybook "Patterns/Module Federation" for the full setup.
106
124
  //
107
- // 4. Banner slot (deploy strip pattern):
108
- // Use the `banner` prop to show a full-width status bar above the content
109
- // area. Common on resource detail pages where changes must be deployed.
110
- // The banner spans edge-to-edge regardless of contentVariant.
111
- //
112
- // <AppLayout
113
- // viewMode="context"
114
- // banner={needsDeploy ? <DeployStrip onDeploy={handleDeploy} /> : undefined}
115
- // bannerSticky
116
- // ...
117
- // >
118
- //
119
- // With useLayoutConfig (module federation):
120
- //
121
- // useLayoutConfig({
122
- // banner: needsDeploy ? <DeployStrip onDeploy={handleDeploy} /> : null,
123
- // bannerSticky: true,
124
- // }, [needsDeploy, handleDeploy]);
125
- //
126
- // See Storybook "Composed/AppLayout → BannerSlot" for the full example.
@@ -0,0 +1,120 @@
1
+ // Snippet: Creation wizard / stepper page with PageFocused
2
+ //
3
+ // Use when building a multi-step creation flow, onboarding sequence,
4
+ // or any focused linear task (Create API, Create Agent, Import, etc.).
5
+ //
6
+ // Content width: Wrap in <PageFocused> to constrain and center within the
7
+ // container. The centering signals to the user that they are in a focused sub-task.
8
+ //
9
+ // Do NOT use for:
10
+ // - Regular settings/form pages (they use the default container as-is)
11
+ // - DataTable list pages (they fill the container naturally)
12
+ // - Wide two-column wizards (use the default container instead)
13
+ //
14
+ // Decision rule: If the user navigated INTO a single-column creation/wizard flow → <PageFocused>.
15
+
16
+ import { useState } from 'react';
17
+ import { Button, Card, CardContent, Field, Input, Label, PageFocused, Separator } from '@gravitee/graphene-core';
18
+ import { ArrowLeftIcon, ArrowRightIcon, RocketIcon } from '@gravitee/graphene-core/icons';
19
+
20
+ // Replace with your actual step definitions
21
+ const STEPS = ['Details', 'Configure', 'Review'] as const;
22
+
23
+ export function CreateResourceWizardPage() {
24
+ const [step, setStep] = useState(0);
25
+ const isLastStep = step === STEPS.length - 1;
26
+
27
+ function handleNext() {
28
+ if (isLastStep) {
29
+ // Replace with your create mutation
30
+ return;
31
+ }
32
+ setStep((s) => s + 1);
33
+ }
34
+
35
+ function handleBack() {
36
+ if (step === 0) {
37
+ // Replace with your navigation back
38
+ return;
39
+ }
40
+ setStep((s) => s - 1);
41
+ }
42
+
43
+ return (
44
+ <PageFocused>
45
+ <div className="space-y-6">
46
+ {/* Step indicator */}
47
+ <nav aria-label="Progress" className="flex items-center justify-center gap-2">
48
+ {STEPS.map((label, i) => (
49
+ <div key={label} className="flex items-center gap-2">
50
+ <div className="flex items-center gap-1.5">
51
+ <div
52
+ className={`flex size-6 items-center justify-center rounded-full text-xs font-medium ${
53
+ i <= step ? 'bg-primary text-primary-foreground' : 'border border-border text-muted-foreground'
54
+ }`}
55
+ >
56
+ {i + 1}
57
+ </div>
58
+ <span className={`text-sm ${i <= step ? 'font-medium' : 'text-muted-foreground'}`}>{label}</span>
59
+ </div>
60
+ {i < STEPS.length - 1 && <div className="h-px w-8 bg-border" />}
61
+ </div>
62
+ ))}
63
+ </nav>
64
+
65
+ {/* Step content */}
66
+ <Card>
67
+ <CardContent className="space-y-4 pt-6">
68
+ {step === 0 && (
69
+ <>
70
+ <Field>
71
+ <Label>Resource name</Label>
72
+ <Input placeholder="Enter a name" />
73
+ </Field>
74
+ <Field>
75
+ <Label>Description</Label>
76
+ <Input placeholder="Optional description" />
77
+ </Field>
78
+ </>
79
+ )}
80
+ {step === 1 && (
81
+ <Field>
82
+ <Label>Configuration</Label>
83
+ <Input placeholder="Enter configuration value" />
84
+ </Field>
85
+ )}
86
+ {step === 2 && (
87
+ <div className="space-y-2">
88
+ <p className="text-sm font-medium">Review your configuration</p>
89
+ <p className="text-sm text-muted-foreground">Confirm the details below before creating.</p>
90
+ </div>
91
+ )}
92
+ </CardContent>
93
+ </Card>
94
+
95
+ <Separator />
96
+
97
+ {/* Navigation buttons */}
98
+ <div className="flex items-center justify-between">
99
+ <Button variant="outline" onClick={handleBack}>
100
+ <ArrowLeftIcon className="size-4" aria-hidden />
101
+ {step === 0 ? 'Cancel' : 'Back'}
102
+ </Button>
103
+ <Button onClick={handleNext}>
104
+ {isLastStep ? (
105
+ <>
106
+ <RocketIcon className="size-4" aria-hidden />
107
+ Create
108
+ </>
109
+ ) : (
110
+ <>
111
+ Next
112
+ <ArrowRightIcon className="size-4" aria-hidden />
113
+ </>
114
+ )}
115
+ </Button>
116
+ </div>
117
+ </div>
118
+ </PageFocused>
119
+ );
120
+ }
@@ -63,7 +63,7 @@ export function PluginConfigPage({
63
63
  // `noValidate` disables the browser's HTML5 validation popups so the resolver +
64
64
  // <FieldError> remain the single source of validation messages.
65
65
  return (
66
- <form noValidate onSubmit={form.handleSubmit(onSave)} className="flex flex-1 flex-col gap-4 p-8">
66
+ <form noValidate onSubmit={form.handleSubmit(onSave)} className="flex flex-1 flex-col gap-4">
67
67
  <JsonSchemaForm schema={pluginSchema} control={form.control} name="" context={formContext} />
68
68
  <Button type="submit">Save</Button>
69
69
  </form>
@@ -87,7 +87,7 @@ export function PluginConfigPage({ pluginSchema, initialValue, environment, onSa
87
87
  const { name: nameError } = form.formState.errors;
88
88
 
89
89
  return (
90
- <form noValidate onSubmit={form.handleSubmit(onSave)} className="flex flex-1 flex-col gap-4 p-8">
90
+ <form noValidate onSubmit={form.handleSubmit(onSave)} className="flex flex-1 flex-col gap-4">
91
91
  {/* Host meta — validated by Zod. Duplicate this block for `description`, etc. */}
92
92
  <Field data-invalid={!!nameError}>
93
93
  <FieldLabel htmlFor="name">Name</FieldLabel>