@ordernow/capacitor-language 0.0.0-stage → 1.0.1

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 MinhVDV
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,18 @@
1
+ require 'json'
2
+
3
+ package = JSON.parse(File.read(File.join(__dir__, 'package.json')))
4
+
5
+ Pod::Spec.new do |s|
6
+ s.name = 'OrdernowCapacitorLanguage'
7
+ s.version = package['version']
8
+ s.summary = package['description']
9
+ s.license = package['license']
10
+ s.homepage = package['repository']['url']
11
+ s.author = package['author']
12
+ s.source = { :git => package['repository']['url'], :tag => s.version.to_s }
13
+ s.source_files = 'ios/Sources/**/*.{swift,h,m,c,cc,mm,cpp}'
14
+ # Capacitor 6 apps target iOS 13; 7 → 14, 8 → 15 (higher app targets are fine).
15
+ s.ios.deployment_target = '13.0'
16
+ s.dependency 'Capacitor'
17
+ s.swift_version = '5.1'
18
+ end
package/Package.swift ADDED
@@ -0,0 +1,24 @@
1
+ // swift-tools-version: 5.9
2
+ import PackageDescription
3
+
4
+ let package = Package(
5
+ name: "OrdernowCapacitorLanguage",
6
+ platforms: [.iOS(.v13)],
7
+ products: [
8
+ .library(
9
+ name: "OrdernowCapacitorLanguage",
10
+ targets: ["AppLanguagePlugin"])
11
+ ],
12
+ dependencies: [
13
+ .package(url: "https://github.com/ionic-team/capacitor-swift-pm.git", "6.0.0"..<"9.0.0")
14
+ ],
15
+ targets: [
16
+ .target(
17
+ name: "AppLanguagePlugin",
18
+ dependencies: [
19
+ .product(name: "Capacitor", package: "capacitor-swift-pm"),
20
+ .product(name: "Cordova", package: "capacitor-swift-pm")
21
+ ],
22
+ path: "ios/Sources/AppLanguagePlugin")
23
+ ]
24
+ )
package/README.md CHANGED
@@ -1,3 +1,85 @@
1
- # Temporary Holding Version
1
+ # @ordernow/capacitor-language
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ Set the iOS per-app language (Settings → App → Language) from Capacitor apps
4
+
5
+ ## Why this plugin
6
+
7
+ - **One language for web and system UI.** When the user picks a language inside your app, iOS system UI (alerts, share sheets, `PKAddPassButton`, the Wallet add sheet…) follows it too.
8
+ - **Same setting as iOS Settings.** It writes the app's `AppleLanguages`, the value shown in Settings → App → Language, so both places stay in sync.
9
+ - **No native code in your app.** No custom plugin file or `CAPBridgeViewController` subclass to register it: install and call.
10
+ - **No extra dependencies.** Only `@capacitor/core` as a peer dependency.
11
+
12
+ ## Compatibility
13
+
14
+ | Capacitor | iOS |
15
+ | --- | --- |
16
+ | 6.x | 13+ |
17
+ | 7.x | 14+ |
18
+ | 8.x | 15+ |
19
+
20
+ One source for all three (`peerDependencies: @capacitor/core >=6 <9`). Android is not implemented (calls reject as "not implemented"); the web implementation is a no-op.
21
+
22
+ ## Install
23
+
24
+ ```bash
25
+ npm install @ordernow/capacitor-language
26
+ npx cap sync
27
+ ```
28
+
29
+ ### iOS
30
+
31
+ - List every language you support in `CFBundleLocalizations` (Info.plist). iOS only shows Settings → App → Language, and only applies a language, when it is listed there.
32
+ - iOS reads the language at launch: the change shows in system UI from the next launch.
33
+
34
+ ## Usage
35
+
36
+ ```ts
37
+ import { AppLanguage } from '@ordernow/capacitor-language';
38
+
39
+ await AppLanguage.set({ code: 'vi' }); // or 'zh-Hans', 'en'…
40
+ await AppLanguage.set({}); // follow the device language again
41
+ ```
42
+
43
+ ## API
44
+
45
+ <docgen-index>
46
+
47
+ * [`set(...)`](#set)
48
+ * [Interfaces](#interfaces)
49
+
50
+ </docgen-index>
51
+
52
+ <docgen-api>
53
+ <!--Update the source file JSDoc comments and rerun docgen to update the docs below-->
54
+
55
+ ### set(...)
56
+
57
+ ```typescript
58
+ set(options: SetLanguageOptions) => Promise<void>
59
+ ```
60
+
61
+ iOS only (a no-op on the web). Sets the app's iOS language, the one shown in
62
+ Settings → App → Language. iOS reads it at launch, so system UI follows it
63
+ from the next launch.
64
+
65
+ | Param | Type |
66
+ | ------------- | ----------------------------------------------------------------- |
67
+ | **`options`** | <code><a href="#setlanguageoptions">SetLanguageOptions</a></code> |
68
+
69
+ --------------------
70
+
71
+
72
+ ### Interfaces
73
+
74
+
75
+ #### SetLanguageOptions
76
+
77
+ | Prop | Type | Description |
78
+ | ---------- | ------------------- | ------------------------------------------------------------------------------------------------------- |
79
+ | **`code`** | <code>string</code> | iOS language identifier listed in `CFBundleLocalizations` ("vi", "zh-Hans"). Omit to follow the device. |
80
+
81
+ </docgen-api>
82
+
83
+ ## Support
84
+
85
+ Made by **MinhVDV**. If this plugin saves you time, you can support its development via [PayPal](https://paypal.me/MinhVDV).
package/dist/docs.json ADDED
@@ -0,0 +1,50 @@
1
+ {
2
+ "api": {
3
+ "name": "AppLanguagePlugin",
4
+ "slug": "applanguageplugin",
5
+ "docs": "",
6
+ "tags": [],
7
+ "methods": [
8
+ {
9
+ "name": "set",
10
+ "signature": "(options: SetLanguageOptions) => Promise<void>",
11
+ "parameters": [
12
+ {
13
+ "name": "options",
14
+ "docs": "",
15
+ "type": "SetLanguageOptions"
16
+ }
17
+ ],
18
+ "returns": "Promise<void>",
19
+ "tags": [],
20
+ "docs": "iOS only (a no-op on the web). Sets the app's iOS language, the one shown in\nSettings → App → Language. iOS reads it at launch, so system UI follows it\nfrom the next launch.",
21
+ "complexTypes": [
22
+ "SetLanguageOptions"
23
+ ],
24
+ "slug": "set"
25
+ }
26
+ ],
27
+ "properties": []
28
+ },
29
+ "interfaces": [
30
+ {
31
+ "name": "SetLanguageOptions",
32
+ "slug": "setlanguageoptions",
33
+ "docs": "",
34
+ "tags": [],
35
+ "methods": [],
36
+ "properties": [
37
+ {
38
+ "name": "code",
39
+ "tags": [],
40
+ "docs": "iOS language identifier listed in `CFBundleLocalizations` (\"vi\", \"zh-Hans\"). Omit to follow the device.",
41
+ "complexTypes": [],
42
+ "type": "string | undefined"
43
+ }
44
+ ]
45
+ }
46
+ ],
47
+ "enums": [],
48
+ "typeAliases": [],
49
+ "pluginConfigs": []
50
+ }
@@ -0,0 +1,12 @@
1
+ export interface SetLanguageOptions {
2
+ /** iOS language identifier listed in `CFBundleLocalizations` ("vi", "zh-Hans"). Omit to follow the device. */
3
+ code?: string;
4
+ }
5
+ export interface AppLanguagePlugin {
6
+ /**
7
+ * iOS only (a no-op on the web). Sets the app's iOS language, the one shown in
8
+ * Settings → App → Language. iOS reads it at launch, so system UI follows it
9
+ * from the next launch.
10
+ */
11
+ set(options: SetLanguageOptions): Promise<void>;
12
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,3 @@
1
+ import type { AppLanguagePlugin } from './definitions.js';
2
+ export * from './definitions.js';
3
+ export declare const AppLanguage: AppLanguagePlugin;
@@ -0,0 +1,5 @@
1
+ import { registerPlugin } from '@capacitor/core';
2
+ export * from './definitions.js';
3
+ export const AppLanguage = registerPlugin('AppLanguage', {
4
+ web: () => import('./web.js').then((m) => new m.AppLanguageWeb()),
5
+ });
@@ -0,0 +1,5 @@
1
+ import { WebPlugin } from '@capacitor/core';
2
+ /** The web has no app-level language: nothing to set. */
3
+ export declare class AppLanguageWeb extends WebPlugin {
4
+ set(): Promise<void>;
5
+ }
@@ -0,0 +1,7 @@
1
+ import { WebPlugin } from '@capacitor/core';
2
+ /** The web has no app-level language: nothing to set. */
3
+ export class AppLanguageWeb extends WebPlugin {
4
+ async set() {
5
+ return;
6
+ }
7
+ }
@@ -0,0 +1,21 @@
1
+ 'use strict';
2
+
3
+ var core = require('@capacitor/core');
4
+
5
+ const AppLanguage = core.registerPlugin('AppLanguage', {
6
+ web: () => Promise.resolve().then(function () { return web; }).then((m) => new m.AppLanguageWeb()),
7
+ });
8
+
9
+ /** The web has no app-level language: nothing to set. */
10
+ class AppLanguageWeb extends core.WebPlugin {
11
+ async set() {
12
+ return;
13
+ }
14
+ }
15
+
16
+ var web = /*#__PURE__*/Object.freeze({
17
+ __proto__: null,
18
+ AppLanguageWeb: AppLanguageWeb
19
+ });
20
+
21
+ exports.AppLanguage = AppLanguage;
@@ -0,0 +1,25 @@
1
+ import Capacitor
2
+ import Foundation
3
+
4
+ /// Writes the in-app language choice to the app's iOS language (Settings → App →
5
+ /// Language). AppleLanguages is read at launch, so system UI such as
6
+ /// PKAddPassButton follows it from the next launch.
7
+ /// CAPBridgedPlugin registration works on Capacitor 6, 7 and 8.
8
+ @objc(AppLanguagePlugin)
9
+ public class AppLanguagePlugin: CAPPlugin, CAPBridgedPlugin {
10
+ public let identifier = "AppLanguagePlugin"
11
+ public let jsName = "AppLanguage"
12
+ public let pluginMethods: [CAPPluginMethod] = [
13
+ CAPPluginMethod(name: "set", returnType: CAPPluginReturnPromise)
14
+ ]
15
+
16
+ /// `code` is an iOS language identifier ("vi", "zh-Hans"); none = follow the device.
17
+ @objc func set(_ call: CAPPluginCall) {
18
+ if let code = call.getString("code") {
19
+ UserDefaults.standard.set([code], forKey: "AppleLanguages")
20
+ } else {
21
+ UserDefaults.standard.removeObject(forKey: "AppleLanguages")
22
+ }
23
+ call.resolve()
24
+ }
25
+ }
package/package.json CHANGED
@@ -1,6 +1,81 @@
1
1
  {
2
2
  "name": "@ordernow/capacitor-language",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "1.0.1",
4
+ "description": "Set the iOS per-app language (Settings → App → Language) from Capacitor apps",
5
+ "main": "dist/plugin.cjs.js",
6
+ "module": "dist/esm/index.js",
7
+ "types": "dist/esm/index.d.ts",
8
+ "files": [
9
+ "dist/",
10
+ "ios/Sources",
11
+ "Package.swift",
12
+ "OrdernowCapacitorLanguage.podspec",
13
+ "LICENSE"
14
+ ],
15
+ "author": "MinhVDV",
16
+ "license": "MIT",
17
+ "repository": {
18
+ "type": "git",
19
+ "url": "git+https://github.com/mark-ordernow/capacitor-language-setting.git"
20
+ },
21
+ "bugs": {
22
+ "url": "https://github.com/mark-ordernow/capacitor-language-setting/issues"
23
+ },
24
+ "funding": {
25
+ "type": "paypal",
26
+ "url": "https://paypal.me/MinhVDV"
27
+ },
28
+ "keywords": [
29
+ "capacitor",
30
+ "plugin",
31
+ "native",
32
+ "language",
33
+ "locale",
34
+ "i18n"
35
+ ],
36
+ "scripts": {
37
+ "verify": "npm run verify:ios && npm run verify:web",
38
+ "verify:ios": "xcodebuild -scheme OrdernowCapacitorLanguage -destination generic/platform=iOS",
39
+ "verify:web": "npm run build",
40
+ "lint": "npm run eslint && npm run prettier -- --check && npm run swiftlint -- lint",
41
+ "fmt": "npm run eslint -- --fix && npm run prettier -- --write && npm run swiftlint -- --fix --format",
42
+ "eslint": "eslint . --ext ts",
43
+ "prettier": "prettier \"**/*.{css,html,ts,js}\"",
44
+ "swiftlint": "node-swiftlint",
45
+ "docgen": "docgen --api AppLanguagePlugin --output-readme README.md --output-json dist/docs.json",
46
+ "build": "npm run clean && npm run docgen && tsc && rollup -c rollup.config.mjs",
47
+ "clean": "rimraf ./dist",
48
+ "watch": "tsc --watch",
49
+ "prepare": "npm run build",
50
+ "test": "vitest run test"
51
+ },
52
+ "devDependencies": {
53
+ "@capacitor/core": "^7.4.4",
54
+ "@capacitor/docgen": "^0.3.1",
55
+ "@capacitor/ios": "^7.4.4",
56
+ "@ionic/eslint-config": "^0.4.0",
57
+ "@ionic/prettier-config": "^4.0.0",
58
+ "@ionic/swiftlint-config": "^2.0.0",
59
+ "eslint": "^8.57.1",
60
+ "prettier": "^3.6.2",
61
+ "rimraf": "^6.1.0",
62
+ "rollup": "^4.53.2",
63
+ "swiftlint": "^2.0.0",
64
+ "typescript": "^5.9.3",
65
+ "vitest": "^5.0.5"
66
+ },
67
+ "peerDependencies": {
68
+ "@capacitor/core": ">=6.0.0 <9.0.0"
69
+ },
70
+ "prettier": "@ionic/prettier-config",
71
+ "swiftlint": "@ionic/swiftlint-config",
72
+ "eslintConfig": {
73
+ "extends": "@ionic/eslint-config/recommended"
74
+ },
75
+ "capacitor": {
76
+ "ios": {
77
+ "src": "ios"
78
+ }
79
+ },
80
+ "homepage": "https://github.com/mark-ordernow/capacitor-language-setting#readme"
81
+ }