@grandbazar/ui-baza 1.9.0 → 1.10.0

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/bento.cjs CHANGED
@@ -112,6 +112,37 @@ function toBentoSpan(size, columns) {
112
112
  return { columns: Math.min(span.columns, columns), rows: span.rows };
113
113
  }
114
114
 
115
+ function countBentoHoles(sizes, columns) {
116
+ const takenRows = [];
117
+ let takenCellCount = 0;
118
+ const fits = (row, mask, rowSpan) => {
119
+ for (let offset = 0; offset < rowSpan; offset++) {
120
+ if ((takenRows[row + offset] ?? 0) & mask) {
121
+ return false;
122
+ }
123
+ }
124
+ return true;
125
+ };
126
+ for (const size of sizes) {
127
+ const span = toBentoSpan(size, columns);
128
+ const widthMask = (1 << span.columns) - 1;
129
+ let isPlaced = false;
130
+ for (let row = 0; !isPlaced; row++) {
131
+ for (let column = 0; column + span.columns <= columns && !isPlaced; column++) {
132
+ const mask = widthMask << column;
133
+ if (fits(row, mask, span.rows)) {
134
+ for (let offset = 0; offset < span.rows; offset++) {
135
+ takenRows[row + offset] = (takenRows[row + offset] ?? 0) | mask;
136
+ }
137
+ isPlaced = true;
138
+ }
139
+ }
140
+ }
141
+ takenCellCount += span.columns * span.rows;
142
+ }
143
+ return takenRows.length * columns - takenCellCount;
144
+ }
145
+
115
146
  function findHoleFreeBentoSizes(preferredSizes, slots, columns) {
116
147
  const fullRow = (1 << columns) - 1;
117
148
  const innerEdges = (1 << columns - 1) - 1;
@@ -206,6 +237,14 @@ function findHoleFreeBentoSizes(preferredSizes, slots, columns) {
206
237
  return null;
207
238
  }
208
239
 
240
+ function isBentoDevMode() {
241
+ try {
242
+ return process.env.NODE_ENV !== "production";
243
+ } catch {
244
+ return false;
245
+ }
246
+ }
247
+
209
248
  function arrangeBento(slots, { columns, presets, rhythm }) {
210
249
  const fitAllowed = (size, { allowedSizes }) => {
211
250
  return [size, ...BENTO_FALLBACKS[size]].find((candidate) => allowedSizes.includes(candidate)) ?? allowedSizes[0] ?? size;
@@ -224,7 +263,16 @@ function arrangeBento(slots, { columns, presets, rhythm }) {
224
263
  });
225
264
  };
226
265
  const preferredSizes = layOut({ isPreferenceKept: true });
227
- return findHoleFreeBentoSizes(preferredSizes, slots, columns) ?? findHoleFreeBentoSizes(layOut({ isPreferenceKept: false }), slots, columns) ?? preferredSizes;
266
+ const arrangedSizes = findHoleFreeBentoSizes(preferredSizes, slots, columns) ?? findHoleFreeBentoSizes(layOut({ isPreferenceKept: false }), slots, columns) ?? preferredSizes;
267
+ if (isBentoDevMode()) {
268
+ const holeCount = countBentoHoles(arrangedSizes, columns);
269
+ if (holeCount > 0) {
270
+ console.warn(
271
+ `arrangeBento: no hole-free arrangement on a ${columns}-column grid, ${holeCount} cell(s) left empty: ${arrangedSizes.join(", ")}`
272
+ );
273
+ }
274
+ }
275
+ return arrangedSizes;
228
276
  }
229
277
 
230
278
  function arrangeBentoGrids(slotsByGrid) {
@@ -236,47 +284,21 @@ function arrangeBentoGrids(slotsByGrid) {
236
284
  });
237
285
  }
238
286
 
239
- function countBentoHoles(sizes, columns) {
240
- const takenRows = [];
241
- let takenCellCount = 0;
242
- const fits = (row, mask, rowSpan) => {
243
- for (let offset = 0; offset < rowSpan; offset++) {
244
- if ((takenRows[row + offset] ?? 0) & mask) {
245
- return false;
246
- }
247
- }
248
- return true;
249
- };
250
- for (const size of sizes) {
251
- const span = toBentoSpan(size, columns);
252
- const widthMask = (1 << span.columns) - 1;
253
- let isPlaced = false;
254
- for (let row = 0; !isPlaced; row++) {
255
- for (let column = 0; column + span.columns <= columns && !isPlaced; column++) {
256
- const mask = widthMask << column;
257
- if (fits(row, mask, span.rows)) {
258
- for (let offset = 0; offset < span.rows; offset++) {
259
- takenRows[row + offset] = (takenRows[row + offset] ?? 0) | mask;
260
- }
261
- isPlaced = true;
262
- }
263
- }
264
- }
265
- takenCellCount += span.columns * span.rows;
266
- }
267
- return takenRows.length * columns - takenCellCount;
268
- }
269
-
270
- function toBentoSlot(grid, { allowedSizes, sizes, defaultSize }) {
271
- const fixedSize = allowedSizes.length === 1 && allowedSizes[0] || sizes[grid];
287
+ function toBentoSlot(grid, { allowedSizes, sizes, defaultSize, isAdjustable = false }) {
288
+ const givenSize = sizes[grid];
289
+ const fixedSize = allowedSizes.length === 1 && allowedSizes[0] || !isAdjustable && givenSize;
290
+ const autoSizes = BENTO_AUTO_SIZES[grid].filter((size) => allowedSizes.includes(size));
272
291
  if (fixedSize) {
273
292
  return { preferredSize: fixedSize, allowedSizes: [fixedSize] };
274
293
  }
294
+ if (givenSize) {
295
+ return {
296
+ preferredSize: givenSize,
297
+ allowedSizes: autoSizes.includes(givenSize) ? autoSizes : [...autoSizes, givenSize]
298
+ };
299
+ }
275
300
  const sizeFromDesktop = grid === "mobile" && sizes.desktop && BENTO_MOBILE_SIZE_BY_DESKTOP[sizes.desktop];
276
- return {
277
- preferredSize: sizeFromDesktop || defaultSize,
278
- allowedSizes: BENTO_AUTO_SIZES[grid].filter((size) => allowedSizes.includes(size))
279
- };
301
+ return { preferredSize: sizeFromDesktop || defaultSize, allowedSizes: autoSizes };
280
302
  }
281
303
 
282
304
  exports.BENTO_AUTO_SIZES = BENTO_AUTO_SIZES;
package/dist/bento.d.ts CHANGED
@@ -45,10 +45,11 @@ declare type TBentoSlotSource = {
45
45
  allowedSizes: readonly TBentoSize[];
46
46
  sizes: Partial<Record<TBentoGrid, TBentoSize | null>>;
47
47
  defaultSize: TBentoSize | null;
48
+ isAdjustable?: boolean;
48
49
  };
49
50
 
50
51
  export declare type TBentoTileShape = TArrayElement<typeof BENTO_TILE_SHAPES>;
51
52
 
52
- export declare function toBentoSlot(grid: TBentoGrid, { allowedSizes, sizes, defaultSize }: TBentoSlotSource): TBentoSlot;
53
+ export declare function toBentoSlot(grid: TBentoGrid, { allowedSizes, sizes, defaultSize, isAdjustable }: TBentoSlotSource): TBentoSlot;
53
54
 
54
55
  export { }
package/dist/bento.js CHANGED
@@ -108,6 +108,37 @@ function toBentoSpan(size, columns) {
108
108
  return { columns: Math.min(span.columns, columns), rows: span.rows };
109
109
  }
110
110
 
111
+ function countBentoHoles(sizes, columns) {
112
+ const takenRows = [];
113
+ let takenCellCount = 0;
114
+ const fits = (row, mask, rowSpan) => {
115
+ for (let offset = 0; offset < rowSpan; offset++) {
116
+ if ((takenRows[row + offset] ?? 0) & mask) {
117
+ return false;
118
+ }
119
+ }
120
+ return true;
121
+ };
122
+ for (const size of sizes) {
123
+ const span = toBentoSpan(size, columns);
124
+ const widthMask = (1 << span.columns) - 1;
125
+ let isPlaced = false;
126
+ for (let row = 0; !isPlaced; row++) {
127
+ for (let column = 0; column + span.columns <= columns && !isPlaced; column++) {
128
+ const mask = widthMask << column;
129
+ if (fits(row, mask, span.rows)) {
130
+ for (let offset = 0; offset < span.rows; offset++) {
131
+ takenRows[row + offset] = (takenRows[row + offset] ?? 0) | mask;
132
+ }
133
+ isPlaced = true;
134
+ }
135
+ }
136
+ }
137
+ takenCellCount += span.columns * span.rows;
138
+ }
139
+ return takenRows.length * columns - takenCellCount;
140
+ }
141
+
111
142
  function findHoleFreeBentoSizes(preferredSizes, slots, columns) {
112
143
  const fullRow = (1 << columns) - 1;
113
144
  const innerEdges = (1 << columns - 1) - 1;
@@ -202,6 +233,14 @@ function findHoleFreeBentoSizes(preferredSizes, slots, columns) {
202
233
  return null;
203
234
  }
204
235
 
236
+ function isBentoDevMode() {
237
+ try {
238
+ return process.env.NODE_ENV !== "production";
239
+ } catch {
240
+ return false;
241
+ }
242
+ }
243
+
205
244
  function arrangeBento(slots, { columns, presets, rhythm }) {
206
245
  const fitAllowed = (size, { allowedSizes }) => {
207
246
  return [size, ...BENTO_FALLBACKS[size]].find((candidate) => allowedSizes.includes(candidate)) ?? allowedSizes[0] ?? size;
@@ -220,7 +259,16 @@ function arrangeBento(slots, { columns, presets, rhythm }) {
220
259
  });
221
260
  };
222
261
  const preferredSizes = layOut({ isPreferenceKept: true });
223
- return findHoleFreeBentoSizes(preferredSizes, slots, columns) ?? findHoleFreeBentoSizes(layOut({ isPreferenceKept: false }), slots, columns) ?? preferredSizes;
262
+ const arrangedSizes = findHoleFreeBentoSizes(preferredSizes, slots, columns) ?? findHoleFreeBentoSizes(layOut({ isPreferenceKept: false }), slots, columns) ?? preferredSizes;
263
+ if (isBentoDevMode()) {
264
+ const holeCount = countBentoHoles(arrangedSizes, columns);
265
+ if (holeCount > 0) {
266
+ console.warn(
267
+ `arrangeBento: no hole-free arrangement on a ${columns}-column grid, ${holeCount} cell(s) left empty: ${arrangedSizes.join(", ")}`
268
+ );
269
+ }
270
+ }
271
+ return arrangedSizes;
224
272
  }
225
273
 
226
274
  function arrangeBentoGrids(slotsByGrid) {
@@ -232,47 +280,21 @@ function arrangeBentoGrids(slotsByGrid) {
232
280
  });
233
281
  }
234
282
 
235
- function countBentoHoles(sizes, columns) {
236
- const takenRows = [];
237
- let takenCellCount = 0;
238
- const fits = (row, mask, rowSpan) => {
239
- for (let offset = 0; offset < rowSpan; offset++) {
240
- if ((takenRows[row + offset] ?? 0) & mask) {
241
- return false;
242
- }
243
- }
244
- return true;
245
- };
246
- for (const size of sizes) {
247
- const span = toBentoSpan(size, columns);
248
- const widthMask = (1 << span.columns) - 1;
249
- let isPlaced = false;
250
- for (let row = 0; !isPlaced; row++) {
251
- for (let column = 0; column + span.columns <= columns && !isPlaced; column++) {
252
- const mask = widthMask << column;
253
- if (fits(row, mask, span.rows)) {
254
- for (let offset = 0; offset < span.rows; offset++) {
255
- takenRows[row + offset] = (takenRows[row + offset] ?? 0) | mask;
256
- }
257
- isPlaced = true;
258
- }
259
- }
260
- }
261
- takenCellCount += span.columns * span.rows;
262
- }
263
- return takenRows.length * columns - takenCellCount;
264
- }
265
-
266
- function toBentoSlot(grid, { allowedSizes, sizes, defaultSize }) {
267
- const fixedSize = allowedSizes.length === 1 && allowedSizes[0] || sizes[grid];
283
+ function toBentoSlot(grid, { allowedSizes, sizes, defaultSize, isAdjustable = false }) {
284
+ const givenSize = sizes[grid];
285
+ const fixedSize = allowedSizes.length === 1 && allowedSizes[0] || !isAdjustable && givenSize;
286
+ const autoSizes = BENTO_AUTO_SIZES[grid].filter((size) => allowedSizes.includes(size));
268
287
  if (fixedSize) {
269
288
  return { preferredSize: fixedSize, allowedSizes: [fixedSize] };
270
289
  }
290
+ if (givenSize) {
291
+ return {
292
+ preferredSize: givenSize,
293
+ allowedSizes: autoSizes.includes(givenSize) ? autoSizes : [...autoSizes, givenSize]
294
+ };
295
+ }
271
296
  const sizeFromDesktop = grid === "mobile" && sizes.desktop && BENTO_MOBILE_SIZE_BY_DESKTOP[sizes.desktop];
272
- return {
273
- preferredSize: sizeFromDesktop || defaultSize,
274
- allowedSizes: BENTO_AUTO_SIZES[grid].filter((size) => allowedSizes.includes(size))
275
- };
297
+ return { preferredSize: sizeFromDesktop || defaultSize, allowedSizes: autoSizes };
276
298
  }
277
299
 
278
300
  export { BENTO_AUTO_SIZES, BENTO_CONFIGURABLE_SIZES, BENTO_GRIDS, BENTO_GRID_NAMES, BENTO_MOBILE_SIZE_BY_DESKTOP, BENTO_SIZES, BENTO_THIN_SIZES, BENTO_TILE_SHAPES, BENTO_TILE_SHAPE_BY_SIZE, arrangeBento, arrangeBentoGrids, countBentoHoles, toBentoSlot };
package/dist/index.d.ts CHANGED
@@ -821,6 +821,7 @@ declare type TBentoSlotSource = {
821
821
  allowedSizes: readonly TBentoSize[];
822
822
  sizes: Partial<Record<TBentoGrid, TBentoSize | null>>;
823
823
  defaultSize: TBentoSize | null;
824
+ isAdjustable?: boolean;
824
825
  };
825
826
 
826
827
  export declare type TBentoTileShape = TArrayElement<typeof BENTO_TILE_SHAPES>;
@@ -986,7 +987,7 @@ declare type TNotificationInlineProps = Omit<React.HTMLAttributes<HTMLDivElement
986
987
  onClose?: () => void;
987
988
  };
988
989
 
989
- export declare function toBentoSlot(grid: TBentoGrid, { allowedSizes, sizes, defaultSize }: TBentoSlotSource): TBentoSlot;
990
+ export declare function toBentoSlot(grid: TBentoGrid, { allowedSizes, sizes, defaultSize, isAdjustable }: TBentoSlotSource): TBentoSlot;
990
991
 
991
992
  /**
992
993
  * Tooltip is a compound component for displaying contextual hints.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@grandbazar/ui-baza",
3
- "version": "1.9.0",
3
+ "version": "1.10.0",
4
4
  "description": "A lightweight and modular UI kit for building modern, accessible web interfaces. Designed for flexibility, scalability, and developer happiness.",
5
5
  "repository": {
6
6
  "type": "git",