haori-bootstrap 0.2.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/LICENSE +21 -0
- package/README.ja.md +180 -0
- package/README.md +180 -0
- package/dist/bootstrap_haori.d.ts +73 -0
- package/dist/bootstrap_resolver.d.ts +45 -0
- package/dist/browser.d.ts +1 -0
- package/dist/dialog.d.ts +17 -0
- package/dist/haori-bootstrap.iife.js +3 -0
- package/dist/haori-bootstrap.iife.js.map +1 -0
- package/dist/haori-bootstrap.js +505 -0
- package/dist/haori-bootstrap.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/install.d.ts +27 -0
- package/dist/message.d.ts +15 -0
- package/dist/modal.d.ts +17 -0
- package/dist/toast.d.ts +10 -0
- package/dist/types.d.ts +147 -0
- package/package.json +74 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Kazuyuki Nishijima
|
|
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.
|
package/README.ja.md
ADDED
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
# Haori.js Bootstrap
|
|
2
|
+
|
|
3
|
+
Haori.js Bootstrap は、Haori.js 向けの Bootstrap ベース UI 拡張ライブラリです。
|
|
4
|
+
|
|
5
|
+
Version: 0.2.0
|
|
6
|
+
|
|
7
|
+
## 概要
|
|
8
|
+
|
|
9
|
+
- 正式名称: Haori.js Bootstrap
|
|
10
|
+
- パッケージ識別子: haori-bootstrap
|
|
11
|
+
- 参照元 Haori.js リポジトリ: https://github.com/meibinlab/haori-js
|
|
12
|
+
- GitHub リポジトリ: https://github.com/meibinlab/haori-js-bootstrap
|
|
13
|
+
- 対応 Bootstrap バージョン: 5.3.x
|
|
14
|
+
- 配布形式: ESM と IIFE
|
|
15
|
+
|
|
16
|
+
npm パッケージ名は `haori-js-bootstrap` から `haori-bootstrap` へ変更しました。既存利用者は新しい package 名へ移行してください。GitHub リポジトリ名は変更していません。
|
|
17
|
+
|
|
18
|
+
Haori.js の dialog、confirm、toast、openDialog、closeDialog、addErrorMessage、clearMessages などの UI 系静的メソッドを Bootstrap ベース実装へ差し替えつつ、既存の Procedure 連携を維持します。
|
|
19
|
+
|
|
20
|
+
## インストール
|
|
21
|
+
|
|
22
|
+
npm からインストールします。
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
npm install haori-bootstrap
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
利用時は、アプリケーション側で Haori.js と Bootstrap CSS/JS を別途読み込んでください。
|
|
29
|
+
|
|
30
|
+
## CDN 利用
|
|
31
|
+
|
|
32
|
+
ブラウザ直読み込み時は、次の順で依存を読み込みます。
|
|
33
|
+
|
|
34
|
+
1. Haori.js
|
|
35
|
+
2. Bootstrap CSS
|
|
36
|
+
3. bootstrap.bundle.js
|
|
37
|
+
4. haori-bootstrap
|
|
38
|
+
|
|
39
|
+
```html
|
|
40
|
+
<link
|
|
41
|
+
rel="stylesheet"
|
|
42
|
+
href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/css/bootstrap.min.css"
|
|
43
|
+
/>
|
|
44
|
+
<script src="https://cdn.jsdelivr.net/npm/haori@0.1.2/dist/haori.iife.js"></script>
|
|
45
|
+
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/js/bootstrap.bundle.min.js"></script>
|
|
46
|
+
<script src="https://cdn.jsdelivr.net/npm/haori-bootstrap@0.2.0/dist/haori-bootstrap.iife.js"></script>
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
IIFE 版は、window.Haori と window.bootstrap が利用可能な場合に自動で有効化されます。
|
|
50
|
+
|
|
51
|
+
## ESM 利用
|
|
52
|
+
|
|
53
|
+
ESM 版も、window.Haori と window.bootstrap が利用可能な場合は import 時点で自動有効化されます。
|
|
54
|
+
|
|
55
|
+
```js
|
|
56
|
+
import 'haori-bootstrap';
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
既定設定を上書きしたい場合は install を明示的に呼び出します。
|
|
60
|
+
|
|
61
|
+
```js
|
|
62
|
+
import { install } from 'haori-bootstrap';
|
|
63
|
+
|
|
64
|
+
install({
|
|
65
|
+
fallbackToNative: true,
|
|
66
|
+
});
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## 公開 API
|
|
70
|
+
|
|
71
|
+
| API | 目的 | 戻り値 |
|
|
72
|
+
| ---- | ---- | ---- |
|
|
73
|
+
| dialog(message) | 情報表示ダイアログ | Promise<void> |
|
|
74
|
+
| confirm(message) | 確認ダイアログ | Promise<boolean> |
|
|
75
|
+
| toast(message, level) | トースト通知 | Promise<void> |
|
|
76
|
+
| openDialog(element) | 任意要素の表示 | Promise<void> |
|
|
77
|
+
| closeDialog(element) | 任意要素の非表示 | Promise<void> |
|
|
78
|
+
| addErrorMessage(target, message) | 管理対象エラーメッセージの追加 | Promise<void> |
|
|
79
|
+
| clearMessages(parentOrTarget) | 管理対象メッセージのみ削除 | Promise<void> |
|
|
80
|
+
| install(options) | Bootstrap 対応 Haori を再適用し設定を上書き | void |
|
|
81
|
+
| uninstall() | 元の Haori 実装を復元 | void |
|
|
82
|
+
|
|
83
|
+
## Procedure 連携例
|
|
84
|
+
|
|
85
|
+
既存の Procedure は、data-click-* と data-click-*-message をそのまま利用できます。
|
|
86
|
+
|
|
87
|
+
```html
|
|
88
|
+
<button
|
|
89
|
+
type="button"
|
|
90
|
+
data-click-confirm="deleteUser"
|
|
91
|
+
data-click-confirm-message="ユーザーを削除しますか。\nこの操作は元に戻せません。"
|
|
92
|
+
>
|
|
93
|
+
削除
|
|
94
|
+
</button>
|
|
95
|
+
|
|
96
|
+
<button
|
|
97
|
+
type="button"
|
|
98
|
+
data-click-toast="notifySaved"
|
|
99
|
+
data-click-toast-message="保存しました。\n一覧を再読み込みしてください。"
|
|
100
|
+
>
|
|
101
|
+
保存通知
|
|
102
|
+
</button>
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
- message は HTML として解釈せず、プレーンテキストとして描画します。
|
|
106
|
+
- message 中の `\n` は改行へ正規化され、dialog、confirm、toast で複数行表示されます。
|
|
107
|
+
- data-click-* の解釈とイベント実行は Haori.js / Procedure 側が担当します。
|
|
108
|
+
|
|
109
|
+
## Build & Publish
|
|
110
|
+
|
|
111
|
+
ローカル確認手順:
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
npm install
|
|
115
|
+
npm run compile
|
|
116
|
+
npm run test
|
|
117
|
+
npm run build
|
|
118
|
+
npm pack --dry-run
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
通常リリース手順:
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
npm version patch
|
|
125
|
+
git push origin main --follow-tags
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
push 後に、そのタグから GitHub Release を published にします。公開 workflow が npm publish と `dist.zip` 添付を自動で実行します。
|
|
129
|
+
|
|
130
|
+
次回 patch リリースの例:
|
|
131
|
+
|
|
132
|
+
```bash
|
|
133
|
+
# version が 0.2.1 になる
|
|
134
|
+
npm version patch
|
|
135
|
+
git push origin main --follow-tags
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
その後、push 済みタグの GitHub Release を作成して published にします。例として次回は `0.2.1` タグになります。
|
|
139
|
+
|
|
140
|
+
自動公開:
|
|
141
|
+
|
|
142
|
+
- `npm version patch` で、src/index.ts の公開用 `version` 定数も package.json と同期されます。
|
|
143
|
+
- publish-on-release.yml がパッケージを build し、npm publish を実行します。
|
|
144
|
+
- release-archive.yml が dist/ を build し、dist.zip を同じ GitHub Release へ添付します。
|
|
145
|
+
|
|
146
|
+
初回公開のみ:
|
|
147
|
+
|
|
148
|
+
- current version が未公開の場合は、`npm version patch` を実行せず、対象 version のタグをそのまま作成して push します。
|
|
149
|
+
- npm アカウント上で `Read and write` 権限の granular access token を作成し、リポジトリシークレット `NPM_TOKEN` として登録します。
|
|
150
|
+
- npm アカウントで 2FA を有効化している場合は、write 操作用の bypass 2FA を有効にした token を使います。
|
|
151
|
+
- `NPM_TOKEN` の作成に、パッケージの事前公開は不要です。
|
|
152
|
+
|
|
153
|
+
名称変更後の初回 `0.2.0` 公開の例:
|
|
154
|
+
|
|
155
|
+
```bash
|
|
156
|
+
git push origin main
|
|
157
|
+
git tag 0.2.0
|
|
158
|
+
git push origin 0.2.0
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
初回公開チェックリスト:
|
|
162
|
+
|
|
163
|
+
1. npm 上で `haori-bootstrap` の名前が空いていることを確認する。
|
|
164
|
+
2. `NPM_TOKEN` を作成して GitHub repository secrets に登録する。
|
|
165
|
+
3. ローカル確認と `npm pack --dry-run` を実行する。
|
|
166
|
+
4. リリースタグを push する。
|
|
167
|
+
5. そのタグから GitHub Release を published にする。
|
|
168
|
+
|
|
169
|
+
## 文書
|
|
170
|
+
|
|
171
|
+
- English README: [README.md](README.md)
|
|
172
|
+
- 初期設計書: [doc/Haori.js Bootstrap初期設計書.md](doc/Haori.js Bootstrap初期設計書.md)
|
|
173
|
+
- 変更履歴: [CHANGELOG.md](CHANGELOG.md)
|
|
174
|
+
|
|
175
|
+
## 補足
|
|
176
|
+
|
|
177
|
+
- Bootstrap CSS と JS は利用者側で用意する前提です。
|
|
178
|
+
- Haori.js は前提依存として扱い、本ライブラリへ同梱しません。
|
|
179
|
+
- CDN でブラウザ直読み込みする場合の配布物は dist/haori-bootstrap.iife.js です。
|
|
180
|
+
- npm 公開時のエントリは dist/haori-bootstrap.js、型定義は dist/index.d.ts です。
|
package/README.md
ADDED
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
# Haori.js Bootstrap
|
|
2
|
+
|
|
3
|
+
Haori.js Bootstrap is a Bootstrap-based UI extension library for Haori.js.
|
|
4
|
+
|
|
5
|
+
Version: 0.2.0
|
|
6
|
+
|
|
7
|
+
## Overview
|
|
8
|
+
|
|
9
|
+
- Official name: Haori.js Bootstrap
|
|
10
|
+
- Package identifier: haori-bootstrap
|
|
11
|
+
- Upstream Haori.js repository: https://github.com/meibinlab/haori-js
|
|
12
|
+
- GitHub repository: https://github.com/meibinlab/haori-js-bootstrap
|
|
13
|
+
- Supported Bootstrap version: 5.3.x
|
|
14
|
+
- Distributed formats: ESM and IIFE
|
|
15
|
+
|
|
16
|
+
The npm package has been renamed from `haori-js-bootstrap` to `haori-bootstrap`. Existing installations should migrate to the new package name. The GitHub repository name remains unchanged.
|
|
17
|
+
|
|
18
|
+
The library replaces Haori.js static UI methods such as dialog, confirm, toast, openDialog, closeDialog, addErrorMessage, and clearMessages with Bootstrap-based behavior while keeping existing Procedure integration intact.
|
|
19
|
+
|
|
20
|
+
## Installation
|
|
21
|
+
|
|
22
|
+
Install from npm:
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
npm install haori-bootstrap
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
This package expects Haori.js and Bootstrap CSS/JS to be available in the application.
|
|
29
|
+
|
|
30
|
+
## CDN Usage
|
|
31
|
+
|
|
32
|
+
Load dependencies in this order for browser direct loading:
|
|
33
|
+
|
|
34
|
+
1. Haori.js
|
|
35
|
+
2. Bootstrap CSS
|
|
36
|
+
3. bootstrap.bundle.js
|
|
37
|
+
4. haori-bootstrap
|
|
38
|
+
|
|
39
|
+
```html
|
|
40
|
+
<link
|
|
41
|
+
rel="stylesheet"
|
|
42
|
+
href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/css/bootstrap.min.css"
|
|
43
|
+
/>
|
|
44
|
+
<script src="https://cdn.jsdelivr.net/npm/haori@0.1.2/dist/haori.iife.js"></script>
|
|
45
|
+
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/js/bootstrap.bundle.min.js"></script>
|
|
46
|
+
<script src="https://cdn.jsdelivr.net/npm/haori-bootstrap@0.2.0/dist/haori-bootstrap.iife.js"></script>
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
The IIFE build auto-enables when both window.Haori and window.bootstrap are available.
|
|
50
|
+
|
|
51
|
+
## ESM Usage
|
|
52
|
+
|
|
53
|
+
The ESM build also auto-enables on import when window.Haori and window.bootstrap are available.
|
|
54
|
+
|
|
55
|
+
```js
|
|
56
|
+
import 'haori-bootstrap';
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
When you need to override default options, call install explicitly.
|
|
60
|
+
|
|
61
|
+
```js
|
|
62
|
+
import { install } from 'haori-bootstrap';
|
|
63
|
+
|
|
64
|
+
install({
|
|
65
|
+
fallbackToNative: true,
|
|
66
|
+
});
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## Public API
|
|
70
|
+
|
|
71
|
+
| API | Purpose | Return value |
|
|
72
|
+
| ---- | ---- | ---- |
|
|
73
|
+
| dialog(message) | Informational dialog | Promise<void> |
|
|
74
|
+
| confirm(message) | Confirmation dialog | Promise<boolean> |
|
|
75
|
+
| toast(message, level) | Toast notification | Promise<void> |
|
|
76
|
+
| openDialog(element) | Open an arbitrary dialog element | Promise<void> |
|
|
77
|
+
| closeDialog(element) | Close an arbitrary dialog element | Promise<void> |
|
|
78
|
+
| addErrorMessage(target, message) | Append managed error messages | Promise<void> |
|
|
79
|
+
| clearMessages(parentOrTarget) | Remove only managed messages | Promise<void> |
|
|
80
|
+
| install(options) | Re-apply Bootstrap-backed Haori with overridden options | void |
|
|
81
|
+
| uninstall() | Restore the original Haori implementation | void |
|
|
82
|
+
|
|
83
|
+
## Procedure Integration Example
|
|
84
|
+
|
|
85
|
+
Existing Procedure flows can keep using data-click-* and data-click-*-message attributes.
|
|
86
|
+
|
|
87
|
+
```html
|
|
88
|
+
<button
|
|
89
|
+
type="button"
|
|
90
|
+
data-click-confirm="deleteUser"
|
|
91
|
+
data-click-confirm-message="Delete this user?\nThis action cannot be undone."
|
|
92
|
+
>
|
|
93
|
+
Delete
|
|
94
|
+
</button>
|
|
95
|
+
|
|
96
|
+
<button
|
|
97
|
+
type="button"
|
|
98
|
+
data-click-toast="notifySaved"
|
|
99
|
+
data-click-toast-message="Saved successfully.\nPlease refresh the list."
|
|
100
|
+
>
|
|
101
|
+
Show saved toast
|
|
102
|
+
</button>
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
- Messages are rendered as plain text, not HTML.
|
|
106
|
+
- Literal `\n` sequences are normalized to line breaks for dialog, confirm, and toast.
|
|
107
|
+
- Haori.js and Procedure remain responsible for interpreting data-click-* attributes and dispatching static method calls.
|
|
108
|
+
|
|
109
|
+
## Build & Publish
|
|
110
|
+
|
|
111
|
+
Local verification:
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
npm install
|
|
115
|
+
npm run compile
|
|
116
|
+
npm run test
|
|
117
|
+
npm run build
|
|
118
|
+
npm pack --dry-run
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
Regular release flow:
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
npm version patch
|
|
125
|
+
git push origin main --follow-tags
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
After pushing, publish a GitHub Release from the generated version tag. The release workflow then publishes the package and uploads `dist.zip` automatically.
|
|
129
|
+
|
|
130
|
+
Example next patch release after `0.2.0`:
|
|
131
|
+
|
|
132
|
+
```bash
|
|
133
|
+
# version becomes 0.2.1
|
|
134
|
+
npm version patch
|
|
135
|
+
git push origin main --follow-tags
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
Create and publish the GitHub Release for the pushed tag such as `0.2.1`.
|
|
139
|
+
|
|
140
|
+
Release automation:
|
|
141
|
+
|
|
142
|
+
- `npm version patch` also keeps the exported `version` constant in src/index.ts in sync.
|
|
143
|
+
- publish-on-release.yml builds the package and runs npm publish.
|
|
144
|
+
- release-archive.yml builds dist/ and uploads dist.zip to the same GitHub Release.
|
|
145
|
+
|
|
146
|
+
First release only:
|
|
147
|
+
|
|
148
|
+
- If the current version is not published yet, skip `npm version patch` and create/push the tag for that version directly.
|
|
149
|
+
- Create a granular npm access token with `Read and write` permission and register it as the repository secret `NPM_TOKEN`.
|
|
150
|
+
- If npm account 2FA is enabled, create the token with bypass 2FA for write actions.
|
|
151
|
+
- The package does not need to be published already to create `NPM_TOKEN`.
|
|
152
|
+
|
|
153
|
+
Example for the first `0.2.0` release after the package rename:
|
|
154
|
+
|
|
155
|
+
```bash
|
|
156
|
+
git push origin main
|
|
157
|
+
git tag 0.2.0
|
|
158
|
+
git push origin 0.2.0
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
First release checklist:
|
|
162
|
+
|
|
163
|
+
1. Confirm the npm package name `haori-bootstrap` is still available.
|
|
164
|
+
2. Create and register `NPM_TOKEN` in GitHub repository secrets.
|
|
165
|
+
3. Run local verification and `npm pack --dry-run`.
|
|
166
|
+
4. Push the release tag.
|
|
167
|
+
5. Publish a GitHub Release from that tag.
|
|
168
|
+
|
|
169
|
+
## Documents
|
|
170
|
+
|
|
171
|
+
- Japanese README: [README.ja.md](README.ja.md)
|
|
172
|
+
- Initial design: [doc/Haori.js Bootstrap初期設計書.md](doc/Haori.js Bootstrap初期設計書.md)
|
|
173
|
+
- Changelog: [CHANGELOG.md](CHANGELOG.md)
|
|
174
|
+
|
|
175
|
+
## Notes
|
|
176
|
+
|
|
177
|
+
- Bootstrap CSS and JS are provided by the application side.
|
|
178
|
+
- Haori.js is treated as a prerequisite and is not bundled into this package.
|
|
179
|
+
- Browser direct loading for CDN consumers uses dist/haori-bootstrap.iife.js.
|
|
180
|
+
- The published npm entry is dist/haori-bootstrap.js with types at dist/index.d.ts.
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { HaoriGlobalObject, ResolvedInstallOptions } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* BootstrapHaori が利用する内部コンテキスト。
|
|
4
|
+
*/
|
|
5
|
+
export interface BootstrapHaoriContext {
|
|
6
|
+
/** 差し替え前の Haori 実装。 */
|
|
7
|
+
originalHaori?: HaoriGlobalObject;
|
|
8
|
+
/** 解決済みの導入設定。 */
|
|
9
|
+
options: ResolvedInstallOptions;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* BootstrapHaori が参照する内部状態を更新する。
|
|
13
|
+
*
|
|
14
|
+
* @param nextContext 差し替え先が参照する内部コンテキスト。
|
|
15
|
+
* @return 戻り値はない。
|
|
16
|
+
*/
|
|
17
|
+
export declare function setBootstrapHaoriContext(nextContext: BootstrapHaoriContext): void;
|
|
18
|
+
/**
|
|
19
|
+
* Haori の UI 系静的メソッドを差し替える最小ファサード。
|
|
20
|
+
*/
|
|
21
|
+
export declare class BootstrapHaori {
|
|
22
|
+
/**
|
|
23
|
+
* 情報表示ダイアログを表示する。
|
|
24
|
+
*
|
|
25
|
+
* @param message 表示するメッセージ。
|
|
26
|
+
* @return 完了時に解決される Promise。
|
|
27
|
+
*/
|
|
28
|
+
static dialog(message: string): Promise<void>;
|
|
29
|
+
/**
|
|
30
|
+
* 確認ダイアログを表示する。
|
|
31
|
+
*
|
|
32
|
+
* @param message 表示するメッセージ。
|
|
33
|
+
* @return OK のみ true を返す Promise。
|
|
34
|
+
*/
|
|
35
|
+
static confirm(message: string): Promise<boolean>;
|
|
36
|
+
/**
|
|
37
|
+
* トースト通知を表示する。
|
|
38
|
+
*
|
|
39
|
+
* @param message 表示するメッセージ。
|
|
40
|
+
* @param level 通知レベル。
|
|
41
|
+
* @return 完了時に解決される Promise。
|
|
42
|
+
*/
|
|
43
|
+
static toast(message: string, level?: string): Promise<void>;
|
|
44
|
+
/**
|
|
45
|
+
* 任意のダイアログ要素を開く。
|
|
46
|
+
*
|
|
47
|
+
* @param element 開く対象の要素。
|
|
48
|
+
* @return 完了時に解決される Promise。
|
|
49
|
+
*/
|
|
50
|
+
static openDialog(element: HTMLElement): Promise<void>;
|
|
51
|
+
/**
|
|
52
|
+
* 任意のダイアログ要素を閉じる。
|
|
53
|
+
*
|
|
54
|
+
* @param element 閉じる対象の要素。
|
|
55
|
+
* @return 完了時に解決される Promise。
|
|
56
|
+
*/
|
|
57
|
+
static closeDialog(element: HTMLElement): Promise<void>;
|
|
58
|
+
/**
|
|
59
|
+
* 管理対象のエラーメッセージを追加する。
|
|
60
|
+
*
|
|
61
|
+
* @param target 追加先の要素。
|
|
62
|
+
* @param message 表示するメッセージ。
|
|
63
|
+
* @return 完了時に解決される Promise。
|
|
64
|
+
*/
|
|
65
|
+
static addErrorMessage(target: HTMLElement, message: string): Promise<void>;
|
|
66
|
+
/**
|
|
67
|
+
* 管理対象のメッセージを削除する。
|
|
68
|
+
*
|
|
69
|
+
* @param parentOrTarget 削除対象の親要素または対象要素。
|
|
70
|
+
* @return 完了時に解決される Promise。
|
|
71
|
+
*/
|
|
72
|
+
static clearMessages(parentOrTarget: HTMLElement): Promise<void>;
|
|
73
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { BootstrapModalConstructor, BootstrapModalInstance, BootstrapModalOptions, BootstrapNamespace, BootstrapToastConstructor, BootstrapToastInstance } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* Bootstrap の Modal コンストラクターを返す。
|
|
4
|
+
*
|
|
5
|
+
* @param bootstrap Bootstrap 名前空間。
|
|
6
|
+
* @return Modal コンストラクター。見つからない場合は undefined。
|
|
7
|
+
*/
|
|
8
|
+
export declare function resolveModalConstructor(bootstrap?: BootstrapNamespace): BootstrapModalConstructor | undefined;
|
|
9
|
+
/**
|
|
10
|
+
* Bootstrap の Toast コンストラクターを返す。
|
|
11
|
+
*
|
|
12
|
+
* @param bootstrap Bootstrap 名前空間。
|
|
13
|
+
* @return Toast コンストラクター。見つからない場合は undefined。
|
|
14
|
+
*/
|
|
15
|
+
export declare function resolveToastConstructor(bootstrap?: BootstrapNamespace): BootstrapToastConstructor | undefined;
|
|
16
|
+
/**
|
|
17
|
+
* Modal が利用可能かどうかを返す。
|
|
18
|
+
*
|
|
19
|
+
* @param bootstrap Bootstrap 名前空間。
|
|
20
|
+
* @return 利用可能なら true。
|
|
21
|
+
*/
|
|
22
|
+
export declare function hasModalSupport(bootstrap?: BootstrapNamespace): boolean;
|
|
23
|
+
/**
|
|
24
|
+
* Toast が利用可能かどうかを返す。
|
|
25
|
+
*
|
|
26
|
+
* @param bootstrap Bootstrap 名前空間。
|
|
27
|
+
* @return 利用可能なら true。
|
|
28
|
+
*/
|
|
29
|
+
export declare function hasToastSupport(bootstrap?: BootstrapNamespace): boolean;
|
|
30
|
+
/**
|
|
31
|
+
* Modal インスタンスを取得または生成する。
|
|
32
|
+
*
|
|
33
|
+
* @param element 対象要素。
|
|
34
|
+
* @param bootstrap Bootstrap 名前空間。
|
|
35
|
+
* @return Modal インスタンス。生成できない場合は undefined。
|
|
36
|
+
*/
|
|
37
|
+
export declare function createModalInstance(element: HTMLElement, options?: BootstrapModalOptions, bootstrap?: BootstrapNamespace): BootstrapModalInstance | undefined;
|
|
38
|
+
/**
|
|
39
|
+
* Toast インスタンスを取得または生成する。
|
|
40
|
+
*
|
|
41
|
+
* @param element 対象要素。
|
|
42
|
+
* @param bootstrap Bootstrap 名前空間。
|
|
43
|
+
* @return Toast インスタンス。生成できない場合は undefined。
|
|
44
|
+
*/
|
|
45
|
+
export declare function createToastInstance(element: HTMLElement, bootstrap?: BootstrapNamespace): BootstrapToastInstance | undefined;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/dialog.d.ts
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { ResolvedInstallOptions } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* 情報表示用の Bootstrap Modal を表示する。
|
|
4
|
+
*
|
|
5
|
+
* @param message 表示するメッセージ。
|
|
6
|
+
* @param options 解決済み導入設定。
|
|
7
|
+
* @return 完了時に解決される Promise。
|
|
8
|
+
*/
|
|
9
|
+
export declare function showDialog(message: string, options: ResolvedInstallOptions): Promise<void>;
|
|
10
|
+
/**
|
|
11
|
+
* 確認用の Bootstrap Modal を表示する。
|
|
12
|
+
*
|
|
13
|
+
* @param message 表示するメッセージ。
|
|
14
|
+
* @param options 解決済み導入設定。
|
|
15
|
+
* @return OK のみ true を返す Promise。
|
|
16
|
+
*/
|
|
17
|
+
export declare function showConfirm(message: string, options: ResolvedInstallOptions): Promise<boolean>;
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
var HaoriBootstrap=(function(m){"use strict";function P(e){return typeof e=="function"}function _(e){return P(e?.Modal)?e?.Modal:void 0}function x(e){return P(e?.Toast)?e?.Toast:void 0}function E(e){return!!_(e)}function Y(e){return!!x(e)}function C(e,t,o){const n=_(o);if(n)return typeof n.getOrCreateInstance=="function"?n.getOrCreateInstance(e,t):new n(e,t)}function Z(e,t){const o=x(t);if(o)return typeof o.getOrCreateInstance=="function"?o.getOrCreateInstance(e):new o(e)}const ee="data-haori-bootstrap-dialog",v="data-haori-bootstrap-action";function D(){return{backdrop:"static"}}function R(e,t){if(t.dialogContainerSelector){const o=e.querySelector(t.dialogContainerSelector);if(o)return o}return e.body}function q(e,t,o){const n=e.createElement("div");n.className="modal fade",n.tabIndex=-1,n.setAttribute(ee,"true"),n.setAttribute("aria-hidden","true");const r=e.createElement("div");r.className="modal-dialog modal-dialog-centered";const i=e.createElement("div");i.className="modal-content";const u=e.createElement("div");u.className="modal-body";const a=e.createElement("p");a.className="mb-0",a.style.whiteSpace="pre-line",a.textContent=t,u.appendChild(a);const s=e.createElement("div");if(s.className="modal-footer",o){const f=e.createElement("button");f.type="button",f.className="btn btn-secondary",f.setAttribute(v,"cancel"),f.textContent="Cancel",s.appendChild(f)}const c=e.createElement("button");return c.type="button",c.className="btn btn-primary",c.setAttribute(v,"ok"),c.textContent="OK",s.appendChild(c),i.append(u,s),r.appendChild(i),n.appendChild(r),n}function te(e,t){const o=globalThis.document,n=q(o,e,!1);R(o,t).appendChild(n);const r=C(n,D(),t.bootstrap);return r?new Promise((i,u)=>{const a=()=>{n.removeEventListener("hidden.bs.modal",s),n.remove(),r.dispose?.(),i()},s=()=>{a()};n.querySelector(`[${v}="ok"]`)?.addEventListener("click",()=>{r.hide()},{once:!0}),n.addEventListener("hidden.bs.modal",s,{once:!0});try{r.show()}catch(f){n.removeEventListener("hidden.bs.modal",s),n.remove(),r.dispose?.(),u(f)}}):(n.remove(),Promise.reject(new Error("Bootstrap Modal is unavailable.")))}function oe(e,t){const o=globalThis.document,n=q(o,e,!0);R(o,t).appendChild(n);const r=C(n,D(),t.bootstrap);return r?new Promise((i,u)=>{let a=!1;const s=()=>{n.removeEventListener("hidden.bs.modal",c),n.remove(),r.dispose?.(),i(a)},c=()=>{s()},f=n.querySelector(`[${v}="ok"]`),ke=n.querySelector(`[${v}="cancel"]`);f?.addEventListener("click",()=>{a=!0,r.hide()},{once:!0}),ke?.addEventListener("click",()=>{a=!1,r.hide()},{once:!0}),n.addEventListener("hidden.bs.modal",c,{once:!0});try{r.show()}catch(Be){n.removeEventListener("hidden.bs.modal",c),n.remove(),r.dispose?.(),u(Be)}}):(n.remove(),Promise.reject(new Error("Bootstrap Modal is unavailable.")))}const T="data-haori-bootstrap-owned",p="data-haori-bootstrap-message-container",h="data-haori-bootstrap-invalid-target";function M(e){return e instanceof HTMLInputElement&&(e.type==="checkbox"||e.type==="radio")}function g(e){return e instanceof HTMLInputElement&&e.type==="radio"}function I(e){return e instanceof HTMLInputElement||e instanceof HTMLSelectElement||e instanceof HTMLTextAreaElement}function N(e){return Array.from(e.children).find(t=>t instanceof HTMLElement&&t.getAttribute(p)==="true")}function ne(e,t){const o=e.createElement("div");return o.setAttribute(T,"true"),o.textContent=t,o}function re(e){return N(e)}function S(e){if(e.name){const t=e.form??e.ownerDocument,o=typeof CSS<"u"&&typeof CSS.escape=="function"?CSS.escape(e.name):e.name.replace(/(["\\])/g,"\\$1"),n=Array.from(t.querySelectorAll(`input[type="radio"][name="${o}"]`));if(n.length>0)return n}return[e]}function ie(e){const[t,...o]=e;if(!t)return;let n=t;for(;n;){if(o.every(r=>n?.contains(r)))return n;n=n.parentElement}}function $(e){const o=S(e).map(n=>n.closest(".form-check")).filter(n=>n instanceof HTMLElement);if(o.length>1){const n=ie(o);if(n&&!o.includes(n))return n}return k(e)}function k(e){const t=e.closest(".form-check");return t instanceof HTMLElement?t:void 0}function U(e){const t=e.nextElementSibling;if(t instanceof HTMLElement&&t.getAttribute(p)==="true")return t;const o=document.createElement("div");return o.className="invalid-feedback d-block",o.setAttribute(T,"true"),o.setAttribute(p,"true"),e.insertAdjacentElement("afterend",o),o}function ae(e){const t=g(e)?$(e):k(e);if(!t)return U(e);const o=N(t);if(o)return o;const n=document.createElement("div");return n.className="invalid-feedback d-block",n.setAttribute(T,"true"),n.setAttribute(p,"true"),t.appendChild(n),n}function se(e){const t=re(e);if(t)return t;const o=document.createElement("div");return o.className="alert alert-danger",o.setAttribute("role","alert"),o.setAttribute(T,"true"),o.setAttribute(p,"true"),e.insertAdjacentElement("afterbegin",o),o}function B(e){e.getAttribute(h)==="true"&&(e.classList.remove("is-invalid"),e.removeAttribute(h))}function ce(e){(g(e)?S(e):[e]).forEach(o=>{o.classList.add("is-invalid"),o.setAttribute(h,"true")})}function le(e){(g(e)?S(e):[e]).forEach(o=>{B(o)})}function ue(e,t){return(M(e)?ae(e):I(e)?U(e):se(e)).appendChild(ne(document,t)),M(e)?ce(e):I(e)&&(e.classList.add("is-invalid"),e.setAttribute(h,"true")),Promise.resolve()}function de(e){if(M(e)){const n=g(e)?$(e):k(e);(n?N(n):void 0)?.remove(),le(e)}else if(I(e)){const n=e.nextElementSibling;n instanceof HTMLElement&&n.getAttribute(p)==="true"&&n.remove(),B(e)}return e.querySelectorAll(`[${p}="true"]`).forEach(n=>{n.remove()}),e.querySelectorAll(`[${h}="true"]`).forEach(n=>{B(n)}),Promise.resolve()}function z(e){e.classList.contains("modal")||e.classList.add("modal"),e.tabIndex<0&&(e.tabIndex=-1),e.hasAttribute("aria-hidden")||e.setAttribute("aria-hidden","true")}function fe(e,t){z(e);const o=C(e,void 0,t.bootstrap);return o?(o.show(),Promise.resolve()):Promise.reject(new Error("Bootstrap Modal is unavailable."))}function me(e,t){z(e);const o=C(e,void 0,t.bootstrap);return o?(o.hide(),Promise.resolve()):Promise.reject(new Error("Bootstrap Modal is unavailable."))}const W="data-haori-bootstrap-toast-container",pe="data-haori-bootstrap-toast",be="data-haori-bootstrap-toast-accent";function ve(e){switch(e){case"warning":return{accentClassName:"bg-warning"};case"error":return{accentClassName:"bg-danger"};default:return{accentClassName:"bg-info"}}}function he(e,t){if(t.toastContainerSelector){const o=e.querySelector(t.toastContainerSelector);if(o)return o}return e.body}function Ee(e,t){const o=he(e,t),n=o.querySelector(`[${W}="true"]`);if(n)return n;const r=e.createElement("div");return r.className="toast-container position-fixed bottom-0 end-0 p-3",r.setAttribute(W,"true"),o.appendChild(r),r}function Ce(e,t,o){const n=globalThis.document,r=ve(t),i=n.createElement("div");i.className="toast border bg-body text-body shadow-sm",i.setAttribute("role","status"),i.setAttribute("aria-live","polite"),i.setAttribute("aria-atomic","true"),i.setAttribute(pe,"true");const u=n.createElement("div");u.className="d-flex align-items-stretch";const a=n.createElement("div");a.className=`flex-shrink-0 rounded-start ${r.accentClassName}`,a.style.width="0.375rem",a.setAttribute(be,"true");const s=n.createElement("div");s.className="toast-body",s.style.whiteSpace="pre-line",s.textContent=e,u.appendChild(a),u.appendChild(s),i.appendChild(u),Ee(n,o).appendChild(i);const c=Z(i,o.bootstrap);if(!c)return i.remove(),Promise.reject(new Error("Bootstrap Toast is unavailable."));i.addEventListener("hidden.bs.toast",()=>{i.remove(),c.dispose?.()},{once:!0});try{return c.show(),Promise.resolve()}catch(f){return i.remove(),c.dispose?.(),Promise.reject(f)}}let l={options:{fallbackToNative:!0}};function b(e){return e.replace(/\\n/g,`
|
|
2
|
+
`)}function O(){return globalThis.window}function H(e){return Promise.resolve(e).then(()=>{})}function A(e){const t=l.originalHaori?.[e];return typeof t=="function"?t:void 0}function w(e){console.warn(`[haori-bootstrap] ${e} skipped because Bootstrap support is unavailable.`)}function F(e){const t=b(e),o=A("dialog");if(o)return H(o(t));const n=O();return l.options.fallbackToNative&&typeof n?.alert=="function"?(n.alert(t),Promise.resolve()):(w("dialog"),Promise.resolve())}function G(e){const t=b(e),o=A("confirm");if(o)return Promise.resolve(o(t)).then(r=>!!r);const n=O();return l.options.fallbackToNative&&typeof n?.confirm=="function"?Promise.resolve(n.confirm(t)):(w("confirm"),Promise.resolve(!1))}function j(e,t){const o=b(e),n=A("toast");return n?H(n(o,t)):(w("toast"),Promise.resolve())}function y(e,t){const o=A(e);return o?H(o(t)):(w(e),Promise.resolve())}function Te(e){l=e}class K{static dialog(t){const o=b(t);return E(l.options.bootstrap)?te(o,l.options).catch(()=>F(o)):F(o)}static confirm(t){const o=b(t);return E(l.options.bootstrap)?oe(o,l.options).catch(()=>G(o)):G(o)}static toast(t,o){const n=b(t);return Y(l.options.bootstrap)?Ce(n,o,l.options).catch(()=>j(n,o)):j(n,o)}static openDialog(t){return E(l.options.bootstrap)?fe(t,l.options).catch(()=>y("openDialog",t)):y("openDialog",t)}static closeDialog(t){return E(l.options.bootstrap)?me(t,l.options).catch(()=>y("closeDialog",t)):y("closeDialog",t)}static addErrorMessage(t,o){return ue(t,o)}static clearMessages(t){return de(t)}}const V={fallbackToNative:!0},d={installed:!1,options:V};function L(){return globalThis.window}function ge(e,t){return{bootstrap:e.bootstrap??t?.bootstrap,fallbackToNative:e.fallbackToNative??V.fallbackToNative,toastContainerSelector:e.toastContainerSelector,dialogContainerSelector:e.dialogContainerSelector}}function J(e=L()){return!!(e?.Haori&&e.bootstrap)}function Q(e={}){const t=L();if(!t?.Haori)throw new Error("window.Haori is required before calling install().");d.originalHaori||(d.originalHaori=t.Haori),d.options=ge(e,t),Te({originalHaori:d.originalHaori,options:d.options}),t.Haori=K,d.installed=!0}function Ae(){const e=L();!e||!d.originalHaori||(e.Haori=d.originalHaori,d.installed=!1,d.originalHaori=void 0)}function we(){return d.installed}const X="__haoriJsBootstrapAutoEnabled__";function ye(){return globalThis.window}function Me(e){return!!e[X]}function Ie(e){e[X]=!0}function Ne(){const e=ye();if(!(!e||Me(e))){if(!J(e)){console.warn("[haori-bootstrap] Auto-enable skipped because window.Haori or window.bootstrap is missing.");return}try{Q({bootstrap:e.bootstrap}),Ie(e)}catch(t){console.warn("[haori-bootstrap] Auto-enable failed.",t)}}}Ne();const Se="0.2.0";return m.BootstrapHaori=K,m.hasAutoEnablePrerequisites=J,m.install=Q,m.isInstalled=we,m.uninstall=Ae,m.version=Se,Object.defineProperty(m,Symbol.toStringTag,{value:"Module"}),m})({});
|
|
3
|
+
//# sourceMappingURL=haori-bootstrap.iife.js.map
|