@g4rcez/components 3.0.0-0 → 3.0.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.
Files changed (265) hide show
  1. package/dist/ai/SKILL.md +266 -0
  2. package/dist/ai/docs/Alert.md +167 -0
  3. package/dist/ai/docs/AnimatedList.md +205 -0
  4. package/dist/ai/docs/Autocomplete.md +225 -0
  5. package/dist/ai/docs/Button.md +182 -0
  6. package/dist/ai/docs/Calendar.md +219 -0
  7. package/dist/ai/docs/Card.md +174 -0
  8. package/dist/ai/docs/Checkbox.md +199 -0
  9. package/dist/ai/docs/CommandPalette.md +293 -0
  10. package/dist/ai/docs/DatePicker.md +171 -0
  11. package/dist/ai/docs/Dropdown.md +223 -0
  12. package/dist/ai/docs/Empty.md +163 -0
  13. package/dist/ai/docs/Expand.md +143 -0
  14. package/dist/ai/docs/FileUpload.md +225 -0
  15. package/dist/ai/docs/Form.md +107 -0
  16. package/dist/ai/docs/FormReset.md +117 -0
  17. package/dist/ai/docs/Heading.md +88 -0
  18. package/dist/ai/docs/Input.md +237 -0
  19. package/dist/ai/docs/InputField.md +170 -0
  20. package/dist/ai/docs/List.md +205 -0
  21. package/dist/ai/docs/Menu.md +166 -0
  22. package/dist/ai/docs/Modal.md +280 -0
  23. package/dist/ai/docs/MultiSelect.md +196 -0
  24. package/dist/ai/docs/Notifications.md +231 -0
  25. package/dist/ai/docs/PageCalendar.md +271 -0
  26. package/dist/ai/docs/Polymorph.md +159 -0
  27. package/dist/ai/docs/Progress.md +145 -0
  28. package/dist/ai/docs/Radiobox.md +128 -0
  29. package/dist/ai/docs/RenderOnView.md +138 -0
  30. package/dist/ai/docs/Resizable.md +159 -0
  31. package/dist/ai/docs/Select.md +284 -0
  32. package/dist/ai/docs/Shortcut.md +105 -0
  33. package/dist/ai/docs/Skeleton.md +166 -0
  34. package/dist/ai/docs/Slider.md +144 -0
  35. package/dist/ai/docs/Slot.md +173 -0
  36. package/dist/ai/docs/Spinner.md +118 -0
  37. package/dist/ai/docs/Stats.md +137 -0
  38. package/dist/ai/docs/Step.md +159 -0
  39. package/dist/ai/docs/Switch.md +167 -0
  40. package/dist/ai/docs/Table.md +298 -0
  41. package/dist/ai/docs/Tabs.md +191 -0
  42. package/dist/ai/docs/Tag.md +224 -0
  43. package/dist/ai/docs/TaskList.md +144 -0
  44. package/dist/ai/docs/Textarea.md +167 -0
  45. package/dist/ai/docs/Timeline.md +210 -0
  46. package/dist/ai/docs/Toolbar.md +132 -0
  47. package/dist/ai/docs/Tooltip.md +231 -0
  48. package/dist/ai/docs/TransferList.md +142 -0
  49. package/dist/ai/docs/Typography.md +187 -0
  50. package/dist/ai/docs/Wizard.md +213 -0
  51. package/dist/ai/docs/index.md +183 -0
  52. package/dist/components/core/button.d.ts +2 -8
  53. package/dist/components/core/button.d.ts.map +1 -1
  54. package/dist/components/core/polymorph.d.ts.map +1 -1
  55. package/dist/components/core/slot.d.ts +1 -1
  56. package/dist/components/core/slot.d.ts.map +1 -1
  57. package/dist/components/core/tag.d.ts +2 -2
  58. package/dist/components/core/tag.d.ts.map +1 -1
  59. package/dist/components/core/typography.d.ts.map +1 -1
  60. package/dist/components/display/alert.d.ts.map +1 -1
  61. package/dist/components/display/calendar.d.ts.map +1 -1
  62. package/dist/components/display/card.d.ts.map +1 -1
  63. package/dist/components/display/list.d.ts.map +1 -1
  64. package/dist/components/display/notifications.d.ts +2 -0
  65. package/dist/components/display/notifications.d.ts.map +1 -1
  66. package/dist/components/display/progress.d.ts.map +1 -1
  67. package/dist/components/display/skeleton.d.ts.map +1 -1
  68. package/dist/components/display/step.d.ts.map +1 -1
  69. package/dist/components/display/tabs.d.ts.map +1 -1
  70. package/dist/components/floating/command-palette.d.ts +1 -0
  71. package/dist/components/floating/command-palette.d.ts.map +1 -1
  72. package/dist/components/floating/dropdown.d.ts +1 -0
  73. package/dist/components/floating/dropdown.d.ts.map +1 -1
  74. package/dist/components/floating/menu.d.ts +2 -2
  75. package/dist/components/floating/menu.d.ts.map +1 -1
  76. package/dist/components/floating/modal.d.ts +20 -53
  77. package/dist/components/floating/modal.d.ts.map +1 -1
  78. package/dist/components/floating/tooltip.d.ts.map +1 -1
  79. package/dist/components/floating/wizard.d.ts +1 -1
  80. package/dist/components/floating/wizard.d.ts.map +1 -1
  81. package/dist/components/form/autocomplete.d.ts.map +1 -1
  82. package/dist/components/form/date-picker.d.ts.map +1 -1
  83. package/dist/components/form/free-text.d.ts.map +1 -1
  84. package/dist/components/form/input-field.d.ts +3 -2
  85. package/dist/components/form/input-field.d.ts.map +1 -1
  86. package/dist/components/form/multi-select.d.ts.map +1 -1
  87. package/dist/components/form/select.d.ts.map +1 -1
  88. package/dist/components/form/slider.d.ts.map +1 -1
  89. package/dist/components/index.d.ts +2 -0
  90. package/dist/components/index.d.ts.map +1 -1
  91. package/dist/components/page-calendar/calendar-header.d.ts +16 -0
  92. package/dist/components/page-calendar/calendar-header.d.ts.map +1 -0
  93. package/dist/components/page-calendar/day-view.d.ts +12 -0
  94. package/dist/components/page-calendar/day-view.d.ts.map +1 -0
  95. package/dist/components/page-calendar/event-pill.d.ts +9 -0
  96. package/dist/components/page-calendar/event-pill.d.ts.map +1 -0
  97. package/dist/components/page-calendar/index.d.ts +4 -0
  98. package/dist/components/page-calendar/index.d.ts.map +1 -0
  99. package/dist/components/page-calendar/month-view.d.ts +11 -0
  100. package/dist/components/page-calendar/month-view.d.ts.map +1 -0
  101. package/dist/components/page-calendar/page-calendar.d.ts +18 -0
  102. package/dist/components/page-calendar/page-calendar.d.ts.map +1 -0
  103. package/dist/components/page-calendar/page-calendar.types.d.ts +18 -0
  104. package/dist/components/page-calendar/page-calendar.types.d.ts.map +1 -0
  105. package/dist/components/page-calendar/page-calendar.utils.d.ts +18 -0
  106. package/dist/components/page-calendar/page-calendar.utils.d.ts.map +1 -0
  107. package/dist/components/page-calendar/week-view.d.ts +11 -0
  108. package/dist/components/page-calendar/week-view.d.ts.map +1 -0
  109. package/dist/components/table/index.d.ts.map +1 -1
  110. package/dist/components/table/inner-table.d.ts.map +1 -1
  111. package/dist/components/table/metadata.d.ts.map +1 -1
  112. package/dist/components/table/row.d.ts.map +1 -1
  113. package/dist/components/table/table-lib.d.ts.map +1 -1
  114. package/dist/components/table/thead.d.ts.map +1 -1
  115. package/dist/config/context.d.ts.map +1 -1
  116. package/dist/config/default-translations.d.ts +21 -4
  117. package/dist/config/default-translations.d.ts.map +1 -1
  118. package/dist/constants.d.ts.map +1 -1
  119. package/dist/hooks/use-components-provider.d.ts.map +1 -1
  120. package/dist/hooks/use-form.d.ts +11 -11
  121. package/dist/hooks/use-form.d.ts.map +1 -1
  122. package/dist/hooks/use-input-id.d.ts.map +1 -1
  123. package/dist/hooks/use-preferences.d.ts.map +1 -1
  124. package/dist/hooks/use-previous.d.ts.map +1 -1
  125. package/dist/hooks/use-reactive.d.ts.map +1 -1
  126. package/dist/hooks/use-resize-observer.d.ts.map +1 -1
  127. package/dist/hooks/use-stable-ref.d.ts.map +1 -1
  128. package/dist/hooks/use-swipe.d.ts.map +1 -1
  129. package/dist/hooks/use-translations.d.ts +21 -4
  130. package/dist/hooks/use-translations.d.ts.map +1 -1
  131. package/dist/index.css +1 -0
  132. package/dist/index.d.ts.map +1 -1
  133. package/dist/index.js +28 -20
  134. package/dist/index.js.map +1 -1
  135. package/dist/index.mjs +13862 -12512
  136. package/dist/index.mjs.map +1 -1
  137. package/dist/index.umd.js +24 -17
  138. package/dist/index.umd.js.map +1 -1
  139. package/dist/lib/dom.d.ts +1 -0
  140. package/dist/lib/dom.d.ts.map +1 -1
  141. package/dist/lib/fns.d.ts.map +1 -1
  142. package/dist/preset/plugin.tailwind.d.ts +9 -0
  143. package/dist/preset/plugin.tailwind.d.ts.map +1 -0
  144. package/dist/preset/plugin.tailwind.js +27 -0
  145. package/dist/preset/preset.tailwind.d.ts +8 -0
  146. package/dist/preset/preset.tailwind.d.ts.map +1 -0
  147. package/dist/preset/preset.tailwind.js +54 -0
  148. package/dist/preset/src/styles/common.d.ts +2 -14
  149. package/dist/preset/src/styles/common.d.ts.map +1 -1
  150. package/dist/preset/src/styles/common.js +1 -0
  151. package/dist/preset/src/styles/dark.d.ts.map +1 -1
  152. package/dist/preset/src/styles/dark.js +119 -114
  153. package/dist/preset/src/styles/light.d.ts.map +1 -1
  154. package/dist/preset/src/styles/light.js +111 -106
  155. package/dist/preset/src/styles/theme.types.d.ts +17 -8
  156. package/dist/preset/src/styles/theme.types.d.ts.map +1 -1
  157. package/dist/styles/common.d.ts +2 -14
  158. package/dist/styles/common.d.ts.map +1 -1
  159. package/dist/styles/dark.d.ts.map +1 -1
  160. package/dist/styles/light.d.ts.map +1 -1
  161. package/dist/styles/theme.types.d.ts +17 -8
  162. package/dist/styles/theme.types.d.ts.map +1 -1
  163. package/package.json +299 -301
  164. package/dist/components/core/button.jsx +0 -86
  165. package/dist/components/core/heading.jsx +0 -4
  166. package/dist/components/core/polymorph.jsx +0 -5
  167. package/dist/components/core/render-on-view.jsx +0 -31
  168. package/dist/components/core/resizable.jsx +0 -51
  169. package/dist/components/core/slot.jsx +0 -163
  170. package/dist/components/core/tag.jsx +0 -51
  171. package/dist/components/core/typography.jsx +0 -26
  172. package/dist/components/display/alert.jsx +0 -56
  173. package/dist/components/display/calendar.jsx +0 -301
  174. package/dist/components/display/card.jsx +0 -43
  175. package/dist/components/display/empty.jsx +0 -11
  176. package/dist/components/display/list.jsx +0 -81
  177. package/dist/components/display/notifications.jsx +0 -98
  178. package/dist/components/display/progress.jsx +0 -13
  179. package/dist/components/display/shortcut.jsx +0 -23
  180. package/dist/components/display/skeleton.jsx +0 -14
  181. package/dist/components/display/spinner.jsx +0 -7
  182. package/dist/components/display/stats.jsx +0 -20
  183. package/dist/components/display/step.jsx +0 -131
  184. package/dist/components/display/tabs.jsx +0 -100
  185. package/dist/components/display/timeline.jsx +0 -25
  186. package/dist/components/floating/command-palette.jsx +0 -172
  187. package/dist/components/floating/dropdown.jsx +0 -53
  188. package/dist/components/floating/expand.jsx +0 -44
  189. package/dist/components/floating/menu.jsx +0 -147
  190. package/dist/components/floating/modal.jsx +0 -241
  191. package/dist/components/floating/toolbar.jsx +0 -5
  192. package/dist/components/floating/tooltip.jsx +0 -64
  193. package/dist/components/floating/wizard.jsx +0 -164
  194. package/dist/components/form/autocomplete.jsx +0 -275
  195. package/dist/components/form/checkbox.jsx +0 -12
  196. package/dist/components/form/date-picker.jsx +0 -115
  197. package/dist/components/form/file-upload.jsx +0 -133
  198. package/dist/components/form/form.jsx +0 -10
  199. package/dist/components/form/formReset.jsx +0 -17
  200. package/dist/components/form/free-text.jsx +0 -41
  201. package/dist/components/form/input-field.jsx +0 -54
  202. package/dist/components/form/input.jsx +0 -36
  203. package/dist/components/form/multi-select.jsx +0 -328
  204. package/dist/components/form/radiobox.jsx +0 -6
  205. package/dist/components/form/select.jsx +0 -42
  206. package/dist/components/form/slider.jsx +0 -45
  207. package/dist/components/form/switch.jsx +0 -46
  208. package/dist/components/form/task-list.jsx +0 -26
  209. package/dist/components/form/textarea.jsx +0 -12
  210. package/dist/components/form/transfer-list.jsx +0 -39
  211. package/dist/components/index.js +0 -43
  212. package/dist/components/table/filter.jsx +0 -141
  213. package/dist/components/table/group.jsx +0 -68
  214. package/dist/components/table/index.jsx +0 -60
  215. package/dist/components/table/inner-table.jsx +0 -104
  216. package/dist/components/table/metadata.jsx +0 -37
  217. package/dist/components/table/pagination.jsx +0 -73
  218. package/dist/components/table/row.jsx +0 -58
  219. package/dist/components/table/sort.jsx +0 -105
  220. package/dist/components/table/table-lib.js +0 -84
  221. package/dist/components/table/table.context.jsx +0 -4
  222. package/dist/components/table/thead.jsx +0 -103
  223. package/dist/config/context.js +0 -12
  224. package/dist/config/default-translations.jsx +0 -66
  225. package/dist/config/default-tweaks.js +0 -4
  226. package/dist/constants.js +0 -2
  227. package/dist/hooks/use-click-outside.js +0 -17
  228. package/dist/hooks/use-color-parser.js +0 -9
  229. package/dist/hooks/use-components-provider.jsx +0 -16
  230. package/dist/hooks/use-debounce.js +0 -12
  231. package/dist/hooks/use-floating-ref.js +0 -6
  232. package/dist/hooks/use-form.js +0 -549
  233. package/dist/hooks/use-hover.js +0 -18
  234. package/dist/hooks/use-input-id.js +0 -5
  235. package/dist/hooks/use-is-coarse-device.js +0 -12
  236. package/dist/hooks/use-locale.js +0 -10
  237. package/dist/hooks/use-media-query.js +0 -25
  238. package/dist/hooks/use-on-event.js +0 -7
  239. package/dist/hooks/use-parent.js +0 -21
  240. package/dist/hooks/use-preferences.js +0 -23
  241. package/dist/hooks/use-previous.js +0 -8
  242. package/dist/hooks/use-reactive.js +0 -8
  243. package/dist/hooks/use-remove-scroll.js +0 -61
  244. package/dist/hooks/use-resize-observer.js +0 -17
  245. package/dist/hooks/use-stable-ref.js +0 -8
  246. package/dist/hooks/use-swipe.js +0 -16
  247. package/dist/hooks/use-translations.js +0 -9
  248. package/dist/hooks/use-tweaks.js +0 -9
  249. package/dist/hooks/use-window-size.js +0 -14
  250. package/dist/lib/combi-keys.js +0 -60
  251. package/dist/lib/dict.js +0 -39
  252. package/dist/lib/dom.js +0 -44
  253. package/dist/lib/fns.js +0 -46
  254. package/dist/lib/fzf.js +0 -117
  255. package/dist/lib/keyboard-area.js +0 -14
  256. package/dist/preset/tailwindcssv4.d.ts +0 -3
  257. package/dist/preset/tailwindcssv4.d.ts.map +0 -1
  258. package/dist/preset/tailwindcssv4.js +0 -75
  259. package/dist/styles/common.js +0 -28
  260. package/dist/styles/dark.js +0 -209
  261. package/dist/styles/design-tokens.js +0 -69
  262. package/dist/styles/light.js +0 -209
  263. package/dist/styles/theme.js +0 -4
  264. package/dist/styles/theme.types.js +0 -1
  265. package/dist/types.js +0 -1
@@ -0,0 +1,225 @@
1
+ ---
2
+ title: Autocomplete
3
+ description: Searchable select with fuzzy matching, virtualized options, keyboard navigation, and dynamic option creation.
4
+ package: "@g4rcez/components"
5
+ export: "{ Autocomplete }"
6
+ import: "import { Autocomplete } from '@g4rcez/components/autocomplete'"
7
+ category: form
8
+ ---
9
+
10
+ # Autocomplete
11
+
12
+ Searchable select with fuzzy matching, virtualized options, keyboard navigation, and dynamic option creation.
13
+
14
+ ## Import
15
+
16
+ ```tsx
17
+ import { Autocomplete } from "@g4rcez/components/autocomplete";
18
+ ```
19
+
20
+ ## Props
21
+
22
+ | Prop | Type | Default | Description |
23
+ |------|------|---------|-------------|
24
+ | `title` | `string` | - | Field label |
25
+ | `value` | `string` | - | Controlled selected value |
26
+ | `options` | `AutocompleteItemProps[]` | - | List of selectable options |
27
+ | `emptyMessage` | `Label` | - | Message displayed when no options match |
28
+ | `dynamicOption` | `boolean` | `false` | Allow creating new options from typed text |
29
+ | `onChange` | `(e: React.ChangeEvent<HTMLInputElement>) => void` | - | Change handler |
30
+ | `error` | `string` | - | Error message displayed below the field |
31
+ | `feedback` | `Label` | - | Success/neutral feedback text below the field |
32
+ | `left` | `Label` | - | Content rendered on the left inside the field border |
33
+ | `right` | `Label` | - | Content rendered on the right inside the field border |
34
+ | `required` | `boolean` | `false` | Marks field as required; hides "Optional" text |
35
+ | `disabled` | `boolean` | `false` | Disables the field |
36
+ | `loading` | `boolean` | `false` | Shows loading state |
37
+ | `container` | `string` | - | Extra CSS classes for the outer `fieldset` |
38
+ | `labelClassName` | `string` | - | Extra CSS classes for the label/border wrapper |
39
+
40
+ ### AutocompleteItemProps
41
+
42
+ ```tsx
43
+ type AutocompleteItemProps = {
44
+ value: string;
45
+ label?: string;
46
+ hidden?: boolean;
47
+ disabled?: boolean;
48
+ "data-dynamic"?: string;
49
+ Render?: React.FC<OptionProps>;
50
+ } & Record<`data-${string}`, string>;
51
+ ```
52
+
53
+ ## Design Tokens
54
+
55
+ Tokens this component reads. Customize by overriding these CSS variables in your theme.
56
+
57
+ | Token | CSS Variable | Purpose |
58
+ |-------|-------------|---------|
59
+ | `h-input-height` | `--input-height` | Input height |
60
+ | `px-input-x` | `--input-x` | Horizontal input padding |
61
+ | `py-input-y` | `--input-y` | Vertical input padding |
62
+ | `border-input-border` | `--input-border` | Default field border color |
63
+ | `placeholder-input-mask` | `--input-mask` | Placeholder text color |
64
+ | `placeholder-input-mask-error` | `--input-mask-error` | Placeholder color in error state |
65
+ | `text-foreground` | `--foreground` | Input text color |
66
+ | `text-danger` | `--danger` | Text color in error state |
67
+ | `text-primary` | `--primary` | Focus/hover border and ring color |
68
+ | `bg-floating-background` | `--floating-background` | Dropdown background |
69
+ | `border-floating-border` | `--floating-border` | Dropdown border color |
70
+ | `bg-floating-hover` | `--floating-hover` | Option background on hover/keyboard focus |
71
+ | `text-disabled` | `--disabled` | Empty message text color |
72
+ | `border-tooltip-border` | `--tooltip-border` | Separator inside dropdown |
73
+ | `z-floating` | `--z-floating` | Z-index for the floating panel |
74
+ | `shadow-floating` | `--shadow-floating` | Drop shadow for the floating panel |
75
+
76
+ ## Examples
77
+
78
+ ### Basic usage
79
+
80
+ ```tsx
81
+ import { Autocomplete } from "@g4rcez/components/autocomplete";
82
+
83
+ const options = [
84
+ { value: "react", label: "React" },
85
+ { value: "vue", label: "Vue" },
86
+ { value: "svelte", label: "Svelte" },
87
+ ];
88
+
89
+ function FrameworkPicker() {
90
+ const [value, setValue] = useState("");
91
+
92
+ return (
93
+ <Autocomplete
94
+ title="Framework"
95
+ placeholder="Search frameworks..."
96
+ options={options}
97
+ value={value}
98
+ onChange={(e) => setValue(e.target.value)}
99
+ />
100
+ );
101
+ }
102
+ ```
103
+
104
+ ### Dynamic option creation
105
+
106
+ ```tsx
107
+ function TagPicker() {
108
+ const [value, setValue] = useState("");
109
+ const [tags, setTags] = useState([
110
+ { value: "typescript", label: "TypeScript" },
111
+ { value: "javascript", label: "JavaScript" },
112
+ ]);
113
+
114
+ const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
115
+ const next = e.target.value;
116
+ setValue(next);
117
+ if (next && !tags.find((t) => t.value === next)) {
118
+ setTags((prev) => [...prev, { value: next, label: next }]);
119
+ }
120
+ };
121
+
122
+ return (
123
+ <Autocomplete
124
+ title="Tag"
125
+ placeholder="Search or create a tag..."
126
+ options={tags}
127
+ value={value}
128
+ onChange={handleChange}
129
+ dynamicOption
130
+ emptyMessage="Type to create a new tag"
131
+ />
132
+ );
133
+ }
134
+ ```
135
+
136
+ ### Custom option renderer
137
+
138
+ ```tsx
139
+ type UserOption = AutocompleteItemProps & { email: string; role: string };
140
+
141
+ const UserRow = ({ value, label, ...props }: UserOption) => (
142
+ <div className="flex flex-col gap-0.5 py-1">
143
+ <span className="font-medium text-sm text-foreground">{label}</span>
144
+ <span className="text-xs text-muted-foreground">{props.email}</span>
145
+ </div>
146
+ );
147
+
148
+ const users: UserOption[] = [
149
+ { value: "alice", label: "Alice", email: "alice@example.com", role: "admin", Render: UserRow },
150
+ { value: "bob", label: "Bob", email: "bob@example.com", role: "member", Render: UserRow },
151
+ ];
152
+
153
+ <Autocomplete title="Assign to" options={users} value="" onChange={() => {}} />;
154
+ ```
155
+
156
+ ### Form integration
157
+
158
+ ```tsx
159
+ import { Form } from "@g4rcez/components/form";
160
+ import { Button } from "@g4rcez/components/button";
161
+
162
+ const countries = [
163
+ { value: "br", label: "Brazil" },
164
+ { value: "us", label: "United States" },
165
+ { value: "de", label: "Germany" },
166
+ ];
167
+
168
+ function ContactForm() {
169
+ const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {
170
+ const data = new FormData(e.currentTarget);
171
+ console.log(Object.fromEntries(data));
172
+ };
173
+
174
+ return (
175
+ <Form onSubmit={handleSubmit} className="flex flex-col gap-base">
176
+ <Autocomplete
177
+ name="country"
178
+ title="Country"
179
+ options={countries}
180
+ required
181
+ emptyMessage="No countries found"
182
+ />
183
+ <Button theme="primary" type="submit">Submit</Button>
184
+ </Form>
185
+ );
186
+ }
187
+ ```
188
+
189
+ ## Do
190
+
191
+ - Provide a meaningful `emptyMessage` so users understand why no results appear.
192
+ - Use `dynamicOption` when users should be able to add values not in the list.
193
+ - Supply a custom `Render` component when each option needs to show more than its label (e.g., avatars, secondary text).
194
+ - Prefer `Autocomplete` over `Select` for lists of more than ~15 items.
195
+
196
+ ## Don't
197
+
198
+ - Don't pass raw Tailwind color classes (`bg-blue-500`, `text-white`, `border-gray-300`) — use theme props or design tokens instead.
199
+ - Don't use arbitrary Tailwind values (`bg-[#abc]`, `bg-[--my-var]`) — override CSS variables in your `@theme` block instead.
200
+ - Don't use `Autocomplete` for small lists where `Select` is simpler and faster.
201
+ - Don't forget to handle the unselected case when `dynamicOption` is off and the user types but never picks an option.
202
+
203
+ ## Accessibility
204
+
205
+ - Renders a `role="listbox"` dropdown managed by `@floating-ui/react`.
206
+ - The visible input carries `aria-autocomplete="list"`.
207
+ - Each option button has `aria-selected`, `aria-current`, and `aria-checked` set to reflect the active state.
208
+ - Full keyboard navigation: Arrow Up/Down to move, Enter to select, Escape to close.
209
+ - The caret button includes an `sr-only` label from the translation system.
210
+ - Focus is returned to the trigger input when the dropdown closes.
211
+
212
+ ## Data Attributes
213
+
214
+ - `data-value` — on the hidden `<input>`: the committed option value.
215
+ - `data-shadow="true"` — on the visible text input to distinguish it from the real field.
216
+ - `data-dynamic="true"` — on options injected by `dynamicOption`.
217
+ - `data-initialized` — managed internally; used by `formReset` to track interaction state.
218
+ - `data-floating="true"` — on the floating panel element.
219
+
220
+ ## Notes
221
+
222
+ - The component renders two `<input>` elements: a visible shadow input for display/search and a hidden input with `name` that participates in form submission.
223
+ - Option filtering uses a fuzzy-search (`fzf`) algorithm that matches partial text, abbreviations, and out-of-order characters against both `value` and `label`.
224
+ - Large option lists are virtualized via `react-virtuoso` — rendering performance is maintained even with thousands of options.
225
+ - The dropdown width always matches the width of the triggering fieldset.
@@ -0,0 +1,182 @@
1
+ ---
2
+ title: Button
3
+ description: A versatile button component with multiple variants, sizes, and states.
4
+ package: "@g4rcez/components"
5
+ export: "{ Button }"
6
+ import: "import { Button } from '@g4rcez/components/button'"
7
+ category: core
8
+ ---
9
+
10
+ # Button
11
+
12
+ A versatile button component with multiple variants, sizes, and states. Built with polymorphic capabilities to render as different HTML elements.
13
+
14
+ ## Import
15
+
16
+ ```tsx
17
+ import { Button } from "@g4rcez/components/button";
18
+ ```
19
+
20
+ ## Props
21
+
22
+ | Prop | Type | Default | Description |
23
+ |------|------|---------|-------------|
24
+ | `theme` | `"main" \| "primary" \| "secondary" \| "info" \| "warn" \| "danger" \| "success" \| "muted" \| "neutral" \| "ghost-primary" \| "ghost-secondary" \| "ghost-info" \| "ghost-warn" \| "ghost-danger" \| "ghost-success" \| "ghost-muted" \| "ghost-neutral" \| "raw" \| "disabled" \| "loading"` | `"main"` | Visual theme/variant of the button |
25
+ | `size` | `"icon" \| "min" \| "small" \| "default" \| "big" \| "tiny"` | `"default"` | Size of the button |
26
+ | `rounded` | `"rough" \| "squared" \| "default" \| "circle"` | `"default"` | Border radius style |
27
+ | `icon` | `React.ReactNode` | - | Icon to display before button content |
28
+ | `loading` | `boolean` | `false` | Shows loading state with pulse animation and disables interaction |
29
+ | `disabled` | `boolean` | `false` | Disables the button |
30
+ | `as` | `React.ElementType` | `"button"` | HTML element to render as |
31
+ | `type` | `string` | `"button"` | Button type attribute |
32
+ | `className` | `string` | - | Additional CSS classes |
33
+ | `children` | `React.ReactNode` | - | Button content |
34
+
35
+ ## Design Tokens
36
+
37
+ Tokens this component reads. Customize by overriding these CSS variables in your theme.
38
+
39
+ | Token | CSS Variable | Purpose |
40
+ |-------|-------------|---------|
41
+ | `bg-button-primary-bg` | `--button-primary-bg` | Background for primary/main theme |
42
+ | `text-button-primary-text` | `--button-primary-text` | Text color for primary/main theme |
43
+ | `bg-button-secondary-bg` | `--button-secondary-bg` | Background for secondary theme |
44
+ | `text-button-secondary-text` | `--button-secondary-text` | Text color for secondary theme |
45
+ | `bg-button-info-bg` | `--button-info-bg` | Background for info theme |
46
+ | `text-button-info-text` | `--button-info-text` | Text color for info theme |
47
+ | `bg-button-warn-bg` | `--button-warn-bg` | Background for warn theme |
48
+ | `text-button-warn-text` | `--button-warn-text` | Text color for warn theme |
49
+ | `bg-button-danger-bg` | `--button-danger-bg` | Background for danger theme |
50
+ | `text-button-danger-text` | `--button-danger-text` | Text color for danger theme |
51
+ | `bg-button-success-bg` | `--button-success-bg` | Background for success theme |
52
+ | `text-button-success-text` | `--button-success-text` | Text color for success theme |
53
+ | `bg-button-muted-bg` | `--button-muted-bg` | Background for muted theme |
54
+ | `text-button-muted-text` | `--button-muted-text` | Text color for muted theme |
55
+ | `bg-disabled` | `--disabled` | Background for disabled/loading states |
56
+ | `border-card-border` | `--card-border` | Border color for neutral theme |
57
+ | `rounded-button` | `--radius-button` | Default border radius |
58
+ | `focus-visible:ring-ring` | `--ring` | Focus ring color |
59
+
60
+ ## Theme Variants
61
+
62
+ ### Solid Variants
63
+
64
+ - `main` / `primary`: Primary brand action
65
+ - `secondary`: Secondary action
66
+ - `info`: Informational action
67
+ - `warn`: Warning action
68
+ - `danger`: Destructive action
69
+ - `success`: Confirmation/success action
70
+ - `muted`: Subtle/subdued appearance
71
+ - `neutral`: Transparent with card border
72
+
73
+ ### Ghost Variants
74
+
75
+ Transparent background with colored text; shows a tinted background on hover.
76
+
77
+ - `ghost-primary`, `ghost-secondary`, `ghost-info`, `ghost-warn`, `ghost-danger`, `ghost-success`, `ghost-muted`, `ghost-neutral`
78
+
79
+ ### Special Variants
80
+
81
+ - `raw`: No default styling — supply all classes via `className`
82
+ - `disabled`: Disabled visual appearance (use the `disabled` prop for full behavior)
83
+ - `loading`: Pulse animation with muted background
84
+
85
+ ## Examples
86
+
87
+ ### Basic Variants
88
+
89
+ ```tsx
90
+ <Button theme="primary">Primary</Button>
91
+ <Button theme="secondary">Secondary</Button>
92
+ <Button theme="danger">Delete</Button>
93
+ <Button theme="success">Save</Button>
94
+ ```
95
+
96
+ ### Sizes
97
+
98
+ ```tsx
99
+ <Button size="min">Mini</Button>
100
+ <Button size="small">Small</Button>
101
+ <Button size="default">Default</Button>
102
+ <Button size="big">Big</Button>
103
+ ```
104
+
105
+ ### With Icons
106
+
107
+ ```tsx
108
+ import { PlusIcon } from "lucide-react";
109
+
110
+ <Button icon={<PlusIcon size={16} />}>Add Item</Button>
111
+
112
+ <Button size="icon" theme="ghost-primary">
113
+ <PlusIcon size={16} />
114
+ </Button>
115
+ ```
116
+
117
+ ### Loading State
118
+
119
+ ```tsx
120
+ <Button loading>Saving...</Button>
121
+ ```
122
+
123
+ ### Ghost Variants
124
+
125
+ ```tsx
126
+ <Button theme="ghost-primary">Ghost Primary</Button>
127
+ <Button theme="ghost-danger">Ghost Danger</Button>
128
+ ```
129
+
130
+ ### Polymorphic Usage
131
+
132
+ ```tsx
133
+ <Button as="a" href="/dashboard" theme="primary">
134
+ Go to Dashboard
135
+ </Button>
136
+ ```
137
+
138
+ ### Rounded Variants
139
+
140
+ ```tsx
141
+ <Button rounded="squared">Squared</Button>
142
+ <Button rounded="circle" size="icon">
143
+ <PlusIcon size={16} />
144
+ </Button>
145
+ ```
146
+
147
+ ## Do
148
+
149
+ - Use `theme="primary"` for the single main action on a page
150
+ - Use `theme="danger"` for destructive actions (delete, remove)
151
+ - Use the `loading` prop to give immediate feedback for async operations
152
+ - Use `as="a"` with `href` when the button navigates to a URL
153
+ - Use design-token classes for any wrapper elements (`bg-primary`, `text-foreground`)
154
+
155
+ ## Don't
156
+
157
+ - Don't pass raw Tailwind color classes (`bg-blue-500`, `text-white`) — use `theme` prop instead
158
+ - Don't use arbitrary Tailwind values (`bg-[#abc]`, `bg-[--my-var]`) — override CSS variables in your `@theme` block
159
+ - Don't place multiple `theme="primary"` buttons in the same view
160
+ - Don't use `theme="primary"` for destructive actions — use `theme="danger"` instead
161
+
162
+ ## Accessibility
163
+
164
+ - Renders as a semantic `<button>` element by default
165
+ - Sets `aria-disabled` when `disabled` or `loading` is true
166
+ - Sets `aria-busy` during loading state
167
+ - Click handlers are automatically removed while loading or disabled
168
+ - Supports visible focus rings via `focus-visible:ring-4 focus-visible:ring-ring`
169
+ - Keyboard navigation is fully supported
170
+
171
+ ## Data Attributes
172
+
173
+ - `data-component="button"`: Identifies the component for styling/testing
174
+ - `data-theme`: Current theme variant value
175
+ - `data-loading`: `"true"` when in loading state, `"false"` otherwise
176
+
177
+ ## Notes
178
+
179
+ - When `loading` is `true`, `disabled` is also set to `true` automatically
180
+ - The component forwards refs correctly to the underlying element
181
+ - All standard HTML button (or target element) attributes are forwarded
182
+ - The `as` prop enables rendering as any HTML element or React component while preserving full TypeScript type safety
@@ -0,0 +1,219 @@
1
+ ---
2
+ title: Calendar
3
+ description: Interactive month-view calendar with single-date and range selection, keyboard navigation, and locale support.
4
+ package: "@g4rcez/components"
5
+ export: "{ Calendar }"
6
+ import: "import { Calendar } from '@g4rcez/components/calendar'"
7
+ category: display
8
+ ---
9
+
10
+ # Calendar
11
+
12
+ Interactive month-view calendar with single-date and range selection, keyboard navigation, and locale support.
13
+
14
+ ## Import
15
+
16
+ ```tsx
17
+ import { Calendar } from "@g4rcez/components/calendar";
18
+ import type { Range, Locales } from "@g4rcez/components/calendar";
19
+ ```
20
+
21
+ ## Props
22
+
23
+ | Prop | Type | Default | Description |
24
+ |------|------|---------|-------------|
25
+ | `date` | `Date` | — | Selected date (single-date mode) |
26
+ | `range` | `Range` | — | Selected range `{ from?: Date; to?: Date }` |
27
+ | `rangeMode` | `boolean` | `false` | Enable range selection mode |
28
+ | `markRange` | `boolean` | `true` | Visually highlight dates inside a range |
29
+ | `markToday` | `boolean` | `true` | Emphasize today's date |
30
+ | `type` | `"date" \| "datetime"` | `"date"` | Show an additional time input when `"datetime"` |
31
+ | `datetimeTitle` | `string` | — | Label for the time input in `"datetime"` mode |
32
+ | `onChange` | `OnChangeDate \| OnChangeRange` | — | Called when a date or range changes |
33
+ | `changeOnlyOnClick` | `boolean` | `false` | Suppress onChange on keyboard navigation; fire only on explicit click |
34
+ | `onChangeYear` | `(date: Date) => void` | — | Called when the year changes |
35
+ | `onChangeMonth` | `(date: Date) => void` | — | Called when the month changes |
36
+ | `disabledDate` | `(date: Date) => boolean` | — | Return `true` to disable a specific date |
37
+ | `RenderOnDay` | `React.FC<{ date: Date }>` | — | Custom renderer overlaid on each day cell |
38
+ | `locale` | `Locales` | — | BCP 47 locale string for month/weekday labels |
39
+ | `labelRange` | `{ from: string; to: string }` | — | Labels shown on the selected range endpoints |
40
+ | `styles` | `CalendarStyles` | — | Fine-grained class overrides per calendar section |
41
+
42
+ ## Design Tokens
43
+
44
+ Tokens this component reads. Customize by overriding these CSS variables in your theme.
45
+
46
+ | Token | CSS Variable | Purpose |
47
+ |-------|-------------|---------|
48
+ | `bg-primary` | `--primary` | Selected day background |
49
+ | `text-primary-foreground` | `--primary-foreground` | Selected day text |
50
+ | `hover:bg-primary` | `--primary` | Navigation button hover background |
51
+ | `hover:text-primary-foreground` | `--primary-foreground` | Navigation button hover text |
52
+ | `text-primary` | `--primary` | "Today" button and year/month hover color |
53
+ | `text-disabled` | `--disabled` | Days outside the current month |
54
+ | `border-card-border` | `--card-border` | Range highlight border |
55
+ | `text-foreground` | `--foreground` | Range endpoint label |
56
+
57
+ ## Examples
58
+
59
+ ### Single Date Selection
60
+
61
+ ```tsx
62
+ import { useState } from "react";
63
+
64
+ function DatePicker() {
65
+ const [selectedDate, setSelectedDate] = useState<Date>(new Date());
66
+
67
+ return (
68
+ <Calendar
69
+ date={selectedDate}
70
+ onChange={setSelectedDate}
71
+ markToday
72
+ />
73
+ );
74
+ }
75
+ ```
76
+
77
+ ### Date Range Selection
78
+
79
+ ```tsx
80
+ import { useState } from "react";
81
+ import { Calendar, type Range } from "@g4rcez/components/calendar";
82
+
83
+ function DateRangePicker() {
84
+ const [range, setRange] = useState<Range>({ from: undefined, to: undefined });
85
+
86
+ return (
87
+ <Calendar
88
+ range={range}
89
+ rangeMode
90
+ markRange
91
+ onChange={setRange}
92
+ labelRange={{ from: "Start Date", to: "End Date" }}
93
+ />
94
+ );
95
+ }
96
+ ```
97
+
98
+ ### Disabled Dates
99
+
100
+ ```tsx
101
+ const isPastDate = (date: Date): boolean => {
102
+ const today = new Date();
103
+ today.setHours(0, 0, 0, 0);
104
+ return date < today;
105
+ };
106
+
107
+ <Calendar
108
+ date={selectedDate}
109
+ onChange={setSelectedDate}
110
+ disabledDate={isPastDate}
111
+ />
112
+ ```
113
+
114
+ ### Booking Calendar with Range Restrictions
115
+
116
+ ```tsx
117
+ function BookingCalendar() {
118
+ const [bookingRange, setBookingRange] = useState<Range>({});
119
+
120
+ const isDateDisabled = (date: Date): boolean => {
121
+ const today = new Date();
122
+ const minDate = new Date(today);
123
+ minDate.setDate(today.getDate() + 2);
124
+ const maxDate = new Date(today);
125
+ maxDate.setDate(today.getDate() + 90);
126
+ return date < minDate || date > maxDate;
127
+ };
128
+
129
+ return (
130
+ <Calendar
131
+ range={bookingRange}
132
+ rangeMode
133
+ markRange
134
+ markToday
135
+ onChange={setBookingRange}
136
+ disabledDate={isDateDisabled}
137
+ labelRange={{ from: "Check-in", to: "Check-out" }}
138
+ />
139
+ );
140
+ }
141
+ ```
142
+
143
+ ### Internationalized Calendar
144
+
145
+ ```tsx
146
+ import { Calendar, type Locales } from "@g4rcez/components/calendar";
147
+
148
+ function InternationalCalendar() {
149
+ const [selectedDate, setSelectedDate] = useState<Date>(new Date());
150
+ const [locale, setLocale] = useState<Locales>("en");
151
+
152
+ return (
153
+ <Calendar
154
+ date={selectedDate}
155
+ onChange={setSelectedDate}
156
+ locale={locale}
157
+ markToday
158
+ />
159
+ );
160
+ }
161
+ ```
162
+
163
+ ### Custom Day Renderer
164
+
165
+ ```tsx
166
+ function EventDot({ date }: { date: Date }) {
167
+ const hasEvent = myEvents.some(
168
+ (e) => e.date.toDateString() === date.toDateString()
169
+ );
170
+ return hasEvent ? (
171
+ <span className="absolute bottom-1 left-1/2 -translate-x-1/2 size-1 rounded-full bg-primary" />
172
+ ) : null;
173
+ }
174
+
175
+ <Calendar
176
+ date={selectedDate}
177
+ onChange={setSelectedDate}
178
+ RenderOnDay={EventDot}
179
+ markToday
180
+ />
181
+ ```
182
+
183
+ ## Do
184
+
185
+ - Use `markToday` to help users orient themselves.
186
+ - Use `disabledDate` to restrict selection to valid periods.
187
+ - Provide `labelRange` labels when using `rangeMode` so users know which endpoint they are selecting.
188
+ - Pass the correct `locale` to match user locale preferences.
189
+ - Use design-token classes for any wrapper elements (`bg-background`, `border-border`).
190
+
191
+ ## Don't
192
+
193
+ - Don't pass raw Tailwind color classes (`bg-blue-500`, `text-white`) in `styles` or `RenderOnDay` — use design tokens instead.
194
+ - Don't use arbitrary Tailwind values (`bg-[#abc]`) — override CSS variables in your `@theme` block.
195
+ - Don't use `Calendar` when only year selection is needed — a `Select` is more efficient.
196
+ - Don't place too many visual markers on each day; keep day-level indicators minimal.
197
+
198
+ ## Accessibility
199
+
200
+ - Full keyboard navigation: Arrow keys move days, Shift+Arrow moves months/years, Enter/Space selects.
201
+ - Month and year controls are accessible `<select>` and masked text inputs with `aria-label`.
202
+ - Navigation buttons include `title` attributes for screen reader description.
203
+ - Disabled dates use the native `disabled` attribute on `<button>`.
204
+
205
+ ## Data Attributes
206
+
207
+ - `data-component="calendar"` — root container.
208
+ - `data-date` — ISO date string on each day button, used for focus management.
209
+ - `data-samemonth` — `"true"` / `"false"` on each day button.
210
+ - `data-range` — `"true"` / `"false"` on each day button.
211
+ - `data-focustrap` — `"prev"` / `"next"` on navigation buttons.
212
+
213
+ ## Notes
214
+
215
+ - Uses `date-fns` for date arithmetic and Framer Motion (`motion/react`) for slide animations.
216
+ - Touch devices get swipe-left/right support for month navigation automatically.
217
+ - When `changeOnlyOnClick` is `false` (default), `onChange` fires on every keyboard navigation move.
218
+ - The calendar always renders 6 weeks (42 cells) to avoid layout shifts when switching months.
219
+ - `type="datetime"` appends a masked time input below the calendar grid.