@godxjp/ui 18.5.0 → 18.7.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/components/charts/compact-bar-trend.d.ts +2 -1
- package/dist/components/charts/index.d.ts +4 -1
- package/dist/components/data-display/data-table.d.ts +25 -4
- package/dist/components/data-display/data-table.js +13 -2
- package/dist/components/data-display/empty-state.js +1 -1
- package/dist/components/data-display/index.d.ts +1 -1
- package/dist/components/data-display/list-row.d.ts +19 -0
- package/dist/components/data-display/list-row.js +2 -0
- package/dist/components/data-display/qr-code.d.ts +1 -1
- package/dist/components/data-display/table.d.ts +47 -2
- package/dist/components/data-display/table.js +29 -4
- package/dist/components/data-entry/command.d.ts +10 -10
- package/dist/components/data-entry/index.d.ts +1 -0
- package/dist/components/data-entry/input-otp.d.ts +1 -0
- package/dist/components/feedback/alert.d.ts +20 -2
- package/dist/components/feedback/alert.js +11 -1
- package/dist/components/feedback/dialog.d.ts +14 -1
- package/dist/components/feedback/dialog.js +4 -0
- package/dist/components/feedback/index.d.ts +3 -3
- package/dist/components/feedback/index.js +5 -1
- package/dist/components/general/logo.d.ts +7 -1
- package/dist/components/general/logo.js +1 -1
- package/dist/components/layout/app-shell.d.ts +1 -1
- package/dist/components/layout/app-shell.js +55 -46
- package/dist/components/layout/auth-account-summary.d.ts +5 -0
- package/dist/components/layout/auth-account-summary.js +31 -0
- package/dist/components/layout/auth-shell.d.ts +5 -2
- package/dist/components/layout/centered-shell.d.ts +1 -1
- package/dist/components/layout/centered-shell.js +28 -19
- package/dist/components/layout/error-surface.d.ts +35 -0
- package/dist/components/layout/error-surface.js +155 -0
- package/dist/components/layout/flex.d.ts +1 -1
- package/dist/components/layout/flex.js +4 -0
- package/dist/components/layout/index.d.ts +7 -0
- package/dist/components/layout/index.js +6 -0
- package/dist/components/layout/page-container.d.ts +1 -1
- package/dist/components/layout/page-container.js +23 -41
- package/dist/components/layout/page-header.d.ts +22 -0
- package/dist/components/layout/page-header.js +89 -0
- package/dist/components/navigation/filter-bar.d.ts +2 -2
- package/dist/components/navigation/filter-bar.js +44 -1
- package/dist/components/navigation/index.d.ts +1 -1
- package/dist/components/navigation/steps.js +38 -19
- package/dist/components/navigation/tabs.js +12 -3
- package/dist/components/ui/avatar.d.ts +2 -1
- package/dist/components/ui/avatar.js +2 -1
- package/dist/components/ui/input-otp.d.ts +4 -1
- package/dist/components/ui/input-otp.js +2 -1
- package/dist/components/ui/toggle-group.d.ts +7 -4
- package/dist/components/ui/toggle-group.js +32 -21
- package/dist/email/brand-mark.d.ts +21 -5
- package/dist/email/brand-mark.js +5 -0
- package/dist/email/color.d.ts +2 -1
- package/dist/email/geometry.d.ts +9 -1
- package/dist/email/geometry.js +1 -0
- package/dist/email/index.d.ts +6 -1
- package/dist/email/index.js +6 -0
- package/dist/email/inline-style.d.ts +7 -5
- package/dist/email/inline-style.js +5 -0
- package/dist/email/tokens.generated.d.ts +40 -20
- package/dist/email/tokens.generated.js +40 -20
- package/dist/email/urgency.d.ts +22 -0
- package/dist/email/urgency.js +14 -0
- package/dist/i18n/messages/en.json +26 -1
- package/dist/i18n/messages/ja.json +23 -1
- package/dist/i18n/messages/vi.json +23 -1
- package/dist/props/components/data-display.prop.d.ts +63 -1
- package/dist/props/components/data-entry.prop.d.ts +6 -0
- package/dist/props/components/feedback.prop.d.ts +6 -0
- package/dist/props/components/index.d.ts +1 -1
- package/dist/props/components/layout.prop.d.ts +244 -4
- package/dist/props/components/navigation.prop.d.ts +57 -1
- package/dist/props/registry.d.ts +205 -5
- package/dist/props/registry.js +270 -6
- package/dist/props/vocabulary/data.prop.d.ts +27 -0
- package/dist/props/vocabulary/index.d.ts +3 -3
- package/dist/props/vocabulary/interaction.prop.d.ts +19 -2
- package/dist/props/vocabulary/layout.prop.d.ts +41 -7
- package/dist/styles/alert-layout.css +36 -0
- package/dist/styles/control.css +28 -0
- package/dist/styles/data-display-layout.css +26 -0
- package/dist/styles/layout.css +212 -0
- package/dist/styles/logo-layout.css +42 -9
- package/dist/styles/navigation-layout.css +109 -0
- package/dist/styles/shell-layout.css +336 -0
- package/dist/styles/table-layout.css +164 -1
- package/dist/theme/dxs.canonical.css +5 -4
- package/dist/tokens/axes.css +4 -3
- package/dist/tokens/base.css +1 -0
- package/dist/tokens/components/data-display.css +13 -0
- package/dist/tokens/components/email.css +43 -16
- package/dist/tokens/components/error-surface.css +36 -0
- package/dist/tokens/components/feedback.css +20 -0
- package/dist/tokens/components/list-row.css +20 -0
- package/dist/tokens/components/logo.css +52 -10
- package/dist/tokens/components/navigation.css +41 -0
- package/dist/tokens/components/shell.css +109 -0
- package/dist/tokens/components/table.css +45 -0
- package/dist/tokens/foundation.css +26 -0
- package/dist/tokens/semantic/layout.css +38 -0
- package/package.json +8 -2
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PageHeader — the canonical page title band (gh#255).
|
|
3
|
+
*
|
|
4
|
+
* This is the geometry `PageContainer` has always rendered, lifted into its own export so a
|
|
5
|
+
* consumer can mount it OUTSIDE a full page shell — a Sheet detail, a `MasterDetail` detail pane, a
|
|
6
|
+
* tab body, a nested route header — without re-authoring `.ui-page-header` CSS locally. There is
|
|
7
|
+
* exactly ONE implementation: `PageContainer` renders this component, so the two can never drift.
|
|
8
|
+
*
|
|
9
|
+
* The band owns: breadcrumbs (a named `<nav>` landmark with `aria-current="page"` on the leaf), the
|
|
10
|
+
* `<h1>` title, the subtitle/description, a status/meta slot, the `extra` action region, the
|
|
11
|
+
* responsive overflow arrangement (`layout`), and the pending state (`loading`). It owns no page
|
|
12
|
+
* chrome — padding, measure and body rhythm stay with `PageContainer`.
|
|
13
|
+
*
|
|
14
|
+
* DENIED / ERROR are deliberately NOT states of this component: a page the user may not see must
|
|
15
|
+
* not render its title, breadcrumb trail or actions at all (they leak the resource's existence and
|
|
16
|
+
* its name). That whole-surface contract belongs to `ErrorSurface`, which is the canonical public
|
|
17
|
+
* replacement — see `docs/CANONICAL-CONTRACTS.md`.
|
|
18
|
+
*/
|
|
19
|
+
import * as React from "react";
|
|
20
|
+
import type { PageHeaderProp } from "../../props/components/layout.prop.js";
|
|
21
|
+
export type { PageHeaderProp, PageHeaderProp as PageHeaderProps, } from "../../props/components/layout.prop.js";
|
|
22
|
+
export declare const PageHeader: React.ForwardRefExoticComponent<PageHeaderProp & React.RefAttributes<HTMLElement>>;
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
import { ChevronRight } from "lucide-react";
|
|
5
|
+
import { useTranslation } from "../../i18n/use-translation.js";
|
|
6
|
+
import { cn } from "../../lib/utils.js";
|
|
7
|
+
const PageHeader = React.forwardRef(function PageHeader2({
|
|
8
|
+
title,
|
|
9
|
+
subtitle,
|
|
10
|
+
meta,
|
|
11
|
+
extra,
|
|
12
|
+
breadcrumb,
|
|
13
|
+
breadcrumbLabel,
|
|
14
|
+
breadcrumbAriaLabel,
|
|
15
|
+
linkComponent: LinkComponent = "a",
|
|
16
|
+
layout = "stack",
|
|
17
|
+
loading = false,
|
|
18
|
+
className
|
|
19
|
+
}, ref) {
|
|
20
|
+
const { t } = useTranslation();
|
|
21
|
+
return (
|
|
22
|
+
// `data-layout` is the only hook the header arrangement needs: `stack` (the default)
|
|
23
|
+
// matches no rule, so the historical geometry is untouched, while `responsive-inline`
|
|
24
|
+
// selects the compact-range rules that keep `extra` beside the title band (gh#231).
|
|
25
|
+
/* @__PURE__ */ jsxs(
|
|
26
|
+
"header",
|
|
27
|
+
{
|
|
28
|
+
ref,
|
|
29
|
+
className: cn("ui-page-header", className),
|
|
30
|
+
"data-layout": layout,
|
|
31
|
+
"aria-busy": loading ? "true" : void 0,
|
|
32
|
+
children: [
|
|
33
|
+
breadcrumb && breadcrumb.length > 0 && /* @__PURE__ */ jsx(
|
|
34
|
+
"nav",
|
|
35
|
+
{
|
|
36
|
+
"aria-label": breadcrumbLabel ?? breadcrumbAriaLabel ?? t("navigation.breadcrumb.ariaLabel"),
|
|
37
|
+
className: "ui-breadcrumb",
|
|
38
|
+
children: /* @__PURE__ */ jsx("ol", { className: "ui-breadcrumb-list", children: breadcrumb.map((item, i) => {
|
|
39
|
+
const isLast = i === breadcrumb.length - 1;
|
|
40
|
+
return /* @__PURE__ */ jsxs("li", { className: "ui-inline-xs", children: [
|
|
41
|
+
item.to && !isLast ? /* @__PURE__ */ jsx(
|
|
42
|
+
LinkComponent,
|
|
43
|
+
{
|
|
44
|
+
href: item.to,
|
|
45
|
+
to: item.to,
|
|
46
|
+
className: "hover:text-foreground hover:underline",
|
|
47
|
+
children: item.label
|
|
48
|
+
}
|
|
49
|
+
) : /* @__PURE__ */ jsx(
|
|
50
|
+
"span",
|
|
51
|
+
{
|
|
52
|
+
className: isLast ? "text-foreground" : "",
|
|
53
|
+
"aria-current": isLast ? "page" : void 0,
|
|
54
|
+
children: item.label
|
|
55
|
+
}
|
|
56
|
+
),
|
|
57
|
+
!isLast && /* @__PURE__ */ jsx(ChevronRight, { className: "size-3", "aria-hidden": "true" })
|
|
58
|
+
] }, i);
|
|
59
|
+
}) })
|
|
60
|
+
}
|
|
61
|
+
),
|
|
62
|
+
/* @__PURE__ */ jsxs("div", { className: "ui-page-header-row", children: [
|
|
63
|
+
/* @__PURE__ */ jsxs("div", { className: "ui-page-header-heading min-w-0", children: [
|
|
64
|
+
loading ? /* @__PURE__ */ jsx("h1", { className: "ui-page-title ui-skeleton-block ui-page-title-placeholder", children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: t("layout.pageHeader.loading") }) }) : meta != null ? /* @__PURE__ */ jsxs("div", { className: "ui-page-title-band", children: [
|
|
65
|
+
/* @__PURE__ */ jsx("h1", { className: "ui-page-title", children: title }),
|
|
66
|
+
/* @__PURE__ */ jsx("div", { className: "ui-page-header-meta", children: meta })
|
|
67
|
+
] }) : /* @__PURE__ */ jsx("h1", { className: "ui-page-title", children: title }),
|
|
68
|
+
loading ? (
|
|
69
|
+
// Decorative only — the pending state is already announced once by the heading above,
|
|
70
|
+
// so a second live placeholder here would double-announce it.
|
|
71
|
+
/* @__PURE__ */ jsx(
|
|
72
|
+
"p",
|
|
73
|
+
{
|
|
74
|
+
className: "ui-page-subtitle ui-skeleton-block ui-page-subtitle-placeholder",
|
|
75
|
+
"aria-hidden": "true"
|
|
76
|
+
}
|
|
77
|
+
)
|
|
78
|
+
) : subtitle && /* @__PURE__ */ jsx("p", { className: "ui-page-subtitle", children: subtitle })
|
|
79
|
+
] }),
|
|
80
|
+
extra && /* @__PURE__ */ jsx("div", { className: "ui-page-header-extra", children: extra })
|
|
81
|
+
] })
|
|
82
|
+
]
|
|
83
|
+
}
|
|
84
|
+
)
|
|
85
|
+
);
|
|
86
|
+
});
|
|
87
|
+
export {
|
|
88
|
+
PageHeader
|
|
89
|
+
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { ToolbarGroupProp, ToolbarProp } from "../../props/components/navigation.prop.js";
|
|
2
|
-
export type { FilterBarOverflowProp, ToolbarGroupProp, ToolbarGroupProp as ToolbarGroupProps, ToolbarGroupProp as FilterBarGroupProp, ToolbarGroupProp as FilterBarGroupProps, ToolbarProp, ToolbarProp as ToolbarProps, ToolbarProp as FilterBarProp, ToolbarProp as FilterBarProps, } from "../../props/components/navigation.prop.js";
|
|
3
|
-
export declare function Toolbar({ onClear, hasActiveFilters, sticky, overflow, className, children, }: ToolbarProp): import("react").JSX.Element;
|
|
2
|
+
export type { FilterBarChipProp, FilterBarChipProp as FilterBarChipProps, FilterBarOverflowProp, ToolbarGroupProp, ToolbarGroupProp as ToolbarGroupProps, ToolbarGroupProp as FilterBarGroupProp, ToolbarGroupProp as FilterBarGroupProps, ToolbarProp, ToolbarProp as ToolbarProps, ToolbarProp as FilterBarProp, ToolbarProp as FilterBarProps, } from "../../props/components/navigation.prop.js";
|
|
3
|
+
export declare function Toolbar({ onClear, hasActiveFilters, sticky, overflow, search, chips, onChipRemove, resultCount, actions, className, children, }: ToolbarProp): import("react").JSX.Element;
|
|
4
4
|
export declare function ToolbarGroup({ label, controlId, className, children }: ToolbarGroupProp): import("react").JSX.Element;
|
|
5
5
|
/**
|
|
6
6
|
* Canonical list-page filter strip.
|
|
@@ -10,10 +10,16 @@ function Toolbar({
|
|
|
10
10
|
hasActiveFilters = true,
|
|
11
11
|
sticky = false,
|
|
12
12
|
overflow = "wrap",
|
|
13
|
+
search,
|
|
14
|
+
chips,
|
|
15
|
+
onChipRemove,
|
|
16
|
+
resultCount,
|
|
17
|
+
actions,
|
|
13
18
|
className,
|
|
14
19
|
children
|
|
15
20
|
}) {
|
|
16
21
|
const { t } = useTranslation();
|
|
22
|
+
const hasChips = chips != null && chips.length > 0;
|
|
17
23
|
return /* @__PURE__ */ jsxs(
|
|
18
24
|
"div",
|
|
19
25
|
{
|
|
@@ -22,11 +28,48 @@ function Toolbar({
|
|
|
22
28
|
"data-overflow": overflow,
|
|
23
29
|
className: cn("ui-toolbar", sticky && "ui-toolbar-sticky", className),
|
|
24
30
|
children: [
|
|
31
|
+
search != null && // A region, not a bare child, so the search control gets ONE measure
|
|
32
|
+
// (--filter-bar-search-width) across every list page instead of whatever width the
|
|
33
|
+
// caller's control happened to have.
|
|
34
|
+
/* @__PURE__ */ jsx("div", { className: "ui-filter-bar-search", children: search }),
|
|
25
35
|
children,
|
|
36
|
+
hasChips && // `group` (not a second toolbar) — a toolbar may own a group, and the chips are a labelled
|
|
37
|
+
// set of related controls rather than an independent toolbar competing for the same role.
|
|
38
|
+
/* @__PURE__ */ jsx(
|
|
39
|
+
"div",
|
|
40
|
+
{
|
|
41
|
+
role: "group",
|
|
42
|
+
"aria-label": t("navigation.filterBar.appliedFilters"),
|
|
43
|
+
className: "ui-filter-bar-chips",
|
|
44
|
+
children: chips.map((chip) => /* @__PURE__ */ jsxs("span", { className: "ui-filter-bar-chip", children: [
|
|
45
|
+
/* @__PURE__ */ jsx("span", { className: "ui-filter-bar-chip-label", children: chip.label }),
|
|
46
|
+
(chip.onRemove || onChipRemove) && /* @__PURE__ */ jsx(
|
|
47
|
+
Button,
|
|
48
|
+
{
|
|
49
|
+
variant: "ghost",
|
|
50
|
+
size: "xs",
|
|
51
|
+
className: "ui-filter-bar-chip-remove",
|
|
52
|
+
"aria-label": t("navigation.filterBar.removeFilter", { label: chip.label }),
|
|
53
|
+
onClick: () => {
|
|
54
|
+
chip.onRemove?.();
|
|
55
|
+
onChipRemove?.(chip.id);
|
|
56
|
+
},
|
|
57
|
+
children: /* @__PURE__ */ jsx(X, { "aria-hidden": "true" })
|
|
58
|
+
}
|
|
59
|
+
)
|
|
60
|
+
] }, chip.id))
|
|
61
|
+
}
|
|
62
|
+
),
|
|
63
|
+
resultCount !== void 0 && // The whole reason this is a prop rather than caller markup: a sighted user SEES the table
|
|
64
|
+
// change, and a polite live region is what tells everyone else that filtering happened.
|
|
65
|
+
// The number is grouped by `Intl.NumberFormat` and the noun selected by CLDR plural rules
|
|
66
|
+
// for the active locale — never a hand-built "N items".
|
|
67
|
+
/* @__PURE__ */ jsx("div", { role: "status", "aria-live": "polite", className: "ui-filter-bar-count", children: t("navigation.filterBar.resultCount", { count: resultCount }) }),
|
|
26
68
|
onClear && hasActiveFilters && /* @__PURE__ */ jsxs(Button, { variant: "ghost", size: "sm", onClick: onClear, className: "ui-toolbar-clear", children: [
|
|
27
69
|
/* @__PURE__ */ jsx(X, { "aria-hidden": "true" }),
|
|
28
70
|
t("common.clearFilters")
|
|
29
|
-
] })
|
|
71
|
+
] }),
|
|
72
|
+
actions != null && /* @__PURE__ */ jsx("div", { className: "ui-filter-bar-actions", children: actions })
|
|
30
73
|
]
|
|
31
74
|
}
|
|
32
75
|
);
|
|
@@ -5,7 +5,7 @@ export { Menubar, MenubarCheckboxItem, MenubarContent, MenubarItem, MenubarLabel
|
|
|
5
5
|
export { NavigationMenu, NavigationMenuContent, NavigationMenuIndicator, NavigationMenuItem, NavigationMenuLink, NavigationMenuList, NavigationMenuTrigger, NavigationMenuViewport, } from "./navigation-menu.js";
|
|
6
6
|
export { Steps } from "./steps.js";
|
|
7
7
|
export { FilterBar, FilterBarGroup, Toolbar, ToolbarGroup } from "./filter-bar.js";
|
|
8
|
-
export type { FilterBarGroupProp, FilterBarGroupProps, FilterBarProp, FilterBarProps, ToolbarGroupProps, ToolbarProps, } from "./filter-bar.js";
|
|
8
|
+
export type { FilterBarChipProp, FilterBarChipProps, FilterBarGroupProp, FilterBarGroupProps, FilterBarProp, FilterBarProps, ToolbarGroupProps, ToolbarProps, } from "./filter-bar.js";
|
|
9
9
|
export { AppSettingPicker } from "./app-setting-picker.js";
|
|
10
10
|
export type { AppSettingPickerProp, AppSettingPickerProps, AppSettingKind, } from "./app-setting-picker.js";
|
|
11
11
|
export type { BreadcrumbItemProp as BreadcrumbItem } from "../../props/vocabulary/navigation.prop.js";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
-
import { Check, Circle, Loader2, X } from "lucide-react";
|
|
3
|
+
import { Check, ChevronRight, Circle, Loader2, X } from "lucide-react";
|
|
4
4
|
import { useTranslation } from "../../i18n/use-translation.js";
|
|
5
5
|
import { cn } from "../../lib/utils.js";
|
|
6
6
|
import { controlIconClass } from "../../lib/control-styles.js";
|
|
@@ -68,12 +68,13 @@ function Steps({
|
|
|
68
68
|
const base = defaultValue;
|
|
69
69
|
const isVertical = orientation === "vertical";
|
|
70
70
|
const compact = size === "sm";
|
|
71
|
+
const inline = type === "inline";
|
|
71
72
|
return /* @__PURE__ */ jsx(
|
|
72
73
|
"ol",
|
|
73
74
|
{
|
|
74
75
|
className: cn(
|
|
75
76
|
"flex w-full",
|
|
76
|
-
isVertical ? "flex-col gap-0" : "flex-row items-start",
|
|
77
|
+
inline ? "ui-steps-inline" : isVertical ? "flex-col gap-0" : "flex-row items-start",
|
|
77
78
|
className
|
|
78
79
|
),
|
|
79
80
|
"aria-label": t("navigation.steps.ariaLabel"),
|
|
@@ -84,12 +85,19 @@ function Steps({
|
|
|
84
85
|
const clickable = interactive && !item.disabled;
|
|
85
86
|
const description = item.description;
|
|
86
87
|
const isCurrent = absoluteIndex === current;
|
|
88
|
+
const statusLabel = t(
|
|
89
|
+
stepStatus === "finish" ? "navigation.steps.status.finish" : stepStatus === "process" ? "navigation.steps.status.process" : stepStatus === "error" ? "navigation.steps.status.error" : "navigation.steps.status.wait"
|
|
90
|
+
);
|
|
87
91
|
const stepClassName = cn(
|
|
88
92
|
"group flex min-w-0",
|
|
89
|
-
isVertical ? "flex-row items-start gap-3" : "flex-col items-center",
|
|
93
|
+
inline ? "ui-steps-inline-control" : isVertical ? "flex-row items-start gap-3" : "flex-col items-center",
|
|
90
94
|
clickable ? "cursor-pointer" : "cursor-default"
|
|
91
95
|
);
|
|
92
|
-
const stepInner = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
96
|
+
const stepInner = inline ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
97
|
+
/* @__PURE__ */ jsx("span", { className: "ui-steps-inline-index", "aria-hidden": "true", children: absoluteIndex + 1 }),
|
|
98
|
+
/* @__PURE__ */ jsx("span", { className: "ui-steps-inline-title", children: item.title }),
|
|
99
|
+
/* @__PURE__ */ jsx("span", { className: "sr-only", children: statusLabel })
|
|
100
|
+
] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
93
101
|
/* @__PURE__ */ jsx(StepIcon, { status: stepStatus, icon: item.icon, type }),
|
|
94
102
|
/* @__PURE__ */ jsxs(
|
|
95
103
|
"div",
|
|
@@ -119,26 +127,37 @@ function Steps({
|
|
|
119
127
|
}
|
|
120
128
|
)
|
|
121
129
|
] });
|
|
122
|
-
return /* @__PURE__ */
|
|
130
|
+
return /* @__PURE__ */ jsxs(
|
|
123
131
|
"li",
|
|
124
132
|
{
|
|
125
133
|
"aria-current": isCurrent ? "step" : void 0,
|
|
126
134
|
className: cn(
|
|
127
|
-
"relative flex min-w-0
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
!isVertical && index < items.length - 1 && "after:
|
|
135
|
+
"relative flex min-w-0",
|
|
136
|
+
!inline && "flex-1",
|
|
137
|
+
inline ? "ui-steps-inline-item" : isVertical ? "flex-row gap-3 pb-8 last:pb-0" : "flex-col items-center text-center",
|
|
138
|
+
!isVertical && !inline && index < items.length - 1 && "after:bg-border after:absolute after:top-4 after:h-px",
|
|
139
|
+
!isVertical && !inline && index < items.length - 1 && "after:left-[calc(50%+1.25rem)] after:w-[calc(100%-2.5rem)]"
|
|
131
140
|
),
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
141
|
+
"data-status": stepStatus,
|
|
142
|
+
children: [
|
|
143
|
+
interactive ? /* @__PURE__ */ jsx(
|
|
144
|
+
"button",
|
|
145
|
+
{
|
|
146
|
+
type: "button",
|
|
147
|
+
disabled: !clickable,
|
|
148
|
+
onClick: clickable ? () => onValueChange?.(absoluteIndex) : void 0,
|
|
149
|
+
className: stepClassName,
|
|
150
|
+
children: stepInner
|
|
151
|
+
}
|
|
152
|
+
) : /* @__PURE__ */ jsx("span", { className: stepClassName, children: stepInner }),
|
|
153
|
+
inline && index < items.length - 1 ? /* @__PURE__ */ jsx(
|
|
154
|
+
ChevronRight,
|
|
155
|
+
{
|
|
156
|
+
className: "ui-steps-inline-separator rtl:rotate-180",
|
|
157
|
+
"aria-hidden": "true"
|
|
158
|
+
}
|
|
159
|
+
) : null
|
|
160
|
+
]
|
|
142
161
|
},
|
|
143
162
|
index
|
|
144
163
|
);
|
|
@@ -42,8 +42,9 @@ function Tabs({
|
|
|
42
42
|
TabsList,
|
|
43
43
|
{
|
|
44
44
|
"data-slot": "tabs-list",
|
|
45
|
+
variant: variant === "line" ? "line" : "default",
|
|
45
46
|
className: cn(
|
|
46
|
-
variant === "line" && "h-auto w-full justify-start
|
|
47
|
+
variant === "line" && "h-auto w-full justify-start border-b p-0",
|
|
47
48
|
variant === "card" && "w-full justify-start",
|
|
48
49
|
listClassName
|
|
49
50
|
),
|
|
@@ -53,7 +54,9 @@ function Tabs({
|
|
|
53
54
|
value: item.value,
|
|
54
55
|
disabled: item.disabled,
|
|
55
56
|
className: cn(
|
|
56
|
-
|
|
57
|
+
// Geometry only — the active underline is the token-owned `::after` bar the
|
|
58
|
+
// line variant already owns (never a second, hand-rolled border-b indicator).
|
|
59
|
+
variant === "line" && "rounded-none px-4 py-2",
|
|
57
60
|
variant === "card" && "data-[state=active]:shadow-sm"
|
|
58
61
|
),
|
|
59
62
|
children: item.label
|
|
@@ -117,7 +120,13 @@ const TabsTrigger = React.forwardRef(({ className, ...props }, ref) => /* @__PUR
|
|
|
117
120
|
ref,
|
|
118
121
|
"data-slot": "tabs-trigger",
|
|
119
122
|
className: cn(
|
|
120
|
-
|
|
123
|
+
// The SELECTED-state ring (`ring-1 ring-primary/25`) is scoped to the default/card lists —
|
|
124
|
+
// the `line` variant is underline-only (gh#248) and must NEVER paint a surrounding ring, or
|
|
125
|
+
// it competes with (and at equal specificity overrides) the `:focus-visible` ring. The
|
|
126
|
+
// focus-visible ring/outline below is deliberately left unscoped: every variant keeps a
|
|
127
|
+
// visible keyboard focus indicator (WCAG 2.4.7). The line indicator itself lives in
|
|
128
|
+
// src/styles/navigation-layout.css so it reads the --tabs-indicator-* tokens.
|
|
129
|
+
"text-muted-foreground ring-offset-background hover:text-foreground focus-visible:border-ring focus-visible:outline-ring focus-visible:ring-ring/50 data-[state=active]:bg-background data-[state=active]:text-foreground group-data-[variant=default]/tabs-list:data-[state=active]:ring-primary/25 relative inline-flex flex-1 items-center justify-center gap-1.5 rounded-md border border-transparent px-3 py-1 text-sm font-medium whitespace-nowrap transition-all group-data-[orientation=vertical]/tabs:w-full group-data-[orientation=vertical]/tabs:justify-start group-data-[variant=line]/tabs-list:border-e-0 group-data-[variant=line]/tabs-list:border-b-0 focus-visible:ring-[3px] focus-visible:outline-1 disabled:pointer-events-none disabled:opacity-50 group-data-[variant=default]/tabs-list:data-[state=active]:shadow-sm group-data-[variant=default]/tabs-list:data-[state=active]:ring-1 group-data-[variant=line]/tabs-list:data-[state=active]:bg-transparent group-data-[variant=line]/tabs-list:data-[state=active]:shadow-none",
|
|
121
130
|
className
|
|
122
131
|
),
|
|
123
132
|
...props
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
2
|
import * as AvatarPrimitive from "@radix-ui/react-avatar";
|
|
3
|
-
|
|
3
|
+
import type { AvatarProp } from "../../props/components/data-display.prop.js";
|
|
4
|
+
export declare const Avatar: React.ForwardRefExoticComponent<Omit<AvatarPrimitive.AvatarProps & React.RefAttributes<HTMLSpanElement>, "ref"> & Pick<AvatarProp, "shape"> & React.RefAttributes<HTMLSpanElement>>;
|
|
4
5
|
export declare const AvatarImage: React.ForwardRefExoticComponent<Omit<AvatarPrimitive.AvatarImageProps & React.RefAttributes<HTMLImageElement>, "ref"> & React.RefAttributes<HTMLImageElement>>;
|
|
5
6
|
export declare const AvatarFallback: React.ForwardRefExoticComponent<Omit<AvatarPrimitive.AvatarFallbackProps & React.RefAttributes<HTMLSpanElement>, "ref"> & React.RefAttributes<HTMLSpanElement>>;
|
|
@@ -3,11 +3,12 @@ import { jsx } from "react/jsx-runtime";
|
|
|
3
3
|
import * as React from "react";
|
|
4
4
|
import * as AvatarPrimitive from "@radix-ui/react-avatar";
|
|
5
5
|
import { cn } from "../../lib/utils.js";
|
|
6
|
-
const Avatar = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
6
|
+
const Avatar = React.forwardRef(({ className, shape = "circle", ...props }, ref) => /* @__PURE__ */ jsx(
|
|
7
7
|
AvatarPrimitive.Root,
|
|
8
8
|
{
|
|
9
9
|
ref,
|
|
10
10
|
"data-slot": "avatar",
|
|
11
|
+
"data-shape": shape === "square" ? "square" : void 0,
|
|
11
12
|
className: cn("ui-avatar", className),
|
|
12
13
|
...props
|
|
13
14
|
}
|
|
@@ -26,7 +26,10 @@ export declare const InputOTP: React.ForwardRefExoticComponent<(Omit<Omit<React.
|
|
|
26
26
|
render?: never;
|
|
27
27
|
children: React.ReactNode;
|
|
28
28
|
} & React.RefAttributes<HTMLInputElement>, "ref">) & React.RefAttributes<HTMLInputElement>>;
|
|
29
|
-
export
|
|
29
|
+
export type { InputOTPGroupAppearanceProp, InputOTPGroupProp, InputOTPGroupProp as InputOTPGroupProps, } from "../../props/components/data-entry.prop.js";
|
|
30
|
+
export declare const InputOTPGroup: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLDivElement> & {
|
|
31
|
+
appearance?: import("./input-otp.js").InputOTPGroupAppearanceProp;
|
|
32
|
+
} & React.RefAttributes<HTMLDivElement>>;
|
|
30
33
|
export declare const InputOTPSlot: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLDivElement> & {
|
|
31
34
|
index: number;
|
|
32
35
|
} & React.RefAttributes<HTMLDivElement>>;
|
|
@@ -16,11 +16,12 @@ const InputOTP = React.forwardRef(({ className, containerClassName, ...props },
|
|
|
16
16
|
));
|
|
17
17
|
InputOTP.displayName = "InputOTP";
|
|
18
18
|
const InputOTPGroup = React.forwardRef(
|
|
19
|
-
({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
19
|
+
({ appearance = "slots", className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
20
20
|
"div",
|
|
21
21
|
{
|
|
22
22
|
ref,
|
|
23
23
|
"data-slot": "input-otp-group",
|
|
24
|
+
"data-appearance": appearance,
|
|
24
25
|
className: cn("ui-otp-group", className),
|
|
25
26
|
...props
|
|
26
27
|
}
|
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
2
|
import * as ToggleGroupPrimitive from "@radix-ui/react-toggle-group";
|
|
3
3
|
import { type ToggleProps } from "./toggle.js";
|
|
4
|
+
type ToggleGroupVariant = ToggleProps["variant"];
|
|
5
|
+
type ToggleGroupSize = ToggleProps["size"];
|
|
4
6
|
export declare const ToggleGroup: React.ForwardRefExoticComponent<((Omit<ToggleGroupPrimitive.ToggleGroupSingleProps & React.RefAttributes<HTMLDivElement>, "ref"> | Omit<ToggleGroupPrimitive.ToggleGroupMultipleProps & React.RefAttributes<HTMLDivElement>, "ref">) & {
|
|
5
|
-
variant?:
|
|
6
|
-
size?:
|
|
7
|
+
variant?: ToggleGroupVariant;
|
|
8
|
+
size?: ToggleGroupSize;
|
|
7
9
|
}) & React.RefAttributes<HTMLDivElement>>;
|
|
8
10
|
export declare const ToggleGroupItem: React.ForwardRefExoticComponent<Omit<ToggleGroupPrimitive.ToggleGroupItemProps & React.RefAttributes<HTMLButtonElement>, "ref"> & {
|
|
9
|
-
variant?:
|
|
10
|
-
size?:
|
|
11
|
+
variant?: ToggleGroupVariant;
|
|
12
|
+
size?: ToggleGroupSize;
|
|
11
13
|
} & React.RefAttributes<HTMLButtonElement>>;
|
|
14
|
+
export {};
|
|
@@ -4,28 +4,39 @@ import * as React from "react";
|
|
|
4
4
|
import * as ToggleGroupPrimitive from "@radix-ui/react-toggle-group";
|
|
5
5
|
import { cn } from "../../lib/utils.js";
|
|
6
6
|
import { toggleVariants } from "./toggle.js";
|
|
7
|
-
const
|
|
8
|
-
|
|
9
|
-
{
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
7
|
+
const ToggleGroupContext = React.createContext({});
|
|
8
|
+
const ToggleGroup = React.forwardRef(({ className, variant, size, children, ...props }, ref) => {
|
|
9
|
+
const context = React.useMemo(() => ({ variant, size }), [variant, size]);
|
|
10
|
+
return /* @__PURE__ */ jsx(
|
|
11
|
+
ToggleGroupPrimitive.Root,
|
|
12
|
+
{
|
|
13
|
+
ref,
|
|
14
|
+
"data-slot": "toggle-group",
|
|
15
|
+
"data-variant": variant,
|
|
16
|
+
"data-size": size,
|
|
17
|
+
className: cn("ui-toggle-group", className),
|
|
18
|
+
...props,
|
|
19
|
+
children: /* @__PURE__ */ jsx(ToggleGroupContext.Provider, { value: context, children })
|
|
20
|
+
}
|
|
21
|
+
);
|
|
22
|
+
});
|
|
19
23
|
ToggleGroup.displayName = ToggleGroupPrimitive.Root.displayName;
|
|
20
|
-
const ToggleGroupItem = React.forwardRef(({ className, variant, size, ...props }, ref) =>
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
24
|
+
const ToggleGroupItem = React.forwardRef(({ className, variant, size, ...props }, ref) => {
|
|
25
|
+
const context = React.useContext(ToggleGroupContext);
|
|
26
|
+
const resolvedVariant = variant ?? context.variant;
|
|
27
|
+
const resolvedSize = size ?? context.size;
|
|
28
|
+
return /* @__PURE__ */ jsx(
|
|
29
|
+
ToggleGroupPrimitive.Item,
|
|
30
|
+
{
|
|
31
|
+
ref,
|
|
32
|
+
"data-slot": "toggle-group-item",
|
|
33
|
+
"data-variant": resolvedVariant,
|
|
34
|
+
"data-size": resolvedSize,
|
|
35
|
+
className: cn(toggleVariants({ variant: resolvedVariant, size: resolvedSize }), className),
|
|
36
|
+
...props
|
|
37
|
+
}
|
|
38
|
+
);
|
|
39
|
+
});
|
|
29
40
|
ToggleGroupItem.displayName = ToggleGroupPrimitive.Item.displayName;
|
|
30
41
|
export {
|
|
31
42
|
ToggleGroup,
|
|
@@ -4,7 +4,10 @@
|
|
|
4
4
|
* The mark is an emerald CAPSULE with an internal light GLYPH bar — the same artwork the React
|
|
5
5
|
* `<Logo mark="godx" />` paints, at the same 32×32 viewBox and the same coordinates (a test asserts
|
|
6
6
|
* the capsule path is byte-identical to the component's, so the two can never diverge). A capsule
|
|
7
|
-
* WITHOUT the internal glyph is the incomplete mark and must not ship.
|
|
7
|
+
* WITHOUT the internal glyph is the incomplete mark and must not ship. The ARTWORK matches the
|
|
8
|
+
* canonical SCR-302 raster exactly; only the rendered BOX is email-specific — the canonical email
|
|
9
|
+
* header sets it at 22px (`--email-mark-width`) beside the "GoDX" wordmark, where the web
|
|
10
|
+
* `<Logo mark="godx" />` box is 32px.
|
|
8
11
|
*
|
|
9
12
|
* Nothing here references an external or relative asset: an email template has no base URL it can
|
|
10
13
|
* trust, remote images are blocked by default in most clients, and a `cid:` attachment needs
|
|
@@ -16,8 +19,10 @@
|
|
|
16
19
|
* Renders everywhere; degrades to a square emerald block with a light bar in Outlook's Word
|
|
17
20
|
* renderer (which drops `border-radius`) — still recognisably the mark, never a broken image.
|
|
18
21
|
*
|
|
19
|
-
* Colours come from `EMAIL_COLORS` (derived from `--
|
|
20
|
-
* `--logo-godx-color`
|
|
22
|
+
* Colours come from `EMAIL_COLORS` (derived from `--brand` / `--brand-foreground`, the roles
|
|
23
|
+
* `--logo-godx-color` points at), so a re-themed identity role re-tints the mark. NOT `--success`:
|
|
24
|
+
* that is the wakatake STATUS green, and binding identity to it rendered the mark ~ΔE76 17 away
|
|
25
|
+
* from the canonical emerald until gh#250 introduced the dedicated `--brand` role.
|
|
21
26
|
*/
|
|
22
27
|
import { type EmailHex } from "./color.js";
|
|
23
28
|
/** A rounded rectangle in the mark's 32×32 coordinate space. */
|
|
@@ -42,9 +47,9 @@ export declare const EMAIL_BRAND_MARK_GLYPH: EmailBrandMarkRect;
|
|
|
42
47
|
export declare function roundedRectPath({ x, y, width, height, radius }: EmailBrandMarkRect): string;
|
|
43
48
|
/** Options for rendering the mark. Every default comes from the token contract. */
|
|
44
49
|
export interface EmailBrandMarkOptions {
|
|
45
|
-
/** Rendered width in px. Default `EMAIL_BRAND_MARK.widthPx` (
|
|
50
|
+
/** Rendered width in px. Default `EMAIL_BRAND_MARK.widthPx` (the canonical 22px header box). */
|
|
46
51
|
width?: number;
|
|
47
|
-
/** Rendered height in px. Default `EMAIL_BRAND_MARK.heightPx` (
|
|
52
|
+
/** Rendered height in px. Default `EMAIL_BRAND_MARK.heightPx` (the canonical 22px header box). */
|
|
48
53
|
height?: number;
|
|
49
54
|
/** Capsule fill. Default `EMAIL_COLORS.brand`. */
|
|
50
55
|
color?: EmailHex;
|
|
@@ -82,6 +87,17 @@ export interface EmailBrandMark {
|
|
|
82
87
|
readonly glyph: EmailBrandMarkRect;
|
|
83
88
|
readonly capsulePath: string;
|
|
84
89
|
readonly glyphPath: string;
|
|
90
|
+
/**
|
|
91
|
+
* Mark ↔ wordmark separation in the canonical header LOCKUP. The mark alone is not the header:
|
|
92
|
+
* the canonical card sets the mark beside a readable "GoDX" wordmark, and the wordmark — not the
|
|
93
|
+
* mark — carries the accessible name (render the mark with `label: ""` in that pairing).
|
|
94
|
+
*/
|
|
95
|
+
readonly gap: string;
|
|
96
|
+
readonly gapPx: number;
|
|
97
|
+
/** Wordmark type size in the lockup. */
|
|
98
|
+
readonly wordmarkFontSize: string;
|
|
99
|
+
readonly wordmarkFontSizePx: number;
|
|
100
|
+
readonly wordmarkFontWeight: number;
|
|
85
101
|
/** Inline `<svg>` — highest fidelity. */
|
|
86
102
|
readonly svg: string;
|
|
87
103
|
/** `data:` URL of the same SVG, for `<img src>`. */
|
package/dist/email/brand-mark.js
CHANGED
|
@@ -67,6 +67,11 @@ const EMAIL_BRAND_MARK = Object.freeze({
|
|
|
67
67
|
glyph: EMAIL_BRAND_MARK_GLYPH,
|
|
68
68
|
capsulePath: CAPSULE_PATH,
|
|
69
69
|
glyphPath: GLYPH_PATH,
|
|
70
|
+
gap: EMAIL_GEOMETRY_SOURCE["--email-mark-gap"],
|
|
71
|
+
gapPx: Number.parseFloat(EMAIL_GEOMETRY_SOURCE["--email-mark-gap"]),
|
|
72
|
+
wordmarkFontSize: EMAIL_GEOMETRY_SOURCE["--email-wordmark-font-size"],
|
|
73
|
+
wordmarkFontSizePx: Number.parseFloat(EMAIL_GEOMETRY_SOURCE["--email-wordmark-font-size"]),
|
|
74
|
+
wordmarkFontWeight: Number.parseFloat(EMAIL_GEOMETRY_SOURCE["--email-wordmark-font-weight"]),
|
|
70
75
|
svg: emailBrandMarkSvg(),
|
|
71
76
|
dataUri: emailBrandMarkDataUri(),
|
|
72
77
|
tableHtml: emailBrandMarkTableHtml()
|
package/dist/email/color.d.ts
CHANGED
|
@@ -41,7 +41,8 @@ export declare function hslToHex(triplet: string): EmailHex;
|
|
|
41
41
|
* | `border` | `--border` | card edge, footer hairline |
|
|
42
42
|
* | `primary` / `primaryForeground`| `--primary` / `--primary-foreground` | the one CTA |
|
|
43
43
|
* | `focus` | `--ring` | focus affordance in webmail panes |
|
|
44
|
-
* | `brand` / `brandForeground` | `--
|
|
44
|
+
* | `brand` / `brandForeground` | `--brand` / `--brand-foreground` | the GoDX capsule + its glyph |
|
|
45
|
+
* | `urgency` / `urgencyForeground`| `--attention` / `--attention-foreground` | action-required accent / solid large label |
|
|
45
46
|
*/
|
|
46
47
|
export declare const EMAIL_COLORS: Readonly<Record<EmailColorToken, EmailHex>>;
|
|
47
48
|
/**
|
package/dist/email/geometry.d.ts
CHANGED
|
@@ -45,8 +45,16 @@ export interface EmailShellTokens {
|
|
|
45
45
|
export declare const EMAIL_SHELL: EmailShellTokens;
|
|
46
46
|
/** Type ramp. Sizes are literal px — no email client resolves the rem scale reliably. */
|
|
47
47
|
export interface EmailTypographyTokens {
|
|
48
|
-
/**
|
|
48
|
+
/**
|
|
49
|
+
* The canonical DXS stack, M PLUS 2 first. Web-font `@font-face` is unavailable in most clients,
|
|
50
|
+
* so this NAMES the face and degrades: a client with M PLUS 2 installed (or a webmail that
|
|
51
|
+
* already loaded it) renders the canonical face; everything else falls to Hiragino (macOS/iOS) →
|
|
52
|
+
* Yu Gothic (Windows) → Noto Sans JP → Meiryo → the system UI face → Arial → `sans-serif`. Family
|
|
53
|
+
* names are SINGLE-quoted so the value drops straight into a double-quoted `style="…"` attribute.
|
|
54
|
+
*/
|
|
49
55
|
readonly fontFamily: string;
|
|
56
|
+
/** Mono stack for invoice ids, masked card numbers, ISO dates and amounts. */
|
|
57
|
+
readonly monoFontFamily: string;
|
|
50
58
|
readonly bodyFontSize: string;
|
|
51
59
|
readonly bodyFontSizePx: number;
|
|
52
60
|
readonly bodyLineHeight: number;
|
package/dist/email/geometry.js
CHANGED
|
@@ -30,6 +30,7 @@ const EMAIL_SHELL = Object.freeze({
|
|
|
30
30
|
});
|
|
31
31
|
const EMAIL_TYPOGRAPHY = Object.freeze({
|
|
32
32
|
fontFamily: raw("--email-font-family-sans"),
|
|
33
|
+
monoFontFamily: raw("--email-font-family-mono"),
|
|
33
34
|
bodyFontSize: raw("--email-body-font-size"),
|
|
34
35
|
bodyFontSizePx: num("--email-body-font-size"),
|
|
35
36
|
bodyLineHeight: num("--email-body-line-height"),
|
package/dist/email/index.d.ts
CHANGED
|
@@ -23,13 +23,14 @@
|
|
|
23
23
|
* ## Usage
|
|
24
24
|
*
|
|
25
25
|
* ```ts
|
|
26
|
-
* import { EMAIL_COLORS, EMAIL_SHELL, EMAIL_CTA, EMAIL_BRAND_MARK, emailInlineStyle } from "@godxjp/ui/email";
|
|
26
|
+
* import { EMAIL_COLORS, EMAIL_URGENCY, EMAIL_SHELL, EMAIL_CTA, EMAIL_BRAND_MARK, emailInlineStyle } from "@godxjp/ui/email";
|
|
27
27
|
*
|
|
28
28
|
* const card = emailInlineStyle({
|
|
29
29
|
* width: EMAIL_SHELL.width,
|
|
30
30
|
* padding: EMAIL_SHELL.padding,
|
|
31
31
|
* backgroundColor: EMAIL_COLORS.surface,
|
|
32
32
|
* border: `${EMAIL_SHELL.borderWidth} solid ${EMAIL_COLORS.border}`,
|
|
33
|
+
* borderTopColor: EMAIL_URGENCY.accent,
|
|
33
34
|
* borderRadius: EMAIL_SHELL.radius,
|
|
34
35
|
* });
|
|
35
36
|
* ```
|
|
@@ -52,14 +53,18 @@ export { hslToHex, EMAIL_COLORS, EMAIL_COLORS_DARK, type EmailColorToken, type E
|
|
|
52
53
|
export { EMAIL_SHELL, EMAIL_TYPOGRAPHY, EMAIL_CTA, EMAIL_FOOTER, EMAIL_FOCUS, EMAIL_MOBILE, type EmailTokenName, type EmailShellTokens, type EmailTypographyTokens, type EmailCtaTokens, type EmailFooterTokens, type EmailFocusTokens, type EmailMobileTokens, } from "./geometry.js";
|
|
53
54
|
export { EMAIL_BRAND_MARK, EMAIL_BRAND_MARK_VIEWBOX, EMAIL_BRAND_MARK_CAPSULE, EMAIL_BRAND_MARK_GLYPH, emailBrandMarkSvg, emailBrandMarkDataUri, emailBrandMarkTableHtml, roundedRectPath, type EmailBrandMark, type EmailBrandMarkOptions, type EmailBrandMarkRect, } from "./brand-mark.js";
|
|
54
55
|
export { emailInlineStyle, type EmailStyleDeclarations } from "./inline-style.js";
|
|
56
|
+
export { EMAIL_URGENCY, EMAIL_URGENCY_DARK, type EmailUrgencyTokens } from "./urgency.js";
|
|
55
57
|
export { EMAIL_COLOR_SOURCE, EMAIL_COLOR_SOURCE_DARK, EMAIL_GEOMETRY_SOURCE, type EmailColorSource, } from "./tokens.generated.js";
|
|
56
58
|
import { EMAIL_COLORS, EMAIL_COLORS_DARK } from "./color.js";
|
|
57
59
|
import { EMAIL_SHELL, EMAIL_TYPOGRAPHY, EMAIL_CTA, EMAIL_FOOTER, EMAIL_FOCUS, EMAIL_MOBILE } from "./geometry.js";
|
|
58
60
|
import { EMAIL_BRAND_MARK } from "./brand-mark.js";
|
|
61
|
+
import { EMAIL_URGENCY, EMAIL_URGENCY_DARK } from "./urgency.js";
|
|
59
62
|
/** The whole contract in one object — the shape `EMAIL_TOKENS_JSON` serialises. */
|
|
60
63
|
export interface EmailTokens {
|
|
61
64
|
readonly colors: typeof EMAIL_COLORS;
|
|
62
65
|
readonly colorsDark: typeof EMAIL_COLORS_DARK;
|
|
66
|
+
readonly urgency: typeof EMAIL_URGENCY;
|
|
67
|
+
readonly urgencyDark: typeof EMAIL_URGENCY_DARK;
|
|
63
68
|
readonly shell: typeof EMAIL_SHELL;
|
|
64
69
|
readonly typography: typeof EMAIL_TYPOGRAPHY;
|
|
65
70
|
readonly cta: typeof EMAIL_CTA;
|