najm-kit 2.2.2 → 2.2.3

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
@@ -2875,6 +2875,8 @@ interface TableState {
2875
2875
  isRefreshing: boolean;
2876
2876
  dynamicHeight: boolean;
2877
2877
  CardComponent: ComponentType<any> | null;
2878
+ /** Placeholder shaped like `CardComponent`; see `renderCardSkeleton`. */
2879
+ CardSkeletonComponent: ComponentType<any> | null;
2878
2880
  className: string;
2879
2881
  classNames: NTableClassNames;
2880
2882
  bordered?: boolean;
@@ -3014,6 +3016,7 @@ declare const createTableStore: (seed?: Partial<TableState>) => {
3014
3016
  isRefreshing: () => boolean;
3015
3017
  dynamicHeight: () => boolean;
3016
3018
  CardComponent: () => ComponentType<any>;
3019
+ CardSkeletonComponent: () => ComponentType<any>;
3017
3020
  className: () => string;
3018
3021
  classNames: () => NTableClassNames;
3019
3022
  bordered?: () => boolean;
@@ -3199,6 +3202,32 @@ interface NTableProps<T = any, M extends ViewMode = ViewMode> {
3199
3202
  'data-row'?: string;
3200
3203
  'data-row-id'?: string;
3201
3204
  }>;
3205
+ /**
3206
+ * A placeholder shaped like `renderCard`.
3207
+ *
3208
+ * The card page size is measured from whatever is on screen, and during a
3209
+ * first load that is the skeleton. The built-in placeholder is an avatar row,
3210
+ * so a consumer whose cards are a different height — a media card, say — gets
3211
+ * a page size measured against a card it does not use, and the grid re-lays
3212
+ * out once real cards arrive. Supplying a placeholder with the real card's
3213
+ * geometry makes the first measurement the correct one.
3214
+ */
3215
+ renderCardSkeleton?: ComponentType<Record<string, never>>;
3216
+ /**
3217
+ * Emit both skeleton shapes and let a media query choose between them.
3218
+ *
3219
+ * A view mode derived from the viewport is unknowable on the server, so the
3220
+ * server renders the card shape and the client corrects it after hydration —
3221
+ * on a desktop table page that is a visible card skeleton followed by a table
3222
+ * skeleton. No client-side detection can fix it, because the first paint is
3223
+ * whatever the server sent. Rendering both and hiding one in CSS puts the
3224
+ * right shape in that first paint. The skeleton is `aria-hidden` decoration,
3225
+ * so the duplicate costs nothing to assistive technology.
3226
+ *
3227
+ * The breakpoint is `lg` (1024px), matching the point at which a table
3228
+ * becomes usable.
3229
+ */
3230
+ responsiveSkeleton?: boolean;
3202
3231
  renderToolbar?: (state: NTableState) => React__default.ReactNode;
3203
3232
  renderEmpty?: () => React__default.ReactNode;
3204
3233
  renderError?: (error: any) => React__default.ReactNode;
@@ -3435,6 +3464,7 @@ declare const TableStoreContext: React$1.Context<{
3435
3464
  isRefreshing: () => boolean;
3436
3465
  dynamicHeight: () => boolean;
3437
3466
  CardComponent: () => React$1.ComponentType<any>;
3467
+ CardSkeletonComponent: () => React$1.ComponentType<any>;
3438
3468
  className: () => string;
3439
3469
  classNames: () => NTableClassNames;
3440
3470
  bordered?: () => boolean;
@@ -3567,6 +3597,7 @@ declare function useStoreSync(props: any): {
3567
3597
  isRefreshing: () => boolean;
3568
3598
  dynamicHeight: () => boolean;
3569
3599
  CardComponent: () => React__default.ComponentType<any>;
3600
+ CardSkeletonComponent: () => React__default.ComponentType<any>;
3570
3601
  className: () => string;
3571
3602
  classNames: () => NTableClassNames;
3572
3603
  bordered?: () => boolean;
package/dist/index.mjs CHANGED
@@ -12183,6 +12183,7 @@ var createTableStore = (seed) => {
12183
12183
  getRowId: null,
12184
12184
  renderToolbar: null,
12185
12185
  CardComponent: null,
12186
+ CardSkeletonComponent: null,
12186
12187
  className: "",
12187
12188
  classNames: {},
12188
12189
  bordered: void 0,
@@ -12492,9 +12493,11 @@ function useDynamicPageSize(containerRef, effectiveViewMode) {
12492
12493
  const bodyEl = container2.querySelector("[data-ntable-body]");
12493
12494
  const tableHeaderEl = container2.querySelector("[data-ntable-table-header]");
12494
12495
  const loadingHeaderEl = container2.querySelector("[data-ntable-loading-header]");
12495
- const cardsGridEl = container2.querySelector(
12496
- "[data-ntable-loading-cards-grid], [data-ntable-cards-grid]"
12497
- );
12496
+ const cardsGridEl = Array.from(
12497
+ container2.querySelectorAll(
12498
+ "[data-ntable-loading-cards-grid], [data-ntable-cards-grid]"
12499
+ )
12500
+ ).find((el) => el.clientHeight > 0 || el.clientWidth > 0) ?? null;
12498
12501
  let bodyHeight = bodyEl?.clientHeight ?? 0;
12499
12502
  const bodyWidth = bodyEl?.clientWidth ?? container2.clientWidth ?? 0;
12500
12503
  if (!bodyHeight) {
@@ -13423,6 +13426,7 @@ function NTableCardsLoadingSkeleton({ rows }) {
13423
13426
  const cardRowHeight = useTableStore.use.cardRowHeight();
13424
13427
  const cardGap = useTableStore.use.cardGap();
13425
13428
  const loadingText = useTableStore.use.loadingText();
13429
+ const CardSkeletonComponent = useTableStore.use.CardSkeletonComponent();
13426
13430
  const cardCount = rows ?? (dynamicHeight && bodyHeight > 0 ? calculateCardSkeletonCount({
13427
13431
  bodyHeight,
13428
13432
  columnCount: cardColumnCount,
@@ -13451,7 +13455,7 @@ function NTableCardsLoadingSkeleton({ rows }) {
13451
13455
  "data-ntable-loading-card-count": cardCount,
13452
13456
  "aria-hidden": "true",
13453
13457
  className: cn(containerClass),
13454
- children: Array.from({ length: cardCount }).map((_, index) => /* @__PURE__ */ jsx(NTableCardSkeleton, { surface }, index))
13458
+ children: Array.from({ length: cardCount }).map((_, index) => CardSkeletonComponent ? /* @__PURE__ */ jsx("div", { "data-ntable-loading-card": true, children: /* @__PURE__ */ jsx(CardSkeletonComponent, {}) }, index) : /* @__PURE__ */ jsx(NTableCardSkeleton, { surface }, index))
13455
13459
  }
13456
13460
  )
13457
13461
  ]
@@ -13561,6 +13565,7 @@ function NTableCards({ effectiveMode }) {
13561
13565
  const showCheckbox = useTableStore.use.showCheckbox();
13562
13566
  const selectedRowId = useTableStore.use.selectedRowId();
13563
13567
  const CardComponent = useTableStore.use.CardComponent();
13568
+ const CardSkeletonComponent = useTableStore.use.CardSkeletonComponent();
13564
13569
  const storeIsCardView = useTableStore.use.isCardView();
13565
13570
  useTableStore.use.isLoading();
13566
13571
  const error = useTableStore.use.error();
@@ -13702,7 +13707,7 @@ function NTableCards({ effectiveMode }) {
13702
13707
  row.id
13703
13708
  );
13704
13709
  }),
13705
- continuation.pending ? Array.from({ length: Math.max(1, cardColumnCount || 1) }).map((_, index) => /* @__PURE__ */ jsx(NTableCardSkeleton, { surface }, `ntable-continuation-skeleton-${index}`)) : null
13710
+ continuation.pending ? Array.from({ length: Math.max(1, cardColumnCount || 1) }).map((_, index) => CardSkeletonComponent ? /* @__PURE__ */ jsx(CardSkeletonComponent, {}, `ntable-continuation-skeleton-${index}`) : /* @__PURE__ */ jsx(NTableCardSkeleton, { surface }, `ntable-continuation-skeleton-${index}`)) : null
13706
13711
  ] }),
13707
13712
  continuation.error ? /* @__PURE__ */ jsxs(
13708
13713
  "div",
@@ -14316,7 +14321,10 @@ function TableLayout(props) {
14316
14321
  "aria-busy": isRefreshing ? "true" : void 0,
14317
14322
  className: "flex min-h-0 flex-1 flex-col gap-2 overflow-hidden",
14318
14323
  children: isCustomMode ? customRenderer ? customRenderer() : null : /* @__PURE__ */ jsxs(Fragment, { children: [
14319
- isLoading && !isRefreshing && (props.renderLoading ? /* @__PURE__ */ jsx(TableStateSlot, { children: props.renderLoading() }) : effectiveMode === "table" ? /* @__PURE__ */ jsx(NTableLoadingSkeleton, {}) : effectiveMode === "cards" ? /* @__PURE__ */ jsx(NTableCardsLoadingSkeleton, {}) : /* @__PURE__ */ jsx(NTableLoadingSkeleton, {})),
14324
+ isLoading && !isRefreshing && (props.renderLoading ? /* @__PURE__ */ jsx(TableStateSlot, { children: props.renderLoading() }) : props.responsiveSkeleton ? /* @__PURE__ */ jsxs(Fragment, { children: [
14325
+ /* @__PURE__ */ jsx("div", { "data-ntable-skeleton-variant": "table", className: "hidden min-h-0 flex-1 flex-col lg:flex", children: /* @__PURE__ */ jsx(NTableLoadingSkeleton, {}) }),
14326
+ /* @__PURE__ */ jsx("div", { "data-ntable-skeleton-variant": "cards", className: "flex min-h-0 flex-1 flex-col lg:hidden", children: /* @__PURE__ */ jsx(NTableCardsLoadingSkeleton, {}) })
14327
+ ] }) : effectiveMode === "table" ? /* @__PURE__ */ jsx(NTableLoadingSkeleton, {}) : effectiveMode === "cards" ? /* @__PURE__ */ jsx(NTableCardsLoadingSkeleton, {}) : /* @__PURE__ */ jsx(NTableLoadingSkeleton, {})),
14320
14328
  error && !isLoading && /* @__PURE__ */ jsx(TableStateSlot, { children: props.renderError ? props.renderError(error) : /* @__PURE__ */ jsx(NErrorState, { message: typeof error === "string" ? error : "An error occurred" }) }),
14321
14329
  showFilteredEmpty && /* @__PURE__ */ jsx(TableStateSlot, { children: props.renderFilteredEmpty ? props.renderFilteredEmpty() : renderFilteredEmpty ? renderFilteredEmpty() : props.renderEmpty ? props.renderEmpty() : /* @__PURE__ */ jsx(DefaultTableFilteredEmptyState, {}) }),
14322
14330
  showEmpty && /* @__PURE__ */ jsx(TableStateSlot, { children: props.renderEmpty ? props.renderEmpty() : /* @__PURE__ */ jsx(DefaultTableEmptyState, { title: noDataText }) }),
@@ -14420,6 +14428,7 @@ function NTable(props) {
14420
14428
  mode,
14421
14429
  onModeChange: props.onModeChange,
14422
14430
  CardComponent: props.renderCard ?? null,
14431
+ CardSkeletonComponent: props.renderCardSkeleton ?? null,
14423
14432
  className: props.className ?? "",
14424
14433
  classNames: props.classNames ?? {},
14425
14434
  bordered: props.bordered ?? (recipeBordered ? true : void 0),
@@ -14501,6 +14510,7 @@ function NTable(props) {
14501
14510
  renderFilteredEmpty: props.renderFilteredEmpty,
14502
14511
  renderError: props.renderError,
14503
14512
  renderLoading: props.renderLoading,
14513
+ responsiveSkeleton: props.responsiveSkeleton,
14504
14514
  contextMenuClose: ctx.close,
14505
14515
  contextMenuOpen: ctx.isOpen
14506
14516
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "najm-kit",
3
- "version": "2.2.2",
3
+ "version": "2.2.3",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "description": "Reusable React UI component package for Najm framework",