@wildwinter/app-shell 0.30.0 → 0.31.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/dist/index.cjs +91 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +30 -1
- package/dist/index.d.ts +30 -1
- package/dist/index.js +89 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -408,6 +408,35 @@ declare function bindPropertyName(input: HTMLInputElement, onCommit: (value: str
|
|
|
408
408
|
* sets of words, one gate.
|
|
409
409
|
*/
|
|
410
410
|
declare function firstIllegalPropertyName(host: ParentNode): HTMLInputElement | null;
|
|
411
|
+
interface PropertyRefOptions {
|
|
412
|
+
/** The names that exist, read fresh on every check so a declaration added in the
|
|
413
|
+
* same dialog clears the complaint. Compared case-insensitively, since the
|
|
414
|
+
* parser folds. */
|
|
415
|
+
known: () => string[];
|
|
416
|
+
/** The scope token this field addresses, for the wording ("no @world property..."). */
|
|
417
|
+
scope?: string;
|
|
418
|
+
/** Shown on the field when there is nothing to complain about. */
|
|
419
|
+
hint?: string;
|
|
420
|
+
}
|
|
421
|
+
/** Why this reference cannot be used, or undefined when it can. */
|
|
422
|
+
declare function propertyRefProblem(name: string, opts: PropertyRefOptions): string | undefined;
|
|
423
|
+
/**
|
|
424
|
+
* Wire a field that POINTS at a declared property: same manners as a declaration
|
|
425
|
+
* field (mark, do not rewrite, Tab coerces), plus the declared names offered as a
|
|
426
|
+
* datalist, because the rule is declare-then-reference and a picker makes that
|
|
427
|
+
* painless rather than pedantic.
|
|
428
|
+
*
|
|
429
|
+
* Marks `.illegal` for an undeclared name too, which gates Save wherever the host
|
|
430
|
+
* already asks `firstIllegalPropertyName`.
|
|
431
|
+
*/
|
|
432
|
+
declare function bindPropertyRef(input: HTMLInputElement, onCommit: (value: string) => void, opts: PropertyRefOptions): void;
|
|
433
|
+
/**
|
|
434
|
+
* Re-check every bound reference field inside `host`. Hosts call this when the
|
|
435
|
+
* DECLARATIONS change, since a reference's validity depends on a list it does not
|
|
436
|
+
* own: rename a property and the driver pointing at it is wrong from that moment,
|
|
437
|
+
* with nothing typed into it.
|
|
438
|
+
*/
|
|
439
|
+
declare function revalidatePropertyRefs(host: ParentNode): void;
|
|
411
440
|
|
|
412
441
|
interface GameIdEditorOptions {
|
|
413
442
|
anchor: HTMLElement;
|
|
@@ -789,4 +818,4 @@ interface StepperBarOptions {
|
|
|
789
818
|
/** Draw (or hide) the bar in `host`. Idempotent: call it again with new state. */
|
|
790
819
|
declare function renderStepperBar(host: HTMLElement, opts: StepperBarOptions): void;
|
|
791
820
|
|
|
792
|
-
export { type AboutOptions, type AnchoredPanel, type AnchoredPanelOptions, type Child, type Comment, type CommentMessage, type CommentsOptions, type ConfirmOptions, type DocLine, type DupGuard, type ElProps, type GameIdEditorOptions, type IconName, type IconSvgName, type Identity, type IdentityOptions, type JobProgressOptions, type JobProgressView, type Notes, type NotesEditorOptions, PALETTE, PALETTE_SIZE, PROPERTY_NAME_HINT, type PaneShell, type PaneShellOptions, type PaneShellState, type PaneSide, type PaneSideConfig, type PinButton, type PinButtonOptions, RESERVED_PROPERTY_NAMES, type SaveController, type SaveControllerOptions, type SaveIndicator, type SaveStatus, type SettingsDialog, type SettingsDialogOptions, type SettingsSection, type SettingsSectionHandle, type ShardVc, type StaleBarOptions, type StepperBarOptions, type StepperItem, type StepperTone, type TipRect, type TooltipOptions, type VcMap, askIdentity, bindPropertyName, closeAnchoredPanel, closeWithExit, colourFor, colourIndex, confirmDialog, createSaveController, dupGuard, el, expandableRow, firstIllegalPropertyName, focusNewRow, foldVc, gameIdify, hideTip, icon, iconBtn, iconSvg, initTooltips, isCaseOnlyPropertyName, isValidGameId, isValidPropertyName, labelled, lockControls, lockNotice, mountJobProgress, mountPaneShell, mountSettingsDialog, moveItem, openAnchoredPanel, openComments, openGameIdEditor, openNotesEditor, paintVcBadges, pinButton, placeAnchored, propertyNameProblem, propertyNameify, renderStepperBar, saveIndicator, showAbout, staleBar, tagChips, tipAt, tipBold, vcBadgeFor };
|
|
821
|
+
export { type AboutOptions, type AnchoredPanel, type AnchoredPanelOptions, type Child, type Comment, type CommentMessage, type CommentsOptions, type ConfirmOptions, type DocLine, type DupGuard, type ElProps, type GameIdEditorOptions, type IconName, type IconSvgName, type Identity, type IdentityOptions, type JobProgressOptions, type JobProgressView, type Notes, type NotesEditorOptions, PALETTE, PALETTE_SIZE, PROPERTY_NAME_HINT, type PaneShell, type PaneShellOptions, type PaneShellState, type PaneSide, type PaneSideConfig, type PinButton, type PinButtonOptions, type PropertyRefOptions, RESERVED_PROPERTY_NAMES, type SaveController, type SaveControllerOptions, type SaveIndicator, type SaveStatus, type SettingsDialog, type SettingsDialogOptions, type SettingsSection, type SettingsSectionHandle, type ShardVc, type StaleBarOptions, type StepperBarOptions, type StepperItem, type StepperTone, type TipRect, type TooltipOptions, type VcMap, askIdentity, bindPropertyName, bindPropertyRef, closeAnchoredPanel, closeWithExit, colourFor, colourIndex, confirmDialog, createSaveController, dupGuard, el, expandableRow, firstIllegalPropertyName, focusNewRow, foldVc, gameIdify, hideTip, icon, iconBtn, iconSvg, initTooltips, isCaseOnlyPropertyName, isValidGameId, isValidPropertyName, labelled, lockControls, lockNotice, mountJobProgress, mountPaneShell, mountSettingsDialog, moveItem, openAnchoredPanel, openComments, openGameIdEditor, openNotesEditor, paintVcBadges, pinButton, placeAnchored, propertyNameProblem, propertyNameify, propertyRefProblem, renderStepperBar, revalidatePropertyRefs, saveIndicator, showAbout, staleBar, tagChips, tipAt, tipBold, vcBadgeFor };
|
package/dist/index.d.ts
CHANGED
|
@@ -408,6 +408,35 @@ declare function bindPropertyName(input: HTMLInputElement, onCommit: (value: str
|
|
|
408
408
|
* sets of words, one gate.
|
|
409
409
|
*/
|
|
410
410
|
declare function firstIllegalPropertyName(host: ParentNode): HTMLInputElement | null;
|
|
411
|
+
interface PropertyRefOptions {
|
|
412
|
+
/** The names that exist, read fresh on every check so a declaration added in the
|
|
413
|
+
* same dialog clears the complaint. Compared case-insensitively, since the
|
|
414
|
+
* parser folds. */
|
|
415
|
+
known: () => string[];
|
|
416
|
+
/** The scope token this field addresses, for the wording ("no @world property..."). */
|
|
417
|
+
scope?: string;
|
|
418
|
+
/** Shown on the field when there is nothing to complain about. */
|
|
419
|
+
hint?: string;
|
|
420
|
+
}
|
|
421
|
+
/** Why this reference cannot be used, or undefined when it can. */
|
|
422
|
+
declare function propertyRefProblem(name: string, opts: PropertyRefOptions): string | undefined;
|
|
423
|
+
/**
|
|
424
|
+
* Wire a field that POINTS at a declared property: same manners as a declaration
|
|
425
|
+
* field (mark, do not rewrite, Tab coerces), plus the declared names offered as a
|
|
426
|
+
* datalist, because the rule is declare-then-reference and a picker makes that
|
|
427
|
+
* painless rather than pedantic.
|
|
428
|
+
*
|
|
429
|
+
* Marks `.illegal` for an undeclared name too, which gates Save wherever the host
|
|
430
|
+
* already asks `firstIllegalPropertyName`.
|
|
431
|
+
*/
|
|
432
|
+
declare function bindPropertyRef(input: HTMLInputElement, onCommit: (value: string) => void, opts: PropertyRefOptions): void;
|
|
433
|
+
/**
|
|
434
|
+
* Re-check every bound reference field inside `host`. Hosts call this when the
|
|
435
|
+
* DECLARATIONS change, since a reference's validity depends on a list it does not
|
|
436
|
+
* own: rename a property and the driver pointing at it is wrong from that moment,
|
|
437
|
+
* with nothing typed into it.
|
|
438
|
+
*/
|
|
439
|
+
declare function revalidatePropertyRefs(host: ParentNode): void;
|
|
411
440
|
|
|
412
441
|
interface GameIdEditorOptions {
|
|
413
442
|
anchor: HTMLElement;
|
|
@@ -789,4 +818,4 @@ interface StepperBarOptions {
|
|
|
789
818
|
/** Draw (or hide) the bar in `host`. Idempotent: call it again with new state. */
|
|
790
819
|
declare function renderStepperBar(host: HTMLElement, opts: StepperBarOptions): void;
|
|
791
820
|
|
|
792
|
-
export { type AboutOptions, type AnchoredPanel, type AnchoredPanelOptions, type Child, type Comment, type CommentMessage, type CommentsOptions, type ConfirmOptions, type DocLine, type DupGuard, type ElProps, type GameIdEditorOptions, type IconName, type IconSvgName, type Identity, type IdentityOptions, type JobProgressOptions, type JobProgressView, type Notes, type NotesEditorOptions, PALETTE, PALETTE_SIZE, PROPERTY_NAME_HINT, type PaneShell, type PaneShellOptions, type PaneShellState, type PaneSide, type PaneSideConfig, type PinButton, type PinButtonOptions, RESERVED_PROPERTY_NAMES, type SaveController, type SaveControllerOptions, type SaveIndicator, type SaveStatus, type SettingsDialog, type SettingsDialogOptions, type SettingsSection, type SettingsSectionHandle, type ShardVc, type StaleBarOptions, type StepperBarOptions, type StepperItem, type StepperTone, type TipRect, type TooltipOptions, type VcMap, askIdentity, bindPropertyName, closeAnchoredPanel, closeWithExit, colourFor, colourIndex, confirmDialog, createSaveController, dupGuard, el, expandableRow, firstIllegalPropertyName, focusNewRow, foldVc, gameIdify, hideTip, icon, iconBtn, iconSvg, initTooltips, isCaseOnlyPropertyName, isValidGameId, isValidPropertyName, labelled, lockControls, lockNotice, mountJobProgress, mountPaneShell, mountSettingsDialog, moveItem, openAnchoredPanel, openComments, openGameIdEditor, openNotesEditor, paintVcBadges, pinButton, placeAnchored, propertyNameProblem, propertyNameify, renderStepperBar, saveIndicator, showAbout, staleBar, tagChips, tipAt, tipBold, vcBadgeFor };
|
|
821
|
+
export { type AboutOptions, type AnchoredPanel, type AnchoredPanelOptions, type Child, type Comment, type CommentMessage, type CommentsOptions, type ConfirmOptions, type DocLine, type DupGuard, type ElProps, type GameIdEditorOptions, type IconName, type IconSvgName, type Identity, type IdentityOptions, type JobProgressOptions, type JobProgressView, type Notes, type NotesEditorOptions, PALETTE, PALETTE_SIZE, PROPERTY_NAME_HINT, type PaneShell, type PaneShellOptions, type PaneShellState, type PaneSide, type PaneSideConfig, type PinButton, type PinButtonOptions, type PropertyRefOptions, RESERVED_PROPERTY_NAMES, type SaveController, type SaveControllerOptions, type SaveIndicator, type SaveStatus, type SettingsDialog, type SettingsDialogOptions, type SettingsSection, type SettingsSectionHandle, type ShardVc, type StaleBarOptions, type StepperBarOptions, type StepperItem, type StepperTone, type TipRect, type TooltipOptions, type VcMap, askIdentity, bindPropertyName, bindPropertyRef, closeAnchoredPanel, closeWithExit, colourFor, colourIndex, confirmDialog, createSaveController, dupGuard, el, expandableRow, firstIllegalPropertyName, focusNewRow, foldVc, gameIdify, hideTip, icon, iconBtn, iconSvg, initTooltips, isCaseOnlyPropertyName, isValidGameId, isValidPropertyName, labelled, lockControls, lockNotice, mountJobProgress, mountPaneShell, mountSettingsDialog, moveItem, openAnchoredPanel, openComments, openGameIdEditor, openNotesEditor, paintVcBadges, pinButton, placeAnchored, propertyNameProblem, propertyNameify, propertyRefProblem, renderStepperBar, revalidatePropertyRefs, saveIndicator, showAbout, staleBar, tagChips, tipAt, tipBold, vcBadgeFor };
|
package/dist/index.js
CHANGED
|
@@ -880,6 +880,7 @@ function isCaseOnlyPropertyName(name) {
|
|
|
880
880
|
}
|
|
881
881
|
|
|
882
882
|
// src/property-name-field.ts
|
|
883
|
+
var refSyncs = /* @__PURE__ */ new WeakMap();
|
|
883
884
|
function propertyNameProblem(name) {
|
|
884
885
|
if (isValidPropertyName(name)) return void 0;
|
|
885
886
|
const suggestion = propertyNameify(name);
|
|
@@ -926,6 +927,93 @@ function bindPropertyName(input, onCommit, opts = {}) {
|
|
|
926
927
|
function firstIllegalPropertyName(host) {
|
|
927
928
|
return host.querySelector("input.illegal");
|
|
928
929
|
}
|
|
930
|
+
function nearest(name, known) {
|
|
931
|
+
const n = name.toLowerCase();
|
|
932
|
+
const byPrefix = known.filter((k) => k.toLowerCase().startsWith(n) || n.startsWith(k.toLowerCase()));
|
|
933
|
+
if (byPrefix.length === 1) return byPrefix[0];
|
|
934
|
+
let best;
|
|
935
|
+
let bestScore = 3;
|
|
936
|
+
for (const k of known) {
|
|
937
|
+
const a = k.toLowerCase();
|
|
938
|
+
if (Math.abs(a.length - n.length) > 2) continue;
|
|
939
|
+
let prev = Array.from({ length: n.length + 1 }, (_, i) => i);
|
|
940
|
+
for (let i = 1; i <= a.length; i++) {
|
|
941
|
+
const row = [i];
|
|
942
|
+
for (let j = 1; j <= n.length; j++) {
|
|
943
|
+
row[j] = Math.min(prev[j] + 1, row[j - 1] + 1, prev[j - 1] + (a[i - 1] === n[j - 1] ? 0 : 1));
|
|
944
|
+
}
|
|
945
|
+
prev = row;
|
|
946
|
+
}
|
|
947
|
+
const d = prev[n.length];
|
|
948
|
+
if (d < bestScore) {
|
|
949
|
+
bestScore = d;
|
|
950
|
+
best = k;
|
|
951
|
+
}
|
|
952
|
+
}
|
|
953
|
+
return best;
|
|
954
|
+
}
|
|
955
|
+
function propertyRefProblem(name, opts) {
|
|
956
|
+
const scope = opts.scope ? `@${opts.scope}` : "that scope";
|
|
957
|
+
const folded = name.toLowerCase();
|
|
958
|
+
if (!isValidPropertyName(folded)) {
|
|
959
|
+
const suggestion = propertyNameify(name);
|
|
960
|
+
const tail = suggestion ? ` Try "${suggestion}", or press Tab.` : "";
|
|
961
|
+
if (RESERVED_PROPERTY_NAMES.includes(folded)) return `Cannot be used: "${folded}" is a keyword in expressions.${tail}`;
|
|
962
|
+
if (name.includes("-")) return `Cannot be used: a hyphen reads as subtraction in an expression.${tail}`;
|
|
963
|
+
if (/^[0-9]/.test(name)) return `Cannot be used: a name cannot start with a digit.${tail}`;
|
|
964
|
+
return `Cannot be used: only lower case letters, digits and underscores.${tail}`;
|
|
965
|
+
}
|
|
966
|
+
const known = opts.known();
|
|
967
|
+
if (known.some((k) => k.toLowerCase() === folded)) return void 0;
|
|
968
|
+
const near = nearest(folded, known);
|
|
969
|
+
if (near) return `No ${scope} property is called "${name}". Did you mean "${near}"?`;
|
|
970
|
+
if (known.length === 0) return `No ${scope} properties are declared yet. Declare one above first.`;
|
|
971
|
+
const shown = known.slice(0, 3).map((k) => `"${k}"`).join(", ");
|
|
972
|
+
const more = known.length > 3 ? `, and ${known.length - 3} more` : "";
|
|
973
|
+
return `No ${scope} property is called "${name}". Declared: ${shown}${more}.`;
|
|
974
|
+
}
|
|
975
|
+
function bindPropertyRef(input, onCommit, opts) {
|
|
976
|
+
const list = document.createElement("datalist");
|
|
977
|
+
list.id = `shell-propref-${Math.random().toString(36).slice(2, 9)}`;
|
|
978
|
+
input.setAttribute("list", list.id);
|
|
979
|
+
input.after(list);
|
|
980
|
+
const sync = () => {
|
|
981
|
+
const known = opts.known();
|
|
982
|
+
list.replaceChildren(...known.map((k) => {
|
|
983
|
+
const o = document.createElement("option");
|
|
984
|
+
o.value = k;
|
|
985
|
+
return o;
|
|
986
|
+
}));
|
|
987
|
+
const v = input.value.trim();
|
|
988
|
+
const problem = v === "" ? void 0 : propertyRefProblem(v, opts);
|
|
989
|
+
input.classList.toggle("illegal", !!problem);
|
|
990
|
+
if (problem) input.title = problem;
|
|
991
|
+
else if (input.title.startsWith("Cannot be used") || input.title.startsWith("No ")) {
|
|
992
|
+
if (opts.hint) input.title = opts.hint;
|
|
993
|
+
else input.removeAttribute("title");
|
|
994
|
+
}
|
|
995
|
+
};
|
|
996
|
+
refSyncs.set(input, sync);
|
|
997
|
+
input.addEventListener("input", () => {
|
|
998
|
+
onCommit(input.value);
|
|
999
|
+
sync();
|
|
1000
|
+
});
|
|
1001
|
+
input.addEventListener("keydown", (e) => {
|
|
1002
|
+
if (e.key !== "Tab" || e.shiftKey) return;
|
|
1003
|
+
const typed = input.value.trim();
|
|
1004
|
+
if (typed === "" || isValidPropertyName(typed.toLowerCase())) return;
|
|
1005
|
+
const coerced = propertyNameify(typed);
|
|
1006
|
+
if (!coerced || coerced === input.value) return;
|
|
1007
|
+
e.preventDefault();
|
|
1008
|
+
input.value = coerced;
|
|
1009
|
+
onCommit(coerced);
|
|
1010
|
+
sync();
|
|
1011
|
+
});
|
|
1012
|
+
sync();
|
|
1013
|
+
}
|
|
1014
|
+
function revalidatePropertyRefs(host) {
|
|
1015
|
+
for (const input of host.querySelectorAll("input")) refSyncs.get(input)?.();
|
|
1016
|
+
}
|
|
929
1017
|
|
|
930
1018
|
// src/id-editor.ts
|
|
931
1019
|
function openGameIdEditor(opts) {
|
|
@@ -1587,6 +1675,6 @@ function renderStepperBar(host, opts) {
|
|
|
1587
1675
|
);
|
|
1588
1676
|
}
|
|
1589
1677
|
|
|
1590
|
-
export { PALETTE, PALETTE_SIZE, PROPERTY_NAME_HINT, RESERVED_PROPERTY_NAMES, askIdentity, bindPropertyName, closeAnchoredPanel, closeWithExit, colourFor, colourIndex, confirmDialog, createSaveController, dupGuard, el, expandableRow, firstIllegalPropertyName, focusNewRow, foldVc, gameIdify, hideTip, icon, iconBtn, iconSvg, initTooltips, isCaseOnlyPropertyName, isValidGameId, isValidPropertyName, labelled, lockControls, lockNotice, mountJobProgress, mountPaneShell, mountSettingsDialog, moveItem, openAnchoredPanel, openComments, openGameIdEditor, openNotesEditor, paintVcBadges, pinButton, placeAnchored, propertyNameProblem, propertyNameify, renderStepperBar, saveIndicator, showAbout, staleBar, tagChips, tipAt, tipBold, vcBadgeFor };
|
|
1678
|
+
export { PALETTE, PALETTE_SIZE, PROPERTY_NAME_HINT, RESERVED_PROPERTY_NAMES, askIdentity, bindPropertyName, bindPropertyRef, closeAnchoredPanel, closeWithExit, colourFor, colourIndex, confirmDialog, createSaveController, dupGuard, el, expandableRow, firstIllegalPropertyName, focusNewRow, foldVc, gameIdify, hideTip, icon, iconBtn, iconSvg, initTooltips, isCaseOnlyPropertyName, isValidGameId, isValidPropertyName, labelled, lockControls, lockNotice, mountJobProgress, mountPaneShell, mountSettingsDialog, moveItem, openAnchoredPanel, openComments, openGameIdEditor, openNotesEditor, paintVcBadges, pinButton, placeAnchored, propertyNameProblem, propertyNameify, propertyRefProblem, renderStepperBar, revalidatePropertyRefs, saveIndicator, showAbout, staleBar, tagChips, tipAt, tipBold, vcBadgeFor };
|
|
1591
1679
|
//# sourceMappingURL=index.js.map
|
|
1592
1680
|
//# sourceMappingURL=index.js.map
|