@signalcore/ui 1.0.0-beta.2 → 1.0.0-beta.4
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 +126 -21
- package/dist/AgentAbout.js +6 -2
- package/dist/AgentAbout.js.map +1 -1
- package/dist/AgentChat.d.ts +25 -3
- package/dist/AgentChat.js +302 -28
- package/dist/AgentChat.js.map +1 -1
- package/dist/AgentSpace.d.ts +25 -4
- package/dist/AgentSpace.js +55 -11
- package/dist/AgentSpace.js.map +1 -1
- package/dist/Threads.d.ts +73 -0
- package/dist/Threads.js +140 -0
- package/dist/Threads.js.map +1 -0
- package/dist/View.d.ts +48 -0
- package/dist/View.js +101 -0
- package/dist/View.js.map +1 -0
- package/dist/automation/marks.js +7 -3
- package/dist/automation/marks.js.map +1 -1
- package/dist/automation/messages.d.ts +4 -0
- package/dist/automation/messages.js +5 -1
- package/dist/automation/messages.js.map +1 -1
- package/dist/automation/when.js +8 -0
- package/dist/automation/when.js.map +1 -1
- package/dist/blocks.d.ts +83 -2
- package/dist/client.d.ts +23 -5
- package/dist/client.js +8 -2
- package/dist/client.js.map +1 -1
- package/dist/contract.d.ts +9 -4
- package/dist/es.d.ts +2 -0
- package/dist/es.js +34 -3
- package/dist/es.js.map +1 -1
- package/dist/frames.d.ts +7 -1
- package/dist/frames.js.map +1 -1
- package/dist/index.d.ts +14 -7
- package/dist/index.js +11 -4
- package/dist/kit/Agenda.d.ts +25 -0
- package/dist/kit/Agenda.js +119 -0
- package/dist/kit/Agenda.js.map +1 -0
- package/dist/kit/Combobox.js +1 -1
- package/dist/kit/DateField.js +1 -1
- package/dist/kit/Kanban.d.ts +17 -0
- package/dist/kit/Kanban.js +157 -0
- package/dist/kit/Kanban.js.map +1 -0
- package/dist/kit/TimeField.js +1 -1
- package/dist/kit/Timeline.d.ts +14 -0
- package/dist/kit/Timeline.js +71 -0
- package/dist/kit/Timeline.js.map +1 -0
- package/dist/kit/context.d.ts +1 -1
- package/dist/kit/context.js.map +1 -1
- package/dist/kit/messages.d.ts +22 -0
- package/dist/kit/messages.js +10 -0
- package/dist/kit/messages.js.map +1 -1
- package/dist/surface/Form.js +1 -1
- package/dist/surface/Placed.d.ts +20 -0
- package/dist/surface/Placed.js +70 -0
- package/dist/surface/Placed.js.map +1 -0
- package/dist/surface/Surface.d.ts +4 -2
- package/dist/surface/Surface.js +78 -2
- package/dist/surface/Surface.js.map +1 -1
- package/dist/surface/places.d.ts +16 -0
- package/dist/surface/places.js +15 -0
- package/dist/surface/places.js.map +1 -0
- package/dist/surface/scope.d.ts +17 -1
- package/dist/surface/scope.js +1 -0
- package/dist/surface/scope.js.map +1 -1
- package/dist/types.d.ts +23 -0
- package/dist/types.js.map +1 -1
- package/dist/useConversation.d.ts +2 -0
- package/dist/useConversation.js +16 -0
- package/dist/useConversation.js.map +1 -1
- package/dist/widget.js +17 -16
- package/package.json +1 -1
- package/src/AgentAbout.tsx +4 -0
- package/src/AgentChat.tsx +417 -34
- package/src/AgentSpace.tsx +106 -14
- package/src/Threads.tsx +218 -0
- package/src/View.tsx +117 -0
- package/src/automation/marks.tsx +7 -0
- package/src/automation/messages.ts +8 -0
- package/src/automation/when.ts +4 -0
- package/src/blocks.ts +100 -2
- package/src/client.ts +42 -10
- package/src/contract.ts +404 -29
- package/src/es.ts +30 -0
- package/src/frames.ts +3 -1
- package/src/index.ts +36 -3
- package/src/kit/Agenda.tsx +161 -0
- package/src/kit/Kanban.tsx +182 -0
- package/src/kit/Timeline.tsx +58 -0
- package/src/kit/context.tsx +45 -1
- package/src/kit/messages.ts +31 -0
- package/src/styles.css +825 -66
- package/src/surface/Placed.tsx +98 -0
- package/src/surface/Surface.tsx +92 -1
- package/src/surface/places.ts +19 -0
- package/src/surface/scope.ts +24 -1
- package/src/types.ts +24 -0
- package/src/useConversation.ts +10 -0
- package/src/widget/element.tsx +54 -7
- package/src/widget/widget.css +13 -0
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { useKit, useParts } from "./context.js";
|
|
2
|
+
import { TIME, dayOf, formatTime, isoDay, momentParts } from "./dates.js";
|
|
3
|
+
import { Fragment } from "react";
|
|
4
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
5
|
+
//#region src/kit/Agenda.tsx
|
|
6
|
+
/** The days a calendar shows from its first: a day's, or a week's. */
|
|
7
|
+
function daysOf(span, start) {
|
|
8
|
+
const first = dayOf(start);
|
|
9
|
+
if (!first) return [];
|
|
10
|
+
return Array.from({ length: span === "week" ? 7 : 1 }, (_, index) => {
|
|
11
|
+
const day = new Date(first);
|
|
12
|
+
day.setDate(first.getDate() + index);
|
|
13
|
+
return isoDay(day);
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
/** An event's hours as the language writes them: "10:00 – 11:00", one end, or none (a day). */
|
|
17
|
+
function hoursOf(event, code) {
|
|
18
|
+
const [day, from] = momentParts(event.start);
|
|
19
|
+
if (!TIME.test(from)) return null;
|
|
20
|
+
const [endDay, to] = momentParts(event.end ?? null);
|
|
21
|
+
const until = endDay === day && TIME.test(to) ? to : null;
|
|
22
|
+
return until === null ? formatTime(from, code) : `${formatTime(from, code)} – ${formatTime(until, code)}`;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* A day's events, or a week's, at their hours: each day under its weekday and number (today in
|
|
26
|
+
* the accent), its events in order, each with its hours (or "all day"), its title and a quiet
|
|
27
|
+
* line of detail. In a narrow place the days go one under another, an empty one a single quiet
|
|
28
|
+
* line; wide enough, the week stands as seven columns. An event with a page opens it apart;
|
|
29
|
+
* with `onEvent`, pressing one sends it.
|
|
30
|
+
*/
|
|
31
|
+
function Agenda({ span, start, events, onEvent, disabled = false, today = /* @__PURE__ */ new Date() }) {
|
|
32
|
+
const part = useParts();
|
|
33
|
+
const { code, messages } = useKit();
|
|
34
|
+
const now = isoDay(today);
|
|
35
|
+
const days = daysOf(span, start);
|
|
36
|
+
const weekday = new Intl.DateTimeFormat(code, { weekday: "short" });
|
|
37
|
+
const whole = new Intl.DateTimeFormat(code, {
|
|
38
|
+
weekday: "long",
|
|
39
|
+
day: "numeric",
|
|
40
|
+
month: "long"
|
|
41
|
+
});
|
|
42
|
+
return /* @__PURE__ */ jsx("div", {
|
|
43
|
+
part: "agenda",
|
|
44
|
+
className: part("sc-agenda", ...span === "day" ? ["sc-agenda--day"] : []),
|
|
45
|
+
children: /* @__PURE__ */ jsx("div", {
|
|
46
|
+
className: part("sc-agenda__days"),
|
|
47
|
+
children: days.map((day) => {
|
|
48
|
+
const date = dayOf(day) ?? today;
|
|
49
|
+
const own = events.filter((event) => event.start.slice(0, 10) === day);
|
|
50
|
+
return /* @__PURE__ */ jsxs("section", {
|
|
51
|
+
"aria-label": whole.format(date),
|
|
52
|
+
className: part("sc-agenda__day", ...day === now ? ["sc-agenda__day--today"] : [], ...own.length === 0 ? ["sc-agenda__day--empty"] : []),
|
|
53
|
+
children: [span === "week" && /* @__PURE__ */ jsxs("h4", {
|
|
54
|
+
"aria-hidden": true,
|
|
55
|
+
className: part("sc-agenda__date"),
|
|
56
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
57
|
+
className: part("sc-agenda__weekday"),
|
|
58
|
+
children: weekday.format(date)
|
|
59
|
+
}), /* @__PURE__ */ jsx("span", {
|
|
60
|
+
className: part("sc-agenda__number"),
|
|
61
|
+
children: date.getDate()
|
|
62
|
+
})]
|
|
63
|
+
}), own.length === 0 ? /* @__PURE__ */ jsx("p", {
|
|
64
|
+
className: part("sc-agenda__empty"),
|
|
65
|
+
children: messages.calendar.empty
|
|
66
|
+
}) : /* @__PURE__ */ jsx("ol", {
|
|
67
|
+
className: part("sc-agenda__events"),
|
|
68
|
+
children: own.map((event) => /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsxs(Event, {
|
|
69
|
+
event,
|
|
70
|
+
onEvent,
|
|
71
|
+
disabled,
|
|
72
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
73
|
+
className: part("sc-agenda__time"),
|
|
74
|
+
children: (hoursOf(event, code) ?? messages.calendar.allDay).split(" – ").map((end, index) => index === 0 ? /* @__PURE__ */ jsx("span", { children: end }, index) : /* @__PURE__ */ jsxs(Fragment, { children: [" ", /* @__PURE__ */ jsxs("span", { children: ["– ", end] })] }, index))
|
|
75
|
+
}), /* @__PURE__ */ jsxs("span", {
|
|
76
|
+
className: part("sc-agenda__what"),
|
|
77
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
78
|
+
className: part("sc-agenda__title"),
|
|
79
|
+
children: event.title
|
|
80
|
+
}), event.detail !== void 0 && /* @__PURE__ */ jsx("span", {
|
|
81
|
+
className: part("sc-agenda__detail"),
|
|
82
|
+
children: event.detail
|
|
83
|
+
})]
|
|
84
|
+
})]
|
|
85
|
+
}) }, event.id))
|
|
86
|
+
})]
|
|
87
|
+
}, day);
|
|
88
|
+
})
|
|
89
|
+
})
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
/** One event: a link to its page, a button that sends it, or just its words. */
|
|
93
|
+
function Event({ event, onEvent, disabled, children }) {
|
|
94
|
+
const className = useParts()("sc-agenda__event");
|
|
95
|
+
if (event.url !== void 0 && /^https:\/\//i.test(event.url)) return /* @__PURE__ */ jsx("a", {
|
|
96
|
+
className,
|
|
97
|
+
href: event.url,
|
|
98
|
+
target: "_blank",
|
|
99
|
+
rel: "noreferrer noopener",
|
|
100
|
+
children
|
|
101
|
+
});
|
|
102
|
+
if (onEvent !== void 0) return /* @__PURE__ */ jsx("button", {
|
|
103
|
+
type: "button",
|
|
104
|
+
className,
|
|
105
|
+
disabled,
|
|
106
|
+
onClick: () => {
|
|
107
|
+
onEvent(event);
|
|
108
|
+
},
|
|
109
|
+
children
|
|
110
|
+
});
|
|
111
|
+
return /* @__PURE__ */ jsx("div", {
|
|
112
|
+
className,
|
|
113
|
+
children
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
//#endregion
|
|
117
|
+
export { Agenda, daysOf, hoursOf };
|
|
118
|
+
|
|
119
|
+
//# sourceMappingURL=Agenda.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Agenda.js","names":[],"sources":["../../src/kit/Agenda.tsx"],"sourcesContent":["import { Fragment, type ReactNode } from \"react\";\n\nimport type { CalendarEvent } from \"../blocks\";\nimport { useKit, useParts } from \"./context\";\nimport { dayOf, formatTime, isoDay, momentParts, TIME } from \"./dates\";\n\n/** The days a calendar shows from its first: a day's, or a week's. */\nexport function daysOf(span: \"day\" | \"week\", start: string): string[] {\n const first = dayOf(start);\n if (!first) return [];\n return Array.from({ length: span === \"week\" ? 7 : 1 }, (_, index) => {\n const day = new Date(first);\n day.setDate(first.getDate() + index);\n return isoDay(day);\n });\n}\n\n/** An event's hours as the language writes them: \"10:00 – 11:00\", one end, or none (a day). */\nexport function hoursOf(event: CalendarEvent, code: string): string | null {\n const [day, from] = momentParts(event.start);\n if (!TIME.test(from)) return null;\n const [endDay, to] = momentParts(event.end ?? null);\n const until = endDay === day && TIME.test(to) ? to : null;\n return until === null\n ? formatTime(from, code)\n : `${formatTime(from, code)} – ${formatTime(until, code)}`;\n}\n\n/**\n * A day's events, or a week's, at their hours: each day under its weekday and number (today in\n * the accent), its events in order, each with its hours (or \"all day\"), its title and a quiet\n * line of detail. In a narrow place the days go one under another, an empty one a single quiet\n * line; wide enough, the week stands as seven columns. An event with a page opens it apart;\n * with `onEvent`, pressing one sends it.\n */\nexport function Agenda({\n span,\n start,\n events,\n onEvent,\n disabled = false,\n today = new Date(),\n}: {\n span: \"day\" | \"week\";\n /** The first day shown, \"YYYY-MM-DD\". */\n start: string;\n events: CalendarEvent[];\n onEvent?: ((event: CalendarEvent) => void) | undefined;\n disabled?: boolean | undefined;\n /** What counts as today; now by default. */\n today?: Date | undefined;\n}) {\n const part = useParts();\n const { code, messages } = useKit();\n const now = isoDay(today);\n const days = daysOf(span, start);\n const weekday = new Intl.DateTimeFormat(code, { weekday: \"short\" });\n const whole = new Intl.DateTimeFormat(code, { weekday: \"long\", day: \"numeric\", month: \"long\" });\n return (\n <div\n part=\"agenda\"\n className={part(\"sc-agenda\", ...(span === \"day\" ? ([\"sc-agenda--day\"] as const) : []))}\n >\n <div className={part(\"sc-agenda__days\")}>\n {days.map((day) => {\n const date = dayOf(day) ?? today;\n const own = events.filter((event) => event.start.slice(0, 10) === day);\n return (\n <section\n key={day}\n aria-label={whole.format(date)}\n className={part(\n \"sc-agenda__day\",\n ...(day === now ? ([\"sc-agenda__day--today\"] as const) : []),\n ...(own.length === 0 ? ([\"sc-agenda__day--empty\"] as const) : []),\n )}\n >\n {span === \"week\" && (\n <h4 aria-hidden className={part(\"sc-agenda__date\")}>\n <span className={part(\"sc-agenda__weekday\")}>{weekday.format(date)}</span>\n <span className={part(\"sc-agenda__number\")}>{date.getDate()}</span>\n </h4>\n )}\n {own.length === 0 ? (\n <p className={part(\"sc-agenda__empty\")}>{messages.calendar.empty}</p>\n ) : (\n <ol className={part(\"sc-agenda__events\")}>\n {own.map((event) => (\n <li key={event.id}>\n <Event event={event} onEvent={onEvent} disabled={disabled}>\n <span className={part(\"sc-agenda__time\")}>\n {(hoursOf(event, code) ?? messages.calendar.allDay)\n .split(\" – \")\n .map((end, index) =>\n // A range breaks before its dash, never inside a time (\"5:00 PM\").\n index === 0 ? (\n <span key={index}>{end}</span>\n ) : (\n <Fragment key={index}>\n {\" \"}\n <span>– {end}</span>\n </Fragment>\n ),\n )}\n </span>\n <span className={part(\"sc-agenda__what\")}>\n <span className={part(\"sc-agenda__title\")}>{event.title}</span>\n {event.detail !== undefined && (\n <span className={part(\"sc-agenda__detail\")}>{event.detail}</span>\n )}\n </span>\n </Event>\n </li>\n ))}\n </ol>\n )}\n </section>\n );\n })}\n </div>\n </div>\n );\n}\n\n/** One event: a link to its page, a button that sends it, or just its words. */\nfunction Event({\n event,\n onEvent,\n disabled,\n children,\n}: {\n event: CalendarEvent;\n onEvent: ((event: CalendarEvent) => void) | undefined;\n disabled: boolean;\n children: ReactNode;\n}) {\n const part = useParts();\n const className = part(\"sc-agenda__event\");\n if (event.url !== undefined && /^https:\\/\\//i.test(event.url)) {\n return (\n <a className={className} href={event.url} target=\"_blank\" rel=\"noreferrer noopener\">\n {children}\n </a>\n );\n }\n if (onEvent !== undefined) {\n return (\n <button\n type=\"button\"\n className={className}\n disabled={disabled}\n onClick={() => {\n onEvent(event);\n }}\n >\n {children}\n </button>\n );\n }\n return <div className={className}>{children}</div>;\n}\n"],"mappings":"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"}
|
package/dist/kit/Combobox.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { useKit, useParts } from "./context.js";
|
|
2
2
|
import { ariaOf } from "./Field.js";
|
|
3
|
-
import { matches } from "./options.js";
|
|
4
3
|
import { Popover, usePopover } from "./Popover.js";
|
|
4
|
+
import { matches } from "./options.js";
|
|
5
5
|
import { useId, useLayoutEffect, useRef, useState } from "react";
|
|
6
6
|
import { CaretUpDownIcon, CheckIcon, XIcon } from "@phosphor-icons/react";
|
|
7
7
|
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
|
package/dist/kit/DateField.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { useKit, useParts } from "./context.js";
|
|
2
2
|
import { ariaOf } from "./Field.js";
|
|
3
|
-
import { Popover, usePopover } from "./Popover.js";
|
|
4
3
|
import { dayAllowed, dayOf, daySpan, formatDay, isoDay, openingDay } from "./dates.js";
|
|
4
|
+
import { Popover, usePopover } from "./Popover.js";
|
|
5
5
|
import { useState } from "react";
|
|
6
6
|
import { CalendarBlankIcon, CaretDownIcon, CaretLeftIcon, CaretRightIcon } from "@phosphor-icons/react";
|
|
7
7
|
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { BoardCard, BoardColumn } from "../blocks.js";
|
|
2
|
+
//#region src/kit/Kanban.d.ts
|
|
3
|
+
/** The columns with each card where the person last put it (`moved`, card id to column id). */
|
|
4
|
+
export declare function placed(columns: readonly BoardColumn[], moved: Readonly<Record<string, string>>): BoardColumn[];
|
|
5
|
+
/**
|
|
6
|
+
* Cards in columns, a column per stage, side by side, scrolling across when they don't fit: each
|
|
7
|
+
* column's title and how many it holds over its cards (a title, a quieter line, a detail at its
|
|
8
|
+
* foot). With `onMove`, the person moves a card to another column by dragging it there, or from
|
|
9
|
+
* its button's list of the other columns (the keyboard's way); the card goes there at once.
|
|
10
|
+
*/
|
|
11
|
+
export declare function Kanban({ columns, onMove, disabled }: {
|
|
12
|
+
columns: BoardColumn[];
|
|
13
|
+
onMove?: ((card: BoardCard, column: BoardColumn) => void) | undefined;
|
|
14
|
+
disabled?: boolean | undefined;
|
|
15
|
+
}): import("react").JSX.Element;
|
|
16
|
+
//#endregion
|
|
17
|
+
//# sourceMappingURL=Kanban.d.ts.map
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
import { useKit, useParts } from "./context.js";
|
|
2
|
+
import { Popover, usePopover } from "./Popover.js";
|
|
3
|
+
import { useState } from "react";
|
|
4
|
+
import { ArrowsLeftRightIcon } from "@phosphor-icons/react";
|
|
5
|
+
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
|
|
6
|
+
//#region src/kit/Kanban.tsx
|
|
7
|
+
/** What a dragged card carries, so a drop elsewhere on the page takes nothing of it. */
|
|
8
|
+
const CARD = "application/x-signalcore-card";
|
|
9
|
+
/** The columns with each card where the person last put it (`moved`, card id to column id). */
|
|
10
|
+
function placed(columns, moved) {
|
|
11
|
+
const cards = columns.flatMap((column) => column.cards.map((card) => ({
|
|
12
|
+
card,
|
|
13
|
+
column: moved[card.id] ?? column.id
|
|
14
|
+
})));
|
|
15
|
+
return columns.map((column) => ({
|
|
16
|
+
...column,
|
|
17
|
+
cards: cards.filter((each) => each.column === column.id).map((each) => each.card)
|
|
18
|
+
}));
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Cards in columns, a column per stage, side by side, scrolling across when they don't fit: each
|
|
22
|
+
* column's title and how many it holds over its cards (a title, a quieter line, a detail at its
|
|
23
|
+
* foot). With `onMove`, the person moves a card to another column by dragging it there, or from
|
|
24
|
+
* its button's list of the other columns (the keyboard's way); the card goes there at once.
|
|
25
|
+
*/
|
|
26
|
+
function Kanban({ columns, onMove, disabled = false }) {
|
|
27
|
+
const part = useParts();
|
|
28
|
+
const { messages } = useKit();
|
|
29
|
+
const [moved, setMoved] = useState({});
|
|
30
|
+
const [dragging, setDragging] = useState(null);
|
|
31
|
+
const [over, setOver] = useState(null);
|
|
32
|
+
const movable = onMove !== void 0 && !disabled;
|
|
33
|
+
const shown = placed(columns, moved);
|
|
34
|
+
const move = (card, to) => {
|
|
35
|
+
const from = shown.find((column) => column.cards.some((each) => each.id === card.id));
|
|
36
|
+
if (!onMove || from?.id === to.id) return;
|
|
37
|
+
setMoved((before) => ({
|
|
38
|
+
...before,
|
|
39
|
+
[card.id]: to.id
|
|
40
|
+
}));
|
|
41
|
+
onMove(card, to);
|
|
42
|
+
};
|
|
43
|
+
const dropOn = (column) => (event) => {
|
|
44
|
+
event.preventDefault();
|
|
45
|
+
setOver(null);
|
|
46
|
+
setDragging(null);
|
|
47
|
+
const id = event.dataTransfer.getData(CARD);
|
|
48
|
+
const card = columns.flatMap((each) => each.cards).find((each) => each.id === id);
|
|
49
|
+
if (card) move(card, column);
|
|
50
|
+
};
|
|
51
|
+
return /* @__PURE__ */ jsx("div", {
|
|
52
|
+
part: "board",
|
|
53
|
+
className: part("sc-board"),
|
|
54
|
+
children: shown.map((column) => /* @__PURE__ */ jsxs("section", {
|
|
55
|
+
"aria-label": column.title,
|
|
56
|
+
className: part("sc-board__column", ...over === column.id ? ["sc-board__column--over"] : []),
|
|
57
|
+
onDragOver: (event) => {
|
|
58
|
+
if (!movable || dragging === null) return;
|
|
59
|
+
event.preventDefault();
|
|
60
|
+
event.dataTransfer.dropEffect = "move";
|
|
61
|
+
setOver(column.id);
|
|
62
|
+
},
|
|
63
|
+
onDragLeave: (event) => {
|
|
64
|
+
const to = event.relatedTarget;
|
|
65
|
+
if (!(to instanceof Node && event.currentTarget.contains(to))) setOver(null);
|
|
66
|
+
},
|
|
67
|
+
onDrop: movable ? dropOn(column) : void 0,
|
|
68
|
+
children: [/* @__PURE__ */ jsxs("h4", {
|
|
69
|
+
className: part("sc-board__head"),
|
|
70
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
71
|
+
className: part("sc-board__title"),
|
|
72
|
+
children: column.title
|
|
73
|
+
}), /* @__PURE__ */ jsx("span", {
|
|
74
|
+
className: part("sc-board__count"),
|
|
75
|
+
children: column.cards.length
|
|
76
|
+
})]
|
|
77
|
+
}), column.cards.length === 0 ? /* @__PURE__ */ jsx("p", {
|
|
78
|
+
className: part("sc-board__empty"),
|
|
79
|
+
children: messages.board.empty
|
|
80
|
+
}) : /* @__PURE__ */ jsx("ul", {
|
|
81
|
+
className: part("sc-board__cards"),
|
|
82
|
+
children: column.cards.map((card) => /* @__PURE__ */ jsxs("li", {
|
|
83
|
+
draggable: movable,
|
|
84
|
+
onDragStart: (event) => {
|
|
85
|
+
event.dataTransfer.setData(CARD, card.id);
|
|
86
|
+
event.dataTransfer.effectAllowed = "move";
|
|
87
|
+
setDragging(card.id);
|
|
88
|
+
},
|
|
89
|
+
onDragEnd: () => {
|
|
90
|
+
setDragging(null);
|
|
91
|
+
setOver(null);
|
|
92
|
+
},
|
|
93
|
+
className: part("sc-board__card", ...dragging === card.id ? ["sc-board__card--dragging"] : []),
|
|
94
|
+
children: [
|
|
95
|
+
/* @__PURE__ */ jsx("span", {
|
|
96
|
+
className: part("sc-board__card-title"),
|
|
97
|
+
children: card.title
|
|
98
|
+
}),
|
|
99
|
+
card.subtitle !== void 0 && /* @__PURE__ */ jsx("span", {
|
|
100
|
+
className: part("sc-board__card-subtitle"),
|
|
101
|
+
children: card.subtitle
|
|
102
|
+
}),
|
|
103
|
+
card.meta !== void 0 && /* @__PURE__ */ jsx("span", {
|
|
104
|
+
className: part("sc-board__card-meta"),
|
|
105
|
+
children: card.meta
|
|
106
|
+
}),
|
|
107
|
+
movable && /* @__PURE__ */ jsx(Move, {
|
|
108
|
+
card,
|
|
109
|
+
to: shown.filter((other) => other.id !== column.id),
|
|
110
|
+
onMove: move
|
|
111
|
+
})
|
|
112
|
+
]
|
|
113
|
+
}, card.id))
|
|
114
|
+
})]
|
|
115
|
+
}, column.id))
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
/** A card's button that opens the other columns, to move it to one of them. */
|
|
119
|
+
function Move({ card, to, onMove }) {
|
|
120
|
+
const part = useParts();
|
|
121
|
+
const { messages } = useKit();
|
|
122
|
+
const [open, setOpen] = useState(false);
|
|
123
|
+
const popover = usePopover(open, setOpen, {
|
|
124
|
+
width: "own",
|
|
125
|
+
role: "dialog"
|
|
126
|
+
});
|
|
127
|
+
return /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx("button", {
|
|
128
|
+
ref: popover.refs.setReference,
|
|
129
|
+
type: "button",
|
|
130
|
+
"aria-label": messages.board.move(card.title),
|
|
131
|
+
title: messages.board.move(card.title),
|
|
132
|
+
"aria-expanded": open,
|
|
133
|
+
className: part("sc-board__move"),
|
|
134
|
+
...popover.getReferenceProps({ onClick: () => setOpen(!open) }),
|
|
135
|
+
children: /* @__PURE__ */ jsx(ArrowsLeftRightIcon, { "aria-hidden": true })
|
|
136
|
+
}), open && /* @__PURE__ */ jsx(Popover, {
|
|
137
|
+
popover,
|
|
138
|
+
focus: true,
|
|
139
|
+
label: messages.board.moveTo,
|
|
140
|
+
children: /* @__PURE__ */ jsxs("div", {
|
|
141
|
+
className: part("sc-board__menu"),
|
|
142
|
+
children: [/* @__PURE__ */ jsx("p", { children: messages.board.moveTo }), to.map((column) => /* @__PURE__ */ jsx("button", {
|
|
143
|
+
type: "button",
|
|
144
|
+
className: part("sc-listbox__item"),
|
|
145
|
+
onClick: () => {
|
|
146
|
+
setOpen(false);
|
|
147
|
+
onMove(card, column);
|
|
148
|
+
},
|
|
149
|
+
children: column.title
|
|
150
|
+
}, column.id))]
|
|
151
|
+
})
|
|
152
|
+
})] });
|
|
153
|
+
}
|
|
154
|
+
//#endregion
|
|
155
|
+
export { Kanban, placed };
|
|
156
|
+
|
|
157
|
+
//# sourceMappingURL=Kanban.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Kanban.js","names":[],"sources":["../../src/kit/Kanban.tsx"],"sourcesContent":["import { ArrowsLeftRightIcon } from \"@phosphor-icons/react\";\nimport { useState, type DragEvent } from \"react\";\n\nimport type { BoardCard, BoardColumn } from \"../blocks\";\nimport { useKit, useParts } from \"./context\";\nimport { Popover, usePopover } from \"./Popover\";\n\n/** What a dragged card carries, so a drop elsewhere on the page takes nothing of it. */\nconst CARD = \"application/x-signalcore-card\";\n\n/** The columns with each card where the person last put it (`moved`, card id to column id). */\nexport function placed(\n columns: readonly BoardColumn[],\n moved: Readonly<Record<string, string>>,\n): BoardColumn[] {\n const cards = columns.flatMap((column) =>\n column.cards.map((card) => ({ card, column: moved[card.id] ?? column.id })),\n );\n return columns.map((column) => ({\n ...column,\n cards: cards.filter((each) => each.column === column.id).map((each) => each.card),\n }));\n}\n\n/**\n * Cards in columns, a column per stage, side by side, scrolling across when they don't fit: each\n * column's title and how many it holds over its cards (a title, a quieter line, a detail at its\n * foot). With `onMove`, the person moves a card to another column by dragging it there, or from\n * its button's list of the other columns (the keyboard's way); the card goes there at once.\n */\nexport function Kanban({\n columns,\n onMove,\n disabled = false,\n}: {\n columns: BoardColumn[];\n onMove?: ((card: BoardCard, column: BoardColumn) => void) | undefined;\n disabled?: boolean | undefined;\n}) {\n const part = useParts();\n const { messages } = useKit();\n const [moved, setMoved] = useState<Record<string, string>>({});\n const [dragging, setDragging] = useState<string | null>(null);\n const [over, setOver] = useState<string | null>(null);\n const movable = onMove !== undefined && !disabled;\n const shown = placed(columns, moved);\n const move = (card: BoardCard, to: BoardColumn) => {\n const from = shown.find((column) => column.cards.some((each) => each.id === card.id));\n if (!onMove || from?.id === to.id) return;\n setMoved((before) => ({ ...before, [card.id]: to.id }));\n onMove(card, to);\n };\n const dropOn = (column: BoardColumn) => (event: DragEvent) => {\n event.preventDefault();\n setOver(null);\n setDragging(null);\n const id = event.dataTransfer.getData(CARD);\n const card = columns.flatMap((each) => each.cards).find((each) => each.id === id);\n if (card) move(card, column);\n };\n return (\n <div part=\"board\" className={part(\"sc-board\")}>\n {shown.map((column) => (\n <section\n key={column.id}\n aria-label={column.title}\n className={part(\n \"sc-board__column\",\n ...(over === column.id ? ([\"sc-board__column--over\"] as const) : []),\n )}\n onDragOver={(event) => {\n if (!movable || dragging === null) return;\n event.preventDefault();\n event.dataTransfer.dropEffect = \"move\";\n setOver(column.id);\n }}\n onDragLeave={(event) => {\n const to = event.relatedTarget;\n if (!(to instanceof Node && event.currentTarget.contains(to))) setOver(null);\n }}\n onDrop={movable ? dropOn(column) : undefined}\n >\n <h4 className={part(\"sc-board__head\")}>\n <span className={part(\"sc-board__title\")}>{column.title}</span>\n <span className={part(\"sc-board__count\")}>{column.cards.length}</span>\n </h4>\n {column.cards.length === 0 ? (\n <p className={part(\"sc-board__empty\")}>{messages.board.empty}</p>\n ) : (\n <ul className={part(\"sc-board__cards\")}>\n {column.cards.map((card) => (\n <li\n key={card.id}\n draggable={movable}\n onDragStart={(event) => {\n event.dataTransfer.setData(CARD, card.id);\n event.dataTransfer.effectAllowed = \"move\";\n setDragging(card.id);\n }}\n onDragEnd={() => {\n setDragging(null);\n setOver(null);\n }}\n className={part(\n \"sc-board__card\",\n ...(dragging === card.id ? ([\"sc-board__card--dragging\"] as const) : []),\n )}\n >\n <span className={part(\"sc-board__card-title\")}>{card.title}</span>\n {card.subtitle !== undefined && (\n <span className={part(\"sc-board__card-subtitle\")}>{card.subtitle}</span>\n )}\n {card.meta !== undefined && (\n <span className={part(\"sc-board__card-meta\")}>{card.meta}</span>\n )}\n {movable && (\n <Move\n card={card}\n to={shown.filter((other) => other.id !== column.id)}\n onMove={move}\n />\n )}\n </li>\n ))}\n </ul>\n )}\n </section>\n ))}\n </div>\n );\n}\n\n/** A card's button that opens the other columns, to move it to one of them. */\nfunction Move({\n card,\n to,\n onMove,\n}: {\n card: BoardCard;\n to: BoardColumn[];\n onMove: (card: BoardCard, column: BoardColumn) => void;\n}) {\n const part = useParts();\n const { messages } = useKit();\n const [open, setOpen] = useState(false);\n const popover = usePopover(open, setOpen, { width: \"own\", role: \"dialog\" });\n return (\n <>\n <button\n ref={popover.refs.setReference}\n type=\"button\"\n aria-label={messages.board.move(card.title)}\n title={messages.board.move(card.title)}\n aria-expanded={open}\n className={part(\"sc-board__move\")}\n {...popover.getReferenceProps({ onClick: () => setOpen(!open) })}\n >\n <ArrowsLeftRightIcon aria-hidden />\n </button>\n {open && (\n <Popover popover={popover} focus label={messages.board.moveTo}>\n <div className={part(\"sc-board__menu\")}>\n <p>{messages.board.moveTo}</p>\n {to.map((column) => (\n <button\n key={column.id}\n type=\"button\"\n className={part(\"sc-listbox__item\")}\n onClick={() => {\n setOpen(false);\n onMove(card, column);\n }}\n >\n {column.title}\n </button>\n ))}\n </div>\n </Popover>\n )}\n </>\n );\n}\n"],"mappings":"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"}
|
package/dist/kit/TimeField.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { useKit, useParts } from "./context.js";
|
|
2
2
|
import { ariaOf } from "./Field.js";
|
|
3
|
+
import { DAY_END, formatTime, halfHours, momentOf, momentParts, parseEndTime, parseTime } from "./dates.js";
|
|
3
4
|
import { useRadios } from "./Choices.js";
|
|
4
5
|
import { Combobox } from "./Combobox.js";
|
|
5
|
-
import { DAY_END, formatTime, halfHours, momentOf, momentParts, parseEndTime, parseTime } from "./dates.js";
|
|
6
6
|
import { DateField } from "./DateField.js";
|
|
7
7
|
import { ClockIcon } from "@phosphor-icons/react";
|
|
8
8
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { TimelineItem } from "../blocks.js";
|
|
2
|
+
//#region src/kit/Timeline.d.ts
|
|
3
|
+
/** When a timeline's item was, short: "20 oct, 16:00"; its year when not this one's. */
|
|
4
|
+
export declare function formatWhen(at: string, code: string, today?: Date): string;
|
|
5
|
+
/**
|
|
6
|
+
* Dated things, one under another along a hairline, the newest first: each a dot on the line (in
|
|
7
|
+
* its tone, when it has one), its title with where it stands in a quiet word at its right, when
|
|
8
|
+
* it was under it, and a line about it.
|
|
9
|
+
*/
|
|
10
|
+
export declare function Timeline({ items }: {
|
|
11
|
+
items: TimelineItem[];
|
|
12
|
+
}): import("react").JSX.Element;
|
|
13
|
+
//#endregion
|
|
14
|
+
//# sourceMappingURL=Timeline.d.ts.map
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { useKit, useParts } from "./context.js";
|
|
2
|
+
import { TIME, dayOf, momentParts } from "./dates.js";
|
|
3
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
4
|
+
//#region src/kit/Timeline.tsx
|
|
5
|
+
/** When a timeline's item was, short: "20 oct, 16:00"; its year when not this one's. */
|
|
6
|
+
function formatWhen(at, code, today = /* @__PURE__ */ new Date()) {
|
|
7
|
+
const [date, time] = momentParts(at);
|
|
8
|
+
const day = dayOf(date);
|
|
9
|
+
if (!day) return at;
|
|
10
|
+
const timed = TIME.test(time);
|
|
11
|
+
if (timed) {
|
|
12
|
+
const [hours = 0, minutes = 0] = time.split(":").map(Number);
|
|
13
|
+
day.setHours(hours, minutes);
|
|
14
|
+
}
|
|
15
|
+
return new Intl.DateTimeFormat(code, {
|
|
16
|
+
day: "numeric",
|
|
17
|
+
month: "short",
|
|
18
|
+
...day.getFullYear() !== today.getFullYear() && { year: "numeric" },
|
|
19
|
+
...timed && {
|
|
20
|
+
hour: "numeric",
|
|
21
|
+
minute: "2-digit"
|
|
22
|
+
}
|
|
23
|
+
}).format(day);
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Dated things, one under another along a hairline, the newest first: each a dot on the line (in
|
|
27
|
+
* its tone, when it has one), its title with where it stands in a quiet word at its right, when
|
|
28
|
+
* it was under it, and a line about it.
|
|
29
|
+
*/
|
|
30
|
+
function Timeline({ items }) {
|
|
31
|
+
const part = useParts();
|
|
32
|
+
const { code } = useKit();
|
|
33
|
+
return /* @__PURE__ */ jsx("ol", {
|
|
34
|
+
part: "timeline",
|
|
35
|
+
className: part("sc-timeline"),
|
|
36
|
+
children: items.map((item, index) => /* @__PURE__ */ jsxs("li", {
|
|
37
|
+
className: part("sc-timeline__item", ...item.tone ? [`sc-timeline__item--${item.tone}`] : []),
|
|
38
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
39
|
+
"aria-hidden": true,
|
|
40
|
+
className: part("sc-timeline__dot")
|
|
41
|
+
}), /* @__PURE__ */ jsxs("div", {
|
|
42
|
+
className: part("sc-timeline__body"),
|
|
43
|
+
children: [
|
|
44
|
+
/* @__PURE__ */ jsxs("p", {
|
|
45
|
+
className: part("sc-timeline__head"),
|
|
46
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
47
|
+
className: part("sc-timeline__title"),
|
|
48
|
+
children: item.title
|
|
49
|
+
}), item.status !== void 0 && /* @__PURE__ */ jsx("span", {
|
|
50
|
+
className: part("sc-timeline__status"),
|
|
51
|
+
children: item.status
|
|
52
|
+
})]
|
|
53
|
+
}),
|
|
54
|
+
/* @__PURE__ */ jsx("time", {
|
|
55
|
+
dateTime: item.at,
|
|
56
|
+
className: part("sc-timeline__when"),
|
|
57
|
+
children: formatWhen(item.at, code)
|
|
58
|
+
}),
|
|
59
|
+
item.text !== void 0 && /* @__PURE__ */ jsx("p", {
|
|
60
|
+
className: part("sc-timeline__text"),
|
|
61
|
+
children: item.text
|
|
62
|
+
})
|
|
63
|
+
]
|
|
64
|
+
})]
|
|
65
|
+
}, item.id ?? index))
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
//#endregion
|
|
69
|
+
export { Timeline, formatWhen };
|
|
70
|
+
|
|
71
|
+
//# sourceMappingURL=Timeline.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Timeline.js","names":[],"sources":["../../src/kit/Timeline.tsx"],"sourcesContent":["import type { TimelineItem } from \"../blocks\";\nimport { useKit, useParts } from \"./context\";\nimport { dayOf, momentParts, TIME } from \"./dates\";\n\n/** When a timeline's item was, short: \"20 oct, 16:00\"; its year when not this one's. */\nexport function formatWhen(at: string, code: string, today: Date = new Date()): string {\n const [date, time] = momentParts(at);\n const day = dayOf(date);\n if (!day) return at;\n const timed = TIME.test(time);\n if (timed) {\n const [hours = 0, minutes = 0] = time.split(\":\").map(Number);\n day.setHours(hours, minutes);\n }\n return new Intl.DateTimeFormat(code, {\n day: \"numeric\",\n month: \"short\",\n ...(day.getFullYear() !== today.getFullYear() && { year: \"numeric\" }),\n ...(timed && { hour: \"numeric\", minute: \"2-digit\" }),\n }).format(day);\n}\n\n/**\n * Dated things, one under another along a hairline, the newest first: each a dot on the line (in\n * its tone, when it has one), its title with where it stands in a quiet word at its right, when\n * it was under it, and a line about it.\n */\nexport function Timeline({ items }: { items: TimelineItem[] }) {\n const part = useParts();\n const { code } = useKit();\n return (\n <ol part=\"timeline\" className={part(\"sc-timeline\")}>\n {items.map((item, index) => (\n <li\n key={item.id ?? index}\n className={part(\n \"sc-timeline__item\",\n ...(item.tone ? ([`sc-timeline__item--${item.tone}`] as const) : []),\n )}\n >\n <span aria-hidden className={part(\"sc-timeline__dot\")} />\n <div className={part(\"sc-timeline__body\")}>\n <p className={part(\"sc-timeline__head\")}>\n <span className={part(\"sc-timeline__title\")}>{item.title}</span>\n {item.status !== undefined && (\n <span className={part(\"sc-timeline__status\")}>{item.status}</span>\n )}\n </p>\n <time dateTime={item.at} className={part(\"sc-timeline__when\")}>\n {formatWhen(item.at, code)}\n </time>\n {item.text !== undefined && <p className={part(\"sc-timeline__text\")}>{item.text}</p>}\n </div>\n </li>\n ))}\n </ol>\n );\n}\n"],"mappings":";;;;;AAKA,SAAgB,WAAW,IAAY,MAAc,wBAAc,IAAI,KAAK,GAAW;CACrF,MAAM,CAAC,MAAM,QAAQ,YAAY,EAAE;CACnC,MAAM,MAAM,MAAM,IAAI;CACtB,IAAI,CAAC,KAAK,OAAO;CACjB,MAAM,QAAQ,KAAK,KAAK,IAAI;CAC5B,IAAI,OAAO;EACT,MAAM,CAAC,QAAQ,GAAG,UAAU,KAAK,KAAK,MAAM,GAAG,CAAC,CAAC,IAAI,MAAM;EAC3D,IAAI,SAAS,OAAO,OAAO;CAC7B;CACA,OAAO,IAAI,KAAK,eAAe,MAAM;EACnC,KAAK;EACL,OAAO;EACP,GAAI,IAAI,YAAY,MAAM,MAAM,YAAY,KAAK,EAAE,MAAM,UAAU;EACnE,GAAI,SAAS;GAAE,MAAM;GAAW,QAAQ;EAAU;CACpD,CAAC,CAAC,CAAC,OAAO,GAAG;AACf;;;;;;AAOA,SAAgB,SAAS,EAAE,SAAoC;CAC7D,MAAM,OAAO,SAAS;CACtB,MAAM,EAAE,SAAS,OAAO;CACxB,OACE,oBAAC,MAAD;EAAI,MAAK;EAAW,WAAW,KAAK,aAAa;EAC9C,UAAA,MAAM,KAAK,MAAM,UAChB,qBAAC,MAAD;GAEE,WAAW,KACT,qBACA,GAAI,KAAK,OAAQ,CAAC,sBAAsB,KAAK,MAAM,IAAc,CAAC,CACpE;GALF,UAAA,CAOE,oBAAC,QAAD;IAAM,eAAA;IAAY,WAAW,KAAK,kBAAkB;GAAI,CAAA,GACxD,qBAAC,OAAD;IAAK,WAAW,KAAK,mBAAmB;IAAxC,UAAA;KACE,qBAAC,KAAD;MAAG,WAAW,KAAK,mBAAmB;MAAtC,UAAA,CACE,oBAAC,QAAD;OAAM,WAAW,KAAK,oBAAoB;OAAI,UAAA,KAAK;MAAY,CAAA,GAC9D,KAAK,WAAW,KAAA,KACf,oBAAC,QAAD;OAAM,WAAW,KAAK,qBAAqB;OAAI,UAAA,KAAK;MAAa,CAAA,CAElE;;KACH,oBAAC,QAAD;MAAM,UAAU,KAAK;MAAI,WAAW,KAAK,mBAAmB;MACzD,UAAA,WAAW,KAAK,IAAI,IAAI;KACrB,CAAA;KACL,KAAK,SAAS,KAAA,KAAa,oBAAC,KAAD;MAAG,WAAW,KAAK,mBAAmB;MAAI,UAAA,KAAK;KAAQ,CAAA;IAChF;GACH,CAAA,CAAA;EAnBG,GAAA,KAAK,MAAM,KAmBd,CACL;CACC,CAAA;AAER"}
|
package/dist/kit/context.d.ts
CHANGED
|
@@ -6,7 +6,7 @@ import { ReactNode } from "react";
|
|
|
6
6
|
* host's own under the same keys, so a host styles every place a primitive appears at once.
|
|
7
7
|
* (`sc-card` is the Ficha's; the kit's card is `sc-panel`.)
|
|
8
8
|
*/
|
|
9
|
-
export type KitPart = "sc-panel" | "sc-panel__head" | "sc-panel__head--image" | "sc-panel__heading" | "sc-panel__title" | "sc-panel__subtitle" | "sc-list" | "sc-row" | "sc-row--quiet" | "sc-row--pressed" | "sc-row__main" | "sc-row__text" | "sc-row__title" | "sc-row__subtitle" | "sc-row__error" | "sc-row__meta" | "sc-row__trailing" | "sc-mark" | "sc-mark--logo" | "sc-mark--photo" | "sc-mark--round" | "sc-tiles" | "sc-tiles__grid" | "sc-tile" | "sc-tile--quiet" | "sc-tile__main" | "sc-tile__count" | "sc-tile__title" | "sc-stack" | "sc-stack__item" | "sc-stack__more" | "sc-tag" | "sc-tag--info" | "sc-tag--success" | "sc-tag--warning" | "sc-tag--danger" | "sc-stat" | "sc-stat--info" | "sc-stat--success" | "sc-stat--warning" | "sc-stat--danger" | "sc-stat__label" | "sc-stat__value" | "sc-stat__hint" | "sc-stats" | "sc-stats__grid" | "sc-chart" | "sc-chart--bar" | "sc-chart--line" | "sc-chart__row" | "sc-chart__label" | "sc-chart__track" | "sc-chart__bar" | "sc-chart__value" | "sc-chart__top" | "sc-chart__plot" | "sc-chart__wash" | "sc-chart__axis" | "sc-chart__line" | "sc-chart__dot" | "sc-chart__tip" | "sc-chart__ends" | "sc-chart__data" | "sc-note" | "sc-note--info" | "sc-note--success" | "sc-note--warning" | "sc-note--danger" | "sc-note__body" | "sc-button" | "sc-button--primary" | "sc-button--neutral" | "sc-button--danger" | "sc-button--ghost" | "sc-button--sm" | "sc-button--icon" | "sc-switch" | "sc-audio" | "sc-audio--compact" | "sc-audio__play" | "sc-audio__wave" | "sc-audio__time" | "sc-field" | "sc-field__label" | "sc-field__optional" | "sc-field__help" | "sc-field__error" | "sc-control" | "sc-control--trigger" | "sc-control__input" | "sc-control__unit" | "sc-control__steppers" | "sc-control__reveal" | "sc-control__tag" | "sc-check" | "sc-popover" | "sc-listbox" | "sc-listbox__item" | "sc-listbox__empty" | "sc-calendar" | "sc-picks" | "sc-segments" | "sc-pick" | "sc-chips" | "sc-chip" | "sc-slots" | "sc-moment" | "sc-range" | "sc-rating" | "sc-upload" | "sc-upload__zone" | "sc-upload__icon" | "sc-upload__text" | "sc-attachments" | "sc-attachment" | "sc-attachment--failed" | "sc-attachment__main" | "sc-attachment__text" | "sc-attachment__name" | "sc-attachment__meta" | "sc-attachment__action" | "sc-attachment__bar" | "sc-orb" | "sc-orb--idle" | "sc-orb--listening" | "sc-orb--thinking" | "sc-orb--speaking" | "sc-orb--still" | "sc-orb--loading" | "sc-orb__ring" | "sc-orb__core" | "sc-automation" | "sc-automation--gone" | "sc-automation__head" | "sc-automation__heading" | "sc-automation__title" | "sc-automation__when" | "sc-automation__end" | "sc-automation__dot" | "sc-automation__summary" | "sc-automation__section" | "sc-automation__label" | "sc-automation__steps" | "sc-automation__step" | "sc-automation__number" | "sc-automation__name" | "sc-automation__uses" | "sc-automation__use" | "sc-automation__board" | "sc-automation__more" | "sc-automation__runs" | "sc-automation__run--open" | "sc-automation__status" | "sc-automation__empty" | "sc-run" | "sc-run__head" | "sc-run__by" | "sc-run__end" | "sc-run__took" | "sc-run__heading" | "sc-run__title" | "sc-run__meta" | "sc-run__summary" | "sc-run__section" | "sc-run__label" | "sc-run__steps" | "sc-run__step" | "sc-run__number" | "sc-run__name" | "sc-run__calls" | "sc-run__call" | "sc-run__call--would" | "sc-run__call--failed" | "sc-run__count" | "sc-run__error" | "sc-run__live" | "sc-run__links" | "sc-run__empty";
|
|
9
|
+
export type KitPart = "sc-panel" | "sc-panel__head" | "sc-panel__head--image" | "sc-panel__heading" | "sc-panel__title" | "sc-panel__subtitle" | "sc-list" | "sc-row" | "sc-row--quiet" | "sc-row--pressed" | "sc-row__main" | "sc-row__text" | "sc-row__title" | "sc-row__subtitle" | "sc-row__error" | "sc-row__meta" | "sc-row__trailing" | "sc-mark" | "sc-mark--logo" | "sc-mark--photo" | "sc-mark--round" | "sc-tiles" | "sc-tiles__grid" | "sc-tile" | "sc-tile--quiet" | "sc-tile__main" | "sc-tile__count" | "sc-tile__title" | "sc-stack" | "sc-stack__item" | "sc-stack__more" | "sc-tag" | "sc-tag--info" | "sc-tag--success" | "sc-tag--warning" | "sc-tag--danger" | "sc-stat" | "sc-stat--info" | "sc-stat--success" | "sc-stat--warning" | "sc-stat--danger" | "sc-stat__label" | "sc-stat__value" | "sc-stat__hint" | "sc-stats" | "sc-stats__grid" | "sc-chart" | "sc-chart--bar" | "sc-chart--line" | "sc-chart__row" | "sc-chart__label" | "sc-chart__track" | "sc-chart__bar" | "sc-chart__value" | "sc-chart__top" | "sc-chart__plot" | "sc-chart__wash" | "sc-chart__axis" | "sc-chart__line" | "sc-chart__dot" | "sc-chart__tip" | "sc-chart__ends" | "sc-chart__data" | "sc-note" | "sc-note--info" | "sc-note--success" | "sc-note--warning" | "sc-note--danger" | "sc-note__body" | "sc-button" | "sc-button--primary" | "sc-button--neutral" | "sc-button--danger" | "sc-button--ghost" | "sc-button--sm" | "sc-button--icon" | "sc-switch" | "sc-audio" | "sc-audio--compact" | "sc-audio__play" | "sc-audio__wave" | "sc-audio__time" | "sc-field" | "sc-field__label" | "sc-field__optional" | "sc-field__help" | "sc-field__error" | "sc-control" | "sc-control--trigger" | "sc-control__input" | "sc-control__unit" | "sc-control__steppers" | "sc-control__reveal" | "sc-control__tag" | "sc-check" | "sc-popover" | "sc-listbox" | "sc-listbox__item" | "sc-listbox__empty" | "sc-calendar" | "sc-picks" | "sc-segments" | "sc-pick" | "sc-chips" | "sc-chip" | "sc-slots" | "sc-moment" | "sc-range" | "sc-rating" | "sc-upload" | "sc-upload__zone" | "sc-upload__icon" | "sc-upload__text" | "sc-attachments" | "sc-attachment" | "sc-attachment--failed" | "sc-attachment__main" | "sc-attachment__text" | "sc-attachment__name" | "sc-attachment__meta" | "sc-attachment__action" | "sc-attachment__bar" | "sc-orb" | "sc-orb--idle" | "sc-orb--listening" | "sc-orb--thinking" | "sc-orb--speaking" | "sc-orb--still" | "sc-orb--loading" | "sc-orb__ring" | "sc-orb__core" | "sc-automation" | "sc-automation--gone" | "sc-automation__head" | "sc-automation__heading" | "sc-automation__title" | "sc-automation__when" | "sc-automation__end" | "sc-automation__dot" | "sc-automation__summary" | "sc-automation__section" | "sc-automation__label" | "sc-automation__steps" | "sc-automation__step" | "sc-automation__number" | "sc-automation__name" | "sc-automation__uses" | "sc-automation__use" | "sc-automation__board" | "sc-automation__more" | "sc-automation__runs" | "sc-automation__run--open" | "sc-automation__status" | "sc-automation__empty" | "sc-run" | "sc-run__head" | "sc-run__by" | "sc-run__end" | "sc-run__took" | "sc-run__heading" | "sc-run__title" | "sc-run__meta" | "sc-run__summary" | "sc-run__section" | "sc-run__label" | "sc-run__steps" | "sc-run__step" | "sc-run__number" | "sc-run__name" | "sc-run__calls" | "sc-run__call" | "sc-run__call--would" | "sc-run__call--failed" | "sc-run__count" | "sc-run__error" | "sc-run__live" | "sc-run__links" | "sc-run__empty" | "sc-agenda" | "sc-agenda--day" | "sc-agenda__days" | "sc-agenda__day" | "sc-agenda__day--today" | "sc-agenda__day--empty" | "sc-agenda__date" | "sc-agenda__weekday" | "sc-agenda__number" | "sc-agenda__events" | "sc-agenda__event" | "sc-agenda__time" | "sc-agenda__what" | "sc-agenda__title" | "sc-agenda__detail" | "sc-agenda__empty" | "sc-timeline" | "sc-timeline__item" | "sc-timeline__item--info" | "sc-timeline__item--success" | "sc-timeline__item--warning" | "sc-timeline__item--danger" | "sc-timeline__dot" | "sc-timeline__body" | "sc-timeline__head" | "sc-timeline__title" | "sc-timeline__status" | "sc-timeline__when" | "sc-timeline__text" | "sc-board" | "sc-board__column" | "sc-board__column--over" | "sc-board__head" | "sc-board__title" | "sc-board__count" | "sc-board__cards" | "sc-board__card" | "sc-board__card--dragging" | "sc-board__card-title" | "sc-board__card-subtitle" | "sc-board__card-meta" | "sc-board__move" | "sc-board__menu" | "sc-board__empty";
|
|
10
10
|
export type KitClassNames = Partial<Record<KitPart, string>> | undefined;
|
|
11
11
|
/**
|
|
12
12
|
* Gives the primitives under it the host's classes, words and language; without it they are
|
package/dist/kit/context.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context.js","names":[],"sources":["../../src/kit/context.tsx"],"sourcesContent":["import { createContext, useContext, type ReactNode } from \"react\";\n\nimport { classes } from \"../classes\";\nimport { KIT_MESSAGES, type KitLocale, type KitMessages } from \"./messages\";\n\n/**\n * The kit's parts, by the class each carries: one BEM family per primitive. `classNames` adds a\n * host's own under the same keys, so a host styles every place a primitive appears at once.\n * (`sc-card` is the Ficha's; the kit's card is `sc-panel`.)\n */\nexport type KitPart =\n | \"sc-panel\"\n | \"sc-panel__head\"\n | \"sc-panel__head--image\"\n | \"sc-panel__heading\"\n | \"sc-panel__title\"\n | \"sc-panel__subtitle\"\n | \"sc-list\"\n | \"sc-row\"\n | \"sc-row--quiet\"\n | \"sc-row--pressed\"\n | \"sc-row__main\"\n | \"sc-row__text\"\n | \"sc-row__title\"\n | \"sc-row__subtitle\"\n | \"sc-row__error\"\n | \"sc-row__meta\"\n | \"sc-row__trailing\"\n | \"sc-mark\"\n | \"sc-mark--logo\"\n | \"sc-mark--photo\"\n | \"sc-mark--round\"\n | \"sc-tiles\"\n | \"sc-tiles__grid\"\n | \"sc-tile\"\n | \"sc-tile--quiet\"\n | \"sc-tile__main\"\n | \"sc-tile__count\"\n | \"sc-tile__title\"\n | \"sc-stack\"\n | \"sc-stack__item\"\n | \"sc-stack__more\"\n | \"sc-tag\"\n | \"sc-tag--info\"\n | \"sc-tag--success\"\n | \"sc-tag--warning\"\n | \"sc-tag--danger\"\n | \"sc-stat\"\n | \"sc-stat--info\"\n | \"sc-stat--success\"\n | \"sc-stat--warning\"\n | \"sc-stat--danger\"\n | \"sc-stat__label\"\n | \"sc-stat__value\"\n | \"sc-stat__hint\"\n | \"sc-stats\"\n | \"sc-stats__grid\"\n | \"sc-chart\"\n | \"sc-chart--bar\"\n | \"sc-chart--line\"\n | \"sc-chart__row\"\n | \"sc-chart__label\"\n | \"sc-chart__track\"\n | \"sc-chart__bar\"\n | \"sc-chart__value\"\n | \"sc-chart__top\"\n | \"sc-chart__plot\"\n | \"sc-chart__wash\"\n | \"sc-chart__axis\"\n | \"sc-chart__line\"\n | \"sc-chart__dot\"\n | \"sc-chart__tip\"\n | \"sc-chart__ends\"\n | \"sc-chart__data\"\n | \"sc-note\"\n | \"sc-note--info\"\n | \"sc-note--success\"\n | \"sc-note--warning\"\n | \"sc-note--danger\"\n | \"sc-note__body\"\n | \"sc-button\"\n | \"sc-button--primary\"\n | \"sc-button--neutral\"\n | \"sc-button--danger\"\n | \"sc-button--ghost\"\n | \"sc-button--sm\"\n | \"sc-button--icon\"\n | \"sc-switch\"\n | \"sc-audio\"\n | \"sc-audio--compact\"\n | \"sc-audio__play\"\n | \"sc-audio__wave\"\n | \"sc-audio__time\"\n | \"sc-field\"\n | \"sc-field__label\"\n | \"sc-field__optional\"\n | \"sc-field__help\"\n | \"sc-field__error\"\n | \"sc-control\"\n | \"sc-control--trigger\"\n | \"sc-control__input\"\n | \"sc-control__unit\"\n | \"sc-control__steppers\"\n | \"sc-control__reveal\"\n | \"sc-control__tag\"\n | \"sc-check\"\n | \"sc-popover\"\n | \"sc-listbox\"\n | \"sc-listbox__item\"\n | \"sc-listbox__empty\"\n | \"sc-calendar\"\n | \"sc-picks\"\n | \"sc-segments\"\n | \"sc-pick\"\n | \"sc-chips\"\n | \"sc-chip\"\n | \"sc-slots\"\n | \"sc-moment\"\n | \"sc-range\"\n | \"sc-rating\"\n | \"sc-upload\"\n | \"sc-upload__zone\"\n | \"sc-upload__icon\"\n | \"sc-upload__text\"\n | \"sc-attachments\"\n | \"sc-attachment\"\n | \"sc-attachment--failed\"\n | \"sc-attachment__main\"\n | \"sc-attachment__text\"\n | \"sc-attachment__name\"\n | \"sc-attachment__meta\"\n | \"sc-attachment__action\"\n | \"sc-attachment__bar\"\n | \"sc-orb\"\n | \"sc-orb--idle\"\n | \"sc-orb--listening\"\n | \"sc-orb--thinking\"\n | \"sc-orb--speaking\"\n | \"sc-orb--still\"\n | \"sc-orb--loading\"\n | \"sc-orb__ring\"\n | \"sc-orb__core\"\n | \"sc-automation\"\n | \"sc-automation--gone\"\n | \"sc-automation__head\"\n | \"sc-automation__heading\"\n | \"sc-automation__title\"\n | \"sc-automation__when\"\n | \"sc-automation__end\"\n | \"sc-automation__dot\"\n | \"sc-automation__summary\"\n | \"sc-automation__section\"\n | \"sc-automation__label\"\n | \"sc-automation__steps\"\n | \"sc-automation__step\"\n | \"sc-automation__number\"\n | \"sc-automation__name\"\n | \"sc-automation__uses\"\n | \"sc-automation__use\"\n | \"sc-automation__board\"\n | \"sc-automation__more\"\n | \"sc-automation__runs\"\n | \"sc-automation__run--open\"\n | \"sc-automation__status\"\n | \"sc-automation__empty\"\n | \"sc-run\"\n | \"sc-run__head\"\n | \"sc-run__by\"\n | \"sc-run__end\"\n | \"sc-run__took\"\n | \"sc-run__heading\"\n | \"sc-run__title\"\n | \"sc-run__meta\"\n | \"sc-run__summary\"\n | \"sc-run__section\"\n | \"sc-run__label\"\n | \"sc-run__steps\"\n | \"sc-run__step\"\n | \"sc-run__number\"\n | \"sc-run__name\"\n | \"sc-run__calls\"\n | \"sc-run__call\"\n | \"sc-run__call--would\"\n | \"sc-run__call--failed\"\n | \"sc-run__count\"\n | \"sc-run__error\"\n | \"sc-run__live\"\n | \"sc-run__links\"\n | \"sc-run__empty\";\n\nexport type KitClassNames = Partial<Record<KitPart, string>> | undefined;\n\n/** What every primitive under one host shares: its classes, its words, its language. */\ninterface KitScope {\n classNames: KitClassNames;\n messages: KitMessages;\n locale: KitLocale | undefined;\n /** The locale's code, for Intl: \"es\", \"en-US\". */\n code: string;\n}\n\nconst KitContext = createContext<KitScope>({\n classNames: undefined,\n messages: KIT_MESSAGES,\n locale: undefined,\n code: \"en-US\",\n});\n\n/**\n * Gives the primitives under it the host's classes, words and language; without it they are\n * the package's, in English.\n */\nexport function KitProvider({\n classNames,\n messages,\n locale,\n children,\n}: {\n classNames?: KitClassNames;\n messages?: Partial<KitMessages> | undefined;\n locale?: KitLocale | undefined;\n children: ReactNode;\n}) {\n const scope: KitScope = {\n classNames,\n messages: { ...KIT_MESSAGES, ...messages },\n locale,\n code: locale?.code ?? \"en-US\",\n };\n return <KitContext value={scope}>{children}</KitContext>;\n}\n\nexport function useKit(): KitScope {\n return useContext(KitContext);\n}\n\n/** The classes of the kit's parts, each with the host's own under it. */\nexport function useParts(): (...parts: KitPart[]) => string {\n const { classNames } = useKit();\n return (...parts) => classes(classNames, ...parts);\n}\n\n/** A part's classes and the caller's own, as one `className`. */\nexport function joined(...names: (string | false | undefined)[]): string {\n return names.filter(Boolean).join(\" \");\n}\n"],"mappings":";;;;;
|
|
1
|
+
{"version":3,"file":"context.js","names":[],"sources":["../../src/kit/context.tsx"],"sourcesContent":["import { createContext, useContext, type ReactNode } from \"react\";\n\nimport { classes } from \"../classes\";\nimport { KIT_MESSAGES, type KitLocale, type KitMessages } from \"./messages\";\n\n/**\n * The kit's parts, by the class each carries: one BEM family per primitive. `classNames` adds a\n * host's own under the same keys, so a host styles every place a primitive appears at once.\n * (`sc-card` is the Ficha's; the kit's card is `sc-panel`.)\n */\nexport type KitPart =\n | \"sc-panel\"\n | \"sc-panel__head\"\n | \"sc-panel__head--image\"\n | \"sc-panel__heading\"\n | \"sc-panel__title\"\n | \"sc-panel__subtitle\"\n | \"sc-list\"\n | \"sc-row\"\n | \"sc-row--quiet\"\n | \"sc-row--pressed\"\n | \"sc-row__main\"\n | \"sc-row__text\"\n | \"sc-row__title\"\n | \"sc-row__subtitle\"\n | \"sc-row__error\"\n | \"sc-row__meta\"\n | \"sc-row__trailing\"\n | \"sc-mark\"\n | \"sc-mark--logo\"\n | \"sc-mark--photo\"\n | \"sc-mark--round\"\n | \"sc-tiles\"\n | \"sc-tiles__grid\"\n | \"sc-tile\"\n | \"sc-tile--quiet\"\n | \"sc-tile__main\"\n | \"sc-tile__count\"\n | \"sc-tile__title\"\n | \"sc-stack\"\n | \"sc-stack__item\"\n | \"sc-stack__more\"\n | \"sc-tag\"\n | \"sc-tag--info\"\n | \"sc-tag--success\"\n | \"sc-tag--warning\"\n | \"sc-tag--danger\"\n | \"sc-stat\"\n | \"sc-stat--info\"\n | \"sc-stat--success\"\n | \"sc-stat--warning\"\n | \"sc-stat--danger\"\n | \"sc-stat__label\"\n | \"sc-stat__value\"\n | \"sc-stat__hint\"\n | \"sc-stats\"\n | \"sc-stats__grid\"\n | \"sc-chart\"\n | \"sc-chart--bar\"\n | \"sc-chart--line\"\n | \"sc-chart__row\"\n | \"sc-chart__label\"\n | \"sc-chart__track\"\n | \"sc-chart__bar\"\n | \"sc-chart__value\"\n | \"sc-chart__top\"\n | \"sc-chart__plot\"\n | \"sc-chart__wash\"\n | \"sc-chart__axis\"\n | \"sc-chart__line\"\n | \"sc-chart__dot\"\n | \"sc-chart__tip\"\n | \"sc-chart__ends\"\n | \"sc-chart__data\"\n | \"sc-note\"\n | \"sc-note--info\"\n | \"sc-note--success\"\n | \"sc-note--warning\"\n | \"sc-note--danger\"\n | \"sc-note__body\"\n | \"sc-button\"\n | \"sc-button--primary\"\n | \"sc-button--neutral\"\n | \"sc-button--danger\"\n | \"sc-button--ghost\"\n | \"sc-button--sm\"\n | \"sc-button--icon\"\n | \"sc-switch\"\n | \"sc-audio\"\n | \"sc-audio--compact\"\n | \"sc-audio__play\"\n | \"sc-audio__wave\"\n | \"sc-audio__time\"\n | \"sc-field\"\n | \"sc-field__label\"\n | \"sc-field__optional\"\n | \"sc-field__help\"\n | \"sc-field__error\"\n | \"sc-control\"\n | \"sc-control--trigger\"\n | \"sc-control__input\"\n | \"sc-control__unit\"\n | \"sc-control__steppers\"\n | \"sc-control__reveal\"\n | \"sc-control__tag\"\n | \"sc-check\"\n | \"sc-popover\"\n | \"sc-listbox\"\n | \"sc-listbox__item\"\n | \"sc-listbox__empty\"\n | \"sc-calendar\"\n | \"sc-picks\"\n | \"sc-segments\"\n | \"sc-pick\"\n | \"sc-chips\"\n | \"sc-chip\"\n | \"sc-slots\"\n | \"sc-moment\"\n | \"sc-range\"\n | \"sc-rating\"\n | \"sc-upload\"\n | \"sc-upload__zone\"\n | \"sc-upload__icon\"\n | \"sc-upload__text\"\n | \"sc-attachments\"\n | \"sc-attachment\"\n | \"sc-attachment--failed\"\n | \"sc-attachment__main\"\n | \"sc-attachment__text\"\n | \"sc-attachment__name\"\n | \"sc-attachment__meta\"\n | \"sc-attachment__action\"\n | \"sc-attachment__bar\"\n | \"sc-orb\"\n | \"sc-orb--idle\"\n | \"sc-orb--listening\"\n | \"sc-orb--thinking\"\n | \"sc-orb--speaking\"\n | \"sc-orb--still\"\n | \"sc-orb--loading\"\n | \"sc-orb__ring\"\n | \"sc-orb__core\"\n | \"sc-automation\"\n | \"sc-automation--gone\"\n | \"sc-automation__head\"\n | \"sc-automation__heading\"\n | \"sc-automation__title\"\n | \"sc-automation__when\"\n | \"sc-automation__end\"\n | \"sc-automation__dot\"\n | \"sc-automation__summary\"\n | \"sc-automation__section\"\n | \"sc-automation__label\"\n | \"sc-automation__steps\"\n | \"sc-automation__step\"\n | \"sc-automation__number\"\n | \"sc-automation__name\"\n | \"sc-automation__uses\"\n | \"sc-automation__use\"\n | \"sc-automation__board\"\n | \"sc-automation__more\"\n | \"sc-automation__runs\"\n | \"sc-automation__run--open\"\n | \"sc-automation__status\"\n | \"sc-automation__empty\"\n | \"sc-run\"\n | \"sc-run__head\"\n | \"sc-run__by\"\n | \"sc-run__end\"\n | \"sc-run__took\"\n | \"sc-run__heading\"\n | \"sc-run__title\"\n | \"sc-run__meta\"\n | \"sc-run__summary\"\n | \"sc-run__section\"\n | \"sc-run__label\"\n | \"sc-run__steps\"\n | \"sc-run__step\"\n | \"sc-run__number\"\n | \"sc-run__name\"\n | \"sc-run__calls\"\n | \"sc-run__call\"\n | \"sc-run__call--would\"\n | \"sc-run__call--failed\"\n | \"sc-run__count\"\n | \"sc-run__error\"\n | \"sc-run__live\"\n | \"sc-run__links\"\n | \"sc-run__empty\"\n | \"sc-agenda\"\n | \"sc-agenda--day\"\n | \"sc-agenda__days\"\n | \"sc-agenda__day\"\n | \"sc-agenda__day--today\"\n | \"sc-agenda__day--empty\"\n | \"sc-agenda__date\"\n | \"sc-agenda__weekday\"\n | \"sc-agenda__number\"\n | \"sc-agenda__events\"\n | \"sc-agenda__event\"\n | \"sc-agenda__time\"\n | \"sc-agenda__what\"\n | \"sc-agenda__title\"\n | \"sc-agenda__detail\"\n | \"sc-agenda__empty\"\n | \"sc-timeline\"\n | \"sc-timeline__item\"\n | \"sc-timeline__item--info\"\n | \"sc-timeline__item--success\"\n | \"sc-timeline__item--warning\"\n | \"sc-timeline__item--danger\"\n | \"sc-timeline__dot\"\n | \"sc-timeline__body\"\n | \"sc-timeline__head\"\n | \"sc-timeline__title\"\n | \"sc-timeline__status\"\n | \"sc-timeline__when\"\n | \"sc-timeline__text\"\n | \"sc-board\"\n | \"sc-board__column\"\n | \"sc-board__column--over\"\n | \"sc-board__head\"\n | \"sc-board__title\"\n | \"sc-board__count\"\n | \"sc-board__cards\"\n | \"sc-board__card\"\n | \"sc-board__card--dragging\"\n | \"sc-board__card-title\"\n | \"sc-board__card-subtitle\"\n | \"sc-board__card-meta\"\n | \"sc-board__move\"\n | \"sc-board__menu\"\n | \"sc-board__empty\";\n\nexport type KitClassNames = Partial<Record<KitPart, string>> | undefined;\n\n/** What every primitive under one host shares: its classes, its words, its language. */\ninterface KitScope {\n classNames: KitClassNames;\n messages: KitMessages;\n locale: KitLocale | undefined;\n /** The locale's code, for Intl: \"es\", \"en-US\". */\n code: string;\n}\n\nconst KitContext = createContext<KitScope>({\n classNames: undefined,\n messages: KIT_MESSAGES,\n locale: undefined,\n code: \"en-US\",\n});\n\n/**\n * Gives the primitives under it the host's classes, words and language; without it they are\n * the package's, in English.\n */\nexport function KitProvider({\n classNames,\n messages,\n locale,\n children,\n}: {\n classNames?: KitClassNames;\n messages?: Partial<KitMessages> | undefined;\n locale?: KitLocale | undefined;\n children: ReactNode;\n}) {\n const scope: KitScope = {\n classNames,\n messages: { ...KIT_MESSAGES, ...messages },\n locale,\n code: locale?.code ?? \"en-US\",\n };\n return <KitContext value={scope}>{children}</KitContext>;\n}\n\nexport function useKit(): KitScope {\n return useContext(KitContext);\n}\n\n/** The classes of the kit's parts, each with the host's own under it. */\nexport function useParts(): (...parts: KitPart[]) => string {\n const { classNames } = useKit();\n return (...parts) => classes(classNames, ...parts);\n}\n\n/** A part's classes and the caller's own, as one `className`. */\nexport function joined(...names: (string | false | undefined)[]): string {\n return names.filter(Boolean).join(\" \");\n}\n"],"mappings":";;;;;AAqPA,MAAM,aAAa,cAAwB;CACzC,YAAY,KAAA;CACZ,UAAU;CACV,QAAQ,KAAA;CACR,MAAM;AACR,CAAC;;;;;AAMD,SAAgB,YAAY,EAC1B,YACA,UACA,QACA,YAMC;CACD,MAAM,QAAkB;EACtB;EACA,UAAU;GAAE,GAAG;GAAc,GAAG;EAAS;EACzC;EACA,MAAM,QAAQ,QAAQ;CACxB;CACA,OAAO,oBAAC,YAAD;EAAY,OAAO;EAAQ;CAAqB,CAAA;AACzD;AAEA,SAAgB,SAAmB;CACjC,OAAO,WAAW,UAAU;AAC9B;;AAGA,SAAgB,WAA4C;CAC1D,MAAM,EAAE,eAAe,OAAO;CAC9B,QAAQ,GAAG,UAAU,QAAQ,YAAY,GAAG,KAAK;AACnD;;AAGA,SAAgB,OAAO,GAAG,OAA+C;CACvE,OAAO,MAAM,OAAO,OAAO,CAAC,CAAC,KAAK,GAAG;AACvC"}
|
package/dist/kit/messages.d.ts
CHANGED
|
@@ -95,6 +95,28 @@ export interface KitMessages {
|
|
|
95
95
|
automation: AutomationMessages;
|
|
96
96
|
/** An app for the person to connect, as its connection stands. */
|
|
97
97
|
connect: ConnectMessages;
|
|
98
|
+
/** A calendar's words. */
|
|
99
|
+
calendar: CalendarMessages;
|
|
100
|
+
/** A board's words. */
|
|
101
|
+
board: BoardMessages;
|
|
102
|
+
}
|
|
103
|
+
/** What a calendar says besides its events. */
|
|
104
|
+
export interface CalendarMessages {
|
|
105
|
+
/** An event that takes the whole day, where its hours would be. */
|
|
106
|
+
allDay: string;
|
|
107
|
+
/** A day with nothing on it. */
|
|
108
|
+
empty: string;
|
|
109
|
+
}
|
|
110
|
+
/** What a board says besides its cards. */
|
|
111
|
+
export interface BoardMessages {
|
|
112
|
+
/** A card's button that moves it to another column, given the card, for screen readers. */
|
|
113
|
+
move: (card: string) => string;
|
|
114
|
+
/** Over the columns it may go to. */
|
|
115
|
+
moveTo: string;
|
|
116
|
+
/** A card moved, as the person's answer reads. */
|
|
117
|
+
moved: (card: string, column: string) => string;
|
|
118
|
+
/** A column with no cards. */
|
|
119
|
+
empty: string;
|
|
98
120
|
}
|
|
99
121
|
/** The words of an app's card: its button, and what it says where the button isn't. */
|
|
100
122
|
export interface ConnectMessages {
|
package/dist/kit/messages.js
CHANGED
|
@@ -64,6 +64,16 @@ const KIT_MESSAGES = {
|
|
|
64
64
|
connected: "Connected",
|
|
65
65
|
failed: "It couldn't be connected",
|
|
66
66
|
preparing: "Getting it ready"
|
|
67
|
+
},
|
|
68
|
+
calendar: {
|
|
69
|
+
allDay: "All day",
|
|
70
|
+
empty: "Nothing planned"
|
|
71
|
+
},
|
|
72
|
+
board: {
|
|
73
|
+
move: (card) => `Move ${card}`,
|
|
74
|
+
moveTo: "Move to",
|
|
75
|
+
moved: (card, column) => `${card} to ${column}`,
|
|
76
|
+
empty: "Nothing here"
|
|
67
77
|
}
|
|
68
78
|
};
|
|
69
79
|
//#endregion
|