@vespercms/admin 0.1.0-next.0 → 0.1.0-next.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/README.md +1 -1
- package/dist/{BodyEditor-CAGNfofv.js → BodyEditor-_mkh0BSQ.js} +735 -735
- package/dist/{markdown-KUkv11EB.js → markdown-4fVeej3c.js} +14 -14
- package/dist/schedule/times.d.ts +1 -3
- package/dist/screens/EntryList.d.ts +0 -2
- package/dist/screens/status.d.ts +36 -0
- package/dist/{shortcuts-B_JMAvF9.js → shortcuts-CarKeDqp.js} +534 -498
- package/dist/studio.css +1 -1
- package/dist/studio.js +1873 -1736
- package/dist/widgets/blank-date.d.ts +8 -0
- package/package.json +2 -2
- package/src/github/GitHubGate.tsx +47 -10
- package/src/schedule/ScheduleDialog.tsx +3 -0
- package/src/schedule/times.ts +0 -11
- package/src/screens/EntryEditor.tsx +23 -9
- package/src/screens/EntryList.tsx +24 -26
- package/src/screens/ListPane.tsx +48 -30
- package/src/screens/PageTree.tsx +45 -25
- package/src/screens/status.tsx +104 -0
- package/src/studio.css +5 -0
- package/src/widgets/basic.tsx +5 -1
- package/src/widgets/blank-date.ts +32 -0
- package/src/widgets/special.tsx +5 -1
package/src/widgets/basic.tsx
CHANGED
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
import { MultiCombobox, RadioGroup, Select, Switch, cx } from '@vespercms/ui';
|
|
9
9
|
import { useState } from 'react';
|
|
10
10
|
import type { WidgetProps } from '../types.ts';
|
|
11
|
+
import { useBlankWhenEmpty } from './blank-date.ts';
|
|
11
12
|
|
|
12
13
|
/*
|
|
13
14
|
* The simple built-in widgets (spec §6.3.2). Each follows the custom widget
|
|
@@ -148,11 +149,14 @@ export function DateWidget({
|
|
|
148
149
|
invalid,
|
|
149
150
|
disabled,
|
|
150
151
|
}: WidgetProps<Date | string>) {
|
|
152
|
+
const text = dateText(value);
|
|
153
|
+
const blank = useBlankWhenEmpty(text);
|
|
151
154
|
return (
|
|
152
155
|
<input
|
|
153
156
|
id={id}
|
|
154
157
|
type="date"
|
|
155
|
-
value={
|
|
158
|
+
value={text}
|
|
159
|
+
{...blank}
|
|
156
160
|
onChange={(event) => {
|
|
157
161
|
const text = event.target.value;
|
|
158
162
|
if (text === '')
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { useState, type FocusEvent, type KeyboardEvent } from 'react';
|
|
2
|
+
|
|
3
|
+
/*
|
|
4
|
+
* Safari draws today's date and time, greyed, in an empty date field, and
|
|
5
|
+
* editors took it for a time already chosen: "Comes down" looked set when it
|
|
6
|
+
* wasn't (WebKit bug 233215). An empty field is drawn blank until it's
|
|
7
|
+
* clicked or typed in, and blank again when it's left with nothing in it (studio.css
|
|
8
|
+
* hides `::-webkit-datetime-edit` under `data-blank`). Chrome's
|
|
9
|
+
* "mm/dd/yyyy" goes with it; the label says what goes there, and Firefox,
|
|
10
|
+
* which draws neither, is unchanged.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
/** Keys that pass through or leave a field without starting to fill it in. */
|
|
14
|
+
const PASSING = new Set(['Tab', 'Shift', 'Escape', 'Enter', 'Meta', 'Control', 'Alt']);
|
|
15
|
+
|
|
16
|
+
/** Props for a `date` or `datetime-local` input whose value is `value`. */
|
|
17
|
+
export function useBlankWhenEmpty(value: string) {
|
|
18
|
+
const [engaged, setEngaged] = useState(false);
|
|
19
|
+
return {
|
|
20
|
+
'data-blank': value === '' && !engaged ? '' : undefined,
|
|
21
|
+
onPointerDown: () => {
|
|
22
|
+
setEngaged(true);
|
|
23
|
+
},
|
|
24
|
+
onKeyDown: (event: KeyboardEvent) => {
|
|
25
|
+
if (!PASSING.has(event.key)) setEngaged(true);
|
|
26
|
+
},
|
|
27
|
+
// A date typed partway has no value yet, but its parts must stay in sight.
|
|
28
|
+
onBlur: (event: FocusEvent<HTMLInputElement>) => {
|
|
29
|
+
if (!event.currentTarget.validity.badInput) setEngaged(false);
|
|
30
|
+
},
|
|
31
|
+
};
|
|
32
|
+
}
|
package/src/widgets/special.tsx
CHANGED
|
@@ -14,6 +14,7 @@ import { useEditor } from '../editor/context.tsx';
|
|
|
14
14
|
import { ChoosePageButton } from '../editor/PagePicker.tsx';
|
|
15
15
|
import type { WidgetProps } from '../types.ts';
|
|
16
16
|
import { inputClass } from './basic.tsx';
|
|
17
|
+
import { useBlankWhenEmpty } from './blank-date.ts';
|
|
17
18
|
|
|
18
19
|
/*
|
|
19
20
|
* The built-in widgets with behaviour of their own (spec §6.3.2). Every one
|
|
@@ -253,12 +254,15 @@ export function DateTimeWidget({
|
|
|
253
254
|
value instanceof Date ? value : typeof value === 'string' && value ? new Date(value) : null;
|
|
254
255
|
const valid = instant !== null && !Number.isNaN(instant.getTime());
|
|
255
256
|
const name = zoneName(zone, valid ? instant : new Date());
|
|
257
|
+
const wall = valid ? wallTime(instant, zone) : '';
|
|
258
|
+
const blank = useBlankWhenEmpty(wall);
|
|
256
259
|
return (
|
|
257
260
|
<>
|
|
258
261
|
<input
|
|
259
262
|
id={id}
|
|
260
263
|
type="datetime-local"
|
|
261
|
-
value={
|
|
264
|
+
value={wall}
|
|
265
|
+
{...blank}
|
|
262
266
|
onChange={(event) => {
|
|
263
267
|
if (event.target.value === '') {
|
|
264
268
|
onChange(undefined);
|