@qr-platform/qr-code.js 0.10.0 → 0.10.2

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/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # @qr-platform/qr-code-js
2
2
 
3
+ ## 0.10.2
4
+
5
+ ### Patch Changes
6
+
7
+ - 45342a8: added useSettings and setSettings to combine all options and templates into one json object
8
+
3
9
  ## 0.10.0
4
10
 
5
11
  ### Minor Changes
@@ -95,6 +95,8 @@ qrCode.append(document.getElementById('qr-container'));
95
95
  | `setBorder` | `borderNameOrOptions: string \| RecursivePartial<BorderOptions>` | Sets a global default border configuration (by name or options object) for subsequent instances. Returns `void`. |
96
96
  | `setBorderId` | `borderId: string` | Sets a global default border configuration by its ID. Returns `void`. |
97
97
  | `setImage` | `imageUrl: string \| DataURL \| null, options?: { override?: boolean }` | Sets a global default image URL for subsequent instances. With `{ override: true }`, the image will take precedence over any instance-specific images.
98
+ | `settings` | `settings: SettingsOptions \| null` | **(Static)** Sets global default settings from a `SettingsOptions` object. This will override/reset any previously set static template, style, text, or border. Returns `typeof QRCodeJs`. |
99
+ | `setSettings` | `settings: SettingsOptions` | **(Instance)** Applies settings from a `SettingsOptions` object to the current instance, completely replacing its current options. Returns `Promise<void>`. |
98
100
  | `useTemplate` | `templateNameOrOptions: string \| RecursivePartial<Options>` | Initiates a builder pattern pre-configured with a template (by name or options object). Returns `QRCodeBuilder`. |
99
101
  | `useTemplateId` | `templateId: string` | Initiates a builder pattern pre-configured with a template by its ID. Returns `QRCodeBuilder`. |
100
102
  | `useStyle` | `styleNameOrOptions: string \| StyleOptions` | Initiates a builder pattern pre-configured with a style (by name or options object). Returns `QRCodeBuilder`. |
@@ -158,7 +160,8 @@ The `borderOptions` object is a premium feature that allows you to add decorativ
158
160
  | `style.fontSize` | `number` | `28` | The font size for the text in pixels. |
159
161
  | `style.fontColor` | `string` | `'#ffffff'` | The color of the text. |
160
162
  | `style.letterSpacing` | `number` | `0` | The letter spacing for the text in pixels. |
161
- | `style.fontWeight` | `'normal' \| 'bold'` | `'normal'` | The font weight for the text. |
163
+ | `style.textTransform` | `'uppercase' \| 'lowercase' \| 'capitalize'` | `uppercase` | The text transformation style. |
164
+ | `style.fontWeight` | `'normal' \| 'bold'` | `'bold'` | The font weight for the text. |
162
165
 
163
166
  ### Enums
164
167
 
@@ -300,6 +303,7 @@ const qr3 = QRCodeJs.useTemplate('basic')
300
303
  | `useBorder` | `borderNameOrOptions: string \| BorderOptions` | Applies border configuration (by name or options object) to the current configuration. Returns `this`. |
301
304
  | `useBorderId` | `borderId: string` | Applies border configuration by its ID to the current configuration. Returns `this`. |
302
305
  | `useImage` | `imageUrl: string, options?: { override?: boolean }` | Sets the image URL for the current configuration. With `{ override: true}`, the image will take precedence over any image set in final options. Returns `this`. |
306
+ | `useSettings` | `settings: SettingsOptions` | Applies a comprehensive `SettingsOptions` object to the builder. This will override/reset any previously set builder configurations (template, style, text, border, image, data). Returns `this`. |
303
307
  | `options` | `options: RecursivePartial<Options>` | Merges the provided `Options` into the current configuration and returns the final `QRCodeJs` instance. |
304
308
  | `build` | - | Creates and returns the final `QRCodeJs` instance based on the accumulated configuration. |
305
309
  ### See Also
@@ -698,6 +698,7 @@ Options for adding decorative borders around the QR code. Borders can be configu
698
698
  fontFace: 'Helvetica',
699
699
  fontSize: 28,
700
700
  fontColor: '#ffffff',
701
+ textTransform: 'uppercase',
701
702
  letterSpacing: 2,
702
703
  fontWeight: 'bold'
703
704
  }
@@ -826,10 +827,10 @@ QRCode.js provides dedicated methods for managing text on QR code borders, allow
826
827
  - **Example**:
827
828
  ```typescript
828
829
  // Set global text using a predefined template ID
829
- QRCodeJs.setTextId('visit-website-bottom');
830
+ QRCodeJs.setTextId('scan-to-visit-website');
830
831
 
831
832
  // With override option
832
- QRCodeJs.setTextId('lost-found-all-sides', { override: true });
833
+ QRCodeJs.setTextId('lost-found', { override: true });
833
834
 
834
835
  // Clear global text
835
836
  QRCodeJs.setTextId(null);
@@ -884,11 +885,11 @@ QRCode.js provides dedicated methods for managing text on QR code borders, allow
884
885
  - **Example**:
885
886
  ```typescript
886
887
  // Start builder with a predefined text template by ID
887
- const qrCode = QRCodeJs.useTextId('visit-website-bottom')
888
+ const qrCode = QRCodeJs.useTextId('scan-to-visit-website')
888
889
  .options({ data: 'https://example.com' });
889
890
 
890
891
  // With override option
891
- const qrWithOverride = QRCodeJs.useTextId('scan-me-top', { override: true })
892
+ const qrWithOverride = QRCodeJs.useTextId('scan-me', { override: true })
892
893
  .options({ data: 'https://example.com' });
893
894
  ```
894
895
 
@@ -0,0 +1,124 @@
1
+ # Feature Task FT009 - Settings Option - Continuation Plan
2
+
3
+ ## 1. Original Task Description (FT009)
4
+
5
+ **Feature:** Settings Option
6
+ **Task Description:** Add a mechanism to configure QR code instances using a comprehensive `SettingsOptions` object. This was initially planned as an instance method `setSettings()` and a static builder-style method `QRCodeJs.settings()`. The requirements evolved to include a `useSettings()` method for the `QRCodeBuilder` and to make the instance-level application a static utility method.
7
+
8
+ **Core Requirements:**
9
+ * Provide a centralized way to configure multiple QR code properties: `id`, `name`, `description`, `data`, `image`, `template`, `templateId`, `style`, `styleId`, `text`, `textId`, `border`, `borderId`, and a general `options` override.
10
+ * Ensure this new configuration method interacts correctly with existing setup methods, generally by overriding previous settings.
11
+
12
+ ## 2. Current Implementation Status
13
+
14
+ ### 2.1. Core Class Changes ([`src/core/qr-code-js.ts`](src/core/qr-code-js.ts))
15
+ * **`SettingsOptions` Type:** Defined in [`src/types/settings-options.ts`](src/types/settings-options.ts). It includes:
16
+ ```typescript
17
+ export interface SettingsOptions {
18
+ id?: string;
19
+ name?: string;
20
+ description?: string;
21
+ data?: string;
22
+ image?: string | Buffer | Blob;
23
+ template?: string | RecursivePartial<Options>;
24
+ templateId?: string;
25
+ style?: string | StyleOptions;
26
+ styleId?: string;
27
+ text?: string | TextOptions;
28
+ textId?: string;
29
+ border?: string | RecursivePartial<BorderOptions>;
30
+ borderId?: string;
31
+ options?: RecursivePartial<Options>;
32
+ }
33
+ ```
34
+ * **Static `setSettings` Method:**
35
+ * A `public static async setSettings(instance: QRCodeJs, settings: SettingsOptions): Promise<void>` method has been added to `QRCodeJs`.
36
+ * This method applies the provided `SettingsOptions` to a given `QRCodeJs` instance.
37
+ * It completely replaces the instance's current options by:
38
+ 1. Starting with `baseQRTemplateOptions`.
39
+ 2. Applying `template`, `style`, `text`, `border` from the `settings` object.
40
+ 3. Setting `newOptions.image = settings.image` if `settings.image` is provided.
41
+ 4. Setting `newOptions.data = settings.data` if `settings.data` is provided. If not, it attempts to use `settings.options.data`. If still not present, it retains `instance.options.data`.
42
+ 5. Merging `settings.options` for any other direct overrides.
43
+ 6. Validating and sanitizing the resulting options.
44
+ 7. Calling `await instance.update()`.
45
+ * **Removed Static Configuration:** The previously planned static `QRCodeJs.settings()` method (that would set static defaults like `_selectedSettings`) and related static properties (`_selectedSettings`, `_selectedData`) have been removed from `QRCodeJs` as per user feedback.
46
+
47
+ ### 2.2. Documentation
48
+ * [`docs/typescript-types-definitions.md`](docs/typescript-types-definitions.md): Updated with the `SettingsOptions` interface.
49
+ * [`docs/api-reference-guide.md`](docs/api-reference-guide.md): Updated to reflect the new static `QRCodeJs.setSettings(instance, settings)` method and remove the old static `QRCodeJs.settings()` method.
50
+ * [`docs/usage-guide.md`](docs/usage-guide.md): Updated with examples for the new static `QRCodeJs.setSettings(instance, settings)` method.
51
+
52
+ ### 2.3. Unit Tests
53
+ * [`tests/node/node.settings.test.ts`](tests/node/node.settings.test.ts): Initial tests for the static `setSettings(instance, settings)` method have been created and partially debugged. Import paths and type assertions have been refined.
54
+
55
+ ## 3. Remaining Tasks
56
+
57
+ ### 3.1. Implement `useSettings` in `QRCodeBuilder`
58
+ This is the primary remaining coding task. The `useSettings` method needs to be added to the `QRCodeBuilder` class in both:
59
+ * [`src/index.ts`](src/index.ts) (for browser environment)
60
+ * [`src/node.ts`](src/node.ts) (for Node.js environment)
61
+
62
+ **`QRCodeBuilder.useSettings(settings: SettingsOptions): this` Method Details:**
63
+ * **Store Settings:**
64
+ * Add a new protected property to `QRCodeBuilder`: `protected _settingsSource: SettingsOptions | null = null;`
65
+ * The `useSettings` method will set `this._settingsSource = settings;`.
66
+ * **Override Behavior:**
67
+ * Calling `useSettings` must reset/nullify all other builder-specific configuration sources to ensure it takes precedence over any prior `useTemplate()`, `useStyle()`, `useBorder()`, `useText()`, `useImage()` calls, and `_initialOptions`. This includes:
68
+ * `this._templateSource = null;`
69
+ * `this._isTemplateById = false;`
70
+ * `this._borderSource = null;`
71
+ * `this._isBorderById = false;`
72
+ * `this._styleSource = null;`
73
+ * `this._isStyleById = false;`
74
+ * `this._imageSource = null;`
75
+ * `this._imageOverride = false;`
76
+ * `this._textSource = null;`
77
+ * `this._isTextById = false;`
78
+ * `this._textOverride = false;`
79
+ * `this._initialOptions = null;`
80
+ * **Modify `_resolveAndMergeConfig(finalOptions: RecursivePartial<Options> = {})` in `QRCodeBuilder`:**
81
+ * **Priority for `_settingsSource`:**
82
+ 1. If `this._settingsSource` is set:
83
+ * Initialize `resolvedConfig = mergeDeep({}, baseQRTemplateOptions)`.
84
+ * Apply `template/templateId` from `this._settingsSource` to `resolvedConfig`.
85
+ * Apply `style/styleId` from `this._settingsSource` (mapping style options) to `resolvedConfig`.
86
+ * Apply `border/borderId` from `this._settingsSource` to `resolvedConfig`.
87
+ * Apply `text/textId` from `this._settingsSource` (mapping to `borderOptions.decorations`) to `resolvedConfig`.
88
+ * If `this._settingsSource.image` is defined, set `resolvedConfig.image = this._settingsSource.image;`.
89
+ * If `this._settingsSource.data` is defined, set `resolvedConfig.data = this._settingsSource.data;`.
90
+ * Merge `this._settingsSource.options` into `resolvedConfig`.
91
+ * **Else (no `_settingsSource`):**
92
+ * Follow the existing logic: apply `_initialOptions`, then `_templateSource`, `_borderSource`, `_styleSource`, `_imageSource` (non-override), `_textSource` (non-override).
93
+ * **Final Merge & Overrides:**
94
+ * Merge `finalOptions` (from a subsequent `.options()` call) into `resolvedConfig`. This allows `.options()` to override settings from `useSettings`.
95
+ * The existing `_imageOverride` and `_textOverride` logic should apply last. If `useImage(..., {override:true})` or `useText(..., {override:true})` is called *after* `useSettings()`, it effectively clears `_settingsSource` (because `useSettings` resets those specific sources) and these specific overrides would then apply as intended.
96
+
97
+ ### 3.2. Unit Testing
98
+ * Add comprehensive unit tests for `QRCodeBuilder.useSettings` in both [`tests/node/node.settings.test.ts`](tests/node/node.settings.test.ts) and potentially a new browser-specific test file if behavior differs or requires DOM.
99
+ * Tests should cover:
100
+ * `useSettings` correctly applying all properties from `SettingsOptions`.
101
+ * `useSettings` overriding configurations from previous `useTemplate`, `useStyle`, `useBorder`, `useText`, `useImage` calls.
102
+ * A subsequent `.options()` call overriding configurations set by `useSettings`.
103
+ * `.build()` using the correct configuration when `useSettings` is involved.
104
+ * Interaction with `useImage(..., {override:true})` and `useText(..., {override:true})` when called after `useSettings`.
105
+
106
+ ### 3.3. Documentation Updates
107
+ * **[`docs/api-reference-guide.md`](docs/api-reference-guide.md):** Add `useSettings` to the `QRCodeBuilder` methods table.
108
+ * **[`docs/usage-guide.md`](docs/usage-guide.md):** Add a new subsection explaining `QRCodeBuilder.useSettings` with clear examples, emphasizing its override behavior and interaction with `.options()`.
109
+
110
+ ## 4. Files to be Modified for Remaining Tasks
111
+ * [`src/index.ts`](src/index.ts) (for `QRCodeBuilder`)
112
+ * [`src/node.ts`](src/node.ts) (for `QRCodeBuilder`)
113
+ * [`tests/node/node.settings.test.ts`](tests/node/node.settings.test.ts) (and potentially new test files)
114
+ * [`docs/api-reference-guide.md`](docs/api-reference-guide.md)
115
+ * [`docs/usage-guide.md`](docs/usage-guide.md)
116
+
117
+ ## 5. Key Considerations for `_resolveAndMergeConfig`
118
+ The logic for merging needs to be precise:
119
+ 1. If `_settingsSource` is present, it forms the new "base" by applying its constituent parts (template, style, border, text, image, data, options) sequentially on top of `baseQRTemplateOptions`.
120
+ 2. If `_settingsSource` is NOT present, the old logic of applying `_initialOptions`, `_templateSource`, etc., applies.
121
+ 3. `finalOptions` (from `.options()`) are merged *after* the above, allowing them to override anything set by `useSettings` or other builder methods.
122
+ 4. Specific `override: true` calls for `useImage` or `useText` should still function as the ultimate override for those specific properties if they are called *after* `useSettings` (which would have nulled out `_settingsSource` and re-activated `_imageSource`/`_textSource`).
123
+
124
+ This structured plan should allow for a smooth continuation of the task.
@@ -0,0 +1,254 @@
1
+ # Feature FT009 - Settings Option Implementation Plan
2
+
3
+ This document outlines the plan to implement the `setSettings()` instance method and the `.settings()` builder method for the `QRCodeJs` class, as per Task ID FT009.
4
+
5
+ ## I. Define `SettingsOptions` Type
6
+
7
+ 1. **Create/Update Type Definition File:**
8
+ * A new file, `src/types/settings-options.ts`, will be created.
9
+ * **Content:**
10
+ ```typescript
11
+ import { RecursivePartial } from './helper';
12
+ import { Options, BorderOptions } from '../utils/options';
13
+ import { StyleOptions } from './style-options';
14
+ import { TextOptions } from './text-options';
15
+
16
+ export interface SettingsOptions {
17
+ id?: string;
18
+ name?: string;
19
+ description?: string;
20
+ template?: string | RecursivePartial<Options>;
21
+ templateId?: string;
22
+ style?: string | StyleOptions;
23
+ styleId?: string;
24
+ text?: string | TextOptions;
25
+ textId?: string;
26
+ border?: string | RecursivePartial<BorderOptions>;
27
+ borderId?: string;
28
+ options?: RecursivePartial<Options>; // For direct overrides/merges into the main Options
29
+ }
30
+ ```
31
+ 2. **Export:** Ensure `SettingsOptions` is exported from this new file.
32
+ 3. **Import in `qr-code-js.ts`:** Add the necessary import for `SettingsOptions`.
33
+
34
+ ## II. Implement Static `QRCodeJs.settings()` Method in `qr-code-js.ts`
35
+
36
+ 1. **Add Static Property:**
37
+ ```typescript
38
+ private static _selectedSettings: SettingsOptions | null = null;
39
+ ```
40
+ 2. **Create Static `settings()` Method:**
41
+ * Define the public static method:
42
+ ```typescript
43
+ public static settings(settings: SettingsOptions | null): typeof QRCodeJs {
44
+ // 1. Reset all existing static configurations to ensure "replace" behavior
45
+ QRCodeJs._selectedTemplate = null;
46
+ QRCodeJs._selectedBorder = null;
47
+ QRCodeJs._selectedStyle = null;
48
+ QRCodeJs._selectedImage = null;
49
+ QRCodeJs._selectedImageOverride = false;
50
+ QRCodeJs._selectedText = null;
51
+ QRCodeJs._selectedTextOverride = false;
52
+ // Potentially other static states if any are missed here.
53
+
54
+ if (settings === null) {
55
+ QRCodeJs._selectedSettings = null;
56
+ return QRCodeJs;
57
+ }
58
+
59
+ QRCodeJs._selectedSettings = settings;
60
+
61
+ // 2. Apply individual configurations from the 'settings' object
62
+ if (settings.templateId) {
63
+ QRCodeJs.setTemplateId(settings.templateId);
64
+ } else if (settings.template) {
65
+ QRCodeJs.setTemplate(settings.template);
66
+ }
67
+
68
+ if (settings.styleId) {
69
+ QRCodeJs.setStyleId(settings.styleId);
70
+ } else if (settings.style) {
71
+ QRCodeJs.setStyle(settings.style);
72
+ }
73
+
74
+ if (settings.textId) {
75
+ QRCodeJs.setTextId(settings.textId);
76
+ } else if (settings.text) {
77
+ QRCodeJs.setText(settings.text);
78
+ }
79
+
80
+ if (settings.borderId) {
81
+ QRCodeJs.setBorderId(settings.borderId);
82
+ } else if (settings.border) {
83
+ QRCodeJs.setBorder(settings.border);
84
+ }
85
+
86
+ return QRCodeJs;
87
+ }
88
+ ```
89
+
90
+ ## III. Modify `QRCodeJs` Constructor in `qr-code-js.ts`
91
+
92
+ * The constructor's option merging logic needs to account for `_selectedSettings`.
93
+ * **Revised Constructor Logic (Conceptual):**
94
+ 1. Initialize `baseOptions`.
95
+ 2. Initialize `staticSettingsOptions = {}`.
96
+ 3. **If `QRCodeJs._selectedSettings` exists:**
97
+ * If `QRCodeJs._selectedSettings.options` exists, `staticSettingsOptions` is merged with `QRCodeJs._selectedSettings.options`.
98
+ * The presence of `_selectedSettings` implies that `_selectedTemplate`, `_selectedStyle`, etc., would have already been set by the `QRCodeJs.settings()` static method. The existing constructor logic that processes these will pick up the values derived from `_selectedSettings`.
99
+ 4. The merging order would be: `baseQRTemplateOptions`, then `staticSettingsOptions` (from `_selectedSettings.options`), then options from `_selectedTemplate`, `_selectedBorder`, `_selectedText`, `_selectedStyle`, `_selectedImage` (if any), and finally `rawOptions` passed to the constructor.
100
+ 5. `mergeDeep` will handle the combination.
101
+ 6. Proceed with validation and sanitization.
102
+
103
+ ## IV. Implement Instance `setSettings()` Method in `qr-code-js.ts`
104
+
105
+ 1. **Create Instance `setSettings()` Method:**
106
+ ```typescript
107
+ public async setSettings(settings: SettingsOptions): Promise<void> {
108
+ let newOptions: RecursivePartial<Options> = { ...baseQRTemplateOptions }; // Start fresh for "replace"
109
+
110
+ // 1. Apply template
111
+ if (settings.templateId) {
112
+ const foundTemplate = findTemplateById(settings.templateId);
113
+ if (foundTemplate) newOptions = mergeDeep(newOptions, foundTemplate.options);
114
+ } else if (settings.template) {
115
+ if (typeof settings.template === 'string') {
116
+ const foundTemplate = findTemplateByName(settings.template);
117
+ if (foundTemplate) newOptions = mergeDeep(newOptions, foundTemplate.options);
118
+ } else {
119
+ newOptions = mergeDeep(newOptions, settings.template);
120
+ }
121
+ }
122
+
123
+ // 2. Apply style
124
+ if (settings.styleId) {
125
+ const foundStyleDef = findStyleById(settings.styleId);
126
+ if (foundStyleDef) newOptions = mergeDeep(newOptions, mapStyleToOptions(foundStyleDef.style));
127
+ } else if (settings.style) {
128
+ if (typeof settings.style === 'string') {
129
+ const foundStyleDef = findStyleByName(settings.style);
130
+ if (foundStyleDef) newOptions = mergeDeep(newOptions, mapStyleToOptions(foundStyleDef.style));
131
+ } else {
132
+ const { isValid, errors } = validateStyleOptions(settings.style);
133
+ if (isValid) {
134
+ newOptions = mergeDeep(newOptions, mapStyleToOptions(settings.style));
135
+ } else {
136
+ console.warn('Invalid style options in setSettings:', errors);
137
+ }
138
+ }
139
+ }
140
+
141
+ // 3. Apply text
142
+ let textOptionsToApply: RecursivePartial<Options> = {};
143
+ let textOpts: TextOptions | null = null;
144
+ if (settings.textId) {
145
+ const foundTextTemplate = findTextTemplateById(settings.textId);
146
+ if (foundTextTemplate) textOpts = foundTextTemplate.options;
147
+ } else if (settings.text) {
148
+ if (typeof settings.text === 'string') {
149
+ const foundTextTemplate = findTextByName(settings.text);
150
+ if (foundTextTemplate) textOpts = foundTextTemplate.options;
151
+ } else {
152
+ textOpts = settings.text;
153
+ }
154
+ }
155
+ if (textOpts) {
156
+ // Logic to map textOpts to borderOptions.decorations (similar to constructor)
157
+ if (!textOptionsToApply.borderOptions) textOptionsToApply.borderOptions = {};
158
+ if (!textOptionsToApply.borderOptions.decorations) textOptionsToApply.borderOptions.decorations = {};
159
+ const decorations = textOptionsToApply.borderOptions.decorations;
160
+ // ... (full mapping logic for value, topValue, leftValue, etc.)
161
+ newOptions = mergeDeep(newOptions, textOptionsToApply);
162
+ }
163
+
164
+ // 4. Apply border
165
+ if (settings.borderId) {
166
+ const foundBorder = findBorderById(settings.borderId);
167
+ if (foundBorder) newOptions = mergeDeep(newOptions, foundBorder.options);
168
+ } else if (settings.border) {
169
+ if (typeof settings.border === 'string') {
170
+ const foundBorder = findBorderByName(settings.border);
171
+ if (foundBorder) newOptions = mergeDeep(newOptions, foundBorder.options);
172
+ } else { // It's RecursivePartial<BorderOptions>
173
+ newOptions = mergeDeep(newOptions, { borderOptions: settings.border });
174
+ }
175
+ }
176
+
177
+ // 5. Apply direct options override
178
+ if (settings.options) {
179
+ newOptions = mergeDeep(newOptions, settings.options);
180
+ }
181
+
182
+ // 6. Validate and sanitize the completely new options
183
+ const { warnings, validatedOptions } = validateQROptions(newOptions);
184
+ if (warnings.length > 0) {
185
+ this._logValidationWarnings('QR Code setSettings Validation Warnings:', warnings);
186
+ }
187
+
188
+ this.options = sanitizeOptions(validatedOptions as Options); // Replace current options
189
+
190
+ // 7. Update the QR code
191
+ await this.update();
192
+ }
193
+ ```
194
+
195
+ ## V. Documentation and Tests
196
+
197
+ 1. **Documentation:**
198
+ * Add `SettingsOptions` to `docs/typescript-types-definitions.md`.
199
+ * Document `QRCodeJs.settings()` and `instance.setSettings()` in `docs/api-reference-guide.md` and `docs/usage-guide.md`.
200
+ * Clearly explain the "replace" behavior for both methods.
201
+ * Provide usage examples.
202
+ 2. **Unit Tests:**
203
+ * Add comprehensive tests for static `settings()`, instance `setSettings()`, their "replace" behavior, and interactions.
204
+
205
+ ## Mermaid Diagram
206
+
207
+ ```mermaid
208
+ graph TD
209
+ subgraph Initialization
210
+ A[Define SettingsOptions Interface in src/types/settings-options.ts]
211
+ end
212
+
213
+ subgraph Static/Builder Method
214
+ B[Add static _selectedSettings to QRCodeJs]
215
+ C[Implement static QRCodeJs.settings(settings)]
216
+ C --> C1{settings === null?}
217
+ C1 -- Yes --> C2[Reset _selectedSettings AND all other static config (_template, _style, etc.)]
218
+ C1 -- No --> C3[Reset all other static config (_template, _style, etc.)]
219
+ C3 --> C4[Store in _selectedSettings]
220
+ C4 --> C5[Apply settings.template/Id via QRCodeJs.setTemplate/Id]
221
+ C5 --> C6[Apply settings.style/Id via QRCodeJs.setStyle/Id]
222
+ C6 --> C7[Apply settings.text/Id via QRCodeJs.setText/Id]
223
+ C7 --> C8[Apply settings.border/Id via QRCodeJs.setBorder/Id]
224
+ end
225
+
226
+ subgraph Constructor Modification
227
+ D[Modify QRCodeJs Constructor]
228
+ D --> D1[If _selectedSettings exists, its .options form part of the base]
229
+ D --> D2[Existing logic for _selectedTemplate, _selectedStyle, etc. then applies (values may come from _selectedSettings)]
230
+ end
231
+
232
+ subgraph Instance Method
233
+ E[Implement instance.setSettings(settings)]
234
+ E --> E1[Start with newOptions = baseQRTemplateOptions]
235
+ E1 --> E2[Apply settings.template/Id to newOptions (mergeDeep)]
236
+ E2 --> E3[Apply settings.style/Id to newOptions (map & mergeDeep)]
237
+ E3 --> E4[Apply settings.text/Id to newOptions (convert & mergeDeep)]
238
+ E4 --> E5[Apply settings.border/Id to newOptions (mergeDeep)]
239
+ E5 --> E6[Apply settings.options to newOptions (mergeDeep)]
240
+ E6 --> E7[Validate and Sanitize newOptions]
241
+ E7 --> E8[this.options = sanitizedNewOptions (REPLACE)]
242
+ E8 --> E9[Call this.update()]
243
+ end
244
+
245
+ subgraph Documentation & Testing
246
+ F[Update Documentation (Type, Static Method, Instance Method)]
247
+ G[Add Unit Tests (Static, Instance, Interactions, Replace Behavior)]
248
+ end
249
+
250
+ A --> C
251
+ A --> E
252
+ C8 --> D1
253
+ E9 --> G
254
+ F --> G
@@ -270,6 +270,7 @@ interface DecorationOptions {
270
270
  fontSize: number;
271
271
  fontColor: string;
272
272
  letterSpacing: number;
273
+ textTransform: 'uppercase' | 'lowercase' | 'capitalize';
273
274
  fontWeight: 'normal' | 'bold';
274
275
  };
275
276
  }
@@ -292,6 +293,60 @@ interface Gradient {
292
293
  }
293
294
  ```
294
295
 
296
+ ### SettingsOptions
297
+
298
+ Options for configuring multiple aspects of the QR code in a centralized way via `QRCodeJs.settings()` (static) or `instance.setSettings()` (instance).
299
+
300
+ ```typescript
301
+ interface SettingsOptions {
302
+ /** Optional ID for the settings preset. */
303
+ id?: string;
304
+
305
+ /** Optional name for the settings preset. */
306
+ name?: string;
307
+
308
+ /** Optional description for the settings preset. */
309
+ description?: string;
310
+
311
+ /**
312
+ * Template to apply. Can be a template name (string) or a
313
+ * `RecursivePartial<Options>` object.
314
+ * This will be applied via `QRCodeJs.setTemplate()` or `QRCodeJs.setTemplateId()`.
315
+ */
316
+ template?: string | RecursivePartial<Options>;
317
+ templateId?: string;
318
+
319
+ /**
320
+ * Style to apply. Can be a style name (string) or a `StyleOptions` object.
321
+ * This will be applied via `QRCodeJs.setStyle()` or `QRCodeJs.setStyleId()`.
322
+ */
323
+ style?: string | StyleOptions;
324
+ styleId?: string;
325
+
326
+ /**
327
+ * Text configuration to apply. Can be a text template name (string) or a `TextOptions` object.
328
+ * This will be applied via `QRCodeJs.setText()` or `QRCodeJs.setTextId()`.
329
+ */
330
+ text?: string | TextOptions;
331
+ textId?: string;
332
+
333
+ /**
334
+ * Border configuration to apply. Can be a border template name (string) or a
335
+ * `RecursivePartial<BorderOptions>` object.
336
+ * This will be applied via `QRCodeJs.setBorder()` or `QRCodeJs.setBorderId()`.
337
+ */
338
+ border?: string | RecursivePartial<BorderOptions>;
339
+ borderId?: string;
340
+
341
+ /**
342
+ * A `RecursivePartial<Options>` object that will be deeply merged into
343
+ * the QR code's main options. This allows for direct overrides of any specific
344
+ * properties within the `Options` interface.
345
+ */
346
+ options?: RecursivePartial<Options>;
347
+ }
348
+ ```
349
+
295
350
  ## Enums
296
351
 
297
352
  These enums provide predefined values for certain properties, ensuring type safety.