@mason-ds/react 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js ADDED
@@ -0,0 +1,886 @@
1
+ // src/provider.tsx
2
+ import { jsx } from "react/jsx-runtime";
3
+ function MasonProvider({ children, theme = "light" }) {
4
+ return /* @__PURE__ */ jsx("div", { "data-mason-provider": true, "data-mason-theme": theme, children });
5
+ }
6
+
7
+ // src/styles.ts
8
+ import { getSemanticCssVar } from "@mason-ds/tokens";
9
+ function cssVar(path) {
10
+ return `var(${getSemanticCssVar(path)})`;
11
+ }
12
+ function spacingVar(axis, level) {
13
+ return cssVar(`spacing.${axis}.${level}`);
14
+ }
15
+ function radiusVar(level) {
16
+ return cssVar(`radius.${level}`);
17
+ }
18
+ function shadowVar(level) {
19
+ return cssVar(`shadow.${level}`);
20
+ }
21
+ function textColorVar(tone) {
22
+ return cssVar(`color.text.${tone}`);
23
+ }
24
+ function typographyStyle(variant) {
25
+ return {
26
+ fontFamily: cssVar(`font.${variant}.family`),
27
+ fontSize: cssVar(`font.${variant}.size`),
28
+ fontWeight: cssVar(`font.${variant}.weight`),
29
+ lineHeight: cssVar(`font.${variant}.lineHeight`),
30
+ letterSpacing: cssVar(`font.${variant}.letterSpacing`)
31
+ };
32
+ }
33
+ function mergeClassName(...parts) {
34
+ const merged = parts.filter(Boolean).join(" ");
35
+ return merged.length > 0 ? merged : void 0;
36
+ }
37
+
38
+ // src/textStyles.ts
39
+ function textStyle({
40
+ variant = "body.md",
41
+ tone = "primary",
42
+ align,
43
+ truncate = false
44
+ }) {
45
+ return {
46
+ margin: 0,
47
+ color: textColorVar(tone),
48
+ ...typographyStyle(variant),
49
+ ...align ? { textAlign: align } : null,
50
+ ...truncate ? { overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" } : null
51
+ };
52
+ }
53
+
54
+ // src/Text.tsx
55
+ import { jsx as jsx2 } from "react/jsx-runtime";
56
+ function Text({
57
+ as = "p",
58
+ variant = "body.md",
59
+ tone = "primary",
60
+ align,
61
+ truncate = false,
62
+ className,
63
+ style,
64
+ children,
65
+ ...rest
66
+ }) {
67
+ const Component = as;
68
+ return /* @__PURE__ */ jsx2(
69
+ Component,
70
+ {
71
+ "data-mason-component": "text",
72
+ "data-variant": variant,
73
+ className: mergeClassName(className),
74
+ style: { ...textStyle({ variant, tone, align, truncate }), ...style },
75
+ ...rest,
76
+ children
77
+ }
78
+ );
79
+ }
80
+
81
+ // src/stackStyles.ts
82
+ var FLEX_ALIGN = {
83
+ start: "flex-start",
84
+ center: "center",
85
+ end: "flex-end",
86
+ stretch: "stretch",
87
+ baseline: "baseline"
88
+ };
89
+ var FLEX_JUSTIFY = {
90
+ start: "flex-start",
91
+ center: "center",
92
+ end: "flex-end",
93
+ between: "space-between"
94
+ };
95
+ function stackStyle({
96
+ direction = "column",
97
+ gap = "md",
98
+ align,
99
+ justify,
100
+ wrap = false,
101
+ inline = false
102
+ }) {
103
+ return {
104
+ display: inline ? "inline-flex" : "flex",
105
+ flexDirection: direction,
106
+ gap: spacingVar(direction === "row" ? "inline" : "stack", gap),
107
+ flexWrap: wrap ? "wrap" : "nowrap",
108
+ minWidth: 0,
109
+ ...align ? { alignItems: FLEX_ALIGN[align] } : null,
110
+ ...justify ? { justifyContent: FLEX_JUSTIFY[justify] } : null
111
+ };
112
+ }
113
+
114
+ // src/Stack.tsx
115
+ import { jsx as jsx3 } from "react/jsx-runtime";
116
+ function Stack({
117
+ direction = "column",
118
+ gap = "md",
119
+ align,
120
+ justify,
121
+ wrap = false,
122
+ inline = false,
123
+ className,
124
+ style,
125
+ children,
126
+ ...rest
127
+ }) {
128
+ return /* @__PURE__ */ jsx3(
129
+ "div",
130
+ {
131
+ "data-mason-component": "stack",
132
+ "data-direction": direction,
133
+ className: mergeClassName(className),
134
+ style: {
135
+ ...stackStyle({ direction, gap, align, justify, wrap, inline }),
136
+ ...style
137
+ },
138
+ ...rest,
139
+ children
140
+ }
141
+ );
142
+ }
143
+
144
+ // src/cardStyles.ts
145
+ var TONE_BG = {
146
+ surface: "color.bg.surface",
147
+ canvas: "color.bg.canvas",
148
+ elevated: "color.bg.elevated"
149
+ };
150
+ function cardStyle({
151
+ padding = "md",
152
+ elevation = "sm",
153
+ radius = "md",
154
+ tone = "surface",
155
+ bordered = true
156
+ }) {
157
+ return {
158
+ display: "block",
159
+ padding: spacingVar("inset", padding),
160
+ backgroundColor: cssVar(TONE_BG[tone]),
161
+ color: cssVar("color.text.primary"),
162
+ border: bordered ? `1px solid ${cssVar("color.border.subtle")}` : "none",
163
+ borderRadius: radiusVar(radius),
164
+ boxShadow: shadowVar(elevation),
165
+ boxSizing: "border-box",
166
+ minWidth: 0
167
+ };
168
+ }
169
+
170
+ // src/Card.tsx
171
+ import { jsx as jsx4 } from "react/jsx-runtime";
172
+ function Card({
173
+ padding = "md",
174
+ elevation = "sm",
175
+ radius = "md",
176
+ tone = "surface",
177
+ bordered = true,
178
+ className,
179
+ style,
180
+ children,
181
+ ...rest
182
+ }) {
183
+ return /* @__PURE__ */ jsx4(
184
+ "div",
185
+ {
186
+ "data-mason-component": "card",
187
+ "data-tone": tone,
188
+ className: mergeClassName(className),
189
+ style: {
190
+ ...cardStyle({ padding, elevation, radius, tone, bordered }),
191
+ ...style
192
+ },
193
+ ...rest,
194
+ children
195
+ }
196
+ );
197
+ }
198
+
199
+ // src/dividerStyles.ts
200
+ function dividerStyle(orientation = "horizontal") {
201
+ const line = `1px solid ${cssVar("color.border.subtle")}`;
202
+ if (orientation === "vertical") {
203
+ return {
204
+ alignSelf: "stretch",
205
+ width: 0,
206
+ minHeight: "1em",
207
+ margin: 0,
208
+ border: "none",
209
+ borderInlineStart: line
210
+ };
211
+ }
212
+ return {
213
+ width: "100%",
214
+ height: 0,
215
+ margin: 0,
216
+ border: "none",
217
+ borderBlockStart: line
218
+ };
219
+ }
220
+
221
+ // src/Divider.tsx
222
+ import { jsx as jsx5 } from "react/jsx-runtime";
223
+ function Divider({
224
+ orientation = "horizontal",
225
+ className,
226
+ style,
227
+ ...rest
228
+ }) {
229
+ return /* @__PURE__ */ jsx5(
230
+ "hr",
231
+ {
232
+ "data-mason-component": "divider",
233
+ "data-orientation": orientation,
234
+ "aria-orientation": orientation === "vertical" ? "vertical" : void 0,
235
+ className: mergeClassName(className),
236
+ style: { ...dividerStyle(orientation), ...style },
237
+ ...rest
238
+ }
239
+ );
240
+ }
241
+
242
+ // src/linkStyles.ts
243
+ function linkStyle({
244
+ tone = "link",
245
+ underline = "hover"
246
+ }) {
247
+ return {
248
+ color: tone === "inherit" ? "inherit" : textColorVar("link"),
249
+ textDecoration: underline === "always" ? "underline" : "none",
250
+ textUnderlineOffset: "0.15em",
251
+ borderRadius: radiusVar("sm"),
252
+ cursor: "pointer"
253
+ };
254
+ }
255
+
256
+ // src/Link.tsx
257
+ import { jsx as jsx6 } from "react/jsx-runtime";
258
+ function Link({
259
+ tone = "link",
260
+ underline = "hover",
261
+ external = false,
262
+ className,
263
+ style,
264
+ children,
265
+ ...rest
266
+ }) {
267
+ const externalProps = external ? { target: "_blank", rel: "noreferrer noopener" } : null;
268
+ return /* @__PURE__ */ jsx6(
269
+ "a",
270
+ {
271
+ "data-mason-component": "link",
272
+ "data-tone": tone,
273
+ "data-underline": underline,
274
+ className: mergeClassName(className),
275
+ style: { ...linkStyle({ tone, underline }), ...style },
276
+ ...externalProps,
277
+ ...rest,
278
+ children
279
+ }
280
+ );
281
+ }
282
+
283
+ // src/spinnerStyles.ts
284
+ var SIZE_DIMENSION = {
285
+ sm: cssVar("font.body.sm.size"),
286
+ md: cssVar("font.body.md.size"),
287
+ lg: cssVar("font.display.lg.size"),
288
+ inherit: "1em"
289
+ };
290
+ function spinnerStyle(size = "md") {
291
+ const dimension = SIZE_DIMENSION[size];
292
+ return {
293
+ width: dimension,
294
+ height: dimension,
295
+ border: "2px solid currentColor",
296
+ borderTopColor: "transparent",
297
+ borderRadius: "50%",
298
+ display: "inline-block",
299
+ flexShrink: 0
300
+ };
301
+ }
302
+
303
+ // src/Spinner.tsx
304
+ import { jsx as jsx7 } from "react/jsx-runtime";
305
+ function Spinner({
306
+ size = "md",
307
+ label,
308
+ className,
309
+ style,
310
+ ...rest
311
+ }) {
312
+ return /* @__PURE__ */ jsx7(
313
+ "span",
314
+ {
315
+ "data-mason-component": "spinner",
316
+ "data-size": size,
317
+ role: label ? "status" : void 0,
318
+ "aria-label": label,
319
+ "aria-hidden": label ? void 0 : true,
320
+ className: mergeClassName(className),
321
+ style: { ...spinnerStyle(size), ...style },
322
+ ...rest
323
+ }
324
+ );
325
+ }
326
+
327
+ // src/buttonStyles.ts
328
+ function actionColors(variant) {
329
+ return {
330
+ bg: `color.action.${variant}.bg`,
331
+ text: `color.action.${variant}.text`,
332
+ border: `color.action.${variant}.border`
333
+ };
334
+ }
335
+ var sizeStyles = {
336
+ sm: {
337
+ paddingBlock: cssVar("spacing.inset.sm"),
338
+ paddingInline: cssVar("spacing.inset.md"),
339
+ gap: cssVar("spacing.inline.sm"),
340
+ radius: cssVar("radius.sm"),
341
+ font: "label.sm"
342
+ },
343
+ md: {
344
+ paddingBlock: cssVar("spacing.inset.md"),
345
+ paddingInline: cssVar("spacing.inset.lg"),
346
+ gap: cssVar("spacing.inline.md"),
347
+ radius: cssVar("radius.md"),
348
+ font: "label.md"
349
+ },
350
+ lg: {
351
+ paddingBlock: cssVar("spacing.inset.lg"),
352
+ paddingInline: `calc(${cssVar("spacing.inset.lg")} + ${cssVar("spacing.inset.md")})`,
353
+ gap: cssVar("spacing.inline.md"),
354
+ radius: cssVar("radius.lg"),
355
+ font: "label.lg"
356
+ }
357
+ };
358
+ function buttonStyle({
359
+ variant = "primary",
360
+ size = "md",
361
+ disabled = false,
362
+ loading = false
363
+ }) {
364
+ const inactive = disabled || loading;
365
+ const colors = actionColors(inactive ? "disabled" : variant);
366
+ const sizing = sizeStyles[size];
367
+ return {
368
+ display: "inline-flex",
369
+ alignItems: "center",
370
+ justifyContent: "center",
371
+ gap: sizing.gap,
372
+ paddingBlock: sizing.paddingBlock,
373
+ paddingInline: sizing.paddingInline,
374
+ margin: 0,
375
+ backgroundColor: cssVar(colors.bg),
376
+ color: cssVar(colors.text),
377
+ border: `1px solid ${cssVar(colors.border)}`,
378
+ borderRadius: sizing.radius,
379
+ boxSizing: "border-box",
380
+ ...typographyStyle(sizing.font),
381
+ textDecoration: "none",
382
+ whiteSpace: "nowrap"
383
+ };
384
+ }
385
+
386
+ // src/Button.tsx
387
+ import { jsx as jsx8, jsxs } from "react/jsx-runtime";
388
+ function Button({
389
+ variant = "primary",
390
+ size = "md",
391
+ disabled = false,
392
+ loading = false,
393
+ leadingSlot,
394
+ trailingSlot,
395
+ className,
396
+ style,
397
+ children,
398
+ type = "button",
399
+ ...rest
400
+ }) {
401
+ const isDisabled = disabled || loading;
402
+ return /* @__PURE__ */ jsxs(
403
+ "button",
404
+ {
405
+ type,
406
+ "data-mason-component": "button",
407
+ "data-variant": variant,
408
+ "data-size": size,
409
+ disabled: isDisabled,
410
+ "aria-busy": loading || void 0,
411
+ className: mergeClassName(className),
412
+ style: {
413
+ ...buttonStyle({ variant, size, disabled, loading }),
414
+ ...style
415
+ },
416
+ ...rest,
417
+ children: [
418
+ loading ? /* @__PURE__ */ jsx8(Spinner, { size: "inherit", "data-mason-slot": "spinner" }) : leadingSlot ? /* @__PURE__ */ jsx8("span", { "data-mason-slot": "leading", children: leadingSlot }) : null,
419
+ children ? /* @__PURE__ */ jsx8("span", { "data-mason-slot": "label", children }) : null,
420
+ trailingSlot && !loading ? /* @__PURE__ */ jsx8("span", { "data-mason-slot": "trailing", children: trailingSlot }) : null
421
+ ]
422
+ }
423
+ );
424
+ }
425
+
426
+ // src/badgeStyles.ts
427
+ function badgeStyle({
428
+ tone = "neutral",
429
+ size = "sm"
430
+ }) {
431
+ const colors = tone === "neutral" ? {
432
+ bg: cssVar("color.bg.canvas"),
433
+ text: cssVar("color.text.secondary"),
434
+ border: cssVar("color.border.subtle")
435
+ } : {
436
+ bg: cssVar(`color.feedback.${tone}.bg`),
437
+ text: cssVar(`color.feedback.${tone}.text`),
438
+ border: cssVar(`color.feedback.${tone}.border`)
439
+ };
440
+ return {
441
+ display: "inline-flex",
442
+ alignItems: "center",
443
+ gap: spacingVar("inline", "sm"),
444
+ paddingBlock: "0.125em",
445
+ paddingInline: spacingVar("inset", "sm"),
446
+ backgroundColor: colors.bg,
447
+ color: colors.text,
448
+ border: `1px solid ${colors.border}`,
449
+ borderRadius: radiusVar("full"),
450
+ ...typographyStyle(size === "sm" ? "label.sm" : "label.md"),
451
+ whiteSpace: "nowrap"
452
+ };
453
+ }
454
+
455
+ // src/Badge.tsx
456
+ import { jsx as jsx9 } from "react/jsx-runtime";
457
+ function Badge({
458
+ tone = "neutral",
459
+ size = "sm",
460
+ className,
461
+ style,
462
+ children,
463
+ ...rest
464
+ }) {
465
+ return /* @__PURE__ */ jsx9(
466
+ "span",
467
+ {
468
+ "data-mason-component": "badge",
469
+ "data-tone": tone,
470
+ "data-size": size,
471
+ className: mergeClassName(className),
472
+ style: { ...badgeStyle({ tone, size }), ...style },
473
+ ...rest,
474
+ children
475
+ }
476
+ );
477
+ }
478
+
479
+ // src/calloutStyles.ts
480
+ function calloutStyle(tone = "info") {
481
+ return {
482
+ display: "flex",
483
+ gap: spacingVar("inline", "md"),
484
+ padding: spacingVar("inset", "md"),
485
+ backgroundColor: cssVar(`color.feedback.${tone}.bg`),
486
+ color: cssVar(`color.feedback.${tone}.text`),
487
+ border: `1px solid ${cssVar(`color.feedback.${tone}.border`)}`,
488
+ borderRadius: radiusVar("md"),
489
+ boxSizing: "border-box",
490
+ ...typographyStyle("body.md")
491
+ };
492
+ }
493
+ function calloutContentStyle() {
494
+ return {
495
+ display: "flex",
496
+ flexDirection: "column",
497
+ gap: spacingVar("stack", "sm"),
498
+ minWidth: 0
499
+ };
500
+ }
501
+ function calloutTitleStyle() {
502
+ return { margin: 0, ...typographyStyle("label.md") };
503
+ }
504
+ function calloutBodyStyle() {
505
+ return { margin: 0, ...typographyStyle("body.sm") };
506
+ }
507
+
508
+ // src/Callout.tsx
509
+ import { jsx as jsx10, jsxs as jsxs2 } from "react/jsx-runtime";
510
+ function Callout({
511
+ tone = "info",
512
+ title,
513
+ iconSlot,
514
+ className,
515
+ style,
516
+ children,
517
+ ...rest
518
+ }) {
519
+ return /* @__PURE__ */ jsxs2(
520
+ "div",
521
+ {
522
+ "data-mason-component": "callout",
523
+ "data-tone": tone,
524
+ className: mergeClassName(className),
525
+ style: { ...calloutStyle(tone), ...style },
526
+ ...rest,
527
+ children: [
528
+ iconSlot ? /* @__PURE__ */ jsx10("span", { "data-mason-slot": "icon", "aria-hidden": "true", children: iconSlot }) : null,
529
+ /* @__PURE__ */ jsxs2("div", { "data-mason-slot": "content", style: calloutContentStyle(), children: [
530
+ title ? /* @__PURE__ */ jsx10("p", { "data-mason-slot": "title", style: calloutTitleStyle(), children: title }) : null,
531
+ children ? /* @__PURE__ */ jsx10("div", { "data-mason-slot": "body", style: calloutBodyStyle(), children }) : null
532
+ ] })
533
+ ]
534
+ }
535
+ );
536
+ }
537
+
538
+ // src/field.tsx
539
+ import { useId } from "react";
540
+
541
+ // src/fieldStyles.ts
542
+ var CONTROL_FONT = {
543
+ sm: "body.sm",
544
+ md: "body.md",
545
+ lg: "body.lg"
546
+ };
547
+ var LABEL_FONT = {
548
+ sm: "label.sm",
549
+ md: "label.md",
550
+ lg: "label.lg"
551
+ };
552
+ var CONTROL_PADDING_BLOCK = { sm: "sm", md: "sm", lg: "md" };
553
+ var CONTROL_PADDING_INLINE = { sm: "sm", md: "md", lg: "md" };
554
+ function fieldRootStyle() {
555
+ return {
556
+ display: "flex",
557
+ flexDirection: "column",
558
+ gap: spacingVar("stack", "sm"),
559
+ minWidth: 0
560
+ };
561
+ }
562
+ function fieldLabelStyle(size = "md") {
563
+ return {
564
+ color: cssVar("color.text.primary"),
565
+ ...typographyStyle(LABEL_FONT[size])
566
+ };
567
+ }
568
+ function fieldControlStyle({
569
+ size = "md",
570
+ invalid = false,
571
+ disabled = false
572
+ }) {
573
+ return {
574
+ width: "100%",
575
+ boxSizing: "border-box",
576
+ margin: 0,
577
+ paddingBlock: spacingVar("inset", CONTROL_PADDING_BLOCK[size]),
578
+ paddingInline: spacingVar("inset", CONTROL_PADDING_INLINE[size]),
579
+ backgroundColor: disabled ? cssVar("color.action.disabled.bg") : cssVar("color.field.bg"),
580
+ color: disabled ? cssVar("color.text.disabled") : cssVar("color.field.text"),
581
+ border: `1px solid ${cssVar(
582
+ invalid ? "color.field.borderInvalid" : "color.field.border"
583
+ )}`,
584
+ borderRadius: radiusVar("md"),
585
+ ...typographyStyle(CONTROL_FONT[size])
586
+ };
587
+ }
588
+ function fieldDescriptionStyle() {
589
+ return {
590
+ margin: 0,
591
+ color: cssVar("color.text.secondary"),
592
+ ...typographyStyle("body.sm")
593
+ };
594
+ }
595
+ function fieldErrorStyle() {
596
+ return {
597
+ margin: 0,
598
+ color: cssVar("color.text.danger"),
599
+ ...typographyStyle("body.sm")
600
+ };
601
+ }
602
+
603
+ // src/field.tsx
604
+ import { jsx as jsx11, jsxs as jsxs3 } from "react/jsx-runtime";
605
+ function useFieldIds({
606
+ id,
607
+ description,
608
+ error
609
+ }) {
610
+ const generated = useId();
611
+ const controlId = id ?? `mason-field-${generated}`;
612
+ const descriptionId = `${controlId}-description`;
613
+ const errorId = `${controlId}-error`;
614
+ const describedBy = [description ? descriptionId : null, error ? errorId : null].filter(Boolean).join(" ") || void 0;
615
+ return { controlId, descriptionId, errorId, describedBy };
616
+ }
617
+ function FieldFrame({
618
+ component,
619
+ ids,
620
+ label,
621
+ description,
622
+ error,
623
+ size = "md",
624
+ invalid = false,
625
+ disabled = false,
626
+ className,
627
+ style,
628
+ children
629
+ }) {
630
+ return /* @__PURE__ */ jsxs3(
631
+ "div",
632
+ {
633
+ "data-mason-component": component,
634
+ "data-size": size,
635
+ "data-invalid": invalid || void 0,
636
+ "data-disabled": disabled || void 0,
637
+ className: mergeClassName(className),
638
+ style: { ...fieldRootStyle(), ...style },
639
+ children: [
640
+ label ? /* @__PURE__ */ jsx11(
641
+ "label",
642
+ {
643
+ "data-mason-slot": "label",
644
+ htmlFor: ids.controlId,
645
+ style: fieldLabelStyle(size),
646
+ children: label
647
+ }
648
+ ) : null,
649
+ children,
650
+ description ? /* @__PURE__ */ jsx11(
651
+ "p",
652
+ {
653
+ "data-mason-slot": "description",
654
+ id: ids.descriptionId,
655
+ style: fieldDescriptionStyle(),
656
+ children: description
657
+ }
658
+ ) : null,
659
+ error ? /* @__PURE__ */ jsx11(
660
+ "p",
661
+ {
662
+ "data-mason-slot": "error",
663
+ id: ids.errorId,
664
+ role: "alert",
665
+ style: fieldErrorStyle(),
666
+ children: error
667
+ }
668
+ ) : null
669
+ ]
670
+ }
671
+ );
672
+ }
673
+
674
+ // src/TextField.tsx
675
+ import { jsx as jsx12 } from "react/jsx-runtime";
676
+ function TextField({
677
+ label,
678
+ description,
679
+ error,
680
+ size = "md",
681
+ invalid,
682
+ id,
683
+ disabled = false,
684
+ className,
685
+ style,
686
+ ...rest
687
+ }) {
688
+ const ids = useFieldIds({ id, description, error });
689
+ const isInvalid = invalid ?? Boolean(error);
690
+ return /* @__PURE__ */ jsx12(
691
+ FieldFrame,
692
+ {
693
+ component: "text-field",
694
+ ids,
695
+ label,
696
+ description,
697
+ error,
698
+ size,
699
+ invalid: isInvalid,
700
+ disabled,
701
+ className,
702
+ style,
703
+ children: /* @__PURE__ */ jsx12(
704
+ "input",
705
+ {
706
+ ...rest,
707
+ id: ids.controlId,
708
+ "data-mason-slot": "control",
709
+ disabled,
710
+ "aria-invalid": isInvalid || void 0,
711
+ "aria-describedby": ids.describedBy,
712
+ style: fieldControlStyle({ size, invalid: isInvalid, disabled })
713
+ }
714
+ )
715
+ }
716
+ );
717
+ }
718
+
719
+ // src/Select.tsx
720
+ import { jsx as jsx13, jsxs as jsxs4 } from "react/jsx-runtime";
721
+ function Select({
722
+ label,
723
+ description,
724
+ error,
725
+ size = "md",
726
+ invalid,
727
+ placeholder,
728
+ id,
729
+ disabled = false,
730
+ className,
731
+ style,
732
+ children,
733
+ ...rest
734
+ }) {
735
+ const ids = useFieldIds({ id, description, error });
736
+ const isInvalid = invalid ?? Boolean(error);
737
+ return /* @__PURE__ */ jsx13(
738
+ FieldFrame,
739
+ {
740
+ component: "select",
741
+ ids,
742
+ label,
743
+ description,
744
+ error,
745
+ size,
746
+ invalid: isInvalid,
747
+ disabled,
748
+ className,
749
+ style,
750
+ children: /* @__PURE__ */ jsxs4(
751
+ "select",
752
+ {
753
+ ...rest,
754
+ id: ids.controlId,
755
+ "data-mason-slot": "control",
756
+ disabled,
757
+ "aria-invalid": isInvalid || void 0,
758
+ "aria-describedby": ids.describedBy,
759
+ style: fieldControlStyle({ size, invalid: isInvalid, disabled }),
760
+ children: [
761
+ placeholder ? /* @__PURE__ */ jsx13("option", { value: "", children: placeholder }) : null,
762
+ children
763
+ ]
764
+ }
765
+ )
766
+ }
767
+ );
768
+ }
769
+
770
+ // src/checkboxStyles.ts
771
+ function checkboxRootStyle() {
772
+ return {
773
+ display: "flex",
774
+ flexDirection: "column",
775
+ gap: spacingVar("stack", "sm"),
776
+ minWidth: 0
777
+ };
778
+ }
779
+ function checkboxLabelStyle(disabled = false) {
780
+ return {
781
+ display: "inline-flex",
782
+ alignItems: "flex-start",
783
+ gap: spacingVar("inline", "sm"),
784
+ cursor: disabled ? "not-allowed" : "pointer",
785
+ color: disabled ? cssVar("color.text.disabled") : cssVar("color.text.primary"),
786
+ ...typographyStyle("body.md")
787
+ };
788
+ }
789
+ function checkboxControlStyle() {
790
+ return {
791
+ width: "1em",
792
+ height: "1em",
793
+ margin: 0,
794
+ marginBlockStart: "0.15em",
795
+ accentColor: cssVar("color.action.primary.bg"),
796
+ flexShrink: 0
797
+ };
798
+ }
799
+
800
+ // src/Checkbox.tsx
801
+ import { jsx as jsx14, jsxs as jsxs5 } from "react/jsx-runtime";
802
+ function Checkbox({
803
+ label,
804
+ description,
805
+ error,
806
+ invalid,
807
+ id,
808
+ disabled = false,
809
+ className,
810
+ style,
811
+ ...rest
812
+ }) {
813
+ const ids = useFieldIds({ id, description, error });
814
+ const isInvalid = invalid ?? Boolean(error);
815
+ return /* @__PURE__ */ jsxs5(
816
+ "div",
817
+ {
818
+ "data-mason-component": "checkbox",
819
+ "data-invalid": isInvalid || void 0,
820
+ "data-disabled": disabled || void 0,
821
+ className: mergeClassName(className),
822
+ style: { ...checkboxRootStyle(), ...style },
823
+ children: [
824
+ /* @__PURE__ */ jsxs5(
825
+ "label",
826
+ {
827
+ "data-mason-slot": "label",
828
+ htmlFor: ids.controlId,
829
+ style: checkboxLabelStyle(disabled),
830
+ children: [
831
+ /* @__PURE__ */ jsx14(
832
+ "input",
833
+ {
834
+ ...rest,
835
+ type: "checkbox",
836
+ id: ids.controlId,
837
+ "data-mason-slot": "control",
838
+ disabled,
839
+ "aria-invalid": isInvalid || void 0,
840
+ "aria-describedby": ids.describedBy,
841
+ style: checkboxControlStyle()
842
+ }
843
+ ),
844
+ label ? /* @__PURE__ */ jsx14("span", { "data-mason-slot": "label-text", children: label }) : null
845
+ ]
846
+ }
847
+ ),
848
+ description ? /* @__PURE__ */ jsx14(
849
+ "p",
850
+ {
851
+ "data-mason-slot": "description",
852
+ id: ids.descriptionId,
853
+ style: fieldDescriptionStyle(),
854
+ children: description
855
+ }
856
+ ) : null,
857
+ error ? /* @__PURE__ */ jsx14(
858
+ "p",
859
+ {
860
+ "data-mason-slot": "error",
861
+ id: ids.errorId,
862
+ role: "alert",
863
+ style: fieldErrorStyle(),
864
+ children: error
865
+ }
866
+ ) : null
867
+ ]
868
+ }
869
+ );
870
+ }
871
+ export {
872
+ Badge,
873
+ Button,
874
+ Callout,
875
+ Card,
876
+ Checkbox,
877
+ Divider,
878
+ Link,
879
+ MasonProvider,
880
+ Select,
881
+ Spinner,
882
+ Stack,
883
+ Text,
884
+ TextField
885
+ };
886
+ //# sourceMappingURL=index.js.map