@oods/components-react 0.3.3 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/chunk-2VEQWKGK.js +1 -0
- package/dist/{chunk-BPEHI36W.js → chunk-NLWXBLPA.js} +227 -8
- package/dist/{chunk-XAWAMZUQ.js → chunk-XEX22E24.js} +3 -2
- package/dist/index.cjs +642 -472
- package/dist/index.d.cts +27 -6
- package/dist/index.d.ts +27 -6
- package/dist/index.js +366 -89
- package/dist/ported.cjs +232 -344
- package/dist/ported.js +2 -2
- package/dist/status.cjs +22 -342
- package/dist/status.d.cts +1 -35
- package/dist/status.d.ts +1 -35
- package/dist/status.js +1 -1
- package/dist/table.cjs +5 -303
- package/dist/table.js +2 -2
- package/dist/types.d.cts +111 -3
- package/dist/types.d.ts +111 -3
- package/evidence/react-readiness.v1.json +293 -1
- package/package.json +3 -3
- package/dist/chunk-G74PKSW3.js +0 -338
package/dist/ported.cjs
CHANGED
|
@@ -26,337 +26,6 @@ function _interopNamespace(e) {
|
|
|
26
26
|
var React3__namespace = /*#__PURE__*/_interopNamespace(React3);
|
|
27
27
|
|
|
28
28
|
// src/ported.tsx
|
|
29
|
-
|
|
30
|
-
// src/status-map.json
|
|
31
|
-
var status_map_default = {
|
|
32
|
-
domains: {
|
|
33
|
-
subscription: {
|
|
34
|
-
future: {
|
|
35
|
-
description: "Subscription is scheduled but not yet active.",
|
|
36
|
-
chip: {
|
|
37
|
-
foreground: "color.text.info",
|
|
38
|
-
background: "color.background.info.subtle",
|
|
39
|
-
border: "color.border.info",
|
|
40
|
-
icon: "icon.status.scheduled"
|
|
41
|
-
},
|
|
42
|
-
banner: {
|
|
43
|
-
foreground: "color.text.info",
|
|
44
|
-
background: "color.background.surface.default",
|
|
45
|
-
border: "color.border.info",
|
|
46
|
-
icon: "icon.status.scheduled"
|
|
47
|
-
}
|
|
48
|
-
},
|
|
49
|
-
trialing: {
|
|
50
|
-
description: "Subscription is in a trial period before billing begins.",
|
|
51
|
-
chip: {
|
|
52
|
-
foreground: "color.text.accent",
|
|
53
|
-
background: "color.background.accent.subtle",
|
|
54
|
-
border: "color.border.accent",
|
|
55
|
-
icon: "icon.status.trial"
|
|
56
|
-
},
|
|
57
|
-
banner: {
|
|
58
|
-
foreground: "color.text.accent",
|
|
59
|
-
background: "color.background.surface.default",
|
|
60
|
-
border: "color.border.accent",
|
|
61
|
-
icon: "icon.status.trial"
|
|
62
|
-
}
|
|
63
|
-
},
|
|
64
|
-
active: {
|
|
65
|
-
description: "Subscription is paid and service is provisioned.",
|
|
66
|
-
chip: {
|
|
67
|
-
foreground: "color.text.positive",
|
|
68
|
-
background: "color.background.positive.subtle",
|
|
69
|
-
border: "color.border.positive",
|
|
70
|
-
icon: "icon.status.success"
|
|
71
|
-
},
|
|
72
|
-
banner: {
|
|
73
|
-
foreground: "color.text.positive",
|
|
74
|
-
background: "color.background.surface.default",
|
|
75
|
-
border: "color.border.positive",
|
|
76
|
-
icon: "icon.status.success"
|
|
77
|
-
}
|
|
78
|
-
},
|
|
79
|
-
paused: {
|
|
80
|
-
description: "Billing paused temporarily by finance or customer request.",
|
|
81
|
-
chip: {
|
|
82
|
-
foreground: "color.text.neutral",
|
|
83
|
-
background: "color.background.neutral.subtle",
|
|
84
|
-
border: "color.border.neutral",
|
|
85
|
-
icon: "icon.status.paused"
|
|
86
|
-
},
|
|
87
|
-
banner: {
|
|
88
|
-
foreground: "color.text.neutral",
|
|
89
|
-
background: "color.background.surface.muted",
|
|
90
|
-
border: "color.border.neutral",
|
|
91
|
-
icon: "icon.status.paused"
|
|
92
|
-
}
|
|
93
|
-
},
|
|
94
|
-
pending_cancellation: {
|
|
95
|
-
description: "Subscription will cancel at period end but remains active now.",
|
|
96
|
-
chip: {
|
|
97
|
-
foreground: "color.text.info",
|
|
98
|
-
background: "color.background.info.subtle",
|
|
99
|
-
border: "color.border.info",
|
|
100
|
-
icon: "icon.status.pending"
|
|
101
|
-
},
|
|
102
|
-
banner: {
|
|
103
|
-
foreground: "color.text.info",
|
|
104
|
-
background: "color.background.surface.default",
|
|
105
|
-
border: "color.border.info",
|
|
106
|
-
icon: "icon.status.pending"
|
|
107
|
-
}
|
|
108
|
-
},
|
|
109
|
-
past_due: {
|
|
110
|
-
description: "Renewal payment failed; smart retries ongoing and access retained during the grace window.",
|
|
111
|
-
chip: {
|
|
112
|
-
foreground: "color.text.danger",
|
|
113
|
-
background: "color.background.danger.subtle",
|
|
114
|
-
border: "color.border.danger",
|
|
115
|
-
icon: "icon.status.warning"
|
|
116
|
-
},
|
|
117
|
-
banner: {
|
|
118
|
-
foreground: "color.text.onbold",
|
|
119
|
-
background: "color.background.danger.bold",
|
|
120
|
-
border: "color.border.danger",
|
|
121
|
-
icon: "icon.status.warning"
|
|
122
|
-
}
|
|
123
|
-
},
|
|
124
|
-
unpaid: {
|
|
125
|
-
description: "Payment retries exhausted; service access revoked.",
|
|
126
|
-
chip: {
|
|
127
|
-
foreground: "color.text.danger",
|
|
128
|
-
background: "color.background.danger.subtle",
|
|
129
|
-
border: "color.border.danger",
|
|
130
|
-
icon: "icon.status.error"
|
|
131
|
-
},
|
|
132
|
-
banner: {
|
|
133
|
-
foreground: "color.text.onbold",
|
|
134
|
-
background: "color.background.danger.bold",
|
|
135
|
-
border: "color.border.danger",
|
|
136
|
-
icon: "icon.status.error"
|
|
137
|
-
}
|
|
138
|
-
},
|
|
139
|
-
terminated: {
|
|
140
|
-
description: "Subscription ended; service access revoked and billing stopped.",
|
|
141
|
-
chip: {
|
|
142
|
-
foreground: "color.text.disabled",
|
|
143
|
-
background: "color.background.disabled",
|
|
144
|
-
border: "color.border.disabled",
|
|
145
|
-
icon: "icon.status.canceled"
|
|
146
|
-
},
|
|
147
|
-
banner: {
|
|
148
|
-
foreground: "color.text.neutral",
|
|
149
|
-
background: "color.background.neutral.subtle",
|
|
150
|
-
border: "color.border.neutral",
|
|
151
|
-
icon: "icon.status.canceled"
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
},
|
|
155
|
-
invoice: {
|
|
156
|
-
draft: {
|
|
157
|
-
description: "Invoice is editable and not yet finalized.",
|
|
158
|
-
chip: {
|
|
159
|
-
foreground: "color.text.neutral",
|
|
160
|
-
background: "color.background.neutral.subtle",
|
|
161
|
-
border: "color.border.neutral",
|
|
162
|
-
icon: "icon.status.draft"
|
|
163
|
-
},
|
|
164
|
-
banner: {
|
|
165
|
-
foreground: "color.text.neutral",
|
|
166
|
-
background: "color.background.surface.muted",
|
|
167
|
-
border: "color.border.neutral",
|
|
168
|
-
icon: "icon.status.draft"
|
|
169
|
-
}
|
|
170
|
-
},
|
|
171
|
-
posted: {
|
|
172
|
-
description: "Invoice finalized with terms before collection.",
|
|
173
|
-
chip: {
|
|
174
|
-
foreground: "color.text.info",
|
|
175
|
-
background: "color.background.info.subtle",
|
|
176
|
-
border: "color.border.info",
|
|
177
|
-
icon: "icon.status.pending"
|
|
178
|
-
},
|
|
179
|
-
banner: {
|
|
180
|
-
foreground: "color.text.info",
|
|
181
|
-
background: "color.background.surface.default",
|
|
182
|
-
border: "color.border.info",
|
|
183
|
-
icon: "icon.status.pending"
|
|
184
|
-
}
|
|
185
|
-
},
|
|
186
|
-
paid: {
|
|
187
|
-
description: "Invoice collected successfully in full.",
|
|
188
|
-
chip: {
|
|
189
|
-
foreground: "color.text.positive",
|
|
190
|
-
background: "color.background.positive.subtle",
|
|
191
|
-
border: "color.border.positive",
|
|
192
|
-
icon: "icon.status.success"
|
|
193
|
-
},
|
|
194
|
-
banner: {
|
|
195
|
-
foreground: "color.text.positive",
|
|
196
|
-
background: "color.background.surface.default",
|
|
197
|
-
border: "color.border.positive",
|
|
198
|
-
icon: "icon.status.success"
|
|
199
|
-
}
|
|
200
|
-
},
|
|
201
|
-
past_due: {
|
|
202
|
-
description: "Invoice is unpaid past its due date.",
|
|
203
|
-
chip: {
|
|
204
|
-
foreground: "color.text.danger",
|
|
205
|
-
background: "color.background.danger.subtle",
|
|
206
|
-
border: "color.border.danger",
|
|
207
|
-
icon: "icon.status.error"
|
|
208
|
-
},
|
|
209
|
-
banner: {
|
|
210
|
-
foreground: "color.text.onbold",
|
|
211
|
-
background: "color.background.danger.bold",
|
|
212
|
-
border: "color.border.danger",
|
|
213
|
-
icon: "icon.status.error"
|
|
214
|
-
}
|
|
215
|
-
},
|
|
216
|
-
void: {
|
|
217
|
-
description: "Invoice canceled and no longer payable.",
|
|
218
|
-
chip: {
|
|
219
|
-
foreground: "color.text.disabled",
|
|
220
|
-
background: "color.background.disabled",
|
|
221
|
-
border: "color.border.disabled",
|
|
222
|
-
icon: "icon.status.void"
|
|
223
|
-
},
|
|
224
|
-
banner: {
|
|
225
|
-
foreground: "color.text.neutral",
|
|
226
|
-
background: "color.background.neutral.subtle",
|
|
227
|
-
border: "color.border.neutral",
|
|
228
|
-
icon: "icon.status.void"
|
|
229
|
-
}
|
|
230
|
-
}
|
|
231
|
-
}
|
|
232
|
-
}
|
|
233
|
-
};
|
|
234
|
-
|
|
235
|
-
// src/status.ts
|
|
236
|
-
var TONE_ALIASES = {
|
|
237
|
-
info: "info",
|
|
238
|
-
informational: "info",
|
|
239
|
-
accent: "accent",
|
|
240
|
-
highlight: "accent",
|
|
241
|
-
positive: "success",
|
|
242
|
-
success: "success",
|
|
243
|
-
ok: "success",
|
|
244
|
-
warning: "warning",
|
|
245
|
-
caution: "warning",
|
|
246
|
-
danger: "critical",
|
|
247
|
-
critical: "critical",
|
|
248
|
-
error: "critical",
|
|
249
|
-
negative: "critical",
|
|
250
|
-
neutral: "neutral",
|
|
251
|
-
pending: "info"
|
|
252
|
-
};
|
|
253
|
-
var toLabel = (status) => status.split(/[_-]/).filter(Boolean).map((segment) => segment.charAt(0).toUpperCase() + segment.slice(1)).join(" ");
|
|
254
|
-
var inferTone = (entry) => {
|
|
255
|
-
if (!entry) return "neutral";
|
|
256
|
-
for (const reference of [entry.foreground, entry.background, entry.border]) {
|
|
257
|
-
const segments = reference.replace(/^\{|\}$/g, "").split(/[\s./_-]+/).reverse();
|
|
258
|
-
for (const segment of segments) {
|
|
259
|
-
const tone = TONE_ALIASES[segment.toLowerCase()];
|
|
260
|
-
if (tone) return tone;
|
|
261
|
-
}
|
|
262
|
-
}
|
|
263
|
-
return "neutral";
|
|
264
|
-
};
|
|
265
|
-
var componentTokenSet = (tone) => {
|
|
266
|
-
const normalized = tone === "positive" ? "success" : tone === "danger" ? "critical" : tone;
|
|
267
|
-
return {
|
|
268
|
-
background: `var(--sys-status-${normalized}-surface)`,
|
|
269
|
-
border: `var(--sys-status-${normalized}-border)`,
|
|
270
|
-
foreground: `var(--sys-status-${normalized}-text)`
|
|
271
|
-
};
|
|
272
|
-
};
|
|
273
|
-
var rawTokenSet = (entry) => {
|
|
274
|
-
const tone = inferTone(entry);
|
|
275
|
-
return componentTokenSet(tone);
|
|
276
|
-
};
|
|
277
|
-
var bannerFallback = (tone) => tone === "neutral" ? {
|
|
278
|
-
background: "var(--cmp-banner-background)",
|
|
279
|
-
border: "var(--cmp-banner-border)",
|
|
280
|
-
foreground: "var(--cmp-banner-text)"
|
|
281
|
-
} : componentTokenSet(tone);
|
|
282
|
-
var fallback = (domain, status, tone = "neutral") => ({
|
|
283
|
-
domain,
|
|
284
|
-
status,
|
|
285
|
-
label: toLabel(status || "Unknown"),
|
|
286
|
-
description: "Status not found in registry; falling back to the requested token set.",
|
|
287
|
-
tone,
|
|
288
|
-
badge: { subtle: componentTokenSet(tone), solid: componentTokenSet(tone) },
|
|
289
|
-
banner: { subtle: bannerFallback(tone), solid: componentTokenSet(tone) }
|
|
290
|
-
});
|
|
291
|
-
var registry = /* @__PURE__ */ new Map();
|
|
292
|
-
for (const [domain, entries] of Object.entries(status_map_default.domains)) {
|
|
293
|
-
const domainEntries = /* @__PURE__ */ new Map();
|
|
294
|
-
for (const [status, entry] of Object.entries(entries)) {
|
|
295
|
-
const tone = inferTone(entry.chip);
|
|
296
|
-
domainEntries.set(status.toLowerCase(), {
|
|
297
|
-
domain,
|
|
298
|
-
status,
|
|
299
|
-
label: toLabel(status),
|
|
300
|
-
description: entry.description,
|
|
301
|
-
tone,
|
|
302
|
-
iconName: entry.chip.icon ?? entry.banner?.icon,
|
|
303
|
-
badge: { subtle: rawTokenSet(entry.chip), solid: componentTokenSet(tone) },
|
|
304
|
-
banner: {
|
|
305
|
-
subtle: entry.banner ? rawTokenSet(entry.banner) : bannerFallback(tone),
|
|
306
|
-
solid: componentTokenSet(tone)
|
|
307
|
-
}
|
|
308
|
-
});
|
|
309
|
-
}
|
|
310
|
-
registry.set(domain, domainEntries);
|
|
311
|
-
}
|
|
312
|
-
var LEGACY_STATUS_ALIASES = {
|
|
313
|
-
subscription: { delinquent: "unpaid" }
|
|
314
|
-
};
|
|
315
|
-
Object.freeze([...registry.keys()]);
|
|
316
|
-
function getStatusPresentation(domain, status) {
|
|
317
|
-
const entries = registry.get(domain);
|
|
318
|
-
if (!entries) return fallback(domain, status);
|
|
319
|
-
const normalized = status.toLowerCase();
|
|
320
|
-
const direct = entries.get(normalized);
|
|
321
|
-
if (direct) return direct;
|
|
322
|
-
const alias = LEGACY_STATUS_ALIASES[domain]?.[normalized];
|
|
323
|
-
const aliased = alias ? entries.get(alias) : void 0;
|
|
324
|
-
return aliased ? { ...aliased, status, label: toLabel(status) } : fallback(domain, status);
|
|
325
|
-
}
|
|
326
|
-
function getToneTokenSet(tone) {
|
|
327
|
-
return componentTokenSet(tone);
|
|
328
|
-
}
|
|
329
|
-
function getBannerToneTokenSet(tone) {
|
|
330
|
-
return bannerFallback(tone);
|
|
331
|
-
}
|
|
332
|
-
var ICON_GLYPHS = {
|
|
333
|
-
success: "\u2714\uFE0E",
|
|
334
|
-
warning: "\u26A0\uFE0E",
|
|
335
|
-
critical: "\u2A2F",
|
|
336
|
-
danger: "\u2A2F",
|
|
337
|
-
error: "\u2A2F",
|
|
338
|
-
negative: "\u2A2F",
|
|
339
|
-
pending: "\u2026",
|
|
340
|
-
processing: "\u27F3",
|
|
341
|
-
paused: "\u23F8",
|
|
342
|
-
canceled: "\u2205",
|
|
343
|
-
cancelled: "\u2205",
|
|
344
|
-
draft: "\u270E",
|
|
345
|
-
void: "\u2205",
|
|
346
|
-
paid: "\u2714\uFE0E",
|
|
347
|
-
info: "\u2139\uFE0E",
|
|
348
|
-
trial: "\u2605",
|
|
349
|
-
future: "\u23F2",
|
|
350
|
-
scheduled: "\u23F2",
|
|
351
|
-
refunded: "\u21BA",
|
|
352
|
-
locked: "\u{1F512}",
|
|
353
|
-
unlocked: "\u{1F513}",
|
|
354
|
-
default: "\u2022"
|
|
355
|
-
};
|
|
356
|
-
function resolveStatusGlyph(iconName) {
|
|
357
|
-
const segment = iconName?.split(".").pop()?.toLowerCase();
|
|
358
|
-
return segment ? ICON_GLYPHS[segment] ?? ICON_GLYPHS.default : void 0;
|
|
359
|
-
}
|
|
360
29
|
var classes = (...values) => values.filter(Boolean).join(" ");
|
|
361
30
|
var describedByIds = (id, help, validation, nativeDescription) => [
|
|
362
31
|
nativeDescription,
|
|
@@ -383,7 +52,7 @@ var FieldFrame = ({
|
|
|
383
52
|
}) => {
|
|
384
53
|
const resolvedHelp = help ?? description;
|
|
385
54
|
const validationTone = validation?.state === "error" ? "critical" : validation?.state === "warning" ? "warning" : validation?.state;
|
|
386
|
-
const validationTokens = validationTone ? getToneTokenSet(validationTone) : void 0;
|
|
55
|
+
const validationTokens = validationTone ? componentContracts.getToneTokenSet(validationTone) : void 0;
|
|
387
56
|
const validationStyle = validationTokens ? {
|
|
388
57
|
"--cmp-input-message-border": validationTokens.border,
|
|
389
58
|
"--cmp-input-message-text": validationTokens.foreground,
|
|
@@ -583,6 +252,84 @@ var Checkbox = React3__namespace.forwardRef(
|
|
|
583
252
|
}
|
|
584
253
|
);
|
|
585
254
|
Checkbox.displayName = "OODS.Checkbox";
|
|
255
|
+
var Switch = React3__namespace.forwardRef(
|
|
256
|
+
({
|
|
257
|
+
id,
|
|
258
|
+
label,
|
|
259
|
+
checked,
|
|
260
|
+
defaultChecked = false,
|
|
261
|
+
required,
|
|
262
|
+
help,
|
|
263
|
+
validation,
|
|
264
|
+
size = "md",
|
|
265
|
+
className,
|
|
266
|
+
style,
|
|
267
|
+
onClick,
|
|
268
|
+
onCheckedChange,
|
|
269
|
+
onUpdate,
|
|
270
|
+
"aria-describedby": nativeDescription,
|
|
271
|
+
...rest
|
|
272
|
+
}, ref) => {
|
|
273
|
+
const [internalChecked, setInternalChecked] = React3__namespace.useState(defaultChecked);
|
|
274
|
+
const on = checked ?? internalChecked;
|
|
275
|
+
const validationId = validation?.id ?? `${id}-validation`;
|
|
276
|
+
const describedBy = [nativeDescription, help ? `${id}-help` : void 0, validation?.message ? validationId : void 0].filter(Boolean).join(" ") || void 0;
|
|
277
|
+
const tone = validation ? validation.state === "error" ? "critical" : validation.state : void 0;
|
|
278
|
+
const handleClick = (event) => {
|
|
279
|
+
onClick?.(event);
|
|
280
|
+
if (event.defaultPrevented) return;
|
|
281
|
+
const next = !on;
|
|
282
|
+
if (checked === void 0) setInternalChecked(next);
|
|
283
|
+
onCheckedChange?.(next);
|
|
284
|
+
onUpdate?.(next);
|
|
285
|
+
};
|
|
286
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
287
|
+
"div",
|
|
288
|
+
{
|
|
289
|
+
className: classes("oods-field", "oods-switch", className),
|
|
290
|
+
style: {
|
|
291
|
+
...tone ? {
|
|
292
|
+
"--cmp-input-message-border": `var(--sys-status-${tone}-border)`,
|
|
293
|
+
"--cmp-input-message-text": `var(--sys-status-${tone}-text)`
|
|
294
|
+
} : {},
|
|
295
|
+
...style
|
|
296
|
+
},
|
|
297
|
+
"data-oods-component": "Switch",
|
|
298
|
+
"data-size": size,
|
|
299
|
+
"data-validation-state": validation?.state,
|
|
300
|
+
children: [
|
|
301
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "oods-switch__row", children: [
|
|
302
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
303
|
+
"button",
|
|
304
|
+
{
|
|
305
|
+
ref,
|
|
306
|
+
id,
|
|
307
|
+
type: "button",
|
|
308
|
+
role: "switch",
|
|
309
|
+
className: "oods-switch__control",
|
|
310
|
+
"aria-checked": on,
|
|
311
|
+
"aria-labelledby": `${id}-label`,
|
|
312
|
+
"aria-describedby": describedBy,
|
|
313
|
+
"aria-required": required || void 0,
|
|
314
|
+
"aria-invalid": validation?.state === "error" || void 0,
|
|
315
|
+
onClick: handleClick,
|
|
316
|
+
...rest,
|
|
317
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "oods-switch__thumb", "aria-hidden": "true" })
|
|
318
|
+
}
|
|
319
|
+
),
|
|
320
|
+
/* @__PURE__ */ jsxRuntime.jsxs("label", { id: `${id}-label`, className: "oods-field-label oods-switch__label", htmlFor: id, children: [
|
|
321
|
+
label,
|
|
322
|
+
required ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "oods-field-required", "aria-hidden": "true", children: "*" }) : null
|
|
323
|
+
] })
|
|
324
|
+
] }),
|
|
325
|
+
help ? /* @__PURE__ */ jsxRuntime.jsx("p", { id: `${id}-help`, className: "oods-field-help", children: help }) : null,
|
|
326
|
+
validation?.message ? /* @__PURE__ */ jsxRuntime.jsx("p", { id: validationId, className: "oods-field-error", role: validation.state === "error" ? "alert" : void 0, children: validation.message }) : null
|
|
327
|
+
]
|
|
328
|
+
}
|
|
329
|
+
);
|
|
330
|
+
}
|
|
331
|
+
);
|
|
332
|
+
Switch.displayName = "OODS.Switch";
|
|
586
333
|
var Select = React3__namespace.forwardRef(
|
|
587
334
|
({
|
|
588
335
|
id,
|
|
@@ -721,6 +468,20 @@ var Textarea = React3__namespace.forwardRef(
|
|
|
721
468
|
}
|
|
722
469
|
);
|
|
723
470
|
Textarea.displayName = "OODS.Textarea";
|
|
471
|
+
var REACT_NAMES = {
|
|
472
|
+
viewBox: "viewBox",
|
|
473
|
+
fill: "fill",
|
|
474
|
+
stroke: "stroke",
|
|
475
|
+
"stroke-width": "strokeWidth",
|
|
476
|
+
"stroke-linecap": "strokeLinecap",
|
|
477
|
+
"stroke-linejoin": "strokeLinejoin",
|
|
478
|
+
"aria-hidden": "aria-hidden",
|
|
479
|
+
focusable: "focusable"
|
|
480
|
+
};
|
|
481
|
+
var svgProps = Object.fromEntries(Object.entries(componentContracts.STATUS_ICON_SVG_ATTRS).map(([name, value]) => [REACT_NAMES[name] ?? name, value]));
|
|
482
|
+
function StatusIcon({ name }) {
|
|
483
|
+
return /* @__PURE__ */ jsxRuntime.jsx("svg", { ...svgProps, children: componentContracts.STATUS_ICON_SHAPES[name].map((shape, index) => React3__namespace.createElement(shape.tag, { key: index, ...shape.attrs })) });
|
|
484
|
+
}
|
|
724
485
|
var classes2 = (...values) => values.filter(Boolean).join(" ");
|
|
725
486
|
var Badge = React3__namespace.forwardRef(
|
|
726
487
|
({
|
|
@@ -739,11 +500,12 @@ var Badge = React3__namespace.forwardRef(
|
|
|
739
500
|
"aria-label": ariaLabel,
|
|
740
501
|
...rest
|
|
741
502
|
}, ref) => {
|
|
742
|
-
const presentation = status ? getStatusPresentation(domain, status) : void 0;
|
|
503
|
+
const presentation = status ? componentContracts.getStatusPresentation(domain, status) : void 0;
|
|
743
504
|
const tone = toneOverride ?? presentation?.tone ?? "neutral";
|
|
744
|
-
const tokenSet = toneOverride !== void 0 ? getToneTokenSet(tone) : emphasis === "solid" ? presentation?.badge.solid ?? getToneTokenSet(tone) : presentation?.badge.subtle ?? getToneTokenSet(tone);
|
|
505
|
+
const tokenSet = toneOverride !== void 0 ? componentContracts.getToneTokenSet(tone) : emphasis === "solid" ? presentation?.badge.solid ?? componentContracts.getToneTokenSet(tone) : presentation?.badge.subtle ?? componentContracts.getToneTokenSet(tone);
|
|
745
506
|
const resolvedContent = children ?? content ?? presentation?.label ?? status;
|
|
746
|
-
const
|
|
507
|
+
const statusIcon = componentContracts.resolveStatusIcon(presentation?.iconName);
|
|
508
|
+
const resolvedIcon = icon ?? (statusIcon ? /* @__PURE__ */ jsxRuntime.jsx(StatusIcon, { name: statusIcon }) : void 0);
|
|
747
509
|
const resolvedShowIcon = showIcon ?? resolvedIcon !== void 0;
|
|
748
510
|
const iconNode = resolvedShowIcon && resolvedIcon ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "oods-badge__icon", "aria-hidden": "true", children: resolvedIcon }) : null;
|
|
749
511
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
@@ -795,13 +557,14 @@ var Banner = React3__namespace.forwardRef(
|
|
|
795
557
|
style,
|
|
796
558
|
...rest
|
|
797
559
|
}, ref) => {
|
|
798
|
-
const presentation = status ? getStatusPresentation(domain, status) : void 0;
|
|
560
|
+
const presentation = status ? componentContracts.getStatusPresentation(domain, status) : void 0;
|
|
799
561
|
const tone = toneOverride ?? presentation?.tone ?? "neutral";
|
|
800
|
-
const tokenSet = emphasis === "solid" ? presentation?.banner.solid ?? getToneTokenSet(tone) : presentation?.banner.subtle ?? getBannerToneTokenSet(tone);
|
|
562
|
+
const tokenSet = emphasis === "solid" ? presentation?.banner.solid ?? componentContracts.getToneTokenSet(tone) : presentation?.banner.subtle ?? componentContracts.getBannerToneTokenSet(tone);
|
|
801
563
|
const heading = title ?? presentation?.label ?? status;
|
|
802
564
|
const body = detail ?? description ?? children ?? content ?? presentation?.description;
|
|
803
565
|
const role = tone === "critical" || tone === "danger" ? "alert" : "status";
|
|
804
|
-
const
|
|
566
|
+
const statusIcon = componentContracts.resolveStatusIcon(presentation?.iconName);
|
|
567
|
+
const resolvedIcon = icon ?? (statusIcon ? /* @__PURE__ */ jsxRuntime.jsx(StatusIcon, { name: statusIcon }) : void 0);
|
|
805
568
|
const resolvedShowIcon = showIcon ?? resolvedIcon !== void 0;
|
|
806
569
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
807
570
|
"div",
|
|
@@ -836,7 +599,7 @@ var Banner = React3__namespace.forwardRef(
|
|
|
836
599
|
className: "oods-banner-dismiss oods-banner__dismiss",
|
|
837
600
|
"aria-label": dismissLabel,
|
|
838
601
|
onClick: () => onDismiss(),
|
|
839
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
602
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(StatusIcon, { name: "x" })
|
|
840
603
|
}
|
|
841
604
|
) : null
|
|
842
605
|
]
|
|
@@ -891,6 +654,131 @@ var Button = React3__namespace.forwardRef(
|
|
|
891
654
|
}
|
|
892
655
|
);
|
|
893
656
|
Button.displayName = "OODS.Button";
|
|
657
|
+
var noSubscription = () => () => void 0;
|
|
658
|
+
var useIsomorphicLayoutEffect = typeof window === "undefined" ? React3__namespace.useEffect : React3__namespace.useLayoutEffect;
|
|
659
|
+
var canShowModal = () => typeof HTMLDialogElement !== "undefined" && typeof HTMLDialogElement.prototype.showModal === "function";
|
|
660
|
+
var hasContent = (node) => node !== void 0 && node !== null && node !== false && node !== "";
|
|
661
|
+
var pageLocks = 0;
|
|
662
|
+
var pageStyle;
|
|
663
|
+
function lockPageScroll() {
|
|
664
|
+
const page = document.documentElement;
|
|
665
|
+
if (pageLocks++ === 0) {
|
|
666
|
+
const scrollbar = window.innerWidth - page.clientWidth;
|
|
667
|
+
pageStyle = { overflow: page.style.overflow, paddingRight: page.style.paddingRight };
|
|
668
|
+
if (scrollbar > 0) page.style.paddingRight = `${parseFloat(getComputedStyle(page).paddingRight) + scrollbar}px`;
|
|
669
|
+
page.style.overflow = "hidden";
|
|
670
|
+
}
|
|
671
|
+
let held = true;
|
|
672
|
+
return () => {
|
|
673
|
+
if (!held) return;
|
|
674
|
+
held = false;
|
|
675
|
+
if (--pageLocks === 0 && pageStyle) {
|
|
676
|
+
page.style.overflow = pageStyle.overflow;
|
|
677
|
+
page.style.paddingRight = pageStyle.paddingRight;
|
|
678
|
+
pageStyle = void 0;
|
|
679
|
+
}
|
|
680
|
+
};
|
|
681
|
+
}
|
|
682
|
+
var outsideBox = (event, dialog) => {
|
|
683
|
+
const box = dialog.getBoundingClientRect();
|
|
684
|
+
return event.clientX < box.left || event.clientX > box.right || event.clientY < box.top || event.clientY > box.bottom;
|
|
685
|
+
};
|
|
686
|
+
var Dialog = React3__namespace.forwardRef(
|
|
687
|
+
({
|
|
688
|
+
id,
|
|
689
|
+
open = false,
|
|
690
|
+
modal = true,
|
|
691
|
+
title,
|
|
692
|
+
description,
|
|
693
|
+
dismissLabel = "Close",
|
|
694
|
+
size = "md",
|
|
695
|
+
actions,
|
|
696
|
+
children,
|
|
697
|
+
className,
|
|
698
|
+
onClose,
|
|
699
|
+
onKeyDown,
|
|
700
|
+
onMouseDown,
|
|
701
|
+
onClick,
|
|
702
|
+
...rest
|
|
703
|
+
}, ref) => {
|
|
704
|
+
const generatedId = React3__namespace.useId().replace(/[^\w-]/g, "");
|
|
705
|
+
const dialogId = id ?? `oods-dialog-${generatedId}`;
|
|
706
|
+
const element = React3__namespace.useRef(null);
|
|
707
|
+
const openRef = React3__namespace.useRef(open);
|
|
708
|
+
const scrollLock = React3__namespace.useRef(null);
|
|
709
|
+
const pressedBackdrop = React3__namespace.useRef(false);
|
|
710
|
+
const serverMarkup = React3__namespace.useSyncExternalStore(noSubscription, () => false, () => true);
|
|
711
|
+
const managed = modal && !serverMarkup && canShowModal();
|
|
712
|
+
const setRef = React3__namespace.useCallback((node) => {
|
|
713
|
+
element.current = node;
|
|
714
|
+
if (typeof ref === "function") ref(node);
|
|
715
|
+
else if (ref) ref.current = node;
|
|
716
|
+
}, [ref]);
|
|
717
|
+
const releaseScroll = React3__namespace.useCallback(() => {
|
|
718
|
+
scrollLock.current?.();
|
|
719
|
+
scrollLock.current = null;
|
|
720
|
+
}, []);
|
|
721
|
+
useIsomorphicLayoutEffect(() => {
|
|
722
|
+
openRef.current = open;
|
|
723
|
+
const dialog = element.current;
|
|
724
|
+
if (!dialog || !managed) return;
|
|
725
|
+
if (open && !dialog.open) dialog.showModal();
|
|
726
|
+
else if (!open && dialog.open) dialog.close();
|
|
727
|
+
if (open && dialog.open) scrollLock.current ??= lockPageScroll();
|
|
728
|
+
}, [open, managed]);
|
|
729
|
+
React3__namespace.useEffect(() => releaseScroll, [releaseScroll]);
|
|
730
|
+
const requestClose = (event) => {
|
|
731
|
+
event.preventDefault();
|
|
732
|
+
onClose?.();
|
|
733
|
+
};
|
|
734
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
735
|
+
"dialog",
|
|
736
|
+
{
|
|
737
|
+
ref: setRef,
|
|
738
|
+
id: dialogId,
|
|
739
|
+
className: classes2("oods-dialog", className),
|
|
740
|
+
"data-oods-component": "Dialog",
|
|
741
|
+
"data-size": size,
|
|
742
|
+
"aria-labelledby": `${dialogId}-title`,
|
|
743
|
+
"aria-describedby": hasContent(description) ? `${dialogId}-description` : void 0,
|
|
744
|
+
open: managed ? void 0 : open,
|
|
745
|
+
onKeyDown: (event) => {
|
|
746
|
+
onKeyDown?.(event);
|
|
747
|
+
if (event.key === "Escape" && !event.defaultPrevented) requestClose(event);
|
|
748
|
+
},
|
|
749
|
+
onCancel: requestClose,
|
|
750
|
+
onClose: () => {
|
|
751
|
+
if (element.current?.open) return;
|
|
752
|
+
releaseScroll();
|
|
753
|
+
if (openRef.current) onClose?.();
|
|
754
|
+
},
|
|
755
|
+
onMouseDown: (event) => {
|
|
756
|
+
onMouseDown?.(event);
|
|
757
|
+
pressedBackdrop.current = managed && event.target === event.currentTarget && outsideBox(event, event.currentTarget);
|
|
758
|
+
},
|
|
759
|
+
onClick: (event) => {
|
|
760
|
+
onClick?.(event);
|
|
761
|
+
const backdrop = pressedBackdrop.current && event.target === event.currentTarget && outsideBox(event, event.currentTarget);
|
|
762
|
+
pressedBackdrop.current = false;
|
|
763
|
+
if (backdrop && !event.defaultPrevented) onClose?.();
|
|
764
|
+
},
|
|
765
|
+
...rest,
|
|
766
|
+
children: [
|
|
767
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "oods-dialog__header", children: [
|
|
768
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "oods-dialog__heading", children: [
|
|
769
|
+
/* @__PURE__ */ jsxRuntime.jsx("h2", { id: `${dialogId}-title`, className: "oods-dialog__title", children: title }),
|
|
770
|
+
hasContent(description) ? /* @__PURE__ */ jsxRuntime.jsx("p", { id: `${dialogId}-description`, className: "oods-dialog__description", children: description }) : null
|
|
771
|
+
] }),
|
|
772
|
+
/* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "oods-dialog__close", "aria-label": dismissLabel, onClick: () => onClose?.(), children: /* @__PURE__ */ jsxRuntime.jsx(StatusIcon, { name: "x" }) })
|
|
773
|
+
] }),
|
|
774
|
+
hasContent(children) ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "oods-dialog__body", children }) : null,
|
|
775
|
+
hasContent(actions) ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "oods-dialog__footer", children: actions }) : null
|
|
776
|
+
]
|
|
777
|
+
}
|
|
778
|
+
);
|
|
779
|
+
}
|
|
780
|
+
);
|
|
781
|
+
Dialog.displayName = "OODS.Dialog";
|
|
894
782
|
var Card = React3__namespace.forwardRef(
|
|
895
783
|
({ as = "div", elevated = false, className, ...rest }, ref) => {
|
|
896
784
|
const Element = as;
|
|
@@ -961,7 +849,7 @@ var StatusBadge = React3__namespace.forwardRef(
|
|
|
961
849
|
...rest
|
|
962
850
|
}, ref) => {
|
|
963
851
|
const resolvedStatus = status ?? value ?? "unknown";
|
|
964
|
-
const presentation = getStatusPresentation(domain, resolvedStatus);
|
|
852
|
+
const presentation = componentContracts.getStatusPresentation(domain, resolvedStatus);
|
|
965
853
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
966
854
|
Badge,
|
|
967
855
|
{
|
|
@@ -982,8 +870,8 @@ var StatusBadge = React3__namespace.forwardRef(
|
|
|
982
870
|
}
|
|
983
871
|
);
|
|
984
872
|
StatusBadge.displayName = "OODS.StatusBadge";
|
|
985
|
-
function formatPrice(amount, currency,
|
|
986
|
-
if (amount === void 0 || !Number.isFinite(amount)) return
|
|
873
|
+
function formatPrice(amount, currency, fallback) {
|
|
874
|
+
if (amount === void 0 || !Number.isFinite(amount)) return fallback;
|
|
987
875
|
if (!currency) return new Intl.NumberFormat(void 0, { maximumFractionDigits: 2 }).format(amount);
|
|
988
876
|
try {
|
|
989
877
|
return new Intl.NumberFormat(void 0, {
|
|
@@ -1326,7 +1214,7 @@ var SearchInput = React3__namespace.forwardRef(
|
|
|
1326
1214
|
"aria-label": "Clear search",
|
|
1327
1215
|
disabled,
|
|
1328
1216
|
onClick: clear,
|
|
1329
|
-
children: "
|
|
1217
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(StatusIcon, { name: "x" })
|
|
1330
1218
|
}
|
|
1331
1219
|
) : null
|
|
1332
1220
|
]
|
|
@@ -1514,7 +1402,7 @@ var RelativeTimestamp = React3__namespace.forwardRef(
|
|
|
1514
1402
|
const date = asDate(raw);
|
|
1515
1403
|
if (hideWhenEmpty && !date) return null;
|
|
1516
1404
|
const nowDate = asDate(now) ?? /* @__PURE__ */ new Date();
|
|
1517
|
-
const iso = date?.toISOString() ?? (raw === void 0 ? void 0 : String(raw));
|
|
1405
|
+
const iso = date?.toISOString() ?? (raw === void 0 || raw === "" ? void 0 : String(raw));
|
|
1518
1406
|
const absolute = componentContracts.formatDateTime(date, { timeZone: timezone });
|
|
1519
1407
|
const content = relative ?? label ?? text ?? (now !== void 0 && date ? relativeLabel(date, nowDate) : absolute || children || "Unknown time");
|
|
1520
1408
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
package/dist/ported.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { AuditTimeline, CancellationSummary, PaginationBar, PriceBadge, RelativeTimestamp, SearchInput, StatusBadge, StatusTimeline } from './chunk-
|
|
2
|
-
import './chunk-
|
|
1
|
+
export { AuditTimeline, CancellationSummary, PaginationBar, PriceBadge, RelativeTimestamp, SearchInput, StatusBadge, StatusTimeline } from './chunk-NLWXBLPA.js';
|
|
2
|
+
import './chunk-2VEQWKGK.js';
|