waibu-bootstrap 2.5.0 → 2.6.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.
@@ -2,8 +2,8 @@ import { sizes } from '../method/after-build-tag/_lib.js'
2
2
 
3
3
  const trueValues = ['true', 'on', 'yes', '1', 1, true]
4
4
 
5
- function getInputAttr (group, formControl = true, ro) {
6
- const { omit, get, set, isPlainObject, isArray, isString, has, forOwn, find } = this.app.lib._
5
+ async function getInputAttr (group, formControl = true, ro) {
6
+ const { omit, get, set, isPlainObject, isArray, isString, has, forOwn, find, camelCase, isEmpty } = this.app.lib._
7
7
  const { escape } = this.app.waibu
8
8
  const { req } = this.component
9
9
  if (formControl) group._.class.push('form-control')
@@ -34,8 +34,11 @@ function getInputAttr (group, formControl = true, ro) {
34
34
  else if (has(attr, 'name') === 'lat') attr.value = escape(req.format(val, attr.dataType, { latitude: true }))
35
35
  else if (has(attr, 'name') === 'lng') attr.value = escape(req.format(val, attr.dataType, { longitude: true }))
36
36
  else if (prop.values) {
37
- const item = find(prop.values, { value: val })
38
- attr.value = escape(req.format(item ? req.t(item.text) : val, attr.dataType))
37
+ let items = prop.values
38
+ if (typeof prop.values === 'string') items = await this.app.bajo.callHandler(prop.values)
39
+ const item = find(items, { value: val }) ?? {}
40
+ const ttext = camelCase(`${prop.name} ${item.text}`)
41
+ attr.value = escape(req.format(!isEmpty(item) ? (req.te(ttext) ? req.t(ttext) : item.text) : val, attr.dataType))
39
42
  } else attr.value = escape(req.format(val, attr.dataType))
40
43
  } else attr.value = attr.dataValue
41
44
  if (isArray(val)) attr.value = val.join(' ')
@@ -59,13 +62,13 @@ export async function buildFormLabel (group, tag, cls) {
59
62
  }
60
63
 
61
64
  export async function buildFormInput (group, params) {
62
- const attr = getInputAttr.call(this, group)
65
+ const attr = await getInputAttr.call(this, group)
63
66
  return await this.component.buildTag({ tag: 'input', attr, selfClosing: true })
64
67
  }
65
68
 
66
69
  export async function buildFormCheck (group, params) {
67
70
  const { has, get } = this.app.lib._
68
- const attr = getInputAttr.call(this, group, false)
71
+ const attr = await getInputAttr.call(this, group, false)
69
72
  attr.type = 'checkbox'
70
73
  attr.class.push('form-check-input')
71
74
  if (has(attr, 'name') && !has(attr, 'value')) attr.value = 'true'
@@ -75,7 +78,7 @@ export async function buildFormCheck (group, params) {
75
78
 
76
79
  export async function buildFormSwitch (group, params) {
77
80
  const { has } = this.app.lib._
78
- const attr = getInputAttr.call(this, group, false)
81
+ const attr = await getInputAttr.call(this, group, false)
79
82
  attr.type = 'checkbox'
80
83
  attr.class.push('form-check-input')
81
84
  attr.role = 'switch'
@@ -85,14 +88,14 @@ export async function buildFormSwitch (group, params) {
85
88
  }
86
89
 
87
90
  export async function buildFormRadio (group, params) {
88
- const attr = getInputAttr.call(this, group, false)
91
+ const attr = await getInputAttr.call(this, group, false)
89
92
  attr.type = 'radio'
90
93
  attr.class.push('form-check-input')
91
94
  return await this.component.buildTag({ tag: 'input', attr, selfClosing: true })
92
95
  }
93
96
 
94
97
  export async function buildFormCheckToggle (group, params) {
95
- const attr = getInputAttr.call(this, group, false)
98
+ const attr = await getInputAttr.call(this, group, false)
96
99
  attr.type = 'checkbox'
97
100
  attr.autocomplete = 'off'
98
101
  attr.class.push('btn-check')
@@ -100,7 +103,7 @@ export async function buildFormCheckToggle (group, params) {
100
103
  }
101
104
 
102
105
  export async function buildFormRadioToggle (group, params) {
103
- const attr = getInputAttr.call(this, group, false)
106
+ const attr = await getInputAttr.call(this, group, false)
104
107
  attr.type = 'radio'
105
108
  attr.autocomplete = 'off'
106
109
  attr.class.push('btn-check')
@@ -108,7 +111,7 @@ export async function buildFormRadioToggle (group, params) {
108
111
  }
109
112
 
110
113
  export async function buildFormPlaintext (group, params) {
111
- const attr = getInputAttr.call(this, group, false, true)
114
+ const attr = await getInputAttr.call(this, group, false, true)
112
115
  delete attr.dataValue
113
116
  attr.class.push('form-control-plaintext')
114
117
  attr.readonly = ''
@@ -125,7 +128,7 @@ export async function buildFormPlaintext (group, params) {
125
128
  }
126
129
 
127
130
  export async function buildFormColor (group, params) {
128
- const attr = getInputAttr.call(this, group)
131
+ const attr = await getInputAttr.call(this, group)
129
132
  attr.class.push('form-control-color')
130
133
  attr.type = 'color'
131
134
  if (!attr.dim) attr.dim = 'width:100'
@@ -133,13 +136,13 @@ export async function buildFormColor (group, params) {
133
136
  }
134
137
 
135
138
  export async function buildFormFile (group, params) {
136
- const attr = getInputAttr.call(this, group)
139
+ const attr = await getInputAttr.call(this, group)
137
140
  attr.type = 'file'
138
141
  return await this.component.buildTag({ tag: 'input', attr, selfClosing: true })
139
142
  }
140
143
 
141
144
  export async function buildFormTextarea (group, params) {
142
- const attr = getInputAttr.call(this, group)
145
+ const attr = await getInputAttr.call(this, group)
143
146
  params.html = attr.value
144
147
  attr.style.minHeight = '100px'
145
148
  delete attr.value
@@ -149,12 +152,12 @@ export async function buildFormTextarea (group, params) {
149
152
  export async function buildFormSelect (group, params) {
150
153
  const { omit, trim } = this.app.lib._
151
154
  const { $ } = this.component
152
- let attr = getInputAttr.call(this, group, false)
155
+ let attr = await getInputAttr.call(this, group, false)
153
156
  attr.value = attr.value + ''
154
157
  attr.class.push('form-select')
155
158
  let html = params.html
156
159
  if (sizes.includes(attr.size)) attr.class.push(`form-select-${attr.size}`)
157
- if (attr.options) html = this.component.buildOptions({ attr })
160
+ if (attr.options) html = await this.component.buildOptions({ attr })
158
161
  else {
159
162
  const items = []
160
163
  $(`<div>${trim(html ?? '')}</div>`).find('option').each(function () {
@@ -167,7 +170,7 @@ export async function buildFormSelect (group, params) {
167
170
  }
168
171
 
169
172
  export async function buildFormRange (group, params) {
170
- const attr = getInputAttr.call(this, group, false)
173
+ const attr = await getInputAttr.call(this, group, false)
171
174
  attr.type = 'range'
172
175
  attr.class.push('form-range')
173
176
  return await this.component.buildTag({ tag: 'input', attr, selfClosing: true })
@@ -9,8 +9,7 @@ async function appLauncher () {
9
9
  }
10
10
 
11
11
  build = async () => {
12
- const { locals } = this.component
13
- const { routePath, attrToArray } = this.app.waibu
12
+ const { attrToArray } = this.app.waibu
14
13
  const { groupAttrs } = this.app.waibuMpa
15
14
  const menu = this.params.attr.menu ?? 'pages'
16
15
  const group = groupAttrs(this.params.attr, ['trigger'])
@@ -21,10 +20,11 @@ async function appLauncher () {
21
20
  if (menu === 'pages') toolbar.unshift('home')
22
21
  launcher += `<c:div padding="x-3 ${menu === 'home' ? 'bottom-3' : ''}">`
23
22
  launcher += '<c:navbar padding="y-0"><c:nav tag="ul">\n'
24
- if (locals._meta.isAdmin) launcher += '<c:nav-item text="color:danger" href="' + routePath('waibuAdmin:/') + '" icon="lock" padding="start-0" />\n'
25
- launcher += '</c:nav>\n<c:nav tag="ul">\n'
26
23
  for (const t of toolbar) {
27
24
  if (t === 'home') launcher += '<c:nav-item href="/" icon="house" padding="end-2" />\n'
25
+ }
26
+ launcher += '</c:nav>\n<c:nav tag="ul">\n'
27
+ for (const t of toolbar) {
28
28
  if (t === 'user' && this.app.sumba) launcher += '<c:sumba-nav-dropdown-user padding="end-2" />\n'
29
29
  if (t === '-') launcher += '<c:nav-divider />\n'
30
30
  if (t === 'fullscreen') launcher += '<c:nav-toggle-fullscreen padding="end-2" />\n'
@@ -12,7 +12,8 @@ async function drawer () {
12
12
  build = async () => {
13
13
  const { isString, omit, trim } = this.app.lib._
14
14
  const { groupAttrs } = this.app.waibuMpa
15
- const { $ } = this.component
15
+ const { $, req, locals } = this.component
16
+ const { routePath } = this.app.waibu
16
17
  const group = groupAttrs(this.params.attr, ['trigger'])
17
18
  this.params.attr.responsive = this.params.attr.responsive ?? true
18
19
  this.params.attr.class.push(parseVariant.call(this, { cls, value: this.params.attr.responsive, values: breakpoints }))
@@ -22,6 +23,7 @@ async function drawer () {
22
23
  if (this.params.attr.scroll) this.params.attr.dataBsScroll = 'true'
23
24
  if (this.params.attr.noDismiss) this.params.attr.dataBsBackdrop = 'static'
24
25
  const buttons = []
26
+ if (locals._meta.isAdmin) buttons.push(await this.component.buildTag({ tag: 'btn', attr: { href: routePath('waibuAdmin:/'), icon: 'lock', text: 'color:danger', tooltip: req.t('adminArea') } }))
25
27
  const html = []
26
28
  $(`<div>${this.params.html}</div>`).children().each(function () {
27
29
  if (this.name === 'drawer-toolbar') buttons.push(trim($(this).prop('innerHTML')))
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "waibu-bootstrap",
3
- "version": "2.5.0",
3
+ "version": "2.6.0",
4
4
  "description": "Bootstrap suport for Waibu Framework",
5
5
  "main": "index.js",
6
6
  "scripts": {
package/wiki/CHANGES.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # Changes
2
2
 
3
+ ## 2026-02-20
4
+
5
+ - [2.6.0] Change ```getInputAttr()``` to async function
6
+ - [2.6.0] Update to support a function handler as ```prop.values```
7
+ - [2.6.0] Add button to admin area in ```Drawer``` if user is an admin
8
+
3
9
  ## 2026-02-18
4
10
 
5
11
  - [2.4.0] Update attribute functions from ```waibu```