@becket-ui/react 0.1.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.
Files changed (146) hide show
  1. package/LICENSE +21 -0
  2. package/dist/components/Badge.d.ts +22 -0
  3. package/dist/components/Badge.d.ts.map +1 -0
  4. package/dist/components/Badge.js +39 -0
  5. package/dist/components/Badge.js.map +1 -0
  6. package/dist/components/Button.d.ts +24 -0
  7. package/dist/components/Button.d.ts.map +1 -0
  8. package/dist/components/Button.js +46 -0
  9. package/dist/components/Button.js.map +1 -0
  10. package/dist/components/Button.test.js +45 -0
  11. package/dist/components/Button.test.js.map +1 -0
  12. package/dist/components/Card.d.ts +37 -0
  13. package/dist/components/Card.d.ts.map +1 -0
  14. package/dist/components/Card.js +75 -0
  15. package/dist/components/Card.js.map +1 -0
  16. package/dist/components/Checkbox.d.ts +14 -0
  17. package/dist/components/Checkbox.d.ts.map +1 -0
  18. package/dist/components/Checkbox.js +46 -0
  19. package/dist/components/Checkbox.js.map +1 -0
  20. package/dist/components/Dialog.d.ts +41 -0
  21. package/dist/components/Dialog.d.ts.map +1 -0
  22. package/dist/components/Dialog.js +173 -0
  23. package/dist/components/Dialog.js.map +1 -0
  24. package/dist/components/Dialog.test.js +89 -0
  25. package/dist/components/Dialog.test.js.map +1 -0
  26. package/dist/components/Drawer.d.ts +38 -0
  27. package/dist/components/Drawer.d.ts.map +1 -0
  28. package/dist/components/Drawer.js +174 -0
  29. package/dist/components/Drawer.js.map +1 -0
  30. package/dist/components/Drawer.test.js +50 -0
  31. package/dist/components/Drawer.test.js.map +1 -0
  32. package/dist/components/Field.d.ts +37 -0
  33. package/dist/components/Field.d.ts.map +1 -0
  34. package/dist/components/Field.js +186 -0
  35. package/dist/components/Field.js.map +1 -0
  36. package/dist/components/Field.test.js +33 -0
  37. package/dist/components/Field.test.js.map +1 -0
  38. package/dist/components/Flex.d.ts +38 -0
  39. package/dist/components/Flex.d.ts.map +1 -0
  40. package/dist/components/Flex.js +85 -0
  41. package/dist/components/Flex.js.map +1 -0
  42. package/dist/components/Heading.d.ts +14 -0
  43. package/dist/components/Heading.d.ts.map +1 -0
  44. package/dist/components/Heading.js +33 -0
  45. package/dist/components/Heading.js.map +1 -0
  46. package/dist/components/Hide.d.ts +39 -0
  47. package/dist/components/Hide.d.ts.map +1 -0
  48. package/dist/components/Hide.js +51 -0
  49. package/dist/components/Hide.js.map +1 -0
  50. package/dist/components/Link.d.ts +14 -0
  51. package/dist/components/Link.d.ts.map +1 -0
  52. package/dist/components/Link.js +23 -0
  53. package/dist/components/Link.js.map +1 -0
  54. package/dist/components/Menu.d.ts +11 -0
  55. package/dist/components/Menu.d.ts.map +1 -0
  56. package/dist/components/Menu.js +132 -0
  57. package/dist/components/Menu.js.map +1 -0
  58. package/dist/components/Menu.test.js +69 -0
  59. package/dist/components/Menu.test.js.map +1 -0
  60. package/dist/components/Radio.d.ts +38 -0
  61. package/dist/components/Radio.d.ts.map +1 -0
  62. package/dist/components/Radio.js +144 -0
  63. package/dist/components/Radio.js.map +1 -0
  64. package/dist/components/Select.d.ts +17 -0
  65. package/dist/components/Select.d.ts.map +1 -0
  66. package/dist/components/Select.js +33 -0
  67. package/dist/components/Select.js.map +1 -0
  68. package/dist/components/Separator.d.ts +14 -0
  69. package/dist/components/Separator.d.ts.map +1 -0
  70. package/dist/components/Separator.js +25 -0
  71. package/dist/components/Separator.js.map +1 -0
  72. package/dist/components/SimpleGrid.d.ts +26 -0
  73. package/dist/components/SimpleGrid.d.ts.map +1 -0
  74. package/dist/components/SimpleGrid.js +98 -0
  75. package/dist/components/SimpleGrid.js.map +1 -0
  76. package/dist/components/Spinner.d.ts +10 -0
  77. package/dist/components/Spinner.d.ts.map +1 -0
  78. package/dist/components/Spinner.js +25 -0
  79. package/dist/components/Spinner.js.map +1 -0
  80. package/dist/components/Stack.d.ts +32 -0
  81. package/dist/components/Stack.d.ts.map +1 -0
  82. package/dist/components/Stack.js +81 -0
  83. package/dist/components/Stack.js.map +1 -0
  84. package/dist/components/Switch.d.ts +20 -0
  85. package/dist/components/Switch.d.ts.map +1 -0
  86. package/dist/components/Switch.js +83 -0
  87. package/dist/components/Switch.js.map +1 -0
  88. package/dist/components/Switch.test.js +28 -0
  89. package/dist/components/Switch.test.js.map +1 -0
  90. package/dist/components/Table.d.ts +23 -0
  91. package/dist/components/Table.d.ts.map +1 -0
  92. package/dist/components/Table.js +90 -0
  93. package/dist/components/Table.js.map +1 -0
  94. package/dist/components/Tabs.d.ts +21 -0
  95. package/dist/components/Tabs.d.ts.map +1 -0
  96. package/dist/components/Tabs.js +140 -0
  97. package/dist/components/Tabs.js.map +1 -0
  98. package/dist/components/Tabs.test.js +41 -0
  99. package/dist/components/Tabs.test.js.map +1 -0
  100. package/dist/components/Tag.d.ts +22 -0
  101. package/dist/components/Tag.d.ts.map +1 -0
  102. package/dist/components/Tag.js +39 -0
  103. package/dist/components/Tag.js.map +1 -0
  104. package/dist/components/Text.d.ts +9 -0
  105. package/dist/components/Text.d.ts.map +1 -0
  106. package/dist/components/Text.js +18 -0
  107. package/dist/components/Text.js.map +1 -0
  108. package/dist/components/TextField.d.ts +19 -0
  109. package/dist/components/TextField.d.ts.map +1 -0
  110. package/dist/components/TextField.js +32 -0
  111. package/dist/components/TextField.js.map +1 -0
  112. package/dist/components/Textarea.d.ts +17 -0
  113. package/dist/components/Textarea.d.ts.map +1 -0
  114. package/dist/components/Textarea.js +34 -0
  115. package/dist/components/Textarea.js.map +1 -0
  116. package/dist/components/Tooltip.d.ts +17 -0
  117. package/dist/components/Tooltip.d.ts.map +1 -0
  118. package/dist/components/Tooltip.js +217 -0
  119. package/dist/components/Tooltip.js.map +1 -0
  120. package/dist/components/Tooltip.test.js +58 -0
  121. package/dist/components/Tooltip.test.js.map +1 -0
  122. package/dist/helpers/gradientBorder.d.ts +5 -0
  123. package/dist/helpers/gradientBorder.d.ts.map +1 -0
  124. package/dist/helpers/gradientBorder.js +25 -0
  125. package/dist/helpers/gradientBorder.js.map +1 -0
  126. package/dist/helpers/labelColors.d.ts +17 -0
  127. package/dist/helpers/labelColors.d.ts.map +1 -0
  128. package/dist/helpers/labelColors.js +54 -0
  129. package/dist/helpers/labelColors.js.map +1 -0
  130. package/dist/helpers/nativeDialog.d.ts +23 -0
  131. package/dist/helpers/nativeDialog.d.ts.map +1 -0
  132. package/dist/helpers/nativeDialog.js +85 -0
  133. package/dist/helpers/nativeDialog.js.map +1 -0
  134. package/dist/helpers/responsive.d.ts +63 -0
  135. package/dist/helpers/responsive.d.ts.map +1 -0
  136. package/dist/helpers/responsive.js +78 -0
  137. package/dist/helpers/responsive.js.map +1 -0
  138. package/dist/helpers/storybookControls.d.ts +16 -0
  139. package/dist/helpers/storybookControls.d.ts.map +1 -0
  140. package/dist/helpers/storybookControls.js +40 -0
  141. package/dist/helpers/storybookControls.js.map +1 -0
  142. package/dist/index.d.ts +35 -0
  143. package/dist/index.d.ts.map +1 -0
  144. package/dist/index.js +158 -0
  145. package/dist/index.js.map +1 -0
  146. package/package.json +79 -0
@@ -0,0 +1,186 @@
1
+ "use client";
2
+ import { jsx } from "react/jsx-runtime";
3
+ import {
4
+ createContext,
5
+ forwardRef,
6
+ useCallback,
7
+ useContext,
8
+ useId,
9
+ useLayoutEffect,
10
+ useState
11
+ } from "react";
12
+ import { field, selectRecipe, textFieldRecipe, textareaRecipe } from "@becket-ui/tokens/recipes";
13
+ const FieldContext = createContext(null);
14
+ function toPublicField(ctx) {
15
+ const { registerDescribedBy: _register, ...publicCtx } = ctx;
16
+ return publicCtx;
17
+ }
18
+ function useField() {
19
+ const ctx = useOptionalFieldInternal();
20
+ if (!ctx) {
21
+ throw new Error("useField must be used within Field");
22
+ }
23
+ return toPublicField(ctx);
24
+ }
25
+ function useOptionalFieldInternal() {
26
+ return useContext(FieldContext);
27
+ }
28
+ function useOptionalField() {
29
+ const ctx = useOptionalFieldInternal();
30
+ return ctx ? toPublicField(ctx) : null;
31
+ }
32
+ function useFieldInternal() {
33
+ const ctx = useOptionalFieldInternal();
34
+ if (!ctx) {
35
+ throw new Error("useField must be used within Field");
36
+ }
37
+ return ctx;
38
+ }
39
+ function mergeClassName(...classes) {
40
+ return classes.filter(Boolean).join(" ");
41
+ }
42
+ const Field = forwardRef(
43
+ ({
44
+ size = "md",
45
+ invalid = false,
46
+ fullWidth = false,
47
+ id: idProp,
48
+ className,
49
+ children,
50
+ ...props
51
+ }, ref) => {
52
+ const autoId = useId();
53
+ const id = idProp ?? autoId;
54
+ const helperId = `${id}-helper`;
55
+ const errorId = `${id}-error`;
56
+ const [slots, setSlots] = useState({ helper: false, error: false });
57
+ const registerDescribedBy = useCallback((slot, present) => {
58
+ setSlots((prev) => prev[slot] === present ? prev : { ...prev, [slot]: present });
59
+ }, []);
60
+ const describedBy = invalid && slots.error ? errorId : slots.helper ? helperId : void 0;
61
+ const styles = field({ size, fullWidth });
62
+ return /* @__PURE__ */ jsx(
63
+ FieldContext.Provider,
64
+ {
65
+ value: { id, invalid, size, helperId, errorId, describedBy, registerDescribedBy },
66
+ children: /* @__PURE__ */ jsx("div", { ref, ...props, className: mergeClassName(styles.root, className), children })
67
+ }
68
+ );
69
+ }
70
+ );
71
+ Field.displayName = "Field";
72
+ const FieldLabel = forwardRef(
73
+ ({ className, ...props }, ref) => {
74
+ const { id, size } = useField();
75
+ const styles = field({ size });
76
+ return /* @__PURE__ */ jsx("label", { ref, htmlFor: id, ...props, className: mergeClassName(styles.label, className) });
77
+ }
78
+ );
79
+ FieldLabel.displayName = "FieldLabel";
80
+ const FieldHelper = forwardRef(
81
+ ({ className, ...props }, ref) => {
82
+ const { size, helperId, registerDescribedBy } = useFieldInternal();
83
+ const styles = field({ size });
84
+ useLayoutEffect(() => {
85
+ registerDescribedBy("helper", true);
86
+ return () => registerDescribedBy("helper", false);
87
+ }, [registerDescribedBy]);
88
+ return /* @__PURE__ */ jsx(
89
+ "span",
90
+ {
91
+ ref,
92
+ id: helperId,
93
+ ...props,
94
+ className: mergeClassName(styles.helper, className)
95
+ }
96
+ );
97
+ }
98
+ );
99
+ FieldHelper.displayName = "FieldHelper";
100
+ const FieldError = forwardRef(
101
+ ({ className, ...props }, ref) => {
102
+ const { size, errorId, registerDescribedBy } = useFieldInternal();
103
+ const styles = field({ size });
104
+ useLayoutEffect(() => {
105
+ registerDescribedBy("error", true);
106
+ return () => registerDescribedBy("error", false);
107
+ }, [registerDescribedBy]);
108
+ return /* @__PURE__ */ jsx(
109
+ "span",
110
+ {
111
+ ref,
112
+ id: errorId,
113
+ role: "alert",
114
+ ...props,
115
+ className: mergeClassName(styles.error, className)
116
+ }
117
+ );
118
+ }
119
+ );
120
+ FieldError.displayName = "FieldError";
121
+ const FieldControl = forwardRef(
122
+ ({ className, ...props }, ref) => {
123
+ const { id, invalid, size, describedBy } = useField();
124
+ const controlClass = textFieldRecipe({ size, invalid });
125
+ return /* @__PURE__ */ jsx(
126
+ "input",
127
+ {
128
+ ref,
129
+ id,
130
+ "aria-invalid": invalid || void 0,
131
+ "aria-describedby": describedBy,
132
+ ...props,
133
+ className: mergeClassName(controlClass, className)
134
+ }
135
+ );
136
+ }
137
+ );
138
+ FieldControl.displayName = "FieldControl";
139
+ const FieldSelect = forwardRef(
140
+ ({ className, ...props }, ref) => {
141
+ const { id, invalid, size, describedBy } = useField();
142
+ const controlClass = selectRecipe({ size, invalid });
143
+ return /* @__PURE__ */ jsx(
144
+ "select",
145
+ {
146
+ ref,
147
+ id,
148
+ "aria-invalid": invalid || void 0,
149
+ "aria-describedby": describedBy,
150
+ ...props,
151
+ className: mergeClassName(controlClass, className)
152
+ }
153
+ );
154
+ }
155
+ );
156
+ FieldSelect.displayName = "FieldSelect";
157
+ const FieldTextarea = forwardRef(
158
+ ({ className, ...props }, ref) => {
159
+ const { id, invalid, size, describedBy } = useField();
160
+ const controlClass = textareaRecipe({ size, invalid });
161
+ return /* @__PURE__ */ jsx(
162
+ "textarea",
163
+ {
164
+ ref,
165
+ id,
166
+ "aria-invalid": invalid || void 0,
167
+ "aria-describedby": describedBy,
168
+ ...props,
169
+ className: mergeClassName(controlClass, className)
170
+ }
171
+ );
172
+ }
173
+ );
174
+ FieldTextarea.displayName = "FieldTextarea";
175
+ export {
176
+ Field,
177
+ FieldControl,
178
+ FieldError,
179
+ FieldHelper,
180
+ FieldLabel,
181
+ FieldSelect,
182
+ FieldTextarea,
183
+ useField,
184
+ useOptionalField
185
+ };
186
+ //# sourceMappingURL=Field.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/components/Field.tsx"],"sourcesContent":["'use client';\n\nimport {\n createContext,\n forwardRef,\n useCallback,\n useContext,\n useId,\n useLayoutEffect,\n useState,\n type ComponentPropsWithoutRef,\n type InputHTMLAttributes,\n type LabelHTMLAttributes,\n type ReactNode,\n} from 'react';\nimport { field, selectRecipe, textFieldRecipe, textareaRecipe } from '@becket-ui/tokens/recipes';\n\nexport type FieldSize = 'sm' | 'md' | 'lg';\n\nexport type FieldContextValue = {\n id: string;\n invalid: boolean;\n size: FieldSize;\n helperId: string;\n errorId: string;\n describedBy?: string;\n};\n\ntype DescribedBySlot = 'helper' | 'error';\n\ntype FieldContextInternal = FieldContextValue & {\n registerDescribedBy: (slot: DescribedBySlot, present: boolean) => void;\n};\n\nconst FieldContext = createContext<FieldContextInternal | null>(null);\n\nfunction toPublicField(ctx: FieldContextInternal): FieldContextValue {\n const { registerDescribedBy: _register, ...publicCtx } = ctx;\n return publicCtx;\n}\n\nexport function useField(): FieldContextValue {\n const ctx = useOptionalFieldInternal();\n if (!ctx) {\n throw new Error('useField must be used within Field');\n }\n return toPublicField(ctx);\n}\n\nfunction useOptionalFieldInternal(): FieldContextInternal | null {\n return useContext(FieldContext);\n}\n\nexport function useOptionalField(): FieldContextValue | null {\n const ctx = useOptionalFieldInternal();\n return ctx ? toPublicField(ctx) : null;\n}\n\nfunction useFieldInternal(): FieldContextInternal {\n const ctx = useOptionalFieldInternal();\n if (!ctx) {\n throw new Error('useField must be used within Field');\n }\n return ctx;\n}\n\nfunction mergeClassName(...classes: (string | undefined)[]): string {\n return classes.filter(Boolean).join(' ');\n}\n\nexport type FieldProps = ComponentPropsWithoutRef<'div'> & {\n size?: FieldSize;\n invalid?: boolean;\n fullWidth?: boolean;\n children?: ReactNode;\n};\n\nexport const Field = forwardRef<HTMLDivElement, FieldProps>(\n (\n {\n size = 'md',\n invalid = false,\n fullWidth = false,\n id: idProp,\n className,\n children,\n ...props\n },\n ref,\n ) => {\n const autoId = useId();\n const id = idProp ?? autoId;\n const helperId = `${id}-helper`;\n const errorId = `${id}-error`;\n const [slots, setSlots] = useState({ helper: false, error: false });\n const registerDescribedBy = useCallback((slot: DescribedBySlot, present: boolean) => {\n setSlots((prev) => (prev[slot] === present ? prev : { ...prev, [slot]: present }));\n }, []);\n const describedBy =\n invalid && slots.error ? errorId : slots.helper ? helperId : undefined;\n const styles = field({ size, fullWidth });\n\n return (\n <FieldContext.Provider\n value={{ id, invalid, size, helperId, errorId, describedBy, registerDescribedBy }}\n >\n <div ref={ref} {...props} className={mergeClassName(styles.root, className)}>\n {children}\n </div>\n </FieldContext.Provider>\n );\n },\n);\n\nField.displayName = 'Field';\n\ntype FieldLabelProps = LabelHTMLAttributes<HTMLLabelElement>;\n\nexport const FieldLabel = forwardRef<HTMLLabelElement, FieldLabelProps>(\n ({ className, ...props }, ref) => {\n const { id, size } = useField();\n const styles = field({ size });\n return (\n <label ref={ref} htmlFor={id} {...props} className={mergeClassName(styles.label, className)} />\n );\n },\n);\n\nFieldLabel.displayName = 'FieldLabel';\n\ntype FieldHelperProps = ComponentPropsWithoutRef<'span'>;\n\nexport const FieldHelper = forwardRef<HTMLSpanElement, FieldHelperProps>(\n ({ className, ...props }, ref) => {\n const { size, helperId, registerDescribedBy } = useFieldInternal();\n const styles = field({ size });\n useLayoutEffect(() => {\n registerDescribedBy('helper', true);\n return () => registerDescribedBy('helper', false);\n }, [registerDescribedBy]);\n return (\n <span\n ref={ref}\n id={helperId}\n {...props}\n className={mergeClassName(styles.helper, className)}\n />\n );\n },\n);\n\nFieldHelper.displayName = 'FieldHelper';\n\nexport const FieldError = forwardRef<HTMLSpanElement, FieldHelperProps>(\n ({ className, ...props }, ref) => {\n const { size, errorId, registerDescribedBy } = useFieldInternal();\n const styles = field({ size });\n useLayoutEffect(() => {\n registerDescribedBy('error', true);\n return () => registerDescribedBy('error', false);\n }, [registerDescribedBy]);\n return (\n <span\n ref={ref}\n id={errorId}\n role=\"alert\"\n {...props}\n className={mergeClassName(styles.error, className)}\n />\n );\n },\n);\n\nFieldError.displayName = 'FieldError';\n\ntype FieldControlProps = Omit<InputHTMLAttributes<HTMLInputElement>, 'size'>;\n\n/** Native text input wired to the parent Field (id, aria, size, invalid). */\nexport const FieldControl = forwardRef<HTMLInputElement, FieldControlProps>(\n ({ className, ...props }, ref) => {\n const { id, invalid, size, describedBy } = useField();\n const controlClass = textFieldRecipe({ size, invalid });\n return (\n <input\n ref={ref}\n id={id}\n aria-invalid={invalid || undefined}\n aria-describedby={describedBy}\n {...props}\n className={mergeClassName(controlClass, className)}\n />\n );\n },\n);\n\nFieldControl.displayName = 'FieldControl';\n\ntype FieldSelectProps = Omit<ComponentPropsWithoutRef<'select'>, 'size'>;\n\nexport const FieldSelect = forwardRef<HTMLSelectElement, FieldSelectProps>(\n ({ className, ...props }, ref) => {\n const { id, invalid, size, describedBy } = useField();\n const controlClass = selectRecipe({ size, invalid });\n return (\n <select\n ref={ref}\n id={id}\n aria-invalid={invalid || undefined}\n aria-describedby={describedBy}\n {...props}\n className={mergeClassName(controlClass, className)}\n />\n );\n },\n);\n\nFieldSelect.displayName = 'FieldSelect';\n\ntype FieldTextareaProps = Omit<ComponentPropsWithoutRef<'textarea'>, 'size'>;\n\nexport const FieldTextarea = forwardRef<HTMLTextAreaElement, FieldTextareaProps>(\n ({ className, ...props }, ref) => {\n const { id, invalid, size, describedBy } = useField();\n const controlClass = textareaRecipe({ size, invalid });\n return (\n <textarea\n ref={ref}\n id={id}\n aria-invalid={invalid || undefined}\n aria-describedby={describedBy}\n {...props}\n className={mergeClassName(controlClass, className)}\n />\n );\n },\n);\n\nFieldTextarea.displayName = 'FieldTextarea';\n"],"mappings":"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","names":[]}
@@ -0,0 +1,33 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { describe, expect, it } from "vitest";
3
+ import { render, screen } from "@testing-library/react";
4
+ import { Field } from "./Field";
5
+ import { Radio, RadioGroup } from "./Radio";
6
+ import { TextField } from "./TextField";
7
+ describe("Field describedBy", () => {
8
+ it("omits aria-describedby when TextField has no helper", () => {
9
+ render(/* @__PURE__ */ jsx(TextField, { label: "Offset" }));
10
+ expect(screen.getByLabelText("Offset").getAttribute("aria-describedby")).toBeNull();
11
+ });
12
+ it("points at FieldHelper when valid with helperText", () => {
13
+ render(/* @__PURE__ */ jsx(TextField, { label: "Offset", helperText: "Optional hint" }));
14
+ const describedBy = screen.getByLabelText("Offset").getAttribute("aria-describedby");
15
+ expect(describedBy).toBeTruthy();
16
+ expect(document.getElementById(describedBy)?.textContent).toBe("Optional hint");
17
+ });
18
+ it("points at FieldError when invalid with helperText", () => {
19
+ render(/* @__PURE__ */ jsx(TextField, { label: "Email", invalid: true, helperText: "Enter a valid email address" }));
20
+ const describedBy = screen.getByLabelText("Email").getAttribute("aria-describedby");
21
+ expect(describedBy).toBeTruthy();
22
+ const node = document.getElementById(describedBy);
23
+ expect(node?.getAttribute("role")).toBe("alert");
24
+ expect(node?.textContent).toBe("Enter a valid email address");
25
+ });
26
+ it("does not give RadioGroup a dangling describedBy", () => {
27
+ render(
28
+ /* @__PURE__ */ jsx(Field, { children: /* @__PURE__ */ jsx(RadioGroup, { legend: "Side", children: /* @__PURE__ */ jsx(Radio, { value: "yes", label: "Yes" }) }) })
29
+ );
30
+ expect(screen.getByRole("group", { name: "Side" }).getAttribute("aria-describedby")).toBeNull();
31
+ });
32
+ });
33
+ //# sourceMappingURL=Field.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/components/Field.test.tsx"],"sourcesContent":["import { describe, expect, it } from 'vitest';\nimport { render, screen } from '@testing-library/react';\n\nimport { Field } from './Field';\nimport { Radio, RadioGroup } from './Radio';\nimport { TextField } from './TextField';\n\ndescribe('Field describedBy', () => {\n it('omits aria-describedby when TextField has no helper', () => {\n render(<TextField label=\"Offset\" />);\n expect(screen.getByLabelText('Offset').getAttribute('aria-describedby')).toBeNull();\n });\n\n it('points at FieldHelper when valid with helperText', () => {\n render(<TextField label=\"Offset\" helperText=\"Optional hint\" />);\n const describedBy = screen.getByLabelText('Offset').getAttribute('aria-describedby');\n expect(describedBy).toBeTruthy();\n expect(document.getElementById(describedBy as string)?.textContent).toBe('Optional hint');\n });\n\n it('points at FieldError when invalid with helperText', () => {\n render(<TextField label=\"Email\" invalid helperText=\"Enter a valid email address\" />);\n const describedBy = screen.getByLabelText('Email').getAttribute('aria-describedby');\n expect(describedBy).toBeTruthy();\n const node = document.getElementById(describedBy as string);\n expect(node?.getAttribute('role')).toBe('alert');\n expect(node?.textContent).toBe('Enter a valid email address');\n });\n\n it('does not give RadioGroup a dangling describedBy', () => {\n render(\n <Field>\n <RadioGroup legend=\"Side\">\n <Radio value=\"yes\" label=\"Yes\" />\n </RadioGroup>\n </Field>,\n );\n expect(screen.getByRole('group', { name: 'Side' }).getAttribute('aria-describedby')).toBeNull();\n });\n});\n"],"mappings":"AASW;AATX,SAAS,UAAU,QAAQ,UAAU;AACrC,SAAS,QAAQ,cAAc;AAE/B,SAAS,aAAa;AACtB,SAAS,OAAO,kBAAkB;AAClC,SAAS,iBAAiB;AAE1B,SAAS,qBAAqB,MAAM;AAClC,KAAG,uDAAuD,MAAM;AAC9D,WAAO,oBAAC,aAAU,OAAM,UAAS,CAAE;AACnC,WAAO,OAAO,eAAe,QAAQ,EAAE,aAAa,kBAAkB,CAAC,EAAE,SAAS;AAAA,EACpF,CAAC;AAED,KAAG,oDAAoD,MAAM;AAC3D,WAAO,oBAAC,aAAU,OAAM,UAAS,YAAW,iBAAgB,CAAE;AAC9D,UAAM,cAAc,OAAO,eAAe,QAAQ,EAAE,aAAa,kBAAkB;AACnF,WAAO,WAAW,EAAE,WAAW;AAC/B,WAAO,SAAS,eAAe,WAAqB,GAAG,WAAW,EAAE,KAAK,eAAe;AAAA,EAC1F,CAAC;AAED,KAAG,qDAAqD,MAAM;AAC5D,WAAO,oBAAC,aAAU,OAAM,SAAQ,SAAO,MAAC,YAAW,+BAA8B,CAAE;AACnF,UAAM,cAAc,OAAO,eAAe,OAAO,EAAE,aAAa,kBAAkB;AAClF,WAAO,WAAW,EAAE,WAAW;AAC/B,UAAM,OAAO,SAAS,eAAe,WAAqB;AAC1D,WAAO,MAAM,aAAa,MAAM,CAAC,EAAE,KAAK,OAAO;AAC/C,WAAO,MAAM,WAAW,EAAE,KAAK,6BAA6B;AAAA,EAC9D,CAAC;AAED,KAAG,mDAAmD,MAAM;AAC1D;AAAA,MACE,oBAAC,SACC,8BAAC,cAAW,QAAO,QACjB,8BAAC,SAAM,OAAM,OAAM,OAAM,OAAM,GACjC,GACF;AAAA,IACF;AACA,WAAO,OAAO,UAAU,SAAS,EAAE,MAAM,OAAO,CAAC,EAAE,aAAa,kBAAkB,CAAC,EAAE,SAAS;AAAA,EAChG,CAAC;AACH,CAAC;","names":[]}
@@ -0,0 +1,38 @@
1
+ import { type ComponentPropsWithoutRef, type ElementType } from 'react';
2
+ import { flex } from '@becket-ui/tokens/patterns';
3
+ import { type GradientBorderToken } from '../helpers/gradientBorder';
4
+ import { type GapValue, type ResponsiveValue } from '../helpers/responsive';
5
+ type FlexOptions = NonNullable<Parameters<typeof flex>[0]>;
6
+ type AlignVariant = 'start' | 'center' | 'end' | 'stretch' | 'baseline';
7
+ type JustifyVariant = 'start' | 'center' | 'end' | 'between' | 'around' | 'evenly';
8
+ type BorderProp = FlexOptions['border'] | GradientBorderToken;
9
+ export type FlexProps = ComponentPropsWithoutRef<'div'> & {
10
+ direction?: FlexOptions['direction'];
11
+ gap?: GapValue;
12
+ align?: AlignVariant;
13
+ justify?: JustifyVariant;
14
+ wrap?: FlexOptions['wrap'];
15
+ basis?: FlexOptions['basis'];
16
+ grow?: FlexOptions['grow'];
17
+ shrink?: FlexOptions['shrink'];
18
+ inline?: boolean;
19
+ border?: BorderProp;
20
+ order?: ResponsiveValue<number>;
21
+ as?: ElementType;
22
+ };
23
+ export declare const Flex: import("react").ForwardRefExoticComponent<Omit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & {
24
+ direction?: FlexOptions['direction'];
25
+ gap?: GapValue;
26
+ align?: AlignVariant;
27
+ justify?: JustifyVariant;
28
+ wrap?: FlexOptions['wrap'];
29
+ basis?: FlexOptions['basis'];
30
+ grow?: FlexOptions['grow'];
31
+ shrink?: FlexOptions['shrink'];
32
+ inline?: boolean;
33
+ border?: BorderProp;
34
+ order?: ResponsiveValue<number>;
35
+ as?: ElementType;
36
+ } & import("react").RefAttributes<HTMLDivElement>>;
37
+ export {};
38
+ //# sourceMappingURL=Flex.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Flex.d.ts","sourceRoot":"","sources":["../../src/components/Flex.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAc,KAAK,wBAAwB,EAAE,KAAK,WAAW,EAAE,MAAM,OAAO,CAAC;AAEpF,OAAO,EAAE,IAAI,EAAE,MAAM,4BAA4B,CAAC;AAClD,OAAO,EAGL,KAAK,mBAAmB,EACzB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAA+C,KAAK,QAAQ,EAAE,KAAK,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAEzH,KAAK,WAAW,GAAG,WAAW,CAAC,UAAU,CAAC,OAAO,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC3D,KAAK,YAAY,GAAG,OAAO,GAAG,QAAQ,GAAG,KAAK,GAAG,SAAS,GAAG,UAAU,CAAC;AACxE,KAAK,cAAc,GAAG,OAAO,GAAG,QAAQ,GAAG,KAAK,GAAG,SAAS,GAAG,QAAQ,GAAG,QAAQ,CAAC;AACnF,KAAK,UAAU,GAAG,WAAW,CAAC,QAAQ,CAAC,GAAG,mBAAmB,CAAC;AAuB9D,MAAM,MAAM,SAAS,GAAG,wBAAwB,CAAC,KAAK,CAAC,GAAG;IACxD,SAAS,CAAC,EAAE,WAAW,CAAC,WAAW,CAAC,CAAC;IACrC,GAAG,CAAC,EAAE,QAAQ,CAAC;IACf,KAAK,CAAC,EAAE,YAAY,CAAC;IACrB,OAAO,CAAC,EAAE,cAAc,CAAC;IACzB,IAAI,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAC3B,KAAK,CAAC,EAAE,WAAW,CAAC,OAAO,CAAC,CAAC;IAC7B,IAAI,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAC3B,MAAM,CAAC,EAAE,WAAW,CAAC,QAAQ,CAAC,CAAC;IAC/B,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB,KAAK,CAAC,EAAE,eAAe,CAAC,MAAM,CAAC,CAAC;IAChC,EAAE,CAAC,EAAE,WAAW,CAAC;CAClB,CAAC;AAEF,eAAO,MAAM,IAAI;gBAdH,WAAW,CAAC,WAAW,CAAC;UAC9B,QAAQ;YACN,YAAY;cACV,cAAc;WACjB,WAAW,CAAC,MAAM,CAAC;YAClB,WAAW,CAAC,OAAO,CAAC;WACrB,WAAW,CAAC,MAAM,CAAC;aACjB,WAAW,CAAC,QAAQ,CAAC;aACrB,OAAO;aACP,UAAU;YACX,eAAe,CAAC,MAAM,CAAC;SAC1B,WAAW;kDA8DjB,CAAC"}
@@ -0,0 +1,85 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { forwardRef } from "react";
3
+ import { css } from "@becket-ui/tokens/css";
4
+ import { flex } from "@becket-ui/tokens/patterns";
5
+ import {
6
+ getGradientBorderClassName,
7
+ isGradientBorderToken
8
+ } from "../helpers/gradientBorder";
9
+ import { normalizeGapValue, normalizeResponsiveValue } from "../helpers/responsive";
10
+ const ALIGN_MAP = {
11
+ start: "start",
12
+ center: "center",
13
+ end: "end",
14
+ stretch: "stretch",
15
+ baseline: "baseline"
16
+ };
17
+ const JUSTIFY_MAP = {
18
+ start: "start",
19
+ center: "center",
20
+ end: "end",
21
+ between: "space-between",
22
+ around: "space-around",
23
+ evenly: "space-evenly"
24
+ };
25
+ function mergeClassName(...classes) {
26
+ return classes.filter(Boolean).join(" ");
27
+ }
28
+ const Flex = forwardRef(
29
+ ({
30
+ direction = "row",
31
+ gap = "md",
32
+ align,
33
+ justify,
34
+ wrap,
35
+ basis,
36
+ grow,
37
+ shrink,
38
+ inline = false,
39
+ border,
40
+ order,
41
+ as: Component = "div",
42
+ className,
43
+ style,
44
+ ...props
45
+ }, ref) => {
46
+ const isGradientBorder = isGradientBorderToken(border);
47
+ const resolvedGap = normalizeGapValue(gap);
48
+ const resolvedDirection = normalizeResponsiveValue(direction);
49
+ const resolvedOrder = order != null ? normalizeResponsiveValue(order) : void 0;
50
+ const recipeClassName = css({
51
+ ...flex.raw({
52
+ direction: resolvedDirection,
53
+ gap: resolvedGap,
54
+ ...align && { align: ALIGN_MAP[align] },
55
+ ...justify && { justify: JUSTIFY_MAP[justify] },
56
+ ...wrap != null && { wrap },
57
+ ...basis != null && { basis },
58
+ ...grow != null && { grow },
59
+ ...shrink != null && { shrink },
60
+ ...border && !isGradientBorder && { border },
61
+ ...inline && { display: "inline-flex" }
62
+ }),
63
+ ...resolvedOrder != null && { order: resolvedOrder }
64
+ });
65
+ const gradientBorderClassName = isGradientBorder ? getGradientBorderClassName(border) : void 0;
66
+ return /* @__PURE__ */ jsx(
67
+ Component,
68
+ {
69
+ ref,
70
+ ...props,
71
+ style,
72
+ className: mergeClassName(
73
+ recipeClassName,
74
+ gradientBorderClassName,
75
+ className
76
+ )
77
+ }
78
+ );
79
+ }
80
+ );
81
+ Flex.displayName = "Flex";
82
+ export {
83
+ Flex
84
+ };
85
+ //# sourceMappingURL=Flex.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/components/Flex.tsx"],"sourcesContent":["import { forwardRef, type ComponentPropsWithoutRef, type ElementType } from 'react';\nimport { css } from '@becket-ui/tokens/css';\nimport { flex } from '@becket-ui/tokens/patterns';\nimport {\n getGradientBorderClassName,\n isGradientBorderToken,\n type GradientBorderToken,\n} from '../helpers/gradientBorder';\nimport { normalizeGapValue, normalizeResponsiveValue, type GapValue, type ResponsiveValue } from '../helpers/responsive';\n\ntype FlexOptions = NonNullable<Parameters<typeof flex>[0]>;\ntype AlignVariant = 'start' | 'center' | 'end' | 'stretch' | 'baseline';\ntype JustifyVariant = 'start' | 'center' | 'end' | 'between' | 'around' | 'evenly';\ntype BorderProp = FlexOptions['border'] | GradientBorderToken;\n\nconst ALIGN_MAP: Record<AlignVariant, string> = {\n start: 'start',\n center: 'center',\n end: 'end',\n stretch: 'stretch',\n baseline: 'baseline',\n};\n\nconst JUSTIFY_MAP: Record<JustifyVariant, string> = {\n start: 'start',\n center: 'center',\n end: 'end',\n between: 'space-between',\n around: 'space-around',\n evenly: 'space-evenly',\n};\n\nfunction mergeClassName(...classes: (string | undefined)[]): string {\n return classes.filter(Boolean).join(' ');\n}\n\nexport type FlexProps = ComponentPropsWithoutRef<'div'> & {\n direction?: FlexOptions['direction'];\n gap?: GapValue;\n align?: AlignVariant;\n justify?: JustifyVariant;\n wrap?: FlexOptions['wrap'];\n basis?: FlexOptions['basis'];\n grow?: FlexOptions['grow'];\n shrink?: FlexOptions['shrink'];\n inline?: boolean;\n border?: BorderProp;\n order?: ResponsiveValue<number>;\n as?: ElementType;\n};\n\nexport const Flex = forwardRef<HTMLDivElement, FlexProps>(\n (\n {\n direction = 'row',\n gap = 'md',\n align,\n justify,\n wrap,\n basis,\n grow,\n shrink,\n inline = false,\n border,\n order,\n as: Component = 'div',\n className,\n style,\n ...props\n },\n ref,\n ) => {\n const isGradientBorder = isGradientBorderToken(border);\n const resolvedGap = normalizeGapValue(gap);\n const resolvedDirection = normalizeResponsiveValue(direction);\n const resolvedOrder = order != null ? normalizeResponsiveValue(order) : undefined;\n\n const recipeClassName = css({\n ...flex.raw({\n direction: resolvedDirection as FlexOptions['direction'],\n gap: resolvedGap as FlexOptions['gap'],\n ...(align && { align: ALIGN_MAP[align] }),\n ...(justify && { justify: JUSTIFY_MAP[justify] }),\n ...(wrap != null && { wrap }),\n ...(basis != null && { basis }),\n ...(grow != null && { grow }),\n ...(shrink != null && { shrink }),\n ...(border && !isGradientBorder && { border }),\n ...(inline && { display: 'inline-flex' }),\n }),\n ...(resolvedOrder != null && { order: resolvedOrder }),\n });\n\n const gradientBorderClassName = isGradientBorder\n ? getGradientBorderClassName(border)\n : undefined;\n\n return (\n <Component\n ref={ref}\n {...props}\n style={style}\n className={mergeClassName(\n recipeClassName,\n gradientBorderClassName,\n className,\n )}\n />\n );\n },\n);\n\nFlex.displayName = 'Flex';\n"],"mappings":"AAkGM;AAlGN,SAAS,kBAAmE;AAC5E,SAAS,WAAW;AACpB,SAAS,YAAY;AACrB;AAAA,EACE;AAAA,EACA;AAAA,OAEK;AACP,SAAS,mBAAmB,gCAAqE;AAOjG,MAAM,YAA0C;AAAA,EAC9C,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,KAAK;AAAA,EACL,SAAS;AAAA,EACT,UAAU;AACZ;AAEA,MAAM,cAA8C;AAAA,EAClD,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,KAAK;AAAA,EACL,SAAS;AAAA,EACT,QAAQ;AAAA,EACR,QAAQ;AACV;AAEA,SAAS,kBAAkB,SAAyC;AAClE,SAAO,QAAQ,OAAO,OAAO,EAAE,KAAK,GAAG;AACzC;AAiBO,MAAM,OAAO;AAAA,EAClB,CACE;AAAA,IACE,YAAY;AAAA,IACZ,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,SAAS;AAAA,IACT;AAAA,IACA;AAAA,IACA,IAAI,YAAY;AAAA,IAChB;AAAA,IACA;AAAA,IACA,GAAG;AAAA,EACL,GACA,QACG;AACH,UAAM,mBAAmB,sBAAsB,MAAM;AACrD,UAAM,cAAc,kBAAkB,GAAG;AACzC,UAAM,oBAAoB,yBAAyB,SAAS;AAC5D,UAAM,gBAAgB,SAAS,OAAO,yBAAyB,KAAK,IAAI;AAExE,UAAM,kBAAkB,IAAI;AAAA,MAC1B,GAAG,KAAK,IAAI;AAAA,QACV,WAAW;AAAA,QACX,KAAK;AAAA,QACL,GAAI,SAAS,EAAE,OAAO,UAAU,KAAK,EAAE;AAAA,QACvC,GAAI,WAAW,EAAE,SAAS,YAAY,OAAO,EAAE;AAAA,QAC/C,GAAI,QAAQ,QAAQ,EAAE,KAAK;AAAA,QAC3B,GAAI,SAAS,QAAQ,EAAE,MAAM;AAAA,QAC7B,GAAI,QAAQ,QAAQ,EAAE,KAAK;AAAA,QAC3B,GAAI,UAAU,QAAQ,EAAE,OAAO;AAAA,QAC/B,GAAI,UAAU,CAAC,oBAAoB,EAAE,OAAO;AAAA,QAC5C,GAAI,UAAU,EAAE,SAAS,cAAc;AAAA,MACzC,CAAC;AAAA,MACD,GAAI,iBAAiB,QAAQ,EAAE,OAAO,cAAc;AAAA,IACtD,CAAC;AAED,UAAM,0BAA0B,mBAC5B,2BAA2B,MAAM,IACjC;AAEJ,WACE;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACC,GAAG;AAAA,QACJ;AAAA,QACA,WAAW;AAAA,UACT;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA;AAAA,IACF;AAAA,EAEJ;AACF;AAEA,KAAK,cAAc;","names":[]}
@@ -0,0 +1,14 @@
1
+ import { type ElementType } from 'react';
2
+ type HeadingSize = 'sm' | 'md' | 'lg' | 'xl' | '2xl' | '3xl' | '4xl' | '5xl' | '6xl';
3
+ export type HeadingProps = React.ComponentPropsWithoutRef<'h2'> & {
4
+ size?: HeadingSize;
5
+ withGradient?: boolean;
6
+ as?: ElementType;
7
+ };
8
+ export declare const Heading: import("react").ForwardRefExoticComponent<Omit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLHeadingElement>, HTMLHeadingElement>, "ref"> & {
9
+ size?: HeadingSize;
10
+ withGradient?: boolean;
11
+ as?: ElementType;
12
+ } & import("react").RefAttributes<HTMLHeadingElement>>;
13
+ export {};
14
+ //# sourceMappingURL=Heading.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Heading.d.ts","sourceRoot":"","sources":["../../src/components/Heading.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAc,KAAK,WAAW,EAAE,MAAM,OAAO,CAAC;AAGrD,KAAK,WAAW,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,CAAC;AAErF,MAAM,MAAM,YAAY,GAAG,KAAK,CAAC,wBAAwB,CAAC,IAAI,CAAC,GAAG;IAChE,IAAI,CAAC,EAAE,WAAW,CAAC;IACnB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,EAAE,CAAC,EAAE,WAAW,CAAC;CAClB,CAAC;AAMF,eAAO,MAAM,OAAO;WATX,WAAW;mBACH,OAAO;SACjB,WAAW;sDA+BjB,CAAC"}
@@ -0,0 +1,33 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { forwardRef } from "react";
3
+ import { heading as headingRecipe } from "@becket-ui/tokens/recipes";
4
+ function mergeClassName(...classes) {
5
+ return classes.filter(Boolean).join(" ");
6
+ }
7
+ const Heading = forwardRef(
8
+ ({
9
+ size = "xl",
10
+ withGradient = false,
11
+ as: HeadingComponent = "h2",
12
+ className,
13
+ ...props
14
+ }, ref) => {
15
+ const recipeClassName = headingRecipe({
16
+ size,
17
+ withGradient
18
+ });
19
+ return /* @__PURE__ */ jsx(
20
+ HeadingComponent,
21
+ {
22
+ ref,
23
+ ...props,
24
+ className: mergeClassName(recipeClassName, className)
25
+ }
26
+ );
27
+ }
28
+ );
29
+ Heading.displayName = "Heading";
30
+ export {
31
+ Heading
32
+ };
33
+ //# sourceMappingURL=Heading.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/components/Heading.tsx"],"sourcesContent":["import { forwardRef, type ElementType } from 'react';\nimport { heading as headingRecipe } from '@becket-ui/tokens/recipes';\n\ntype HeadingSize = 'sm' | 'md' | 'lg' | 'xl' | '2xl' | '3xl' | '4xl' | '5xl' | '6xl';\n\nexport type HeadingProps = React.ComponentPropsWithoutRef<'h2'> & {\n size?: HeadingSize;\n withGradient?: boolean;\n as?: ElementType;\n};\n\nfunction mergeClassName(...classes: (string | undefined)[]): string {\n return classes.filter(Boolean).join(' ');\n}\n\nexport const Heading = forwardRef<HTMLHeadingElement, HeadingProps>(\n (\n {\n size = 'xl',\n withGradient = false,\n as: HeadingComponent = 'h2',\n className,\n ...props\n },\n ref,\n ) => {\n const recipeClassName = headingRecipe({\n size,\n withGradient,\n });\n\n return (\n <HeadingComponent\n ref={ref}\n {...props}\n className={mergeClassName(recipeClassName, className)}\n />\n );\n },\n);\n\nHeading.displayName = 'Heading';\n"],"mappings":"AAgCM;AAhCN,SAAS,kBAAoC;AAC7C,SAAS,WAAW,qBAAqB;AAUzC,SAAS,kBAAkB,SAAyC;AAClE,SAAO,QAAQ,OAAO,OAAO,EAAE,KAAK,GAAG;AACzC;AAEO,MAAM,UAAU;AAAA,EACrB,CACE;AAAA,IACE,OAAO;AAAA,IACP,eAAe;AAAA,IACf,IAAI,mBAAmB;AAAA,IACvB;AAAA,IACA,GAAG;AAAA,EACL,GACA,QACG;AACH,UAAM,kBAAkB,cAAc;AAAA,MACpC;AAAA,MACA;AAAA,IACF,CAAC;AAED,WACE;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACC,GAAG;AAAA,QACJ,WAAW,eAAe,iBAAiB,SAAS;AAAA;AAAA,IACtD;AAAA,EAEJ;AACF;AAEA,QAAQ,cAAc;","names":[]}
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Chakra-style visibility helper.
3
+ * Uses CSS media queries — no JS flash; single DOM for UI tests.
4
+ */
5
+ import { type ComponentPropsWithoutRef, type ElementType } from 'react';
6
+ import { type BreakpointAlias } from '../helpers/responsive';
7
+ export type HideProps = ComponentPropsWithoutRef<'div'> & {
8
+ /** Hide when viewport is **below** this breakpoint (show from breakpoint up). */
9
+ below?: BreakpointAlias;
10
+ /** Hide from this breakpoint **and up** (show only below). */
11
+ from?: BreakpointAlias;
12
+ /**
13
+ * When visible, use `display: contents` so the wrapper does not affect flex/grid
14
+ * (Chakra Show/Hide pattern). Set `false` for a real block box.
15
+ */
16
+ asContents?: boolean;
17
+ as?: ElementType;
18
+ };
19
+ /**
20
+ * Conditionally hide children by breakpoint.
21
+ * Prefer over duplicating trees for mobile/desktop — keeps `data-testid` stable.
22
+ *
23
+ * @example
24
+ * <Hide below="desktop">{sidebar}</Hide>
25
+ * <Hide from="desktop">{mobileOnlyNav}</Hide>
26
+ */
27
+ export declare const Hide: import("react").ForwardRefExoticComponent<Omit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & {
28
+ /** Hide when viewport is **below** this breakpoint (show from breakpoint up). */
29
+ below?: BreakpointAlias;
30
+ /** Hide from this breakpoint **and up** (show only below). */
31
+ from?: BreakpointAlias;
32
+ /**
33
+ * When visible, use `display: contents` so the wrapper does not affect flex/grid
34
+ * (Chakra Show/Hide pattern). Set `false` for a real block box.
35
+ */
36
+ asContents?: boolean;
37
+ as?: ElementType;
38
+ } & import("react").RefAttributes<HTMLDivElement>>;
39
+ //# sourceMappingURL=Hide.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Hide.d.ts","sourceRoot":"","sources":["../../src/components/Hide.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAc,KAAK,wBAAwB,EAAE,KAAK,WAAW,EAAE,MAAM,OAAO,CAAC;AAIpF,OAAO,EAA0B,KAAK,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAerF,MAAM,MAAM,SAAS,GAAG,wBAAwB,CAAC,KAAK,CAAC,GAAG;IACxD,iFAAiF;IACjF,KAAK,CAAC,EAAE,eAAe,CAAC;IACxB,8DAA8D;IAC9D,IAAI,CAAC,EAAE,eAAe,CAAC;IACvB;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,EAAE,CAAC,EAAE,WAAW,CAAC;CAClB,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,IAAI;IApBf,iFAAiF;YACzE,eAAe;IACvB,8DAA8D;WACvD,eAAe;IACtB;;;OAGG;iBACU,OAAO;SACf,WAAW;kDAiDjB,CAAC"}
@@ -0,0 +1,51 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { forwardRef } from "react";
3
+ import { hide } from "@becket-ui/tokens/recipes";
4
+ import { resolveBreakpointAlias } from "../helpers/responsive";
5
+ function mergeClassName(...classes) {
6
+ return classes.filter(Boolean).join(" ");
7
+ }
8
+ function asHideBreakpoint(token) {
9
+ if (token === "sm" || token === "md" || token === "lg" || token === "xl" || token === "2xl") {
10
+ return token;
11
+ }
12
+ return void 0;
13
+ }
14
+ const Hide = forwardRef(
15
+ ({
16
+ below,
17
+ from,
18
+ asContents = true,
19
+ as: Component = "div",
20
+ className,
21
+ style,
22
+ children,
23
+ ...props
24
+ }, ref) => {
25
+ if (below && from || !below && !from) {
26
+ console.warn("Hide: pass exactly one of `below` or `from`.");
27
+ }
28
+ const belowBp = below ? asHideBreakpoint(resolveBreakpointAlias(below)) : void 0;
29
+ const fromBp = from ? asHideBreakpoint(resolveBreakpointAlias(from)) : void 0;
30
+ const recipeClassName = hide({
31
+ ...belowBp && { below: belowBp },
32
+ ...fromBp && { from: fromBp },
33
+ asContents
34
+ });
35
+ return /* @__PURE__ */ jsx(
36
+ Component,
37
+ {
38
+ ref,
39
+ ...props,
40
+ style,
41
+ className: mergeClassName(recipeClassName, className),
42
+ children
43
+ }
44
+ );
45
+ }
46
+ );
47
+ Hide.displayName = "Hide";
48
+ export {
49
+ Hide
50
+ };
51
+ //# sourceMappingURL=Hide.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/components/Hide.tsx"],"sourcesContent":["/**\n * Chakra-style visibility helper.\n * Uses CSS media queries — no JS flash; single DOM for UI tests.\n */\n\nimport { forwardRef, type ComponentPropsWithoutRef, type ElementType } from 'react';\nimport { hide } from '@becket-ui/tokens/recipes';\nimport type { HideVariantProps } from '@becket-ui/tokens/recipes';\n\nimport { resolveBreakpointAlias, type BreakpointAlias } from '../helpers/responsive';\n\nfunction mergeClassName(...classes: (string | undefined)[]): string {\n return classes.filter(Boolean).join(' ');\n}\n\ntype HideBreakpoint = NonNullable<HideVariantProps['below']>;\n\nfunction asHideBreakpoint(token: string): HideBreakpoint | undefined {\n if (token === 'sm' || token === 'md' || token === 'lg' || token === 'xl' || token === '2xl') {\n return token;\n }\n return undefined;\n}\n\nexport type HideProps = ComponentPropsWithoutRef<'div'> & {\n /** Hide when viewport is **below** this breakpoint (show from breakpoint up). */\n below?: BreakpointAlias;\n /** Hide from this breakpoint **and up** (show only below). */\n from?: BreakpointAlias;\n /**\n * When visible, use `display: contents` so the wrapper does not affect flex/grid\n * (Chakra Show/Hide pattern). Set `false` for a real block box.\n */\n asContents?: boolean;\n as?: ElementType;\n};\n\n/**\n * Conditionally hide children by breakpoint.\n * Prefer over duplicating trees for mobile/desktop — keeps `data-testid` stable.\n *\n * @example\n * <Hide below=\"desktop\">{sidebar}</Hide>\n * <Hide from=\"desktop\">{mobileOnlyNav}</Hide>\n */\nexport const Hide = forwardRef<HTMLDivElement, HideProps>(\n (\n {\n below,\n from,\n asContents = true,\n as: Component = 'div',\n className,\n style,\n children,\n ...props\n },\n ref,\n ) => {\n if ((below && from) || (!below && !from)) {\n console.warn('Hide: pass exactly one of `below` or `from`.');\n }\n\n const belowBp = below ? asHideBreakpoint(resolveBreakpointAlias(below)) : undefined;\n const fromBp = from ? asHideBreakpoint(resolveBreakpointAlias(from)) : undefined;\n\n const recipeClassName = hide({\n ...(belowBp && { below: belowBp }),\n ...(fromBp && { from: fromBp }),\n asContents,\n });\n\n return (\n <Component\n ref={ref}\n {...props}\n style={style}\n className={mergeClassName(recipeClassName, className)}\n >\n {children}\n </Component>\n );\n },\n);\n\nHide.displayName = 'Hide';\n"],"mappings":"AAyEM;AApEN,SAAS,kBAAmE;AAC5E,SAAS,YAAY;AAGrB,SAAS,8BAAoD;AAE7D,SAAS,kBAAkB,SAAyC;AAClE,SAAO,QAAQ,OAAO,OAAO,EAAE,KAAK,GAAG;AACzC;AAIA,SAAS,iBAAiB,OAA2C;AACnE,MAAI,UAAU,QAAQ,UAAU,QAAQ,UAAU,QAAQ,UAAU,QAAQ,UAAU,OAAO;AAC3F,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAuBO,MAAM,OAAO;AAAA,EAClB,CACE;AAAA,IACE;AAAA,IACA;AAAA,IACA,aAAa;AAAA,IACb,IAAI,YAAY;AAAA,IAChB;AAAA,IACA;AAAA,IACA;AAAA,IACA,GAAG;AAAA,EACL,GACA,QACG;AACH,QAAK,SAAS,QAAU,CAAC,SAAS,CAAC,MAAO;AACxC,cAAQ,KAAK,8CAA8C;AAAA,IAC7D;AAEA,UAAM,UAAU,QAAQ,iBAAiB,uBAAuB,KAAK,CAAC,IAAI;AAC1E,UAAM,SAAS,OAAO,iBAAiB,uBAAuB,IAAI,CAAC,IAAI;AAEvE,UAAM,kBAAkB,KAAK;AAAA,MAC3B,GAAI,WAAW,EAAE,OAAO,QAAQ;AAAA,MAChC,GAAI,UAAU,EAAE,MAAM,OAAO;AAAA,MAC7B;AAAA,IACF,CAAC;AAED,WACE;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACC,GAAG;AAAA,QACJ;AAAA,QACA,WAAW,eAAe,iBAAiB,SAAS;AAAA,QAEnD;AAAA;AAAA,IACH;AAAA,EAEJ;AACF;AAEA,KAAK,cAAc;","names":[]}
@@ -0,0 +1,14 @@
1
+ import { type ComponentPropsWithoutRef, type ElementType } from 'react';
2
+ type LinkVisual = 'default' | 'muted';
3
+ export type LinkProps = ComponentPropsWithoutRef<'a'> & {
4
+ visual?: LinkVisual;
5
+ visited?: boolean;
6
+ as?: ElementType;
7
+ };
8
+ export declare const Link: import("react").ForwardRefExoticComponent<Omit<import("react").DetailedHTMLProps<import("react").AnchorHTMLAttributes<HTMLAnchorElement>, HTMLAnchorElement>, "ref"> & {
9
+ visual?: LinkVisual;
10
+ visited?: boolean;
11
+ as?: ElementType;
12
+ } & import("react").RefAttributes<HTMLAnchorElement>>;
13
+ export {};
14
+ //# sourceMappingURL=Link.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Link.d.ts","sourceRoot":"","sources":["../../src/components/Link.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAc,KAAK,wBAAwB,EAAE,KAAK,WAAW,EAAE,MAAM,OAAO,CAAC;AAGpF,KAAK,UAAU,GAAG,SAAS,GAAG,OAAO,CAAC;AAEtC,MAAM,MAAM,SAAS,GAAG,wBAAwB,CAAC,GAAG,CAAC,GAAG;IACtD,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,EAAE,CAAC,EAAE,WAAW,CAAC;CAClB,CAAC;AAMF,eAAO,MAAM,IAAI;aATN,UAAU;cACT,OAAO;SACZ,WAAW;qDAiBjB,CAAC"}
@@ -0,0 +1,23 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { forwardRef } from "react";
3
+ import { link as linkRecipe } from "@becket-ui/tokens/recipes";
4
+ function mergeClassName(...classes) {
5
+ return classes.filter(Boolean).join(" ");
6
+ }
7
+ const Link = forwardRef(
8
+ ({ visual = "default", visited = false, as: Comp = "a", className, ...props }, ref) => {
9
+ return /* @__PURE__ */ jsx(
10
+ Comp,
11
+ {
12
+ ref,
13
+ ...props,
14
+ className: mergeClassName(linkRecipe({ visual, visited }), className)
15
+ }
16
+ );
17
+ }
18
+ );
19
+ Link.displayName = "Link";
20
+ export {
21
+ Link
22
+ };
23
+ //# sourceMappingURL=Link.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/components/Link.tsx"],"sourcesContent":["import { forwardRef, type ComponentPropsWithoutRef, type ElementType } from 'react';\nimport { link as linkRecipe } from '@becket-ui/tokens/recipes';\n\ntype LinkVisual = 'default' | 'muted';\n\nexport type LinkProps = ComponentPropsWithoutRef<'a'> & {\n visual?: LinkVisual;\n visited?: boolean;\n as?: ElementType;\n};\n\nfunction mergeClassName(...classes: (string | undefined)[]): string {\n return classes.filter(Boolean).join(' ');\n}\n\nexport const Link = forwardRef<HTMLAnchorElement, LinkProps>(\n ({ visual = 'default', visited = false, as: Comp = 'a', className, ...props }, ref) => {\n return (\n <Comp\n ref={ref}\n {...props}\n className={mergeClassName(linkRecipe({ visual, visited }), className)}\n />\n );\n },\n);\n\nLink.displayName = 'Link';\n"],"mappings":"AAkBM;AAlBN,SAAS,kBAAmE;AAC5E,SAAS,QAAQ,kBAAkB;AAUnC,SAAS,kBAAkB,SAAyC;AAClE,SAAO,QAAQ,OAAO,OAAO,EAAE,KAAK,GAAG;AACzC;AAEO,MAAM,OAAO;AAAA,EAClB,CAAC,EAAE,SAAS,WAAW,UAAU,OAAO,IAAI,OAAO,KAAK,WAAW,GAAG,MAAM,GAAG,QAAQ;AACrF,WACE;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACC,GAAG;AAAA,QACJ,WAAW,eAAe,WAAW,EAAE,QAAQ,QAAQ,CAAC,GAAG,SAAS;AAAA;AAAA,IACtE;AAAA,EAEJ;AACF;AAEA,KAAK,cAAc;","names":[]}
@@ -0,0 +1,11 @@
1
+ import { type ButtonHTMLAttributes, type DetailsHTMLAttributes, type ReactNode } from 'react';
2
+ export type MenuProps = Omit<DetailsHTMLAttributes<HTMLDetailsElement>, 'onToggle'> & {
3
+ label: ReactNode;
4
+ };
5
+ export declare const Menu: import("react").ForwardRefExoticComponent<Omit<DetailsHTMLAttributes<HTMLDetailsElement>, "onToggle"> & {
6
+ label: ReactNode;
7
+ } & import("react").RefAttributes<HTMLDetailsElement>>;
8
+ type MenuItemProps = ButtonHTMLAttributes<HTMLButtonElement>;
9
+ export declare const MenuItem: import("react").ForwardRefExoticComponent<MenuItemProps & import("react").RefAttributes<HTMLButtonElement>>;
10
+ export {};
11
+ //# sourceMappingURL=Menu.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Menu.d.ts","sourceRoot":"","sources":["../../src/components/Menu.tsx"],"names":[],"mappings":"AAEA,OAAO,EAML,KAAK,oBAAoB,EACzB,KAAK,qBAAqB,EAE1B,KAAK,SAAS,EAEf,MAAM,OAAO,CAAC;AAiBf,MAAM,MAAM,SAAS,GAAG,IAAI,CAAC,qBAAqB,CAAC,kBAAkB,CAAC,EAAE,UAAU,CAAC,GAAG;IACpF,KAAK,EAAE,SAAS,CAAC;CAClB,CAAC;AAEF,eAAO,MAAM,IAAI;WAHR,SAAS;sDAkGjB,CAAC;AAIF,KAAK,aAAa,GAAG,oBAAoB,CAAC,iBAAiB,CAAC,CAAC;AAE7D,eAAO,MAAM,QAAQ,6GAmBpB,CAAC"}