@godxjp/ui 18.0.3 → 18.1.1

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 (94) hide show
  1. package/dist/app/app-provider.d.ts +2 -1
  2. package/dist/components/charts/area-chart.d.ts +1 -1
  3. package/dist/components/charts/bar-chart.d.ts +1 -1
  4. package/dist/components/charts/chart-cartesian.d.ts +1 -1
  5. package/dist/components/charts/chart-frame.d.ts +1 -1
  6. package/dist/components/charts/line-chart.d.ts +1 -1
  7. package/dist/components/charts/pie-chart.d.ts +1 -1
  8. package/dist/components/data-display/badge.d.ts +1 -1
  9. package/dist/components/data-display/card.d.ts +1 -1
  10. package/dist/components/data-display/data-table.d.ts +10 -10
  11. package/dist/components/data-display/descriptions.d.ts +2 -2
  12. package/dist/components/data-display/empty-state.d.ts +1 -1
  13. package/dist/components/data-display/popover.d.ts +6 -6
  14. package/dist/components/data-display/progress.d.ts +2 -1
  15. package/dist/components/data-display/timeline.d.ts +1 -1
  16. package/dist/components/data-display/tree-list.d.ts +1 -1
  17. package/dist/components/data-entry/calendar.d.ts +1 -1
  18. package/dist/components/data-entry/cascader.d.ts +2 -1
  19. package/dist/components/data-entry/checkbox-group.d.ts +2 -1
  20. package/dist/components/data-entry/color-picker.d.ts +2 -1
  21. package/dist/components/data-entry/date-picker.d.ts +2 -1
  22. package/dist/components/data-entry/date-range-picker.d.ts +2 -1
  23. package/dist/components/data-entry/field.d.ts +2 -1
  24. package/dist/components/data-entry/form-field.d.ts +2 -1
  25. package/dist/components/data-entry/month-picker.d.ts +2 -1
  26. package/dist/components/data-entry/month-range-picker.d.ts +2 -1
  27. package/dist/components/data-entry/password-strength.d.ts +1 -1
  28. package/dist/components/data-entry/radio.d.ts +1 -1
  29. package/dist/components/data-entry/search-input.d.ts +1 -1
  30. package/dist/components/data-entry/search-select.d.ts +2 -1
  31. package/dist/components/data-entry/select.d.ts +3 -3
  32. package/dist/components/data-entry/time-picker.d.ts +2 -1
  33. package/dist/components/data-entry/transfer.d.ts +2 -1
  34. package/dist/components/data-entry/tree-select.d.ts +2 -1
  35. package/dist/components/data-entry/upload-crop-dialog.d.ts +2 -1
  36. package/dist/components/data-entry/upload.d.ts +2 -1
  37. package/dist/components/feedback/alert.d.ts +1 -1
  38. package/dist/components/feedback/dialog.d.ts +13 -13
  39. package/dist/components/feedback/sheet.d.ts +7 -7
  40. package/dist/components/feedback/skeleton.d.ts +5 -5
  41. package/dist/components/feedback/sonner.d.ts +2 -1
  42. package/dist/components/feedback/tooltip.d.ts +2 -2
  43. package/dist/components/general/button.d.ts +1 -1
  44. package/dist/components/general/reveal.d.ts +1 -1
  45. package/dist/components/layout/app-shell.d.ts +2 -1
  46. package/dist/components/layout/app-shell.js +1 -1
  47. package/dist/components/layout/auth-shell.d.ts +1 -1
  48. package/dist/components/layout/breadcrumb.d.ts +1 -1
  49. package/dist/components/layout/centered-shell.d.ts +22 -0
  50. package/dist/components/layout/centered-shell.js +35 -0
  51. package/dist/components/layout/flex.d.ts +1 -1
  52. package/dist/components/layout/index.d.ts +3 -0
  53. package/dist/components/layout/index.js +2 -0
  54. package/dist/components/layout/page-container.d.ts +2 -2
  55. package/dist/components/layout/resizable.d.ts +3 -3
  56. package/dist/components/layout/responsive-grid.d.ts +1 -1
  57. package/dist/components/layout/sidebar.d.ts +4 -4
  58. package/dist/components/layout/split-pane.d.ts +1 -1
  59. package/dist/components/layout/topbar.d.ts +1 -1
  60. package/dist/components/navigation/context-menu.d.ts +2 -2
  61. package/dist/components/navigation/dropdown-menu.d.ts +7 -7
  62. package/dist/components/navigation/filter-bar.d.ts +2 -2
  63. package/dist/components/navigation/menubar.d.ts +3 -3
  64. package/dist/components/navigation/pagination.d.ts +2 -2
  65. package/dist/components/navigation/steps.d.ts +2 -1
  66. package/dist/components/navigation/tabs.d.ts +1 -1
  67. package/dist/components/query/data-state.d.ts +2 -1
  68. package/dist/components/query/infinite-query-state.d.ts +2 -1
  69. package/dist/components/query/mutation-feedback.d.ts +1 -1
  70. package/dist/components/query/prefetch-link.d.ts +2 -1
  71. package/dist/components/query/query-refetch-button.d.ts +1 -1
  72. package/dist/components/ui/hover-card.d.ts +1 -1
  73. package/dist/form/form-context.d.ts +23 -0
  74. package/dist/form/form-context.js +29 -0
  75. package/dist/form/form-field-control.d.ts +1 -1
  76. package/dist/form/form-field-control.js +28 -2
  77. package/dist/form/form-root.d.ts +7 -1
  78. package/dist/form/form-root.js +21 -0
  79. package/dist/form/index.d.ts +2 -1
  80. package/dist/form/index.js +3 -0
  81. package/dist/i18n/messages/en.json +5 -0
  82. package/dist/i18n/messages/ja.json +5 -0
  83. package/dist/i18n/messages/vi.json +5 -0
  84. package/dist/inertia/index.d.ts +65 -0
  85. package/dist/inertia/index.js +22 -0
  86. package/dist/props/components/form.prop.d.ts +33 -1
  87. package/dist/props/components/layout.prop.d.ts +29 -1
  88. package/dist/props/registry.d.ts +10 -0
  89. package/dist/props/registry.js +10 -0
  90. package/dist/props/vocabulary/index.d.ts +1 -1
  91. package/dist/props/vocabulary/layout.prop.d.ts +2 -0
  92. package/dist/styles/shell-layout.css +85 -11
  93. package/dist/tokens/components/shell.css +12 -0
  94. package/package.json +55 -46
@@ -0,0 +1,65 @@
1
+ import type { FormStateAdapter } from "../props/components/form.prop.js";
2
+ /**
3
+ * Structural shape of Inertia's `useForm` return that the adapter needs. Duck-typed on purpose —
4
+ * `@godxjp/ui` keeps ZERO dependency on `@inertiajs/react`; the real `useForm()` object satisfies
5
+ * this shape, so a consumer passes it directly with no import from this package.
6
+ */
7
+ export interface InertiaFormLike<TData extends Record<string, unknown> = Record<string, unknown>> {
8
+ /** Current form values (server-driven state). */
9
+ data: TData;
10
+ /** Write a single field back (Inertia signature: `setData(key, value)`). */
11
+ setData(key: string, value: unknown): void;
12
+ /** Server (Laravel FormRequest) validation errors, keyed by field name. */
13
+ errors: Partial<Record<string, string>>;
14
+ /** True while a submit request is in flight. */
15
+ processing: boolean;
16
+ }
17
+ /**
18
+ * Wrap an Inertia `useForm()` object as a framework-agnostic {@link FormStateAdapter} so it drives
19
+ * `FormRoot`/`FormFieldControl` with the SAME auto-binding as the react-hook-form path — no manual
20
+ * `value`/`onChange`/`error`/`aria-invalid` per field, and `processing` flows to submit-button
21
+ * loading via `useFormSubmitting()`. Server errors in `form.errors` surface on the matching
22
+ * `FormFieldControl` and clear on correction (Inertia clears the error on `setData`).
23
+ *
24
+ * @example
25
+ * ```tsx
26
+ * import { FormRoot, FormFieldControl, useFormSubmitting } from "@godxjp/ui/form";
27
+ * import { inertiaAdapter } from "@godxjp/ui/inertia";
28
+ * import { useForm } from "@inertiajs/react";
29
+ *
30
+ * const form = useForm({ email: "", password: "" });
31
+ * return (
32
+ * <FormRoot adapter={inertiaAdapter(form)} onSubmit={() => form.post("/login")}>
33
+ * <FormFieldControl name="email" label="Email" required>
34
+ * {(field) => <Input {...field} type="email" value={String(field.value ?? "")} />}
35
+ * </FormFieldControl>
36
+ * <Button type="submit" loading={useFormSubmitting()}>Sign in</Button>
37
+ * </FormRoot>
38
+ * );
39
+ * ```
40
+ */
41
+ export declare function inertiaAdapter<TData extends Record<string, unknown>>(form: InertiaFormLike<TData>): FormStateAdapter;
42
+ /**
43
+ * Lighter helper for consumers who compose `FormField` by hand rather than `FormRoot`. Returns the
44
+ * exact props to spread onto a `FormField` + its control — `value`, `onChange`, `error`, `name` —
45
+ * so no field is hand-wired. Use `inertiaAdapter` + `FormRoot` for the full auto-binding instead.
46
+ *
47
+ * @example
48
+ * ```tsx
49
+ * const form = useForm({ email: "" });
50
+ * const email = useInertiaField(form, "email");
51
+ * <FormField id="email" label="Email" error={email.error}>
52
+ * <Input {...email} value={String(email.value ?? "")} type="email" />
53
+ * </FormField>
54
+ * ```
55
+ */
56
+ export declare function useInertiaField<TData extends Record<string, unknown>>(form: InertiaFormLike<TData>, name: string): {
57
+ name: string;
58
+ value: unknown;
59
+ error: string | undefined;
60
+ onChange: (event: {
61
+ target: {
62
+ value: unknown;
63
+ };
64
+ }) => void;
65
+ };
@@ -0,0 +1,22 @@
1
+ "use client";
2
+ function inertiaAdapter(form) {
3
+ return {
4
+ getValue: (name) => form.data[name],
5
+ setValue: (name, value) => form.setData(name, value),
6
+ getError: (name) => form.errors[name],
7
+ isSubmitting: form.processing,
8
+ getValues: () => form.data
9
+ };
10
+ }
11
+ function useInertiaField(form, name) {
12
+ return {
13
+ name,
14
+ value: form.data[name],
15
+ error: form.errors[name],
16
+ onChange: (event) => form.setData(name, event?.target?.value)
17
+ };
18
+ }
19
+ export {
20
+ inertiaAdapter,
21
+ useInertiaField
22
+ };
@@ -9,9 +9,41 @@ export type ZodSchemaProp<T extends z.ZodType = z.ZodType> = T;
9
9
  export type UseZodFormOptionsProp<TFieldValues extends FieldValues> = Omit<UseFormProps<TFieldValues>, "resolver">;
10
10
  /** Return type of useZodForm. */
11
11
  export type UseZodFormReturnProp<TFieldValues extends FieldValues> = UseFormReturn<TFieldValues>;
12
+ /**
13
+ * Framework-agnostic form-state adapter — decouples `FormRoot`/`FormFieldControl` from any single
14
+ * form library. The DS ships the built-in react-hook-form path (`form`), and an adapter lets a
15
+ * SERVER-driven form library plug into the same auto-binding: Inertia's `useForm`
16
+ * (`@godxjp/ui/inertia`), formik, or TanStack Form. The core has ZERO dependency on any of them —
17
+ * a consumer wraps its own form object in an adapter and passes it to `FormRoot`.
18
+ */
19
+ export interface FormStateAdapter {
20
+ /** Current value of the field `name` (dotted paths allowed if the underlying store supports them). */
21
+ getValue(name: string): unknown;
22
+ /** Write `value` back to the field `name` (e.g. Inertia's `setData(name, value)`). */
23
+ setValue(name: string, value: unknown): void;
24
+ /** Server/validation error message for `name`, or undefined when the field is valid. */
25
+ getError(name: string): string | undefined;
26
+ /** True while a submit is in flight (e.g. Inertia's `processing`) — drives submit-button loading. */
27
+ isSubmitting: boolean;
28
+ /** Optional blur handler (e.g. touch-tracking); called with the field name. */
29
+ onBlur?(name: string): void;
30
+ /** Optional snapshot of all values, passed to `onSubmit`; defaults to `{}` when absent. */
31
+ getValues?(): unknown;
32
+ }
12
33
  /** @see FormRoot */
13
34
  export type FormRootProp<TFieldValues extends FieldValues> = {
14
- form: UseZodFormReturnProp<TFieldValues>;
35
+ /**
36
+ * react-hook-form return (client-side Zod validation). Provide EITHER `form` OR `adapter` — `form`
37
+ * is the built-in client path; `adapter` plugs in a server-driven form library (Inertia/formik).
38
+ */
39
+ form?: UseZodFormReturnProp<TFieldValues>;
40
+ /**
41
+ * Framework-agnostic form-state adapter (e.g. `inertiaAdapter(form)` from `@godxjp/ui/inertia`).
42
+ * Provide EITHER `form` OR `adapter`. With an adapter, `FormFieldControl` auto-binds each field by
43
+ * `name` (value/onChange/error/aria) and `useFormSubmitting()` reads `isSubmitting`.
44
+ */
45
+ adapter?: FormStateAdapter;
46
+ /** Submit handler. RHF path receives validated `values`; the adapter path calls it with a snapshot (`getValues()`), typically ignored in favour of the form library's own submit (`form.post(url)`). */
15
47
  onSubmit: (values: TFieldValues) => void | Promise<void>;
16
48
  children: React.ReactNode;
17
49
  className?: string;
@@ -1,7 +1,7 @@
1
1
  /** Layout component prop types — @see docs/COMPONENTS.md#layout */
2
2
  import type * as React from "react";
3
3
  import type { ComponentType, ReactNode, SVGProps } from "react";
4
- import type { BreadcrumbProp, TitleProp, SubtitleProp, ExtraProp, FooterProp, PageDensityProp, PageContainerVariantProp, GapProp, ClassNameProp, ChildrenProp } from "../vocabulary/index.js";
4
+ import type { BreadcrumbProp, TitleProp, SubtitleProp, ExtraProp, FooterProp, PageDensityProp, PageContainerVariantProp, CenteredShellWidthProp, GapProp, ClassNameProp, ChildrenProp } from "../vocabulary/index.js";
5
5
  /** @see PageContainer */
6
6
  export type PageContainerProp = {
7
7
  title: TitleProp;
@@ -108,6 +108,34 @@ export type AuthShellProp = {
108
108
  footer?: ReactNode;
109
109
  className?: ClassNameProp;
110
110
  };
111
+ /**
112
+ * @see CenteredShell — authenticated, no-sidebar, centred-column page shell (hosted-ID "My Page",
113
+ * account / self-service, standalone settings). A padded top bar with real actions (banner) reusing
114
+ * AppShell's `.app-topbar` chrome WITHOUT a sidebar, a scrollable `main` holding a centred column of
115
+ * configurable medium width (`width` = sm|md|lg, all wider than AuthShell's 24rem card) top-aligned
116
+ * so sections flow + scroll, and an optional footer (contentinfo). Fills the gap between AppShell
117
+ * (needs a sidebar) and AuthShell (unauthenticated, narrow vertically-centred card) — so a hosted
118
+ * account page needs ZERO custom CSS and never hand-rolls a bar (the `.ui-topbar` zero-inset
119
+ * footgun). Layout-only; delegate motion to `Reveal`.
120
+ */
121
+ export type CenteredShellProp = {
122
+ /** Centred column content — page sections (identity hero, org picker, service grid, team list). */
123
+ children: ReactNode;
124
+ /**
125
+ * Top bar slot (banner) — a `<Topbar>` with brand + real actions (an `AppSettingPicker`, a user
126
+ * menu, sign-out). CenteredShell wraps it in the SAME padded chrome as AppShell's topbar
127
+ * (padding-inline · border · backdrop), so you never hand-roll a bar. Omit → no banner.
128
+ */
129
+ topbar?: ReactNode;
130
+ /** Footer slot (contentinfo) pinned to the bottom (legal links, locale switch, support). Omit → none. */
131
+ footer?: ReactNode;
132
+ /**
133
+ * Max-width of the centred content column: `sm` ~32rem, `md` (default) ~46rem, `lg` ~64rem — all
134
+ * wider than AuthShell's 24rem auth card. A service retunes each tier via `--centered-shell-width-*`.
135
+ */
136
+ width?: CenteredShellWidthProp;
137
+ className?: ClassNameProp;
138
+ };
111
139
  /** @see Sidebar */
112
140
  export type SidebarProductProp = {
113
141
  name: string;
@@ -184,6 +184,11 @@ export declare const VOCABULARY_REGISTRY: {
184
184
  readonly category: "layout";
185
185
  readonly description: "Page shell layout — default, narrow, flush, ghost";
186
186
  };
187
+ readonly CenteredShellWidthProp: {
188
+ readonly file: "vocabulary/layout.prop.ts";
189
+ readonly category: "layout";
190
+ readonly description: "CenteredShell column max-width — sm, md, lg";
191
+ };
187
192
  readonly GapProp: {
188
193
  readonly file: "vocabulary/layout.prop.ts";
189
194
  readonly category: "layout";
@@ -453,6 +458,11 @@ export declare const COMPONENT_PROP_REGISTRY: {
453
458
  readonly file: "components/layout.prop.ts";
454
459
  readonly vocabulary: readonly ["ChildrenProp", "ClassNameProp"];
455
460
  };
461
+ readonly CenteredShellProp: {
462
+ readonly group: "layout";
463
+ readonly file: "components/layout.prop.ts";
464
+ readonly vocabulary: readonly ["ChildrenProp", "ClassNameProp", "CenteredShellWidthProp"];
465
+ };
456
466
  readonly SidebarProductProp: {
457
467
  readonly group: "layout";
458
468
  readonly file: "components/layout.prop.ts";
@@ -182,6 +182,11 @@ const VOCABULARY_REGISTRY = {
182
182
  category: "layout",
183
183
  description: "Page shell layout \u2014 default, narrow, flush, ghost"
184
184
  },
185
+ CenteredShellWidthProp: {
186
+ file: "vocabulary/layout.prop.ts",
187
+ category: "layout",
188
+ description: "CenteredShell column max-width \u2014 sm, md, lg"
189
+ },
185
190
  GapProp: {
186
191
  file: "vocabulary/layout.prop.ts",
187
192
  category: "layout",
@@ -438,6 +443,11 @@ const COMPONENT_PROP_REGISTRY = {
438
443
  file: "components/layout.prop.ts",
439
444
  vocabulary: ["ChildrenProp", "ClassNameProp"]
440
445
  },
446
+ CenteredShellProp: {
447
+ group: "layout",
448
+ file: "components/layout.prop.ts",
449
+ vocabulary: ["ChildrenProp", "ClassNameProp", "CenteredShellWidthProp"]
450
+ },
441
451
  SidebarProductProp: {
442
452
  group: "layout",
443
453
  file: "components/layout.prop.ts",
@@ -1,7 +1,7 @@
1
1
  /** Barrel — all vocabulary prop types. */
2
2
  export type { ClassNameProp, ChildrenProp, IdProp, OpenProp, DefaultOpenProp, OnOpenChangeProp, HandlerProp, PendingProp, RequiredProp, DisabledProp, LabelProp, HelperProp, ErrorProp, PlaceholderProp, NameProp, ValueProp, DefaultValueProp, OnValueChangeProp, OnChangeProp, OnClickProp, AsChildProp, WidthProp, } from "./shared.prop.js";
3
3
  export type { TitleProp, SubtitleProp, DescriptionProp, ExtraProp, FooterProp, ActionProp, IconProp, ConfirmLabelProp, CancelLabelProp, ActionsProp, EmptyMessageProp, } from "./content.prop.js";
4
- export type { PageDensityProp, PageContainerVariantProp, TableDensityProp, DensityProp, GapProp, } from "./layout.prop.js";
4
+ export type { PageDensityProp, PageContainerVariantProp, CenteredShellWidthProp, TableDensityProp, DensityProp, GapProp, } from "./layout.prop.js";
5
5
  export type { ButtonVariantProp, ButtonSizeProp, BadgeVariantProp, AppSettingPickerAppearanceProp, ShapeProp, TextSizeProp, TextToneProp, FontWeightProp, HeadingLevelProp, TextAlignProp, SizeProp, FormLayoutProp, BreakpointProp, ConfirmVariantProp, ToneProp, AlertVariantProp, SortDirectionProp, ColumnAlignProp, SortStateProp, RevealDelayProp, } from "./interaction.prop.js";
6
6
  export type { BreadcrumbItemProp, BreadcrumbProp } from "./navigation.prop.js";
7
7
  export type { GetRowIdProp, OnRowClickProp, ColumnDefProp, SelectedIdsProp, OnSelectChangeProp, OnTableDensityChangeProp, OnSortChangeProp, OnSearchChangeProp, OnClearFiltersProp, HasActiveFiltersProp, } from "./data.prop.js";
@@ -8,6 +8,8 @@ export type PageDensityProp = "compact" | "default" | "comfortable";
8
8
  export type DensityProp = "compact" | "default" | "comfortable";
9
9
  /** Page shell layout — orthogonal to PageDensityProp. */
10
10
  export type PageContainerVariantProp = "default" | "narrow" | "flush" | "ghost";
11
+ /** CenteredShell content-column max-width tier — sm ~32rem, md ~46rem, lg ~64rem. */
12
+ export type CenteredShellWidthProp = "sm" | "md" | "lg";
11
13
  /** Shared gap between layout children; components may document subsets. */
12
14
  export type GapProp = "xs" | "sm" | "md" | "lg" | "xl";
13
15
  /** DataTable row density subset. */
@@ -123,6 +123,72 @@
123
123
  color: hsl(var(--muted-foreground));
124
124
  }
125
125
 
126
+ /*
127
+ * CENTERED SHELL — authenticated, no-sidebar, centred-column page shell (hosted-ID "My Page",
128
+ * account / self-service, standalone settings). A flex column over the same brand-wash surface as
129
+ * the app/auth shells: a padded top bar that MIRRORS `.app-topbar` chrome (fixed height + inline
130
+ * padding + border + backdrop) but WITHOUT a sidebar grid, a scrollable `main` whose content is a
131
+ * width-tiered centred column that is TOP-aligned (sections flow + scroll, never vertically
132
+ * centred like the auth card), and an optional footer. Every knob reads a token.
133
+ */
134
+ .ui-centered-shell {
135
+ display: flex;
136
+ min-height: 100dvh;
137
+ flex-direction: column;
138
+ background:
139
+ linear-gradient(180deg, hsl(var(--primary) / 0.035), transparent 14rem),
140
+ hsl(var(--background));
141
+ }
142
+
143
+ .ui-centered-shell-bar {
144
+ display: flex;
145
+ min-width: 0;
146
+ min-height: var(--centered-shell-bar-height);
147
+ flex: 0 0 auto;
148
+ align-items: center;
149
+ gap: var(--space-3);
150
+ padding-inline: var(--centered-shell-bar-padding-x);
151
+ border-bottom: 1px solid hsl(var(--border));
152
+ background: hsl(var(--background) / 0.92);
153
+ /* Opt-in brand-chrome wash — shares the topbar hook, invisible by default (none). */
154
+ background-image: var(--topbar-gradient);
155
+ backdrop-filter: blur(12px);
156
+ }
157
+
158
+ .ui-centered-shell-main {
159
+ display: flex;
160
+ min-width: 0;
161
+ flex: 1 1 auto;
162
+ flex-direction: column;
163
+ overflow: auto;
164
+ /* Ambient brand glow hook — shares the app-main hook, invisible by default (none). */
165
+ background-image: var(--gradient-glow);
166
+ /* Sole scroll/clip boundary for the page area (same containment rationale as `.app-main`). */
167
+ contain: paint;
168
+ padding: var(--centered-shell-main-padding);
169
+ }
170
+
171
+ .ui-centered-shell-column {
172
+ width: 100%;
173
+ margin-inline: auto;
174
+ max-width: var(--centered-shell-width-md);
175
+ }
176
+
177
+ .ui-centered-shell-column[data-width="sm"] {
178
+ max-width: var(--centered-shell-width-sm);
179
+ }
180
+
181
+ .ui-centered-shell-column[data-width="lg"] {
182
+ max-width: var(--centered-shell-width-lg);
183
+ }
184
+
185
+ .ui-centered-shell-footer {
186
+ padding: var(--centered-shell-footer-padding);
187
+ border-top: 1px solid hsl(var(--border));
188
+ text-align: center;
189
+ color: hsl(var(--muted-foreground));
190
+ }
191
+
126
192
  .app-topbar-rail {
127
193
  display: flex;
128
194
  min-width: 0;
@@ -169,7 +235,7 @@
169
235
  font-size: var(--font-size-base);
170
236
  }
171
237
 
172
- @media (max-width: 1023px) {
238
+ @media (width < 64rem) {
173
239
  .app-root,
174
240
  .app-root[data-collapsed="true"] {
175
241
  grid-template-areas:
@@ -536,26 +602,34 @@
536
602
  color: hsl(var(--muted-foreground));
537
603
  }
538
604
 
539
- [data-collapsed="true"] .sb-user-meta,
540
- [data-collapsed="true"] .sb-user-menu {
605
+ :is(.app-root[data-collapsed="true"] > .app-sidebar, .sb-root[data-collapsed="true"])
606
+ .sb-user-meta,
607
+ :is(.app-root[data-collapsed="true"] > .app-sidebar, .sb-root[data-collapsed="true"])
608
+ .sb-user-menu {
541
609
  display: none;
542
610
  }
543
611
 
544
- [data-collapsed="true"] .sb-product-name,
545
- [data-collapsed="true"] .sb-product-tenant,
546
- [data-collapsed="true"] .sb-product-caret,
547
- [data-collapsed="true"] .sb-section-label,
548
- [data-collapsed="true"] .sb-label,
549
- [data-collapsed="true"] .sb-badge {
612
+ :is(.app-root[data-collapsed="true"] > .app-sidebar, .sb-root[data-collapsed="true"])
613
+ .sb-product-name,
614
+ :is(.app-root[data-collapsed="true"] > .app-sidebar, .sb-root[data-collapsed="true"])
615
+ .sb-product-tenant,
616
+ :is(.app-root[data-collapsed="true"] > .app-sidebar, .sb-root[data-collapsed="true"])
617
+ .sb-product-caret,
618
+ :is(.app-root[data-collapsed="true"] > .app-sidebar, .sb-root[data-collapsed="true"])
619
+ .sb-section-label,
620
+ :is(.app-root[data-collapsed="true"] > .app-sidebar, .sb-root[data-collapsed="true"]) .sb-label,
621
+ :is(.app-root[data-collapsed="true"] > .app-sidebar, .sb-root[data-collapsed="true"]) .sb-badge {
550
622
  display: none;
551
623
  }
552
624
 
553
- [data-collapsed="true"] .sb-product {
625
+ :is(.app-root[data-collapsed="true"] > .app-sidebar, .sb-root[data-collapsed="true"])
626
+ .sb-product {
554
627
  justify-content: center;
555
628
  padding: 0;
556
629
  }
557
630
 
558
- [data-collapsed="true"] .sb-nav-item {
631
+ :is(.app-root[data-collapsed="true"] > .app-sidebar, .sb-root[data-collapsed="true"])
632
+ .sb-nav-item {
559
633
  width: var(--control-height);
560
634
  justify-content: center;
561
635
  margin-inline: auto;
@@ -42,4 +42,16 @@
42
42
  --auth-shell-bar-padding: var(--space-5) var(--space-6);
43
43
  --auth-shell-main-padding: var(--space-6);
44
44
  --auth-shell-footer-padding: var(--space-3) var(--space-6) var(--space-4);
45
+
46
+ /* CenteredShell — authenticated, no-sidebar, centred-column page shell (hosted-ID "My Page",
47
+ * account, standalone settings). The bar mirrors AppShell's `.app-topbar` chrome (fixed height +
48
+ * inline padding); the column max-width has three tiers, all wider than the 24rem auth card. A
49
+ * service retunes the bar inset, block padding and each width tier without forking CSS. */
50
+ --centered-shell-bar-height: 3.25rem;
51
+ --centered-shell-bar-padding-x: var(--space-4);
52
+ --centered-shell-main-padding: var(--space-6);
53
+ --centered-shell-footer-padding: var(--space-3) var(--space-6) var(--space-4);
54
+ --centered-shell-width-sm: 32rem;
55
+ --centered-shell-width-md: 46rem;
56
+ --centered-shell-width-lg: 64rem;
45
57
  }
package/package.json CHANGED
@@ -1,9 +1,14 @@
1
1
  {
2
2
  "name": "@godxjp/ui",
3
- "version": "18.0.3",
4
- "godxUiMcp": "18.0.2",
3
+ "version": "18.1.1",
4
+ "godxUiMcp": "18.1.0",
5
5
  "type": "module",
6
6
  "packageManager": "pnpm@10.29.1",
7
+ "pnpm": {
8
+ "overrides": {
9
+ "esbuild": ">=0.28.1"
10
+ }
11
+ },
7
12
  "sideEffects": false,
8
13
  "description": "@godxjp/ui — shared React UI framework (shadcn + Radix + Tailwind v4).",
9
14
  "files": [
@@ -88,6 +93,10 @@
88
93
  "types": "./dist/form/index.d.ts",
89
94
  "import": "./dist/form/index.js"
90
95
  },
96
+ "./inertia": {
97
+ "types": "./dist/inertia/index.d.ts",
98
+ "import": "./dist/inertia/index.js"
99
+ },
91
100
  "./app": {
92
101
  "types": "./dist/app/index.d.ts",
93
102
  "import": "./dist/app/index.js"
@@ -363,32 +372,32 @@
363
372
  "@date-fns/tz": "^1.5.0",
364
373
  "@fontsource/montserrat": "^5.2.8",
365
374
  "@fontsource/noto-sans-jp": "^5.2.9",
366
- "@radix-ui/react-accordion": "^1.2.12",
367
- "@radix-ui/react-alert-dialog": "^1.1.15",
368
- "@radix-ui/react-aspect-ratio": "^1.1.8",
369
- "@radix-ui/react-avatar": "^1.1.11",
370
- "@radix-ui/react-checkbox": "^1.3.3",
371
- "@radix-ui/react-collapsible": "^1.1.12",
372
- "@radix-ui/react-context": "^1.1.2",
373
- "@radix-ui/react-context-menu": "^2.2.16",
374
- "@radix-ui/react-dialog": "^1.1.15",
375
- "@radix-ui/react-dropdown-menu": "^2.1.16",
376
- "@radix-ui/react-hover-card": "^1.1.15",
377
- "@radix-ui/react-label": "^2.1.8",
378
- "@radix-ui/react-menubar": "^1.1.16",
379
- "@radix-ui/react-navigation-menu": "^1.2.14",
380
- "@radix-ui/react-popover": "^1.1.15",
381
- "@radix-ui/react-radio-group": "^1.3.8",
382
- "@radix-ui/react-scroll-area": "^1.2.10",
383
- "@radix-ui/react-select": "^2.2.6",
384
- "@radix-ui/react-separator": "^1.1.8",
385
- "@radix-ui/react-slider": "^1.3.6",
386
- "@radix-ui/react-slot": "^1.2.4",
387
- "@radix-ui/react-switch": "^1.2.6",
388
- "@radix-ui/react-tabs": "^1.1.13",
389
- "@radix-ui/react-toggle": "^1.1.10",
390
- "@radix-ui/react-toggle-group": "^1.1.11",
391
- "@radix-ui/react-tooltip": "^1.2.8",
375
+ "@radix-ui/react-accordion": "^1.2.16",
376
+ "@radix-ui/react-alert-dialog": "^1.1.19",
377
+ "@radix-ui/react-aspect-ratio": "^1.1.11",
378
+ "@radix-ui/react-avatar": "^1.2.2",
379
+ "@radix-ui/react-checkbox": "^1.3.7",
380
+ "@radix-ui/react-collapsible": "^1.1.16",
381
+ "@radix-ui/react-context": "^1.2.0",
382
+ "@radix-ui/react-context-menu": "^2.3.3",
383
+ "@radix-ui/react-dialog": "^1.1.19",
384
+ "@radix-ui/react-dropdown-menu": "^2.1.20",
385
+ "@radix-ui/react-hover-card": "^1.1.19",
386
+ "@radix-ui/react-label": "^2.1.11",
387
+ "@radix-ui/react-menubar": "^1.1.20",
388
+ "@radix-ui/react-navigation-menu": "^1.2.18",
389
+ "@radix-ui/react-popover": "^1.1.19",
390
+ "@radix-ui/react-radio-group": "^1.4.3",
391
+ "@radix-ui/react-scroll-area": "^1.2.14",
392
+ "@radix-ui/react-select": "^2.3.3",
393
+ "@radix-ui/react-separator": "^1.1.11",
394
+ "@radix-ui/react-slider": "^1.4.3",
395
+ "@radix-ui/react-slot": "^1.3.0",
396
+ "@radix-ui/react-switch": "^1.3.3",
397
+ "@radix-ui/react-tabs": "^1.1.17",
398
+ "@radix-ui/react-toggle": "^1.1.14",
399
+ "@radix-ui/react-toggle-group": "^1.1.15",
400
+ "@radix-ui/react-tooltip": "^1.2.12",
392
401
  "@tanstack/react-table": "^8.21.3",
393
402
  "class-variance-authority": "^0.7.1",
394
403
  "clsx": "^2.1.1",
@@ -396,9 +405,9 @@
396
405
  "date-fns": "^4.1.0",
397
406
  "embla-carousel-react": "^8.6.0",
398
407
  "input-otp": "^1.4.2",
399
- "lucide-react": "^1.14.0",
408
+ "lucide-react": "^1.25.0",
400
409
  "react-day-picker": "^10.0.1",
401
- "react-resizable-panels": "^4.11.2",
410
+ "react-resizable-panels": "^4.12.2",
402
411
  "sonner": "^2.0.7",
403
412
  "tailwind-merge": "^3.5.0",
404
413
  "tailwindcss-animate": "^1.0.7",
@@ -407,17 +416,17 @@
407
416
  "devDependencies": {
408
417
  "@axe-core/playwright": "^4.12.1",
409
418
  "@eslint/js": "^9.39.4",
410
- "@hookform/resolvers": "^5.2.2",
411
- "@tailwindcss/vite": "^4.2.4",
412
- "@tanstack/react-query": "^5.100.9",
419
+ "@hookform/resolvers": "^5.4.0",
420
+ "@tailwindcss/vite": "^4.3.3",
421
+ "@tanstack/react-query": "^5.101.2",
413
422
  "@testing-library/jest-dom": "^6.9.1",
414
423
  "@testing-library/react": "^16.3.2",
415
424
  "@testing-library/user-event": "^14.6.1",
416
425
  "@types/node": "^22.19.19",
417
- "@types/react": "^19.2.14",
426
+ "@types/react": "^19.2.17",
418
427
  "@types/react-dom": "^19.2.3",
419
- "@vitejs/plugin-react": "^6.0.1",
420
- "@vitest/coverage-v8": "^4.1.5",
428
+ "@vitejs/plugin-react": "^6.0.3",
429
+ "@vitest/coverage-v8": "^4.1.10",
421
430
  "axe-core": "^4.12.1",
422
431
  "eslint": "^9.39.2",
423
432
  "eslint-plugin-react": "^7.37.5",
@@ -425,19 +434,19 @@
425
434
  "globals": "^15.15.0",
426
435
  "jsdom": "^29.1.1",
427
436
  "playwright": "^1.61.1",
428
- "prettier": "^3.6.2",
437
+ "prettier": "^3.9.5",
429
438
  "prettier-plugin-tailwindcss": "^0.6.14",
430
- "react": "^19.2.6",
431
- "react-dom": "^19.2.6",
432
- "react-hook-form": "^7.76.0",
433
- "react-router-dom": "^7.15.0",
434
- "recharts": "^3.8.1",
435
- "tailwindcss": "^4.2.4",
439
+ "react": "^19.2.7",
440
+ "react-dom": "^19.2.7",
441
+ "react-hook-form": "^7.81.0",
442
+ "react-router-dom": "^7.18.1",
443
+ "recharts": "^3.9.2",
444
+ "tailwindcss": "^4.3.3",
436
445
  "tsup": "^8.5.1",
437
446
  "typescript": "^6.0.3",
438
- "typescript-eslint": "^8.60.0",
439
- "vite": "^8.0.10",
440
- "vitest": "^4.1.5",
447
+ "typescript-eslint": "^8.64.0",
448
+ "vite": "^8.1.5",
449
+ "vitest": "^4.1.10",
441
450
  "vitest-axe": "1.0.0-pre.5",
442
451
  "zod": "^4.4.3"
443
452
  },