@loworbitstudio/visor 1.29.0 → 1.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/CHANGELOG.json +13 -1
- package/dist/index.js +314 -4
- package/dist/registry.json +95 -44
- package/dist/visor-manifest.json +396 -16
- package/package.json +2 -2
package/dist/CHANGELOG.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": "0.4.0",
|
|
3
|
-
"generated_at": "2026-
|
|
3
|
+
"generated_at": "2026-10-03T23:23:41.697Z",
|
|
4
4
|
"components": {
|
|
5
5
|
"accessibility-specimen": {
|
|
6
6
|
"changeType": "current",
|
|
@@ -14,6 +14,12 @@
|
|
|
14
14
|
"breakingChange": false,
|
|
15
15
|
"migrationNote": null
|
|
16
16
|
},
|
|
17
|
+
"action-row": {
|
|
18
|
+
"changeType": "current",
|
|
19
|
+
"files": [],
|
|
20
|
+
"breakingChange": false,
|
|
21
|
+
"migrationNote": null
|
|
22
|
+
},
|
|
17
23
|
"activity-feed": {
|
|
18
24
|
"changeType": "current",
|
|
19
25
|
"files": [],
|
|
@@ -746,6 +752,12 @@
|
|
|
746
752
|
"breakingChange": false,
|
|
747
753
|
"migrationNote": null
|
|
748
754
|
},
|
|
755
|
+
"time-picker": {
|
|
756
|
+
"changeType": "current",
|
|
757
|
+
"files": [],
|
|
758
|
+
"breakingChange": false,
|
|
759
|
+
"migrationNote": null
|
|
760
|
+
},
|
|
749
761
|
"timeline": {
|
|
750
762
|
"changeType": "current",
|
|
751
763
|
"files": [],
|
package/dist/index.js
CHANGED
|
@@ -8761,6 +8761,170 @@ import { existsSync as existsSync31, mkdirSync as mkdirSync14, readFileSync as r
|
|
|
8761
8761
|
import { dirname as dirname15, isAbsolute as isAbsolute7, resolve as resolve21 } from "path";
|
|
8762
8762
|
var ICON_X = `React.createElement("svg", { viewBox: "0 0 256 256", width: "1em", height: "1em", fill: "currentColor", "aria-hidden": true }, React.createElement("path", { d: "M205.66,194.34a8,8,0,0,1-11.32,11.32L128,139.31,61.66,205.66a8,8,0,0,1-11.32-11.32L116.69,128,50.34,61.66A8,8,0,0,1,61.66,50.34L128,116.69l66.34-66.35a8,8,0,0,1,11.32,11.32L139.31,128Z" }))`;
|
|
8763
8763
|
var FIXTURES = {
|
|
8764
|
+
// VI-680: hairline consumers. `__mod` is the component module, so a fixture can
|
|
8765
|
+
// reach the compound parts a single export does not expose.
|
|
8766
|
+
table: {
|
|
8767
|
+
default: {
|
|
8768
|
+
export: "Table",
|
|
8769
|
+
props: `(function () {
|
|
8770
|
+
var h = React.createElement;
|
|
8771
|
+
var row = function (cells, key) {
|
|
8772
|
+
return h(__mod.TableRow, { key: key }, cells.map(function (c, i) { return h(__mod.TableCell, { key: i }, c); }));
|
|
8773
|
+
};
|
|
8774
|
+
return {
|
|
8775
|
+
children: [
|
|
8776
|
+
h(__mod.TableHeader, { key: "h" }, h(__mod.TableRow, null, ["Name", "Role", "Status"].map(function (t) { return h(__mod.TableHead, { key: t }, t); }))),
|
|
8777
|
+
h(__mod.TableBody, { key: "b" }, [
|
|
8778
|
+
row(["Ada Lovelace", "Engineer", "Active"], 1),
|
|
8779
|
+
row(["Grace Hopper", "Admiral", "Active"], 2),
|
|
8780
|
+
row(["Alan Turing", "Researcher", "Away"], 3),
|
|
8781
|
+
]),
|
|
8782
|
+
],
|
|
8783
|
+
};
|
|
8784
|
+
})()`
|
|
8785
|
+
}
|
|
8786
|
+
},
|
|
8787
|
+
dialog: {
|
|
8788
|
+
default: {
|
|
8789
|
+
export: "Dialog",
|
|
8790
|
+
props: `(function () {
|
|
8791
|
+
var h = React.createElement;
|
|
8792
|
+
return {
|
|
8793
|
+
open: true,
|
|
8794
|
+
// The trigger gives #root a node; the content itself portals to <body>.
|
|
8795
|
+
children: [h(__mod.DialogTrigger, { key: "tr", asChild: true }, h("button", { type: "button" }, "Open")), h(__mod.DialogContent, { key: "c" }, [
|
|
8796
|
+
h(__mod.DialogHeader, { key: "h" }, [
|
|
8797
|
+
h(__mod.DialogTitle, { key: "t" }, "Invite a teammate"),
|
|
8798
|
+
h(__mod.DialogDescription, { key: "d" }, "They will get an email with a link to join."),
|
|
8799
|
+
]),
|
|
8800
|
+
h("p", { key: "b" }, "Dialog body copy sits between the header and the footer rule."),
|
|
8801
|
+
h(__mod.DialogFooter, { key: "f" }, h("button", { type: "button" }, "Send invite")),
|
|
8802
|
+
])],
|
|
8803
|
+
};
|
|
8804
|
+
})()`
|
|
8805
|
+
},
|
|
8806
|
+
// VI-667: bottom-sheet presentation, with the drag handle and a leading back action.
|
|
8807
|
+
sheet: {
|
|
8808
|
+
export: "Dialog",
|
|
8809
|
+
props: `(function () {
|
|
8810
|
+
var h = React.createElement;
|
|
8811
|
+
return {
|
|
8812
|
+
open: true,
|
|
8813
|
+
presentation: "sheet",
|
|
8814
|
+
children: [h(__mod.DialogTrigger, { key: "tr", asChild: true }, h("button", { type: "button" }, "Open")), h(__mod.DialogContent, { key: "c", showHandle: true }, [
|
|
8815
|
+
h(__mod.DialogHeader, { key: "h", back: h(__mod.DialogBack, null) }, [
|
|
8816
|
+
h(__mod.DialogTitle, { key: "t" }, "Set start time"),
|
|
8817
|
+
h(__mod.DialogDescription, { key: "d" }, "Doors open one hour earlier."),
|
|
8818
|
+
]),
|
|
8819
|
+
h("input", { key: "i", "aria-label": "Start", defaultValue: "21:00", style: { width: "100%", boxSizing: "border-box", padding: "8px" } }),
|
|
8820
|
+
h(__mod.DialogFooter, { key: "f" }, h("button", { type: "button" }, "Save")),
|
|
8821
|
+
])],
|
|
8822
|
+
};
|
|
8823
|
+
})()`
|
|
8824
|
+
},
|
|
8825
|
+
// VI-667: dialog scoped to one pane (#root) under a scrim; the page outside it is untouched.
|
|
8826
|
+
scoped: {
|
|
8827
|
+
export: "Dialog",
|
|
8828
|
+
props: `(function () {
|
|
8829
|
+
var h = React.createElement;
|
|
8830
|
+
var pane = document.getElementById("root");
|
|
8831
|
+
pane.style.minHeight = "420px";
|
|
8832
|
+
pane.style.position = "relative";
|
|
8833
|
+
pane.style.background = "var(--surface-card, #f3f4f6)";
|
|
8834
|
+
return {
|
|
8835
|
+
open: true,
|
|
8836
|
+
container: pane,
|
|
8837
|
+
children: [
|
|
8838
|
+
h("p", { key: "p", style: { margin: 0, padding: "16px" } }, "Editor pane: stays visible behind the scrim."),
|
|
8839
|
+
h(__mod.DialogContent, { key: "c" }, [
|
|
8840
|
+
h(__mod.DialogHeader, { key: "h", back: h(__mod.DialogBack, null) }, [
|
|
8841
|
+
h(__mod.DialogTitle, { key: "t" }, "Sign back in"),
|
|
8842
|
+
h(__mod.DialogDescription, { key: "d" }, "Your session timed out."),
|
|
8843
|
+
]),
|
|
8844
|
+
h(__mod.DialogFooter, { key: "f" }, h("button", { type: "button" }, "Continue")),
|
|
8845
|
+
]),
|
|
8846
|
+
],
|
|
8847
|
+
};
|
|
8848
|
+
})()`
|
|
8849
|
+
}
|
|
8850
|
+
},
|
|
8851
|
+
popover: {
|
|
8852
|
+
selection: {
|
|
8853
|
+
export: "PopoverSelectionList",
|
|
8854
|
+
props: `(function () {
|
|
8855
|
+
var h = React.createElement;
|
|
8856
|
+
return {
|
|
8857
|
+
mode: "checkbox",
|
|
8858
|
+
"aria-label": "Filters",
|
|
8859
|
+
children: ["Design", "Engineering", "Operations"].map(function (t, i) {
|
|
8860
|
+
return h(__mod.PopoverSelectionItem, { key: t, selected: i === 0 }, t);
|
|
8861
|
+
}),
|
|
8862
|
+
};
|
|
8863
|
+
})()`
|
|
8864
|
+
}
|
|
8865
|
+
},
|
|
8866
|
+
tabs: {
|
|
8867
|
+
line: {
|
|
8868
|
+
export: "Tabs",
|
|
8869
|
+
props: `(function () {
|
|
8870
|
+
var h = React.createElement;
|
|
8871
|
+
return {
|
|
8872
|
+
defaultValue: "one",
|
|
8873
|
+
children: [
|
|
8874
|
+
h(__mod.TabsList, { key: "l", variant: "line" }, [
|
|
8875
|
+
h(__mod.TabsTrigger, { key: "1", value: "one" }, "Overview"),
|
|
8876
|
+
h(__mod.TabsTrigger, { key: "2", value: "two" }, "Activity"),
|
|
8877
|
+
h(__mod.TabsTrigger, { key: "3", value: "three" }, "Settings"),
|
|
8878
|
+
]),
|
|
8879
|
+
h(__mod.TabsContent, { key: "c", value: "one" }, "Overview content"),
|
|
8880
|
+
],
|
|
8881
|
+
};
|
|
8882
|
+
})()`
|
|
8883
|
+
}
|
|
8884
|
+
},
|
|
8885
|
+
// VI-669: a block, resolved from blocks/. July 2026 with a stay crossing a week
|
|
8886
|
+
// edge, three overlapping spans plus a fourth ("+1"), a colour-token event, a
|
|
8887
|
+
// day mark, and the week detail slot open under the selected day.
|
|
8888
|
+
"month-calendar": {
|
|
8889
|
+
default: {
|
|
8890
|
+
export: "MonthCalendar",
|
|
8891
|
+
props: `(function () {
|
|
8892
|
+
var h = React.createElement;
|
|
8893
|
+
return {
|
|
8894
|
+
month: "2026-07-01",
|
|
8895
|
+
today: "2026-07-09",
|
|
8896
|
+
selectedDate: "2026-07-15",
|
|
8897
|
+
weekStartsOn: 1,
|
|
8898
|
+
onSelectDate: function () {},
|
|
8899
|
+
events: [
|
|
8900
|
+
{ id: "berlin", start: "2026-07-02", end: "2026-07-05", title: "Berlin stay", series: 1 },
|
|
8901
|
+
{ id: "lisbon", start: "2026-07-13", end: "2026-07-19", title: "Lisbon run", color: "--chart-3" },
|
|
8902
|
+
{ id: "paris", start: "2026-07-20", end: "2026-07-22", title: "Paris", series: 4 },
|
|
8903
|
+
{ id: "a", start: "2026-07-20", end: "2026-07-21", title: "Studio hold", series: 2 },
|
|
8904
|
+
{ id: "b", start: "2026-07-20", end: "2026-07-24", title: "Press week", series: 5 },
|
|
8905
|
+
{ id: "c", start: "2026-07-21", end: "2026-07-22", title: "Fourth lane", series: 3 },
|
|
8906
|
+
{ id: "gig", date: "2026-07-09", title: "Soundcheck", status: "success", series: 2 },
|
|
8907
|
+
],
|
|
8908
|
+
renderDayMark: function (day) { return day.date === "2026-07-17" ? "3" : null; },
|
|
8909
|
+
renderWeekDetail: function (week) {
|
|
8910
|
+
return h("div", null, h("strong", null, "Week of " + week.start), h("p", { style: { margin: 0 } }, "Day sheet content sits here."));
|
|
8911
|
+
},
|
|
8912
|
+
};
|
|
8913
|
+
})()`
|
|
8914
|
+
},
|
|
8915
|
+
overlap: {
|
|
8916
|
+
export: "MonthCalendar",
|
|
8917
|
+
props: `{
|
|
8918
|
+
month: "2026-07-01",
|
|
8919
|
+
events: [
|
|
8920
|
+
{ id: "a", start: "2026-07-07", end: "2026-07-11", title: "Stay A", series: 1 },
|
|
8921
|
+
{ id: "b", start: "2026-07-08", end: "2026-07-12", title: "Stay B", series: 2 },
|
|
8922
|
+
{ id: "c", start: "2026-07-09", end: "2026-07-10", title: "Stay C", series: 3 },
|
|
8923
|
+
{ id: "d", start: "2026-07-09", end: "2026-07-10", title: "Stay D", series: 4 },
|
|
8924
|
+
],
|
|
8925
|
+
}`
|
|
8926
|
+
}
|
|
8927
|
+
},
|
|
8764
8928
|
"stat-card": {
|
|
8765
8929
|
default: {
|
|
8766
8930
|
export: "StatCard",
|
|
@@ -8952,6 +9116,14 @@ var FIXTURES = {
|
|
|
8952
9116
|
default: { export: "Input", interactiveTarget: "input", props: `{ placeholder: "Email address" }` },
|
|
8953
9117
|
invalid: { export: "Input", interactiveTarget: "input", props: `{ defaultValue: "not-an-email", "aria-invalid": true }` }
|
|
8954
9118
|
},
|
|
9119
|
+
// VI-624: `default` is the closed field; the popover fixtures render open so the
|
|
9120
|
+
// two-column (24-hour) and three-column (12-hour) anatomy can be inspected.
|
|
9121
|
+
"time-picker": {
|
|
9122
|
+
default: { export: "TimePicker", interactiveTarget: "input", props: `{ "aria-label": "Doors open", hourCycle: 12, minuteStep: 15, defaultValue: "16:00" }` },
|
|
9123
|
+
"popover-24h": { export: "TimePicker", interactiveTarget: "input", props: `{ "aria-label": "Set start", hourCycle: 24, minuteStep: 15, defaultValue: "16:15", open: true }` },
|
|
9124
|
+
"popover-12h": { export: "TimePicker", interactiveTarget: "input", props: `{ "aria-label": "Doors open", hourCycle: 12, minuteStep: 15, defaultValue: "16:15", open: true }` },
|
|
9125
|
+
invalid: { export: "TimePicker", interactiveTarget: "input", props: `{ "aria-label": "Doors open", hourCycle: 12, defaultValue: "16:00", "aria-invalid": true }` }
|
|
9126
|
+
},
|
|
8955
9127
|
textarea: {
|
|
8956
9128
|
default: { export: "Textarea", interactiveTarget: "textarea", props: `{ placeholder: "Tell us more" }` },
|
|
8957
9129
|
invalid: { export: "Textarea", interactiveTarget: "textarea", props: `{ defaultValue: "Too short", "aria-invalid": true }` }
|
|
@@ -8978,6 +9150,51 @@ var FIXTURES = {
|
|
|
8978
9150
|
checked: { export: "Checkbox", interactiveTarget: "button", props: `{ "aria-label": "Accept", defaultChecked: true }` },
|
|
8979
9151
|
invalid: { export: "Checkbox", interactiveTarget: "button", props: `{ "aria-label": "Accept", "aria-invalid": true }` }
|
|
8980
9152
|
},
|
|
9153
|
+
// VI-668: the card variant — icon, title, line; the third level is drawn disabled.
|
|
9154
|
+
"radio-group": {
|
|
9155
|
+
default: {
|
|
9156
|
+
export: "RadioGroup",
|
|
9157
|
+
interactiveTarget: '[role="radio"]',
|
|
9158
|
+
props: `(function () {
|
|
9159
|
+
var h = React.createElement;
|
|
9160
|
+
return {
|
|
9161
|
+
"aria-label": "Size",
|
|
9162
|
+
defaultValue: "medium",
|
|
9163
|
+
style: { width: 320 },
|
|
9164
|
+
children: ["small", "medium", "large"].map(function (v) {
|
|
9165
|
+
return h(__mod.RadioGroupItem, { key: v, value: v, "aria-label": v });
|
|
9166
|
+
}),
|
|
9167
|
+
};
|
|
9168
|
+
})()`
|
|
9169
|
+
},
|
|
9170
|
+
card: {
|
|
9171
|
+
export: "RadioGroup",
|
|
9172
|
+
interactiveTarget: '[role="radio"]',
|
|
9173
|
+
props: `(function () {
|
|
9174
|
+
var h = React.createElement;
|
|
9175
|
+
var icon = function (shapes) {
|
|
9176
|
+
return h("svg", { width: "1em", height: "1em", viewBox: "0 0 24 24", fill: "currentColor" }, shapes);
|
|
9177
|
+
};
|
|
9178
|
+
var levels = [
|
|
9179
|
+
["just-you", "Just You", "Only you can see this booking.", icon([h("circle", { key: 1, cx: 12, cy: 8, r: 4 }), h("path", { key: 2, d: "M4 21a8 8 0 0 1 16 0Z" })])],
|
|
9180
|
+
["team", "Your Team", "Everyone on your team can see it.", icon([h("circle", { key: 1, cx: 8, cy: 9, r: 3.5 }), h("circle", { key: 2, cx: 16, cy: 9, r: 3.5 }), h("path", { key: 3, d: "M1 20a7 7 0 0 1 14 0ZM9 20a7 7 0 0 1 14 0Z" })])],
|
|
9181
|
+
["public", "Public", "Verified bookers only for now.", icon([h("path", { key: 1, d: "M12 2a10 10 0 1 0 0 20 10 10 0 0 0 0-20Zm0 3a7 7 0 0 1 0 14 7 7 0 0 1 0-14Z", fillRule: "evenodd" })])],
|
|
9182
|
+
];
|
|
9183
|
+
return {
|
|
9184
|
+
variant: "card",
|
|
9185
|
+
"aria-label": "Visibility",
|
|
9186
|
+
defaultValue: "team",
|
|
9187
|
+
style: { width: 360 },
|
|
9188
|
+
children: levels.map(function (l, i) {
|
|
9189
|
+
return h(__mod.RadioGroupItem, {
|
|
9190
|
+
key: l[0], value: l[0], icon: l[3], title: l[1], description: l[2],
|
|
9191
|
+
disabled: i === 2, "aria-describedby": i === 2 ? "radio-reason" : undefined,
|
|
9192
|
+
});
|
|
9193
|
+
}).concat([h("p", { key: "r", id: "radio-reason", style: { margin: 0, fontSize: 12 } }, "Public needs a verified booking.")]),
|
|
9194
|
+
};
|
|
9195
|
+
})()`
|
|
9196
|
+
}
|
|
9197
|
+
},
|
|
8981
9198
|
switch: {
|
|
8982
9199
|
default: { export: "Switch", interactiveTarget: "button", props: `{ "aria-label": "Notifications" }` },
|
|
8983
9200
|
checked: { export: "Switch", interactiveTarget: "button", props: `{ "aria-label": "Notifications", defaultChecked: true }` },
|
|
@@ -9016,13 +9233,37 @@ var FIXTURES = {
|
|
|
9016
9233
|
export: "InlineEdit",
|
|
9017
9234
|
interactiveTarget: "input",
|
|
9018
9235
|
props: `{ as: "h2", style: { margin: 0, fontSize: "21px", lineHeight: 1.25, fontWeight: 600 }, label: "Section title", value: "Track record", defaultValue: "Untitled section", onCommit: function () {}, defaultEditing: true }`
|
|
9236
|
+
},
|
|
9237
|
+
// VI-677: pencil={false}. The text is the button, so hover/focus drive it.
|
|
9238
|
+
"no-pencil": {
|
|
9239
|
+
export: "InlineEdit",
|
|
9240
|
+
interactiveTarget: "button",
|
|
9241
|
+
props: `{ label: "Rider title", value: "Technical rider", defaultValue: "Rider", onCommit: function () {}, pencil: false }`
|
|
9242
|
+
},
|
|
9243
|
+
"no-pencil-default-value": {
|
|
9244
|
+
export: "InlineEdit",
|
|
9245
|
+
interactiveTarget: "button",
|
|
9246
|
+
props: `{ label: "Rider title", value: "", defaultValue: "Rider", onCommit: function () {}, pencil: false }`
|
|
9247
|
+
},
|
|
9248
|
+
// Descenders and accents must survive the cap-band trim.
|
|
9249
|
+
"no-pencil-glyphs": {
|
|
9250
|
+
export: "InlineEdit",
|
|
9251
|
+
interactiveTarget: "button",
|
|
9252
|
+
props: `{ label: "Rider title", value: "Typography jpq \xC9\xC5\xD1", defaultValue: "Rider", onCommit: function () {}, pencil: false }`
|
|
9253
|
+
},
|
|
9254
|
+
"no-pencil-heading": {
|
|
9255
|
+
export: "InlineEdit",
|
|
9256
|
+
interactiveTarget: "button",
|
|
9257
|
+
props: `{ as: "h2", style: { margin: 0, fontSize: "21px", lineHeight: 1.25, fontWeight: 600 }, label: "Section title", value: "Track record", defaultValue: "Untitled section", onCommit: function () {}, pencil: false }`
|
|
9019
9258
|
}
|
|
9020
9259
|
},
|
|
9021
|
-
// VI-657: the autosave readout in each state. It draws no edge in any of them.
|
|
9260
|
+
// VI-657/VI-665: the autosave readout in each state, Unsaved as a dot too. It draws no edge in any of them.
|
|
9022
9261
|
"save-status": {
|
|
9023
9262
|
default: { export: "SaveStatus", props: `{ status: "saved" }` },
|
|
9024
9263
|
saving: { export: "SaveStatus", props: `{ status: "saving" }` },
|
|
9264
|
+
syncing: { export: "SaveStatus", props: `{ status: "syncing" }` },
|
|
9025
9265
|
unsaved: { export: "SaveStatus", props: `{ status: "unsaved" }` },
|
|
9266
|
+
"unsaved-dot": { export: "SaveStatus", props: `{ status: "unsaved", unsavedAs: "dot" }` },
|
|
9026
9267
|
refused: { export: "SaveStatus", props: `{ status: "refused" }` },
|
|
9027
9268
|
"refused-retry": { export: "SaveStatus", interactiveTarget: "button", props: `{ status: "refused", onRetry: function () {} }` }
|
|
9028
9269
|
},
|
|
@@ -9046,6 +9287,55 @@ var FIXTURES = {
|
|
|
9046
9287
|
default: {
|
|
9047
9288
|
export: "EmptyState",
|
|
9048
9289
|
props: `{ heading: "No projects yet", description: "Create a project to get started." }`
|
|
9290
|
+
},
|
|
9291
|
+
error: {
|
|
9292
|
+
export: "EmptyState",
|
|
9293
|
+
props: `{ intent: "error", tone: "subtle", icon: ${ICON_X}, heading: "Could not load the inbox", description: "The request timed out. Check your connection and try again." }`
|
|
9294
|
+
}
|
|
9295
|
+
},
|
|
9296
|
+
// VI-666: ActionRow. Every row is captioned (title = state, line = what it
|
|
9297
|
+
// reads); `edges-off` binds both switches on the list: the resting edge and
|
|
9298
|
+
// the hairline go, the selected state edge and focus stay. `--state hover|focus` drives the
|
|
9299
|
+
// first row.
|
|
9300
|
+
"action-row": {
|
|
9301
|
+
default: {
|
|
9302
|
+
export: "ActionRowList",
|
|
9303
|
+
props: `(function () {
|
|
9304
|
+
var h = React.createElement;
|
|
9305
|
+
var row = function (key, props) {
|
|
9306
|
+
return h(__mod.ActionRow, Object.assign({ key: key, leading: ${ICON_X}, trailing: h("span", null, "Value") }, props), props.title);
|
|
9307
|
+
};
|
|
9308
|
+
return { "aria-label": "States", style: { maxWidth: "420px" }, children: [
|
|
9309
|
+
row("rest", { title: "Rest", line: "no fill, 44px floor" }),
|
|
9310
|
+
row("selected", { title: "Selected", line: "lifted fill + inset edge", selected: true }),
|
|
9311
|
+
row("open", { title: "Open", line: "open fill, aria-expanded", open: true }),
|
|
9312
|
+
row("disabled", { title: "Disabled", line: "disabled opacity", disabled: true }),
|
|
9313
|
+
h(__mod.ActionRow, { key: "bare", trailing: h("span", null, "Review") }, "Title only, trailing value"),
|
|
9314
|
+
h(__mod.ActionRow, { key: "long", leading: ${ICON_X}, line: "A second line that is long enough that it has to wrap onto another line", trailing: h("span", null, "3 suggested") }, "A title long enough that it wraps to a second line at this width"),
|
|
9315
|
+
h(__mod.ActionRow, { key: "glyphs", leading: ${ICON_X}, line: "Descenders jpqgy and accents \xC9\xC5\xD1", trailing: h("span", null, "jpq \xC9\xC5\xD1") }, "Typography jpq \xC9\xC5\xD1"),
|
|
9316
|
+
h(__mod.ActionRow, { key: "link", asChild: true, leading: ${ICON_X}, trailing: h("span", null, "Open") }, h("a", { href: "#billing" }, "Row as a link (asChild)")),
|
|
9317
|
+
] };
|
|
9318
|
+
})()`
|
|
9319
|
+
},
|
|
9320
|
+
interactive: {
|
|
9321
|
+
export: "ActionRowList",
|
|
9322
|
+
props: `(function () {
|
|
9323
|
+
var h = React.createElement;
|
|
9324
|
+
return { "aria-label": "Interactive", style: { maxWidth: "420px" }, children: [
|
|
9325
|
+
h(__mod.ActionRow, { key: "a", leading: ${ICON_X}, line: "driven by --state", trailing: h("span", null, "Value") }, "First row"),
|
|
9326
|
+
h(__mod.ActionRow, { key: "b", leading: ${ICON_X}, line: "left at rest", trailing: h("span", null, "Value") }, "Second row"),
|
|
9327
|
+
] };
|
|
9328
|
+
})()`
|
|
9329
|
+
},
|
|
9330
|
+
"edges-off": {
|
|
9331
|
+
export: "ActionRowList",
|
|
9332
|
+
props: `(function () {
|
|
9333
|
+
var h = React.createElement;
|
|
9334
|
+
return { "aria-label": "Edges off", style: { maxWidth: "420px", "--control-edge-width": "0", "--hairline-width": "0" }, children: [
|
|
9335
|
+
h(__mod.ActionRow, { key: "a", leading: ${ICON_X}, line: "edge kept, resting edge off", trailing: h("span", null, "Value"), selected: true }, "Selected"),
|
|
9336
|
+
h(__mod.ActionRow, { key: "b", leading: ${ICON_X}, line: "hairline off", trailing: h("span", null, "Value") }, "Rest"),
|
|
9337
|
+
] };
|
|
9338
|
+
})()`
|
|
9049
9339
|
}
|
|
9050
9340
|
},
|
|
9051
9341
|
badge: {
|
|
@@ -9096,7 +9386,8 @@ function resolveComponentFile(cwd, name) {
|
|
|
9096
9386
|
return firstExisting([
|
|
9097
9387
|
resolve21(cwd, "components", "ui", name, `${name}.tsx`),
|
|
9098
9388
|
resolve21(cwd, "components", "devtools", name, `${name}.tsx`),
|
|
9099
|
-
resolve21(cwd, "components", "ui", name, "index.tsx")
|
|
9389
|
+
resolve21(cwd, "components", "ui", name, "index.tsx"),
|
|
9390
|
+
resolve21(cwd, "blocks", name, `${name}.tsx`)
|
|
9100
9391
|
]);
|
|
9101
9392
|
}
|
|
9102
9393
|
function resolveThemeCssFile(cwd, slug2) {
|
|
@@ -9112,6 +9403,12 @@ function resolveTokensCssFile(cwd) {
|
|
|
9112
9403
|
resolve21(cwd, "node_modules", "@loworbitstudio", "visor-core", "dist", "tokens.css")
|
|
9113
9404
|
]);
|
|
9114
9405
|
}
|
|
9406
|
+
function resolveResetCssFile(cwd) {
|
|
9407
|
+
return firstExisting([
|
|
9408
|
+
resolve21(cwd, "packages", "tokens", "dist", "reset.css"),
|
|
9409
|
+
resolve21(cwd, "node_modules", "@loworbitstudio", "visor-core", "dist", "reset.css")
|
|
9410
|
+
]);
|
|
9411
|
+
}
|
|
9115
9412
|
async function loadOptional(moduleName) {
|
|
9116
9413
|
try {
|
|
9117
9414
|
return await import(moduleName);
|
|
@@ -9135,6 +9432,9 @@ function buildHtml(opts) {
|
|
|
9135
9432
|
<head>
|
|
9136
9433
|
<meta charset="utf-8" />
|
|
9137
9434
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
9435
|
+
<style data-visor="reset">
|
|
9436
|
+
${opts.resetCss}
|
|
9437
|
+
</style>
|
|
9138
9438
|
<style data-visor="tokens">
|
|
9139
9439
|
${opts.tokensCss}
|
|
9140
9440
|
</style>
|
|
@@ -9155,7 +9455,8 @@ html, body { margin: 0; padding: 0; }
|
|
|
9155
9455
|
justify-content: center;
|
|
9156
9456
|
background: var(--surface-page, #ffffff);
|
|
9157
9457
|
color: var(--text-primary, #111827);
|
|
9158
|
-
|
|
9458
|
+
/* Same token the nextjs adapter's origination binds to body (VI-616). */
|
|
9459
|
+
font-family: var(--font-body, var(--font-sans, system-ui, -apple-system, sans-serif));
|
|
9159
9460
|
}
|
|
9160
9461
|
#root { width: 100%; max-width: 420px; }
|
|
9161
9462
|
</style>
|
|
@@ -9214,7 +9515,7 @@ async function renderCommand(component, cwd, options) {
|
|
|
9214
9515
|
if (!componentFile) {
|
|
9215
9516
|
fail3(
|
|
9216
9517
|
"COMPONENT_NOT_FOUND",
|
|
9217
|
-
`Component "${component}" not found under components/ui/. Expected components/ui/${component}/${component}.tsx.`
|
|
9518
|
+
`Component "${component}" not found under components/ui/ or blocks/. Expected components/ui/${component}/${component}.tsx or blocks/${component}/${component}.tsx.`
|
|
9218
9519
|
);
|
|
9219
9520
|
}
|
|
9220
9521
|
const themeCssFile = resolveThemeCssFile(cwd, options.theme);
|
|
@@ -9233,6 +9534,14 @@ async function renderCommand(component, cwd, options) {
|
|
|
9233
9534
|
{ hint: "Run `npm run build -w packages/tokens` first." }
|
|
9234
9535
|
);
|
|
9235
9536
|
}
|
|
9537
|
+
const resetCssFile = resolveResetCssFile(cwd);
|
|
9538
|
+
if (!resetCssFile) {
|
|
9539
|
+
fail3(
|
|
9540
|
+
"RESET_NOT_FOUND",
|
|
9541
|
+
"visor-core reset.css not found. Expected packages/tokens/dist/reset.css.",
|
|
9542
|
+
{ hint: "Run `npm run build -w packages/tokens` first." }
|
|
9543
|
+
);
|
|
9544
|
+
}
|
|
9236
9545
|
const fixtureName = options.fixture ?? "default";
|
|
9237
9546
|
const componentFixtures = FIXTURES[component];
|
|
9238
9547
|
const fixture = componentFixtures?.[fixtureName] ?? { props: "{}" };
|
|
@@ -9288,6 +9597,7 @@ async function renderCommand(component, cwd, options) {
|
|
|
9288
9597
|
}
|
|
9289
9598
|
const themeClass = `${options.theme}-theme`;
|
|
9290
9599
|
const html = buildHtml({
|
|
9600
|
+
resetCss: readFileSync33(resetCssFile, "utf-8"),
|
|
9291
9601
|
tokensCss: readFileSync33(tokensCssFile, "utf-8"),
|
|
9292
9602
|
themeCss: readFileSync33(themeCssFile, "utf-8"),
|
|
9293
9603
|
componentCss,
|