stalefish 8.1.12 → 8.1.14

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.
@@ -20,7 +20,7 @@ const styles = css`
20
20
  border-radius: 0;
21
21
  font-size: 18px;
22
22
  font-weight: normal;
23
- color: #999;
23
+ color: #666;
24
24
  margin: 5px 5px 5px 5px;
25
25
  border: solid 5px #c9c9c9;
26
26
  user-select: none;
@@ -24,7 +24,7 @@ const styles = css`
24
24
  position: relative;
25
25
  height: 55px;
26
26
  background-color: #FFF;
27
- color: #999;
27
+ color: #666;
28
28
  }
29
29
 
30
30
  .noType {
@@ -36,7 +36,7 @@ const styles = css`
36
36
  left: 5px;
37
37
  font-size: 16px;
38
38
  font-weight: normal;
39
- color: #999;
39
+ color: #666;
40
40
  margin-left: 5px;
41
41
  padding: 9px;
42
42
  background-color: rgba(255,255,255,0.8);
@@ -70,18 +70,19 @@ export default ({ wrapperStyle = null, holdingPen, label, property, options, req
70
70
  return option === holdingPen[property]
71
71
  }
72
72
  })
73
- // text color is always #999 per latest design; placeholder state no longer affects color
74
73
 
75
74
  const wrapperClassName = wrapperStyle
76
75
  ? (typeof wrapperStyle === 'string' ? wrapperStyle : (wrapperStyle.toString ? wrapperStyle.toString() : ''))
77
76
  : ''
78
77
 
78
+ const isPlaceholder = !currentOption || (typeof currentOption === 'object' && currentOption.value === '') || currentOption === ''
79
+
79
80
  return html`
80
81
  <label style="text-align: left; position: relative; display: inline-block; width: 100%;" class="${wrapperClassName}">
81
82
  <div class="${styles.down}">${solidDown({ colour: '#ccc' })}</div>
82
83
  <span class="${styles.label}">${label}${required ? ' *' : ''}</span>
83
- <select ?disabled=${disabled} style="${disabled ? 'cursor: not-allowed; opacity: 0.3;' : ''}background-color: ${typeof currentOption === 'object' && currentOption.colour ? `#${currentOption.colour}` : 'white'}; color: #999;" class="${styles.selectBox} ${fieldIsTouched(holdingPen, property) === true ? styles.touched : ''}" oninput=${e => { formField(holdingPen, property)(e); oninput && oninput(e) }} onchange=${e => { formField(holdingPen, property)(e); onchange && onchange(e) }} onblur=${formField(holdingPen, property)}>
84
- <option value="${required ? 'Select an option' : ''}" ?selected=${!holdingPen[property]} ?disabled=${required} : ''}>${required ? 'Select an option' : ''}</option>
84
+ <select ?disabled=${disabled} style="${disabled ? 'cursor: not-allowed; opacity: 0.3;' : ''}background-color: ${typeof currentOption === 'object' && currentOption.colour ? `#${currentOption.colour}` : 'white'}; color: ${isPlaceholder ? '#999' : '#666'};" class="${styles.selectBox} ${fieldIsTouched(holdingPen, property) === true ? styles.touched : ''}" oninput=${e => { formField(holdingPen, property)(e); oninput && oninput(e) }} onchange=${e => { formField(holdingPen, property)(e); onchange && onchange(e) }} onblur=${formField(holdingPen, property)}>
85
+ <option value="${required ? 'Select an option' : ''}" ?selected=${!holdingPen[property]} ?disabled=${required}>${required ? 'Select an option' : ''}</option>
85
86
  ${options.map(option => {
86
87
  let optionValue
87
88
  let optionName
@@ -91,7 +92,7 @@ export default ({ wrapperStyle = null, holdingPen, label, property, options, req
91
92
  } else {
92
93
  optionValue = option
93
94
  }
94
- return html`<option value="${optionValue}" ?selected=${holdingPen[property] == optionValue}>${optionName || optionValue}</option>` // eslint-disable-line
95
+ return html`<option style="color: ${optionValue === '' ? '#999' : '#666'};" value="${optionValue}" ?selected=${holdingPen[property] == optionValue}>${optionName || optionValue}</option>` // eslint-disable-line
95
96
  })}
96
97
  </select>
97
98
  </label>
@@ -2,7 +2,7 @@ import { html, css, formField, fieldIsTouched } from 'halfcab'
2
2
 
3
3
  let styles = css`
4
4
  .textarea {
5
- color: #999;
5
+ color: #666;
6
6
  padding: 10px;
7
7
  border: solid 5px #c9c9c9;
8
8
  transition: border 0.3s;
@@ -20,11 +20,11 @@ const styles = css`
20
20
  appearance: none;
21
21
  z-index: 20;
22
22
  position: relative;
23
- color: #999;
23
+ color: #666;
24
24
  }
25
25
 
26
26
  /* Provide room for custom right-side controls when present */
27
- .withRightControls { padding-right: 44px; }
27
+ .withRightControls { padding-right: 32px; }
28
28
  /* Legacy fixed padding when valueContext present (no longer used; kept for backward compat) */
29
29
  .withRightControlsAndValueContext { padding-right: 114px; }
30
30
 
@@ -95,7 +95,7 @@ const styles = css`
95
95
  /* Custom up/down controls (aligned with datePicker/timePicker) */
96
96
  .controls {
97
97
  position: absolute;
98
- right: 10px;
98
+ right: 6px;
99
99
  top: 50%;
100
100
  transform: translateY(-50%);
101
101
  display: flex;
@@ -217,7 +217,7 @@ export default ({ highlightBorder = false, wrapperStyle = null, holdingPen, labe
217
217
  }
218
218
  const setValue = (newVal) => {
219
219
  // Provide a faux event compatible with formField and our guarded change()
220
- const faux = { currentTarget: { value: String(newVal), validity: { valid: true } } }
220
+ const faux = { currentTarget: { value: String(newVal), type: normalizedType, validity: { valid: true } } }
221
221
  change({ e: faux, holdingPen, property, label: styles.label })
222
222
  onchange && onchange(faux)
223
223
  rerender()
@@ -266,23 +266,23 @@ export default ({ highlightBorder = false, wrapperStyle = null, holdingPen, labe
266
266
  }
267
267
 
268
268
  const input = html`<input data-gramm="false"
269
- ?disabled=${disabled}
270
- ${maxNumber ? { max: maxNumber } : ''}
271
- ${minNumber ? { min: minNumber } : ''}
272
- ${maxCharacters ? { maxlength: maxCharacters } : ''}
273
- style="${disabled ? 'cursor: not-allowed; opacity: 0.3;' : ''}"
274
- id="${wrapperId}-input"
275
- class="${styles.textfield} ${isNumber ? styles.withRightControls : ''} ${fieldIsTouched(holdingPen, property) === true ? styles.touched : ''} ${highlightBorder ? styles.highlight : ''}"
276
- value="${holdingPen[property] !== undefined && holdingPen[property] !== null ? holdingPen[property] : ''}"
277
- onkeyup=${e => { onkeyup && onkeyup(e); if (isNumber && e && e.key === 'ArrowUp') { e.preventDefault && e.preventDefault(); inc() } else if (isNumber && e && e.key === 'ArrowDown') { e.preventDefault && e.preventDefault(); dec() } }}
278
- ?required=${required}
279
- onchange=${e => { change({ e, holdingPen, property, label: styles.label }); onchange && onchange(e) }}
280
- oninput=${e => { change({ e, holdingPen, property, label: styles.label }); oninput && oninput(e) }}
281
- onblur=${formField(holdingPen, property)}
282
- placeholder="${placeholder || ''}${required ? ' *' : ''}"
283
- type="${normalizedType}"
284
- ${pattern ? { pattern } : ''}
285
- ${isNumber ? { step: determineStep(normalizedType) } : ''}
269
+ ?disabled=${disabled}
270
+ ${maxNumber ? { max: maxNumber } : ''}
271
+ ${minNumber ? { min: minNumber } : ''}
272
+ ${maxCharacters ? { maxlength: maxCharacters } : ''}
273
+ style="${disabled ? 'cursor: not-allowed; opacity: 0.3;' : ''}"
274
+ id="${wrapperId}-input"
275
+ class="${styles.textfield} ${isNumber ? styles.withRightControls : ''} ${fieldIsTouched(holdingPen, property) === true ? styles.touched : ''} ${highlightBorder ? styles.highlight : ''}"
276
+ value="${holdingPen[property] !== undefined && holdingPen[property] !== null ? holdingPen[property] : ''}"
277
+ onkeyup=${e => { onkeyup && onkeyup(e); if (isNumber && e && e.key === 'ArrowUp') { e.preventDefault && e.preventDefault(); inc() } else if (isNumber && e && e.key === 'ArrowDown') { e.preventDefault && e.preventDefault(); dec() } }}
278
+ ?required=${required}
279
+ onchange=${e => { change({ e, holdingPen, property, label: styles.label }); onchange && onchange(e) }}
280
+ oninput=${e => { change({ e, holdingPen, property, label: styles.label }); oninput && oninput(e) }}
281
+ onblur=${formField(holdingPen, property)}
282
+ placeholder="${placeholder || ''}${required ? ' *' : ''}"
283
+ type="${normalizedType}"
284
+ ${pattern ? { pattern } : ''}
285
+ ${isNumber ? { step: determineStep(normalizedType) } : ''}
286
286
  />`
287
287
 
288
288
  if (autofocus) {
@@ -331,14 +331,14 @@ export default ({ highlightBorder = false, wrapperStyle = null, holdingPen, labe
331
331
  ${label ? html`<span class="${styles.label} ${normalizedType === 'color' ? styles.labelColorAdjustForColorType : ''}" style="opacity: ${holdingPen[property] === 0 || holdingPen[property] || (permanentTopPlaceholder || permanentTopLabel) ? 1 : 0}; font-size: 16px; font-weight: normal; color: #999; margin-left: 5px; padding: 9px; background-color: rgba(255,255,255,${darkBackground ? 1 : 0.8}); ">${label}${required ? ' *' : ''}</span>` : ''}
332
332
  ${input}
333
333
  ${
334
- (isNumber && !disabled)
335
- ? html`
336
- <span id="${wrapperId}-ctrls" class="${styles.controls} ${hasValueContext ? styles.controlsWithValueContext : ''}" aria-hidden="false">
334
+ (isNumber && !disabled)
335
+ ? html`
336
+ <span id="${wrapperId}-ctrls" class="${styles.controls} ${hasValueContext ? styles.controlsWithValueContext : ''}" aria-hidden="false">
337
337
  <button type="button" tabindex="-1" aria-label="Increase value" class="${styles.btn}" style="transform: rotate(180deg);" onmousedown=${(e) => e.preventDefault()} onclick=${inc}>${solidDown({ colour: '#CCC', width: '14px', height: '14px' })}</button>
338
338
  <button type="button" tabindex="-1" aria-label="Decrease value" class="${styles.btn}" onmousedown=${(e) => e.preventDefault()} onclick=${dec}>${solidDown({ colour: '#CCC', width: '14px', height: '14px' })}</button>
339
339
  </span>
340
- `
341
- : ''
340
+ `
341
+ : ''
342
342
  }
343
343
  </label>
344
344
  </div>
@@ -23,7 +23,7 @@ const styles = css`
23
23
  position: relative;
24
24
  height: 55px;
25
25
  background-color: #FFF;
26
- color: #999;
26
+ color: #666;
27
27
  }
28
28
 
29
29
  /* Placeholder text color */
@@ -690,7 +690,7 @@ export default function timePicker ({
690
690
  type="text" ${pattern ? { pattern } : ''}
691
691
  .value=${displayValue} data-input />
692
692
 
693
- <div class="${styles.controls}">
693
+ <div class="${styles.controls}" style="${disableClear ? 'right: 34px;' : ''}">
694
694
  <button type="button" tabindex="-1" class="${styles.btn}" style="transform: rotate(180deg);" onmousedown=${(e) => e.preventDefault()} onclick=${stepMinute(minuteStep)} aria-label="Increase time by ${minuteStep} minutes">
695
695
  <span class="${styles.arrowIcon}">${solidDown({ colour: '#ccc', width: '12', height: '12' })}</span>
696
696
  </button>
@@ -605,7 +605,7 @@ export default function uploader (args) {
605
605
  <div class="${wrapperClassName}" style="display: inline-block; width: 100%; margin-top: 36px;">
606
606
  <label style="width: 100%; text-align: left; position: relative; padding: 0; cursor: pointer;">
607
607
  ${label ? html`<span class="${styles.label}" style="opacity: ${holdingPen[property] === 0 || holdingPen[property] || (permanentTopPlaceholder || permanentTopLabel) ? 1 : 0};">${label}${required ? ' *' : ''}</span>` : ''}
608
- <span class="${styles.frame}" data-accept="${acceptAttr || ''}" data-disabled="${!!disabled}" ondragenter=${onDragEnter} ondragover=${onDragOver} ondragleave=${onDragLeave} ondrop=${onDrop} onmousedown=${(e) => {
608
+ <span class="${styles.frame}" style="color: ${holdingPen[property] ? '#666' : '#999'};" data-accept="${acceptAttr || ''}" data-disabled="${!!disabled}" ondragenter=${onDragEnter} ondragover=${onDragOver} ondragleave=${onDragLeave} ondrop=${onDrop} onmousedown=${(e) => {
609
609
  if (disabled) return
610
610
  try {
611
611
  const frame = e.currentTarget
package/example/app.mjs CHANGED
@@ -146,11 +146,12 @@ const Showcase = () => html`
146
146
  </div>
147
147
 
148
148
  <div class="${styles.card}">
149
- <div class="${styles.title}">Date picker (pre-populated)</div>
149
+ <div class="${styles.title}">Date picker (pre-populated and clearDisabled=true)</div>
150
150
  ${sf.datePicker({
151
151
  holdingPen: state.demo,
152
152
  property: 'datePre',
153
- label: 'Date (starts with today)'
153
+ label: 'Date (starts with today)',
154
+ disableClear: true
154
155
  })}
155
156
  <div class="${styles.subtle}">Initial value set to 2025-12-28 for testing.</div>
156
157
  </div>
@@ -195,6 +196,17 @@ const Showcase = () => html`
195
196
  <div class="${styles.subtle}">Use the arrows to verify the first step respects the pre-loaded value.</div>
196
197
  </div>
197
198
 
199
+ <div class="${styles.card}">
200
+ <div class="${styles.title}">Time picker (disableClear)</div>
201
+ ${sf.timePicker({
202
+ holdingPen: state.demo,
203
+ property: 'timeDisableClear',
204
+ label: 'Time (Clear Disabled)',
205
+ minuteStep: 15,
206
+ disableClear: true
207
+ })}
208
+ </div>
209
+
198
210
  <div class="${styles.card}">
199
211
  <div class="${styles.title}">Uploader</div>
200
212
  ${sf.uploader({
@@ -15,6 +15,7 @@
15
15
  "shifty-router/create-location.js": "https://esm.sh/shifty-router@0.1.1/create-location.js",
16
16
 
17
17
  "lit": "https://esm.sh/lit@3.3.2",
18
+ "lit/directives/unsafe-html.js": "https://esm.sh/lit@3.3.2/directives/unsafe-html.js",
18
19
  "@lit-labs/ssr-client": "https://esm.sh/@lit-labs/ssr-client@1.1.8",
19
20
  "@lit-labs/ssr": "/stalefish/example/ssr-browser-stub.js",
20
21
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "stalefish",
3
- "version": "8.1.12",
3
+ "version": "8.1.14",
4
4
  "description": "Simple function based component library for halfcab tagged template literals",
5
5
  "main": "index.mjs",
6
6
  "module": "index.mjs",
@@ -31,7 +31,7 @@
31
31
  },
32
32
  "homepage": "https://github.com/lorengreenfield/stalefish#readme",
33
33
  "devDependencies": {
34
- "halfcab": "^15.0.3",
34
+ "halfcab": "^15.0.4",
35
35
  "standard": "^12.0.1"
36
36
  },
37
37
  "dependencies": {