@djangocfg/ui-core 2.1.534 → 2.1.536

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@djangocfg/ui-core",
3
- "version": "2.1.534",
3
+ "version": "2.1.536",
4
4
  "description": "Pure React UI component library without Next.js dependencies - for Electron, Vite, CRA apps",
5
5
  "keywords": [
6
6
  "ui-components",
@@ -128,7 +128,7 @@
128
128
  "check:contrast": "node scripts/check-preset-contrast.mjs"
129
129
  },
130
130
  "peerDependencies": {
131
- "@djangocfg/i18n": "^2.1.534",
131
+ "@djangocfg/i18n": "^2.1.536",
132
132
  "consola": "^3.4.2",
133
133
  "lucide-react": "^0.545.0",
134
134
  "moment": "^2.30.1",
@@ -206,8 +206,8 @@
206
206
  "@chenglou/pretext": "^0.0.8"
207
207
  },
208
208
  "devDependencies": {
209
- "@djangocfg/i18n": "^2.1.534",
210
- "@djangocfg/typescript-config": "^2.1.534",
209
+ "@djangocfg/i18n": "^2.1.536",
210
+ "@djangocfg/typescript-config": "^2.1.536",
211
211
  "@types/node": "^24.13.3",
212
212
  "@types/react": "19.2.15",
213
213
  "@types/react-dom": "19.2.3",
@@ -31,7 +31,26 @@ export interface LinkComponentProps {
31
31
 
32
32
  export type LinkComponent = ComponentType<LinkComponentProps>;
33
33
 
34
- export const LinkComponentContext = createContext<LinkComponent | null>(null);
34
+ /**
35
+ * Keyed on a global rather than a module-local `createContext`.
36
+ *
37
+ * A consumer reaches this module by two specifiers — the package root (which
38
+ * re-exports `<Link>`) and the `/adapters/*` subpath (which mounts the
39
+ * provider). A bundler may instantiate the module once per specifier, giving
40
+ * two distinct context objects: the provider fills one, `<Link>` reads the
41
+ * other, and every link silently falls back to the History-API `<a>`.
42
+ *
43
+ * The failure is invisible — the URL still changes — so the host framework's
44
+ * router is simply never told, and the app renders the previous route until
45
+ * something else forces a re-render. Sharing one object through the global
46
+ * makes the two instances agree whatever the bundler decides.
47
+ */
48
+ const CONTEXT_KEY = Symbol.for('@djangocfg/ui-core.LinkComponentContext');
49
+ const globalScope = globalThis as unknown as Record<symbol, unknown>;
50
+
51
+ export const LinkComponentContext =
52
+ (globalScope[CONTEXT_KEY] as ReturnType<typeof createContext<LinkComponent | null>> | undefined) ??
53
+ (globalScope[CONTEXT_KEY] = createContext<LinkComponent | null>(null));
35
54
 
36
55
  export interface LinkProviderProps {
37
56
  value: LinkComponent;
@@ -38,6 +38,16 @@ const DialogOverlay = React.forwardRef<
38
38
  ))
39
39
  DialogOverlay.displayName = DialogPrimitive.Overlay.displayName
40
40
 
41
+ /**
42
+ * Width is a CSS variable, not a prop: set `--width-dialog` on the element.
43
+ *
44
+ * <DialogContent className="[--width-dialog:940px]">
45
+ *
46
+ * The card renders at `min(--width-dialog, 100vw - 2rem)`, so raising the token
47
+ * widens it and the viewport margin is kept for you. A Tailwind `max-w-*`
48
+ * instead does nothing — the width is declared, and a maximum above a declared
49
+ * width is inert. Ignored when `fullscreen`.
50
+ */
41
51
  interface DialogContentProps
42
52
  extends React.ComponentPropsWithoutRef<typeof DialogPrimitive.Content> {
43
53
  /**
@@ -84,7 +94,14 @@ const DialogContent = React.forwardRef<
84
94
  // both edges at any viewport. A `sm:` gate reads the window, so a
85
95
  // narrow desktop pane lost its margins and rendered as a sheet with
86
96
  // its rounding cropped.
87
- : "left-1/2 top-1/2 grid w-[min(32rem,calc(100vw-2rem))] -translate-x-1/2 -translate-y-1/2 gap-4 rounded-[var(--radius-dialog)] border p-6 shadow-lg data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95",
97
+ //
98
+ // The size is `--width-dialog` (32rem by default) rather than a
99
+ // literal, so a consumer can widen the card WITHOUT restating the
100
+ // viewport clamp: `className="[--width-dialog:940px]"`. It used to be
101
+ // hard-coded, which made the width unoverridable in practice — a
102
+ // `max-width` beside a declared `width` is inert, so callers that
103
+ // needed a wider dialog silently got 32rem.
104
+ : "left-1/2 top-1/2 grid w-[min(var(--width-dialog),calc(100vw-2rem))] -translate-x-1/2 -translate-y-1/2 gap-4 rounded-[var(--radius-dialog)] border p-6 shadow-lg data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95",
88
105
  className
89
106
  )}
90
107
  {...props}
@@ -107,7 +107,17 @@ export const defaultAdapter: RouterAdapter = Object.freeze({
107
107
  * React context carrying the active adapter. `null` means "use default".
108
108
  * Kept intentionally nullable so we don't burn a Provider for the default case.
109
109
  */
110
- export const RouterAdapterContext = createContext<RouterAdapter | null>(null);
110
+ // Keyed on a global for the same reason as LinkComponentContext: this module is
111
+ // reached both from the package root and from the `/adapters/*` subpath, and a
112
+ // per-specifier instantiation would leave the provider filling one context while
113
+ // every hook reads another — falling back to the History API, which changes the
114
+ // URL without telling the host router.
115
+ const CONTEXT_KEY = Symbol.for('@djangocfg/ui-core.RouterAdapterContext');
116
+ const globalScope = globalThis as unknown as Record<symbol, unknown>;
117
+
118
+ export const RouterAdapterContext =
119
+ (globalScope[CONTEXT_KEY] as ReturnType<typeof createContext<RouterAdapter | null>> | undefined) ??
120
+ (globalScope[CONTEXT_KEY] = createContext<RouterAdapter | null>(null));
111
121
 
112
122
  export interface RouterAdapterProviderProps {
113
123
  /** Adapter implementation. Will be used by every router hook in subtree. */
@@ -19,6 +19,20 @@
19
19
  --radius-dialog: 1rem;
20
20
  --radius-tooltip: 0.375rem;
21
21
 
22
+ /* Centred-dialog width. The card is `min(--width-dialog, 100vw - 2rem)`, so
23
+ * this is the width it WANTS and the viewport clamp is applied for it.
24
+ *
25
+ * A token rather than a literal in the component, because the clamp and the
26
+ * size were previously one hard-coded declaration
27
+ * (`w-[min(32rem,calc(100vw-2rem))]`): a consumer that needed a wider dialog
28
+ * could not raise the size without also restating the margin logic, and
29
+ * `max-width` beside it did nothing — a maximum above a declared width is
30
+ * inert. Set this on the dialog to resize it and keep the clamp:
31
+ *
32
+ * <DialogContent className="[--width-dialog:940px]">
33
+ */
34
+ --width-dialog: 32rem;
35
+
22
36
  /* Modal backdrop frosting — how hard the `.bg-overlay` scrim (dialog / drawer
23
37
  * / sheet) blurs the page behind it. Theme-agnostic (same both modes);
24
38
  * a preset can override for a heavier/lighter frost, or set `0px` to disable