packing-bingo 0.2.0 → 0.4.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/core.d.cts CHANGED
@@ -3,13 +3,27 @@ interface BingoItem {
3
3
  emoji: string;
4
4
  label: string;
5
5
  }
6
- /** The default 16 school-trip items (Japanese), listed row by row from the top left. */
6
+ /**
7
+ * The default 16 school-trip items (Japanese), listed row by row from the top left.
8
+ * Smaller cards (`size` 2 or 3, without `items`) use the first ones.
9
+ * Labels keep each unbreakable run to about 6 characters so they fit the narrow (phone) card;
10
+ * `\u200B` marks where a longer label may wrap.
11
+ */
7
12
  declare const DEFAULT_ITEMS: readonly BingoItem[];
8
13
 
14
+ /**
15
+ * The winning lines of a size × size card, as indices into its items (row by row, skipping the
16
+ * FREE square): first the rows, then the columns, then the diagonal from the top left and the
17
+ * one from the top right. With `free`, the lines through the center have size − 1 items.
18
+ */
19
+ declare function bingoLines(size: number, free?: boolean): number[][];
20
+
9
21
  /** Every piece of UI text. Pass a partial object as `messages` to override some of them. */
10
22
  interface Messages {
11
23
  title: string;
24
+ /** A label above the title; empty (not shown) by default. */
12
25
  tag: string;
26
+ /** A line under the title; empty (not shown) by default. */
13
27
  subtitle: string;
14
28
  packed: string;
15
29
  bingo: string;
@@ -17,9 +31,13 @@ interface Messages {
17
31
  combo: (n: number) => string;
18
32
  comboPop: (n: number) => string;
19
33
  reset: string;
34
+ /** The button that moves the items to random squares. */
35
+ shuffle: string;
20
36
  soundOn: string;
21
37
  soundOff: string;
22
38
  stamp: string;
39
+ /** Text on the FREE square in the center (with `free`). */
40
+ free: string;
23
41
  reachBadge: string;
24
42
  reachPop: string;
25
43
  bannerSingle: string;
@@ -27,17 +45,18 @@ interface Messages {
27
45
  bannerTriple: string;
28
46
  bannerNth: (totalLines: number) => string;
29
47
  bannerMulti: (newLines: number) => string;
48
+ /** The status line before the first line is complete; empty by default. */
30
49
  statusStart: (left: number) => string;
31
50
  statusLines: (lines: number, left: number) => string;
32
- /** `labels` are the items that would each complete a line right now. */
51
+ /** `labels` are the items that would each complete a line right now; empty by default. */
33
52
  statusReach: (labels: string[]) => string;
34
53
  statusDone: string;
35
54
  perfectTag: string;
36
55
  /** Text inside the round stamp; `\n` starts a new line. */
37
56
  perfectStamp: string;
38
57
  perfectTitle: string;
39
- /** `\n` starts a new line. */
40
- perfectBody: string;
58
+ /** `\n` starts a new line. As a function, it gets the number of items on the card. */
59
+ perfectBody: string | ((total: number) => string);
41
60
  perfectBonus: (points: number) => string;
42
61
  statScore: string;
43
62
  statCombo: string;
@@ -53,19 +72,31 @@ declare const ja: Messages;
53
72
  /** English. */
54
73
  declare const en: Messages;
55
74
 
56
- /** The 10 winning lines of a 4×4 card: 4 rows, 4 columns, 2 diagonals (indices are row-major). */
75
+ /**
76
+ * The 10 winning lines of a 4×4 card: 4 rows, 4 columns, 2 diagonals (indices are row-major).
77
+ * For other sizes, use `bingoLines(size, free)`.
78
+ */
57
79
  declare const LINES: readonly (readonly number[])[];
58
80
  interface PackingBingoState {
59
- /** 16 booleans, row-major. */
81
+ /** One boolean per item, row by row (the FREE square is not included). */
60
82
  checked: boolean[];
61
- /** Indices into LINES of the completed lines. */
83
+ /** The completed lines, as indices into `bingoLines(size, free)`. */
62
84
  lines: number[];
63
85
  score: number;
64
86
  maxCombo: number;
65
87
  complete: boolean;
88
+ /** Squares per side. */
89
+ size: number;
90
+ /** Whether the center is a FREE square. */
91
+ free: boolean;
92
+ /**
93
+ * The item in each slot (row by row, skipping the FREE square): `[0, 1, 2, …]` until the card
94
+ * is shuffled. Line `k` holds the items `bingoLines(size, free)[k].map((s) => order[s])`.
95
+ */
96
+ order: number[];
66
97
  }
67
98
  interface BingoEvent {
68
- /** Lines (indices into LINES) completed by this change. */
99
+ /** Lines (indices into `bingoLines(size, free)`, which is LINES for 4×4) completed by this change. */
69
100
  newLines: number[];
70
101
  totalLines: number;
71
102
  score: number;
@@ -75,14 +106,27 @@ interface PerfectEvent {
75
106
  maxCombo: number;
76
107
  }
77
108
  interface PackingBingoOptions {
78
- /** Exactly 16 items, row by row. Defaults to a Japanese school-trip list. */
109
+ /**
110
+ * One item per square, row by row (skipping the FREE square). Defaults to a Japanese
111
+ * school-trip list of 16. The count sets the size unless `size` is given: 9 → 3×3, 16 → 4×4.
112
+ */
79
113
  items?: readonly BingoItem[];
114
+ /**
115
+ * Squares per side, 2 to 10. By default it follows the number of items. Without `items`,
116
+ * a 2×2 or 3×3 card uses the first default items.
117
+ */
118
+ size?: number;
119
+ /**
120
+ * Make the center a FREE square (odd sizes only): it is always stamped and counts toward the
121
+ * lines through it. `items`, `checked` and `defaultChecked` then have size² − 1 entries.
122
+ */
123
+ free?: boolean;
80
124
  /** Overrides for UI text. Start from `ja` (default) or `en`. */
81
125
  messages?: Partial<Messages>;
82
126
  title?: string;
83
127
  tag?: string;
84
128
  subtitle?: string;
85
- /** Initial state (16 booleans), used when nothing is saved under `storageKey`. */
129
+ /** Initial state (one boolean per item), used when nothing is saved under `storageKey`. */
86
130
  defaultChecked?: readonly boolean[];
87
131
  /**
88
132
  * When true, taps don't change the card by themselves: they call `onChange` with the
@@ -97,7 +141,27 @@ interface PackingBingoOptions {
97
141
  storageKey?: string | null;
98
142
  /** Start with sound on (default) or off. A choice made with the sound button is remembered. */
99
143
  sound?: boolean;
100
- /** Load the display fonts from Google Fonts (default true). */
144
+ /**
145
+ * Show the 🔀 button that moves the items to random squares (default true). Checks stay with
146
+ * their items. The arrangement is saved next to the checks, under "packing-bingo-order:" +
147
+ * the storage key.
148
+ */
149
+ shuffle?: boolean;
150
+ /**
151
+ * The starting arrangement, as in `getState().order`, used when no shuffled arrangement is
152
+ * saved. Ignored unless it lists every item index exactly once.
153
+ */
154
+ defaultOrder?: readonly number[];
155
+ /**
156
+ * Buzz on phones (default true): a short buzz on each tap and longer patterns for a bingo, a
157
+ * perfect card and a shuffle where the Vibration API exists (Android), and the system tap
158
+ * haptic on iPhone (iOS 18 and later), which only follows a real tap.
159
+ */
160
+ vibrate?: boolean;
161
+ /**
162
+ * @deprecated Ignored since 0.4.0: the card no longer loads fonts. To get Dela Gothic One and
163
+ * M PLUS Rounded 1c, load them on the page (see the README's フォント section).
164
+ */
101
165
  fonts?: boolean;
102
166
  /** Pre-fill a few items and show demo buttons. */
103
167
  demo?: boolean;
@@ -113,8 +177,13 @@ interface PackingBingoInstance {
113
177
  setChecked(next: readonly boolean[], options?: {
114
178
  animate?: boolean;
115
179
  }): void;
116
- /** Clear the card and score (calls onChange). */
180
+ /** Clear the card and score (calls onChange), and put the items back in their own squares. */
117
181
  reset(): void;
182
+ /**
183
+ * Move the items to random squares, as the 🔀 button does. Checks stay with their items; lines
184
+ * the new arrangement happens to complete count as done but earn no points.
185
+ */
186
+ shuffle(): void;
118
187
  getState(): PackingBingoState;
119
188
  /** Redraw the status text, e.g. after functions in `messages` start returning something else. */
120
189
  refresh(): void;
@@ -124,5 +193,5 @@ interface PackingBingoInstance {
124
193
  /** Render a packing bingo card into `container`. Call only in the browser. */
125
194
  declare function createPackingBingo(container: HTMLElement, options?: PackingBingoOptions): PackingBingoInstance;
126
195
 
127
- export { DEFAULT_ITEMS, LINES, createPackingBingo, en, ja };
196
+ export { DEFAULT_ITEMS, LINES, bingoLines, createPackingBingo, en, ja };
128
197
  export type { BingoEvent, BingoItem, Messages, PackingBingoInstance, PackingBingoOptions, PackingBingoState, PerfectEvent };
package/dist/core.d.ts CHANGED
@@ -3,13 +3,27 @@ interface BingoItem {
3
3
  emoji: string;
4
4
  label: string;
5
5
  }
6
- /** The default 16 school-trip items (Japanese), listed row by row from the top left. */
6
+ /**
7
+ * The default 16 school-trip items (Japanese), listed row by row from the top left.
8
+ * Smaller cards (`size` 2 or 3, without `items`) use the first ones.
9
+ * Labels keep each unbreakable run to about 6 characters so they fit the narrow (phone) card;
10
+ * `\u200B` marks where a longer label may wrap.
11
+ */
7
12
  declare const DEFAULT_ITEMS: readonly BingoItem[];
8
13
 
14
+ /**
15
+ * The winning lines of a size × size card, as indices into its items (row by row, skipping the
16
+ * FREE square): first the rows, then the columns, then the diagonal from the top left and the
17
+ * one from the top right. With `free`, the lines through the center have size − 1 items.
18
+ */
19
+ declare function bingoLines(size: number, free?: boolean): number[][];
20
+
9
21
  /** Every piece of UI text. Pass a partial object as `messages` to override some of them. */
10
22
  interface Messages {
11
23
  title: string;
24
+ /** A label above the title; empty (not shown) by default. */
12
25
  tag: string;
26
+ /** A line under the title; empty (not shown) by default. */
13
27
  subtitle: string;
14
28
  packed: string;
15
29
  bingo: string;
@@ -17,9 +31,13 @@ interface Messages {
17
31
  combo: (n: number) => string;
18
32
  comboPop: (n: number) => string;
19
33
  reset: string;
34
+ /** The button that moves the items to random squares. */
35
+ shuffle: string;
20
36
  soundOn: string;
21
37
  soundOff: string;
22
38
  stamp: string;
39
+ /** Text on the FREE square in the center (with `free`). */
40
+ free: string;
23
41
  reachBadge: string;
24
42
  reachPop: string;
25
43
  bannerSingle: string;
@@ -27,17 +45,18 @@ interface Messages {
27
45
  bannerTriple: string;
28
46
  bannerNth: (totalLines: number) => string;
29
47
  bannerMulti: (newLines: number) => string;
48
+ /** The status line before the first line is complete; empty by default. */
30
49
  statusStart: (left: number) => string;
31
50
  statusLines: (lines: number, left: number) => string;
32
- /** `labels` are the items that would each complete a line right now. */
51
+ /** `labels` are the items that would each complete a line right now; empty by default. */
33
52
  statusReach: (labels: string[]) => string;
34
53
  statusDone: string;
35
54
  perfectTag: string;
36
55
  /** Text inside the round stamp; `\n` starts a new line. */
37
56
  perfectStamp: string;
38
57
  perfectTitle: string;
39
- /** `\n` starts a new line. */
40
- perfectBody: string;
58
+ /** `\n` starts a new line. As a function, it gets the number of items on the card. */
59
+ perfectBody: string | ((total: number) => string);
41
60
  perfectBonus: (points: number) => string;
42
61
  statScore: string;
43
62
  statCombo: string;
@@ -53,19 +72,31 @@ declare const ja: Messages;
53
72
  /** English. */
54
73
  declare const en: Messages;
55
74
 
56
- /** The 10 winning lines of a 4×4 card: 4 rows, 4 columns, 2 diagonals (indices are row-major). */
75
+ /**
76
+ * The 10 winning lines of a 4×4 card: 4 rows, 4 columns, 2 diagonals (indices are row-major).
77
+ * For other sizes, use `bingoLines(size, free)`.
78
+ */
57
79
  declare const LINES: readonly (readonly number[])[];
58
80
  interface PackingBingoState {
59
- /** 16 booleans, row-major. */
81
+ /** One boolean per item, row by row (the FREE square is not included). */
60
82
  checked: boolean[];
61
- /** Indices into LINES of the completed lines. */
83
+ /** The completed lines, as indices into `bingoLines(size, free)`. */
62
84
  lines: number[];
63
85
  score: number;
64
86
  maxCombo: number;
65
87
  complete: boolean;
88
+ /** Squares per side. */
89
+ size: number;
90
+ /** Whether the center is a FREE square. */
91
+ free: boolean;
92
+ /**
93
+ * The item in each slot (row by row, skipping the FREE square): `[0, 1, 2, …]` until the card
94
+ * is shuffled. Line `k` holds the items `bingoLines(size, free)[k].map((s) => order[s])`.
95
+ */
96
+ order: number[];
66
97
  }
67
98
  interface BingoEvent {
68
- /** Lines (indices into LINES) completed by this change. */
99
+ /** Lines (indices into `bingoLines(size, free)`, which is LINES for 4×4) completed by this change. */
69
100
  newLines: number[];
70
101
  totalLines: number;
71
102
  score: number;
@@ -75,14 +106,27 @@ interface PerfectEvent {
75
106
  maxCombo: number;
76
107
  }
77
108
  interface PackingBingoOptions {
78
- /** Exactly 16 items, row by row. Defaults to a Japanese school-trip list. */
109
+ /**
110
+ * One item per square, row by row (skipping the FREE square). Defaults to a Japanese
111
+ * school-trip list of 16. The count sets the size unless `size` is given: 9 → 3×3, 16 → 4×4.
112
+ */
79
113
  items?: readonly BingoItem[];
114
+ /**
115
+ * Squares per side, 2 to 10. By default it follows the number of items. Without `items`,
116
+ * a 2×2 or 3×3 card uses the first default items.
117
+ */
118
+ size?: number;
119
+ /**
120
+ * Make the center a FREE square (odd sizes only): it is always stamped and counts toward the
121
+ * lines through it. `items`, `checked` and `defaultChecked` then have size² − 1 entries.
122
+ */
123
+ free?: boolean;
80
124
  /** Overrides for UI text. Start from `ja` (default) or `en`. */
81
125
  messages?: Partial<Messages>;
82
126
  title?: string;
83
127
  tag?: string;
84
128
  subtitle?: string;
85
- /** Initial state (16 booleans), used when nothing is saved under `storageKey`. */
129
+ /** Initial state (one boolean per item), used when nothing is saved under `storageKey`. */
86
130
  defaultChecked?: readonly boolean[];
87
131
  /**
88
132
  * When true, taps don't change the card by themselves: they call `onChange` with the
@@ -97,7 +141,27 @@ interface PackingBingoOptions {
97
141
  storageKey?: string | null;
98
142
  /** Start with sound on (default) or off. A choice made with the sound button is remembered. */
99
143
  sound?: boolean;
100
- /** Load the display fonts from Google Fonts (default true). */
144
+ /**
145
+ * Show the 🔀 button that moves the items to random squares (default true). Checks stay with
146
+ * their items. The arrangement is saved next to the checks, under "packing-bingo-order:" +
147
+ * the storage key.
148
+ */
149
+ shuffle?: boolean;
150
+ /**
151
+ * The starting arrangement, as in `getState().order`, used when no shuffled arrangement is
152
+ * saved. Ignored unless it lists every item index exactly once.
153
+ */
154
+ defaultOrder?: readonly number[];
155
+ /**
156
+ * Buzz on phones (default true): a short buzz on each tap and longer patterns for a bingo, a
157
+ * perfect card and a shuffle where the Vibration API exists (Android), and the system tap
158
+ * haptic on iPhone (iOS 18 and later), which only follows a real tap.
159
+ */
160
+ vibrate?: boolean;
161
+ /**
162
+ * @deprecated Ignored since 0.4.0: the card no longer loads fonts. To get Dela Gothic One and
163
+ * M PLUS Rounded 1c, load them on the page (see the README's フォント section).
164
+ */
101
165
  fonts?: boolean;
102
166
  /** Pre-fill a few items and show demo buttons. */
103
167
  demo?: boolean;
@@ -113,8 +177,13 @@ interface PackingBingoInstance {
113
177
  setChecked(next: readonly boolean[], options?: {
114
178
  animate?: boolean;
115
179
  }): void;
116
- /** Clear the card and score (calls onChange). */
180
+ /** Clear the card and score (calls onChange), and put the items back in their own squares. */
117
181
  reset(): void;
182
+ /**
183
+ * Move the items to random squares, as the 🔀 button does. Checks stay with their items; lines
184
+ * the new arrangement happens to complete count as done but earn no points.
185
+ */
186
+ shuffle(): void;
118
187
  getState(): PackingBingoState;
119
188
  /** Redraw the status text, e.g. after functions in `messages` start returning something else. */
120
189
  refresh(): void;
@@ -124,5 +193,5 @@ interface PackingBingoInstance {
124
193
  /** Render a packing bingo card into `container`. Call only in the browser. */
125
194
  declare function createPackingBingo(container: HTMLElement, options?: PackingBingoOptions): PackingBingoInstance;
126
195
 
127
- export { DEFAULT_ITEMS, LINES, createPackingBingo, en, ja };
196
+ export { DEFAULT_ITEMS, LINES, bingoLines, createPackingBingo, en, ja };
128
197
  export type { BingoEvent, BingoItem, Messages, PackingBingoInstance, PackingBingoOptions, PackingBingoState, PerfectEvent };
package/dist/core.js CHANGED
@@ -2,13 +2,15 @@
2
2
  import {
3
3
  DEFAULT_ITEMS,
4
4
  LINES,
5
+ bingoLines,
5
6
  createPackingBingo,
6
7
  en,
7
8
  ja
8
- } from "./chunk-WGZKPODU.js";
9
+ } from "./chunk-BAA2CFUA.js";
9
10
  export {
10
11
  DEFAULT_ITEMS,
11
12
  LINES,
13
+ bingoLines,
12
14
  createPackingBingo,
13
15
  en,
14
16
  ja