@soave/ui 0.1.0 → 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.
Files changed (74) hide show
  1. package/dist/adapters/css-variables.d.ts +2 -0
  2. package/dist/adapters/css-variables.mjs +228 -0
  3. package/dist/adapters/headless.d.ts +7 -0
  4. package/dist/adapters/headless.mjs +7 -0
  5. package/dist/adapters/index.d.ts +5 -0
  6. package/dist/adapters/index.mjs +11 -0
  7. package/dist/adapters/tailwind.d.ts +2 -0
  8. package/dist/adapters/tailwind.mjs +443 -0
  9. package/dist/adapters/types.d.ts +38 -0
  10. package/dist/adapters/types.mjs +10 -0
  11. package/dist/build.config.mjs +1 -1
  12. package/dist/components/ui/Alert.vue +18 -16
  13. package/dist/components/ui/AlertDescription.vue +13 -3
  14. package/dist/components/ui/AlertTitle.vue +13 -3
  15. package/dist/components/ui/Button.vue +30 -4
  16. package/dist/components/ui/Card.vue +27 -3
  17. package/dist/components/ui/CardContent.vue +13 -3
  18. package/dist/components/ui/CardDescription.vue +13 -3
  19. package/dist/components/ui/CardFooter.vue +13 -3
  20. package/dist/components/ui/CardHeader.vue +13 -3
  21. package/dist/components/ui/CardTitle.vue +13 -3
  22. package/dist/components/ui/Checkbox.vue +23 -2
  23. package/dist/components/ui/Dialog.vue +31 -9
  24. package/dist/components/ui/DialogDescription.vue +13 -3
  25. package/dist/components/ui/DialogFooter.vue +13 -3
  26. package/dist/components/ui/DialogHeader.vue +13 -3
  27. package/dist/components/ui/DialogTitle.vue +13 -3
  28. package/dist/components/ui/DropdownMenuContent.vue +16 -13
  29. package/dist/components/ui/DropdownMenuItem.vue +11 -17
  30. package/dist/components/ui/Input.vue +26 -3
  31. package/dist/components/ui/PopoverContent.vue +16 -12
  32. package/dist/components/ui/RadioGroup.vue +12 -7
  33. package/dist/components/ui/RadioItem.vue +31 -10
  34. package/dist/components/ui/Select.vue +8 -1
  35. package/dist/components/ui/SelectContent.vue +31 -5
  36. package/dist/components/ui/SelectItem.vue +20 -16
  37. package/dist/components/ui/SelectTrigger.vue +39 -7
  38. package/dist/components/ui/SelectValue.vue +13 -2
  39. package/dist/components/ui/Sheet.vue +32 -24
  40. package/dist/components/ui/SheetDescription.vue +13 -6
  41. package/dist/components/ui/SheetFooter.vue +13 -6
  42. package/dist/components/ui/SheetHeader.vue +13 -6
  43. package/dist/components/ui/SheetTitle.vue +13 -6
  44. package/dist/components/ui/Switch.vue +23 -3
  45. package/dist/components/ui/Textarea.vue +26 -3
  46. package/dist/components/ui/Toast.vue +38 -29
  47. package/dist/components/ui/Toaster.vue +12 -16
  48. package/dist/components/ui/TooltipContent.vue +18 -15
  49. package/dist/components/ui/UIProvider.vue +6 -2
  50. package/dist/composables/index.d.ts +1 -1
  51. package/dist/composables/index.mjs +1 -1
  52. package/dist/composables/useUIConfig.d.ts +16 -5
  53. package/dist/composables/useUIConfig.mjs +26 -9
  54. package/dist/index.d.ts +1 -0
  55. package/dist/index.mjs +1 -0
  56. package/dist/styles/css-variables.css +1 -0
  57. package/dist/styles/index.d.ts +1 -0
  58. package/dist/styles/index.mjs +1 -0
  59. package/dist/types/alert.d.ts +2 -0
  60. package/dist/types/card.d.ts +5 -0
  61. package/dist/types/composables.d.ts +122 -0
  62. package/dist/types/composables.mjs +0 -0
  63. package/dist/types/config.d.ts +8 -0
  64. package/dist/types/dialog.d.ts +7 -0
  65. package/dist/types/dropdown.d.ts +8 -0
  66. package/dist/types/index.d.ts +1 -0
  67. package/dist/types/index.mjs +1 -0
  68. package/dist/types/popover.d.ts +6 -0
  69. package/dist/types/radio.d.ts +4 -0
  70. package/dist/types/select.d.ts +21 -0
  71. package/dist/types/sheet.d.ts +19 -0
  72. package/dist/types/toast.d.ts +2 -0
  73. package/dist/types/tooltip.d.ts +6 -0
  74. package/package.json +9 -1
@@ -0,0 +1,443 @@
1
+ import { cn } from "../utils/cn.mjs";
2
+ export const tailwindAdapter = {
3
+ name: "tailwind",
4
+ description: "Tailwind CSS \u30D9\u30FC\u30B9\u306E\u30B9\u30BF\u30A4\u30EA\u30F3\u30B0",
5
+ getClasses(component, state) {
6
+ switch (component) {
7
+ case "button":
8
+ return getTailwindButtonClasses(state);
9
+ case "input":
10
+ return getTailwindInputClasses(state);
11
+ case "card":
12
+ return getTailwindCardClasses(state);
13
+ case "dialog":
14
+ return getTailwindDialogClasses(state);
15
+ case "dialog-overlay":
16
+ return getTailwindDialogOverlayClasses();
17
+ case "checkbox":
18
+ return getTailwindCheckboxClasses(state);
19
+ case "radio":
20
+ return getTailwindRadioClasses(state);
21
+ case "radio-group":
22
+ return getTailwindRadioGroupClasses(state);
23
+ case "radio-indicator":
24
+ return getTailwindRadioIndicatorClasses();
25
+ case "switch":
26
+ return getTailwindSwitchClasses(state);
27
+ case "textarea":
28
+ return getTailwindTextareaClasses(state);
29
+ case "select":
30
+ return getTailwindSelectClasses(state);
31
+ case "select-content":
32
+ return getTailwindSelectContentClasses();
33
+ case "select-item":
34
+ return getTailwindSelectItemClasses();
35
+ case "select-value":
36
+ return getTailwindSelectValueClasses(state);
37
+ case "select-trigger-icon":
38
+ return getTailwindSelectTriggerIconClasses();
39
+ case "toast":
40
+ return getTailwindToastClasses(state);
41
+ case "toast-title":
42
+ return getTailwindToastTitleClasses();
43
+ case "toast-description":
44
+ return getTailwindToastDescriptionClasses();
45
+ case "toast-action":
46
+ return getTailwindToastActionClasses();
47
+ case "toast-dismiss":
48
+ return getTailwindToastDismissClasses();
49
+ case "toaster":
50
+ return getTailwindToasterClasses(state);
51
+ case "tooltip":
52
+ return getTailwindTooltipClasses(state);
53
+ case "popover":
54
+ return getTailwindPopoverClasses(state);
55
+ case "dropdown":
56
+ return getTailwindDropdownClasses(state);
57
+ case "dropdown-item":
58
+ return getTailwindDropdownItemClasses();
59
+ case "sheet":
60
+ return getTailwindSheetClasses(state);
61
+ case "sheet-overlay":
62
+ return getTailwindSheetOverlayClasses();
63
+ case "sheet-header":
64
+ return getTailwindSheetHeaderClasses();
65
+ case "sheet-title":
66
+ return getTailwindSheetTitleClasses();
67
+ case "sheet-description":
68
+ return getTailwindSheetDescriptionClasses();
69
+ case "sheet-footer":
70
+ return getTailwindSheetFooterClasses();
71
+ case "sheet-close":
72
+ return getTailwindSheetCloseClasses();
73
+ case "alert":
74
+ return getTailwindAlertClasses(state);
75
+ case "alert-title":
76
+ return getTailwindAlertTitleClasses();
77
+ case "alert-description":
78
+ return getTailwindAlertDescriptionClasses();
79
+ case "label":
80
+ return getTailwindLabelClasses();
81
+ // Dialog sub-components
82
+ case "dialog-header":
83
+ return getTailwindDialogHeaderClasses();
84
+ case "dialog-title":
85
+ return getTailwindDialogTitleClasses();
86
+ case "dialog-description":
87
+ return getTailwindDialogDescriptionClasses();
88
+ case "dialog-footer":
89
+ return getTailwindDialogFooterClasses();
90
+ case "dialog-close":
91
+ return getTailwindDialogCloseClasses();
92
+ // Card sub-components
93
+ case "card-header":
94
+ return getTailwindCardHeaderClasses();
95
+ case "card-title":
96
+ return getTailwindCardTitleClasses();
97
+ case "card-description":
98
+ return getTailwindCardDescriptionClasses();
99
+ case "card-content":
100
+ return getTailwindCardContentClasses();
101
+ case "card-footer":
102
+ return getTailwindCardFooterClasses();
103
+ default:
104
+ return "";
105
+ }
106
+ }
107
+ };
108
+ function getTailwindButtonClasses(state) {
109
+ const variant_map = {
110
+ primary: "bg-primary text-primary-foreground hover:bg-primary/90 active:bg-primary/80",
111
+ secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80 active:bg-secondary/70",
112
+ ghost: "hover:bg-accent hover:text-accent-foreground",
113
+ outline: "border border-input bg-background hover:bg-accent hover:text-accent-foreground",
114
+ destructive: "bg-destructive text-destructive-foreground hover:bg-destructive/90"
115
+ };
116
+ const size_map = {
117
+ sm: "h-9 px-3 text-sm",
118
+ md: "h-10 px-4 py-2",
119
+ lg: "h-11 px-8 text-lg"
120
+ };
121
+ return cn(
122
+ "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium",
123
+ "ring-offset-background transition-colors",
124
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
125
+ "disabled:pointer-events-none disabled:opacity-50",
126
+ variant_map[state.variant],
127
+ size_map[state.size],
128
+ state.disabled && "opacity-50 cursor-not-allowed",
129
+ state.loading && "cursor-wait"
130
+ );
131
+ }
132
+ function getTailwindInputClasses(state) {
133
+ const size_map = {
134
+ sm: "h-9 text-sm",
135
+ md: "h-10",
136
+ lg: "h-11 text-lg"
137
+ };
138
+ return cn(
139
+ "flex w-full rounded-md border border-input bg-background px-3 py-2",
140
+ "text-sm ring-offset-background",
141
+ "file:border-0 file:bg-transparent file:text-sm file:font-medium",
142
+ "placeholder:text-muted-foreground",
143
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
144
+ "disabled:cursor-not-allowed disabled:opacity-50",
145
+ size_map[state.size],
146
+ state.error && "border-destructive focus-visible:ring-destructive",
147
+ state.readonly && "bg-muted"
148
+ );
149
+ }
150
+ function getTailwindCardClasses(state) {
151
+ const padding_map = {
152
+ none: "",
153
+ sm: "p-4",
154
+ md: "p-6",
155
+ lg: "p-8"
156
+ };
157
+ return cn(
158
+ "rounded-lg border border-card-border bg-card text-card-foreground shadow-sm",
159
+ padding_map[state.padding]
160
+ );
161
+ }
162
+ function getTailwindDialogClasses(state) {
163
+ return cn(
164
+ "fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg",
165
+ "translate-x-[-50%] translate-y-[-50%] gap-4",
166
+ "border bg-background p-6 shadow-lg duration-200",
167
+ "sm:rounded-lg"
168
+ );
169
+ }
170
+ function getTailwindDialogOverlayClasses() {
171
+ return cn(
172
+ "fixed inset-0 z-50 bg-black/80",
173
+ "data-[state=open]:animate-in data-[state=closed]:animate-out",
174
+ "data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0"
175
+ );
176
+ }
177
+ function getTailwindCheckboxClasses(state) {
178
+ return cn(
179
+ "peer h-4 w-4 shrink-0 rounded-sm border border-primary",
180
+ "ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
181
+ "disabled:cursor-not-allowed disabled:opacity-50",
182
+ state.checked && "bg-primary text-primary-foreground",
183
+ state.disabled && "opacity-50 cursor-not-allowed"
184
+ );
185
+ }
186
+ function getTailwindRadioClasses(state) {
187
+ return cn(
188
+ "aspect-square h-4 w-4 rounded-full border border-primary text-primary",
189
+ "ring-offset-background focus:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
190
+ "disabled:cursor-not-allowed disabled:opacity-50",
191
+ state.disabled && "opacity-50 cursor-not-allowed"
192
+ );
193
+ }
194
+ function getTailwindRadioGroupClasses(state) {
195
+ return cn(
196
+ "grid gap-2",
197
+ state.orientation === "horizontal" && "grid-flow-col"
198
+ );
199
+ }
200
+ function getTailwindRadioIndicatorClasses() {
201
+ return cn("flex items-center justify-center");
202
+ }
203
+ function getTailwindSwitchClasses(state) {
204
+ return cn(
205
+ "peer inline-flex h-6 w-11 shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent",
206
+ "transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background",
207
+ "disabled:cursor-not-allowed disabled:opacity-50",
208
+ state.checked ? "bg-primary" : "bg-input",
209
+ state.disabled && "opacity-50 cursor-not-allowed"
210
+ );
211
+ }
212
+ function getTailwindTextareaClasses(state) {
213
+ const size_map = {
214
+ sm: "min-h-[80px] text-sm",
215
+ md: "min-h-[100px]",
216
+ lg: "min-h-[120px] text-lg"
217
+ };
218
+ return cn(
219
+ "flex w-full rounded-md border border-input bg-background px-3 py-2",
220
+ "text-sm ring-offset-background placeholder:text-muted-foreground",
221
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
222
+ "disabled:cursor-not-allowed disabled:opacity-50",
223
+ size_map[state.size],
224
+ state.error && "border-destructive focus-visible:ring-destructive",
225
+ state.readonly && "bg-muted"
226
+ );
227
+ }
228
+ function getTailwindSelectClasses(state) {
229
+ const size_map = {
230
+ sm: "h-9 text-sm",
231
+ md: "h-10",
232
+ lg: "h-11 text-lg"
233
+ };
234
+ return cn(
235
+ "flex w-full items-center justify-between rounded-md border border-input bg-background px-3 py-2",
236
+ "text-sm ring-offset-background placeholder:text-muted-foreground",
237
+ "focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",
238
+ "disabled:cursor-not-allowed disabled:opacity-50",
239
+ size_map[state.size],
240
+ state.disabled && "opacity-50 cursor-not-allowed"
241
+ );
242
+ }
243
+ function getTailwindSelectContentClasses() {
244
+ return cn(
245
+ "relative z-50 max-h-96 min-w-[8rem] overflow-hidden rounded-md border bg-popover text-popover-foreground shadow-md",
246
+ "data-[state=open]:animate-in data-[state=closed]:animate-out",
247
+ "data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
248
+ "data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95",
249
+ "data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2",
250
+ "data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2"
251
+ );
252
+ }
253
+ function getTailwindSelectItemClasses() {
254
+ return cn(
255
+ "relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none",
256
+ "focus:bg-accent focus:text-accent-foreground",
257
+ "data-[disabled]:pointer-events-none data-[disabled]:opacity-50"
258
+ );
259
+ }
260
+ function getTailwindSelectValueClasses(state) {
261
+ return cn(
262
+ state.hasValue ? "" : "text-muted-foreground"
263
+ );
264
+ }
265
+ function getTailwindSelectTriggerIconClasses() {
266
+ return cn("h-4 w-4 opacity-50");
267
+ }
268
+ function getTailwindToastClasses(state) {
269
+ const variant_map = {
270
+ default: "border bg-background text-foreground",
271
+ success: "border-green-500 bg-green-50 text-green-900 dark:bg-green-900 dark:text-green-50",
272
+ error: "border-destructive bg-destructive/10 text-destructive",
273
+ warning: "border-yellow-500 bg-yellow-50 text-yellow-900 dark:bg-yellow-900 dark:text-yellow-50",
274
+ info: "border-blue-500 bg-blue-50 text-blue-900 dark:bg-blue-900 dark:text-blue-50"
275
+ };
276
+ return cn(
277
+ "pointer-events-auto flex items-start gap-4 rounded-lg border p-4 shadow-lg transition-all",
278
+ variant_map[state.variant]
279
+ );
280
+ }
281
+ function getTailwindToastTitleClasses() {
282
+ return cn("text-sm font-semibold");
283
+ }
284
+ function getTailwindToastDescriptionClasses() {
285
+ return cn("text-sm opacity-90");
286
+ }
287
+ function getTailwindToastActionClasses() {
288
+ return cn(
289
+ "inline-flex items-center justify-center rounded-md text-sm font-medium",
290
+ "h-8 px-3 ring-offset-background transition-colors",
291
+ "hover:bg-secondary focus-visible:outline-none focus-visible:ring-2",
292
+ "focus-visible:ring-ring focus-visible:ring-offset-2"
293
+ );
294
+ }
295
+ function getTailwindToastDismissClasses() {
296
+ return cn(
297
+ "inline-flex items-center justify-center rounded-md",
298
+ "h-6 w-6 shrink-0 opacity-70 transition-opacity",
299
+ "hover:opacity-100 focus-visible:outline-none focus-visible:ring-2",
300
+ "focus-visible:ring-ring"
301
+ );
302
+ }
303
+ function getTailwindToasterClasses(state) {
304
+ const position_map = {
305
+ "top-left": "top-0 left-0 flex-col",
306
+ "top-center": "top-0 left-1/2 -translate-x-1/2 flex-col items-center",
307
+ "top-right": "top-0 right-0 flex-col items-end",
308
+ "bottom-left": "bottom-0 left-0 flex-col-reverse",
309
+ "bottom-center": "bottom-0 left-1/2 -translate-x-1/2 flex-col-reverse items-center",
310
+ "bottom-right": "bottom-0 right-0 flex-col-reverse items-end"
311
+ };
312
+ return cn(
313
+ "fixed z-[100] flex pointer-events-none p-4",
314
+ position_map[state.position] ?? position_map["bottom-right"]
315
+ );
316
+ }
317
+ function getTailwindTooltipClasses(state) {
318
+ return cn(
319
+ "z-50 overflow-hidden rounded-md border bg-popover px-3 py-1.5 text-sm text-popover-foreground shadow-md",
320
+ "animate-in fade-in-0 zoom-in-95",
321
+ "data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95"
322
+ );
323
+ }
324
+ function getTailwindPopoverClasses(state) {
325
+ return cn(
326
+ "z-50 w-72 rounded-md border bg-popover p-4 text-popover-foreground shadow-md outline-none",
327
+ "data-[state=open]:animate-in data-[state=closed]:animate-out",
328
+ "data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
329
+ "data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95"
330
+ );
331
+ }
332
+ function getTailwindDropdownClasses(state) {
333
+ return cn(
334
+ "z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md",
335
+ "data-[state=open]:animate-in data-[state=closed]:animate-out",
336
+ "data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
337
+ "data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95"
338
+ );
339
+ }
340
+ function getTailwindDropdownItemClasses() {
341
+ return cn(
342
+ "relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none transition-colors",
343
+ "focus:bg-accent focus:text-accent-foreground",
344
+ "data-[disabled]:pointer-events-none data-[disabled]:opacity-50"
345
+ );
346
+ }
347
+ function getTailwindSheetClasses(state) {
348
+ const side_map = {
349
+ top: "inset-x-0 top-0 border-b data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top",
350
+ bottom: "inset-x-0 bottom-0 border-t data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom",
351
+ left: "inset-y-0 left-0 h-full w-3/4 border-r data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left sm:max-w-sm",
352
+ right: "inset-y-0 right-0 h-full w-3/4 border-l data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right sm:max-w-sm"
353
+ };
354
+ return cn(
355
+ "fixed z-50 gap-4 bg-background p-6 shadow-lg transition ease-in-out",
356
+ "data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:duration-300 data-[state=open]:duration-500",
357
+ side_map[state.side]
358
+ );
359
+ }
360
+ function getTailwindSheetOverlayClasses() {
361
+ return cn(
362
+ "fixed inset-0 z-50 bg-black/80",
363
+ "data-[state=open]:animate-in data-[state=closed]:animate-out",
364
+ "data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0"
365
+ );
366
+ }
367
+ function getTailwindSheetHeaderClasses() {
368
+ return cn("flex flex-col space-y-2 text-center sm:text-left");
369
+ }
370
+ function getTailwindSheetTitleClasses() {
371
+ return cn("text-lg font-semibold text-foreground");
372
+ }
373
+ function getTailwindSheetDescriptionClasses() {
374
+ return cn("text-sm text-muted-foreground");
375
+ }
376
+ function getTailwindSheetFooterClasses() {
377
+ return cn("flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2");
378
+ }
379
+ function getTailwindSheetCloseClasses() {
380
+ return cn(
381
+ "absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background",
382
+ "transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2"
383
+ );
384
+ }
385
+ function getTailwindAlertClasses(state) {
386
+ const variant_map = {
387
+ default: "bg-background text-foreground",
388
+ info: "border-blue-200 bg-blue-50 text-blue-900 [&>svg]:text-blue-600",
389
+ success: "border-green-200 bg-green-50 text-green-900 [&>svg]:text-green-600",
390
+ warning: "border-yellow-200 bg-yellow-50 text-yellow-900 [&>svg]:text-yellow-600",
391
+ destructive: "border-destructive/50 text-destructive bg-destructive/10 [&>svg]:text-destructive"
392
+ };
393
+ return cn(
394
+ "relative w-full rounded-lg border p-4",
395
+ "[&>svg~*]:pl-7 [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 [&>svg]:text-foreground",
396
+ variant_map[state.variant]
397
+ );
398
+ }
399
+ function getTailwindLabelClasses() {
400
+ return cn(
401
+ "text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
402
+ );
403
+ }
404
+ function getTailwindDialogHeaderClasses() {
405
+ return cn("flex flex-col space-y-1.5 text-center sm:text-left");
406
+ }
407
+ function getTailwindDialogTitleClasses() {
408
+ return cn("text-lg font-semibold leading-none tracking-tight");
409
+ }
410
+ function getTailwindDialogDescriptionClasses() {
411
+ return cn("text-sm text-muted-foreground");
412
+ }
413
+ function getTailwindDialogFooterClasses() {
414
+ return cn("flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2");
415
+ }
416
+ function getTailwindDialogCloseClasses() {
417
+ return cn(
418
+ "absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background",
419
+ "transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",
420
+ "disabled:pointer-events-none"
421
+ );
422
+ }
423
+ function getTailwindAlertTitleClasses() {
424
+ return cn("mb-1 font-medium leading-none tracking-tight");
425
+ }
426
+ function getTailwindAlertDescriptionClasses() {
427
+ return cn("text-sm [&_p]:leading-relaxed");
428
+ }
429
+ function getTailwindCardHeaderClasses() {
430
+ return cn("flex flex-col space-y-1.5 p-6");
431
+ }
432
+ function getTailwindCardTitleClasses() {
433
+ return cn("text-2xl font-semibold leading-none tracking-tight");
434
+ }
435
+ function getTailwindCardDescriptionClasses() {
436
+ return cn("text-sm text-muted-foreground");
437
+ }
438
+ function getTailwindCardContentClasses() {
439
+ return cn("p-6 pt-0");
440
+ }
441
+ function getTailwindCardFooterClasses() {
442
+ return cn("flex items-center p-6 pt-0");
443
+ }
@@ -0,0 +1,38 @@
1
+ import type { ComponentState } from "../types/composables";
2
+ /**
3
+ * Style Adapter インターフェース
4
+ * コンポーネントの状態からスタイルクラスを生成する
5
+ */
6
+ export interface StyleAdapter {
7
+ /**
8
+ * Adapter の識別名
9
+ */
10
+ name: "tailwind" | "css-variables" | "headless" | string;
11
+ /**
12
+ * Adapter の説明
13
+ */
14
+ description?: string;
15
+ /**
16
+ * コンポーネント名と状態からクラス文字列を生成
17
+ * @param component コンポーネント名("button", "input" など)
18
+ * @param state コンポーネントの状態オブジェクト
19
+ * @returns CSS クラス文字列
20
+ */
21
+ getClasses(component: string, state: ComponentState): string;
22
+ }
23
+ /**
24
+ * Adapter レジストリ
25
+ */
26
+ export declare const ADAPTER_REGISTRY: any;
27
+ /**
28
+ * Adapter を登録
29
+ */
30
+ export declare const registerAdapter: (adapter: StyleAdapter) => void;
31
+ /**
32
+ * Adapter を取得
33
+ */
34
+ export declare const getAdapter: (name: string) => StyleAdapter | undefined;
35
+ /**
36
+ * 全ての登録済み Adapter を取得
37
+ */
38
+ export declare const getRegisteredAdapters: () => Map<string, StyleAdapter>;
@@ -0,0 +1,10 @@
1
+ export const ADAPTER_REGISTRY = /* @__PURE__ */ new Map();
2
+ export const registerAdapter = (adapter) => {
3
+ ADAPTER_REGISTRY.set(adapter.name, adapter);
4
+ };
5
+ export const getAdapter = (name) => {
6
+ return ADAPTER_REGISTRY.get(name);
7
+ };
8
+ export const getRegisteredAdapters = () => {
9
+ return ADAPTER_REGISTRY;
10
+ };
@@ -5,7 +5,7 @@ export default defineBuildConfig({
5
5
  builder: "mkdist",
6
6
  input: "./",
7
7
  outDir: "./dist",
8
- pattern: ["**/*.ts", "**/*.vue"],
8
+ pattern: ["**/*.ts", "**/*.vue", "**/*.css"],
9
9
  declaration: true
10
10
  }
11
11
  ],
@@ -1,11 +1,7 @@
1
1
  <template>
2
2
  <div
3
3
  role="alert"
4
- :class="cn(
5
- 'relative w-full rounded-lg border p-4',
6
- variant_classes,
7
- props.class
8
- )"
4
+ :class="[computed_classes, props.class]"
9
5
  >
10
6
  <slot />
11
7
  </div>
@@ -13,27 +9,33 @@
13
9
 
14
10
  <script setup lang="ts">
15
11
  import { computed } from "vue"
16
- import { cn } from "../../utils/cn"
17
- import { useUI } from "../../composables/useUIConfig"
12
+ import { useUI, useStyleAdapter } from "../../composables/useUIConfig"
18
13
  import type { AlertVariant } from "../../types/alert"
14
+ import type { AlertState } from "../../types/composables"
19
15
 
20
16
  interface Props {
21
17
  variant?: AlertVariant
22
18
  class?: string
19
+ unstyled?: boolean
23
20
  }
24
21
 
25
- const props = defineProps<Props>()
22
+ const props = withDefaults(defineProps<Props>(), {
23
+ unstyled: false
24
+ })
26
25
 
27
26
  const ui_config = useUI("alert")
27
+ const style_adapter = useStyleAdapter()
28
+
29
+ // StyleAdapterからクラスを取得
30
+ const computed_classes = computed(() => {
31
+ if (props.unstyled) {
32
+ return ""
33
+ }
28
34
 
29
- const variant_classes = computed(() => {
30
- const variant_map: Record<AlertVariant, string> = {
31
- default: "bg-background text-foreground",
32
- info: "border-blue-200 bg-blue-50 text-blue-900 [&>svg]:text-blue-600",
33
- success: "border-green-200 bg-green-50 text-green-900 [&>svg]:text-green-600",
34
- warning: "border-yellow-200 bg-yellow-50 text-yellow-900 [&>svg]:text-yellow-600",
35
- destructive: "border-destructive/50 text-destructive bg-destructive/10 [&>svg]:text-destructive"
35
+ const state: AlertState = {
36
+ variant: props.variant ?? ui_config.default_variant
36
37
  }
37
- return variant_map[props.variant ?? ui_config.default_variant]
38
+
39
+ return style_adapter.getClasses("alert", state)
38
40
  })
39
41
  </script>
@@ -1,12 +1,22 @@
1
1
  <template>
2
- <div :class="cn('text-sm [&_p]:leading-relaxed', props.class)">
2
+ <div :class="[computed_classes, props.class]">
3
3
  <slot />
4
4
  </div>
5
5
  </template>
6
6
 
7
7
  <script setup lang="ts">
8
- import { cn } from "../../utils/cn"
8
+ import { computed } from "vue"
9
+ import { useStyleAdapter } from "../../composables"
9
10
  import type { AlertDescriptionProps } from "../../types/alert"
10
11
 
11
- const props = defineProps<AlertDescriptionProps>()
12
+ const props = withDefaults(defineProps<AlertDescriptionProps>(), {
13
+ unstyled: false
14
+ })
15
+
16
+ const style_adapter = useStyleAdapter()
17
+
18
+ const computed_classes = computed(() => {
19
+ if (props.unstyled) return ""
20
+ return style_adapter.getClasses("alert-description", {})
21
+ })
12
22
  </script>
@@ -1,12 +1,22 @@
1
1
  <template>
2
- <h5 :class="cn('mb-1 font-medium leading-none tracking-tight', props.class)">
2
+ <h5 :class="[computed_classes, props.class]">
3
3
  <slot />
4
4
  </h5>
5
5
  </template>
6
6
 
7
7
  <script setup lang="ts">
8
- import { cn } from "../../utils/cn"
8
+ import { computed } from "vue"
9
+ import { useStyleAdapter } from "../../composables"
9
10
  import type { AlertTitleProps } from "../../types/alert"
10
11
 
11
- const props = defineProps<AlertTitleProps>()
12
+ const props = withDefaults(defineProps<AlertTitleProps>(), {
13
+ unstyled: false
14
+ })
15
+
16
+ const style_adapter = useStyleAdapter()
17
+
18
+ const computed_classes = computed(() => {
19
+ if (props.unstyled) return ""
20
+ return style_adapter.getClasses("alert-title", {})
21
+ })
12
22
  </script>
@@ -1,6 +1,6 @@
1
1
  <template>
2
2
  <button
3
- :class="composable.base_classes.value"
3
+ :class="[computed_classes, props.class]"
4
4
  :disabled="composable.is_disabled.value"
5
5
  v-bind="composable.aria_attributes.value"
6
6
  @click="handleClick"
@@ -36,21 +36,47 @@
36
36
  </template>
37
37
 
38
38
  <script setup lang="ts">
39
- import { toRef } from "vue"
39
+ import { toRef, computed } from "vue"
40
40
  import { useButton } from "../../composables/useButton"
41
+ import { useStyleAdapter, useUI } from "../../composables/useUIConfig"
41
42
  import type { ButtonProps } from "../../types/button"
43
+ import type { ButtonState } from "../../types/composables"
42
44
 
43
- const props = withDefaults(defineProps<ButtonProps>(), {
45
+ interface ButtonComponentProps extends ButtonProps {
46
+ class?: string
47
+ unstyled?: boolean
48
+ }
49
+
50
+ const props = withDefaults(defineProps<ButtonComponentProps>(), {
44
51
  disabled: false,
45
- loading: false
52
+ loading: false,
53
+ unstyled: false
46
54
  })
47
55
 
48
56
  const emit = defineEmits<{
49
57
  click: [event: MouseEvent]
50
58
  }>()
51
59
 
60
+ const ui_config = useUI("button")
61
+ const style_adapter = useStyleAdapter()
52
62
  const composable = useButton(toRef(() => props))
53
63
 
64
+ // StyleAdapterからクラスを取得
65
+ const computed_classes = computed(() => {
66
+ if (props.unstyled) {
67
+ return ""
68
+ }
69
+
70
+ const state: ButtonState = {
71
+ variant: props.variant ?? ui_config.default_variant,
72
+ size: props.size ?? ui_config.default_size,
73
+ disabled: composable.is_disabled.value,
74
+ loading: composable.is_loading.value
75
+ }
76
+
77
+ return style_adapter.getClasses("button", state)
78
+ })
79
+
54
80
  const handleClick = (event: MouseEvent) => {
55
81
  if (!composable.is_disabled.value && !composable.is_loading.value) {
56
82
  emit("click", event)