@nextlyhq/ui 0.0.2-alpha.60 → 0.0.2-alpha.62

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/theme.css CHANGED
@@ -900,6 +900,39 @@
900
900
  --nx-field-half: 380px;
901
901
  --nx-field-full: 760px;
902
902
 
903
+ /* Page shell — the inset from the content panel's edge to the page's content,
904
+ * and the measure that content is bounded to. `PageShell` spends these as
905
+ * GRID COLUMNS rather than as padding, because padding cannot be cancelled by
906
+ * a descendant: that is why full-bleed content previously had to be rendered
907
+ * OUTSIDE the wrapper to escape the measure, and why two wrappers each
908
+ * applying their own inset silently doubled it.
909
+ *
910
+ * A length rather than a colour, so it is declared once here rather than per
911
+ * light/dark block — a page's inset does not change with the theme. */
912
+ --nx-gutter: 2rem;
913
+ --nx-measure-form: 56rem;
914
+ --nx-measure-wide: 72rem;
915
+
916
+ /* The measure the content column is bounded to, declared here so a theme can
917
+ * retune it centrally and so the token resolves to a real value rather than
918
+ * to a `var()` fallback. `PageShell` overrides it INLINE per its `width`
919
+ * prop, which is what makes the three widths one grid template instead of
920
+ * three near-identical ones; this declaration is the value that applies when
921
+ * the grid is used without that component. */
922
+ --nx-shell-measure: var(--nx-measure-form);
923
+
924
+ /* The single vertical-rhythm token for a form section. `FormSection` applies
925
+ * it to every DIRECT child, so the card's top and bottom breathing room and
926
+ * the gap between two fields are one decision and cannot drift apart — the
927
+ * first child's top padding IS the card's top inset.
928
+ *
929
+ * The rhythm belongs to the section rather than to the rows it is handed. A
930
+ * section renders whatever children it is given, and cannot tell one row
931
+ * idiom from another; leaving each row to supply its own vertical padding
932
+ * makes the card's inset depend on which idiom the caller happened to reach
933
+ * for, and a row that supplies none renders flush against the borders. */
934
+ --nx-field-gap: 1.25rem;
935
+
903
936
  /* Focus ring colors */
904
937
  --nx-focus-ring: var(--nx-primary);
905
938
  --nx-focus-ring-offset: oklch(1 0 0);
@@ -1115,3 +1148,102 @@
1115
1148
  --nx-table-border: var(--nx-border);
1116
1149
  /* inherit the retuned white-alpha border (was a fixed faint slate) */
1117
1150
  }
1151
+
1152
+ /* ============================================================
1153
+ * Page shell
1154
+ * ============================================================
1155
+ *
1156
+ * The gutter and the measure are ONE grid definition, spent as columns rather
1157
+ * than as padding. That is load-bearing rather than stylistic:
1158
+ *
1159
+ * - Padding cannot be cancelled by a descendant, so a block that must run
1160
+ * edge-to-edge previously had to be rendered OUTSIDE the wrapper imposing
1161
+ * the measure. `.nx-bleed` turns that from an accident into a declaration.
1162
+ * - Two wrappers that each apply an inset silently add. As columns there is
1163
+ * one declaration, so double-padding is unrepresentable rather than merely
1164
+ * discouraged.
1165
+ * - Every direct child defaults to the `content` column, so a page header and
1166
+ * the card beneath it cannot disagree about their left edge.
1167
+ *
1168
+ * Centring comes from the two outer tracks being equal rather than from
1169
+ * `margin-inline: auto` on a max-width box, which does nothing at panel widths
1170
+ * where the cap does not bind.
1171
+ */
1172
+ @layer components {
1173
+ /* A form section's vertical rhythm, applied to every DIRECT child.
1174
+ *
1175
+ * Plain CSS rather than a Tailwind utility on the element, for two reasons.
1176
+ * The parenthesised custom-property shorthand is v4-only, so the same class
1177
+ * compiles to a rule under one Tailwind major and to nothing under the other,
1178
+ * and the section renders flush wherever it compiles to nothing — silently,
1179
+ * because the markup is identical either way. And an arbitrary-value token is
1180
+ * EXTRACTED from any file the scanner reads, a comment or a test string
1181
+ * included, so merely naming one of these utilities in prose emits its rule;
1182
+ * a malformed spelling anywhere in the repository fails the whole stylesheet.
1183
+ *
1184
+ * A rule shipped in the theme has neither property: it is the same CSS under
1185
+ * both majors, and there is no token for a scanner to find.
1186
+ *
1187
+ * Children must not pad themselves. The two paddings are additive, so a row
1188
+ * carrying its own `py-*` doubles the rhythm on the sections that are already
1189
+ * correct. */
1190
+ .nx-form-section-rows > * {
1191
+ padding-block: var(--nx-field-gap);
1192
+ }
1193
+
1194
+ .nx-page-shell {
1195
+ display: grid;
1196
+ /* The outer tracks are `minmax(gutter, 1fr)` rather than a fixed gutter so
1197
+ * the grid always spans its container: a fixed pair would total only
1198
+ * `measure + 2 * gutter`, leaving `full-start`/`full-end` short of the
1199
+ * panel's edges in anything wider, and a `Bleed` child short with them. The
1200
+ * `1fr` maximum absorbs the surplus while `gutter` holds as the minimum.
1201
+ *
1202
+ * Their being equal is also what centres the content column, so no
1203
+ * `justify-content` is declared: with flexible tracks the grid fills its
1204
+ * container and there is no free space for it to distribute. */
1205
+ grid-template-columns:
1206
+ [full-start] minmax(var(--nx-gutter), 1fr)
1207
+ [content-start] minmax(0, var(--nx-shell-measure))
1208
+ [content-end] minmax(var(--nx-gutter), 1fr)
1209
+ [full-end];
1210
+ align-content: start;
1211
+ }
1212
+
1213
+ /* `min-width: 0` because a grid item's default `min-width: auto` refuses to
1214
+ * shrink below its content, which lets one wide descendant — a long code
1215
+ * string, a table — push the column past the measure it was given. */
1216
+ .nx-page-shell > * {
1217
+ grid-column: content;
1218
+ min-width: 0;
1219
+ }
1220
+
1221
+ /* Scoped to a DIRECT child: the named lines exist on this grid alone, so a
1222
+ * `.nx-bleed` nested deeper resolves against a grid that never declared them.
1223
+ * Writing the rule this way means such a case is inert rather than
1224
+ * mysteriously half-working. */
1225
+ .nx-page-shell > .nx-bleed {
1226
+ grid-column: full;
1227
+ }
1228
+ }
1229
+
1230
+ /* The gutter steps with the content PANEL rather than the viewport: the panel's
1231
+ * width changes when a sidebar opens, and the panel is what the page sits in.
1232
+ * `content` is the container the admin's <main> already names. The step values
1233
+ * match Payload's --gutter-h ladder (32 / 24 / 16).
1234
+ *
1235
+ * The override lands on `.nx-page-shell`, a DESCENDANT of that container. A
1236
+ * container query styles only elements inside its container, so a rule naming
1237
+ * `:root` or `.nextly-admin` — both ancestors of the `<main>` that declares it —
1238
+ * never matches, and the gutter keeps its widest value at every panel size. */
1239
+ @container content (max-width: 1024px) {
1240
+ .nx-page-shell {
1241
+ --nx-gutter: 1.5rem;
1242
+ }
1243
+ }
1244
+
1245
+ @container content (max-width: 768px) {
1246
+ .nx-page-shell {
1247
+ --nx-gutter: 1rem;
1248
+ }
1249
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nextlyhq/ui",
3
- "version": "0.0.2-alpha.60",
3
+ "version": "0.0.2-alpha.62",
4
4
  "description": "Nextly UI — Reusable React component library for Nextly plugins and custom admin UIs",
5
5
  "license": "MIT",
6
6
  "keywords": [
@@ -100,10 +100,10 @@
100
100
  "typescript": "^5.9.3",
101
101
  "vite-tsconfig-paths": "^5.1.4",
102
102
  "vitest": "^4.1.0",
103
- "@nextlyhq/admin-css": "0.0.2-alpha.60",
104
- "@nextlyhq/module-specifiers": "0.0.2-alpha.60",
105
- "@nextlyhq/eslint-config": "0.0.2-alpha.60",
106
- "@nextlyhq/tsconfig": "0.0.2-alpha.60"
103
+ "@nextlyhq/admin-css": "0.0.2-alpha.62",
104
+ "@nextlyhq/eslint-config": "0.0.2-alpha.62",
105
+ "@nextlyhq/module-specifiers": "0.0.2-alpha.62",
106
+ "@nextlyhq/tsconfig": "0.0.2-alpha.62"
107
107
  },
108
108
  "dependencies": {
109
109
  "@radix-ui/react-accordion": "^1.2.12",
@@ -151,6 +151,7 @@
151
151
  "build": "pnpm build:js && node scripts/build-css.mjs",
152
152
  "build:js": "rimraf dist && tsup && tsup --config tsup.server-safe.config.ts && tsx scripts/check-client-directive.ts && tsx scripts/check-server-safe-artifacts.ts",
153
153
  "build:css": "node scripts/build-css.mjs",
154
+ "build:surface-declarations": "tsx scripts/build-surface-declarations.ts",
154
155
  "dev": "node scripts/dev.mjs",
155
156
  "check-types": "tsc --noEmit && tsc --noEmit -p tsconfig.tests.json",
156
157
  "lint": "eslint . --max-warnings 0",