shadcn-glass-ui 2.1.5 → 2.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -6
- package/context7.json +2 -2
- package/dist/cli/index.cjs +1 -1
- package/dist/components.cjs +4 -4
- package/dist/components.d.ts +87 -144
- package/dist/components.js +1 -1
- package/dist/hooks.cjs +2 -2
- package/dist/index.cjs +5 -5
- package/dist/index.js +1 -1
- package/dist/r/alert-glass.json +1 -1
- package/dist/r/badge-glass.json +1 -1
- package/dist/r/button-glass.json +1 -1
- package/dist/r/card-glass.json +40 -0
- package/dist/r/input-glass.json +1 -1
- package/dist/r/modal-glass.json +5 -5
- package/dist/r/registry.json +7 -1
- package/dist/r/tooltip-glass.json +1 -1
- package/dist/shadcn-glass-ui.css +1 -1
- package/dist/{theme-context-Y98bGvcm.cjs → theme-context-BEA8K_rq.cjs} +2 -2
- package/dist/{theme-context-Y98bGvcm.cjs.map → theme-context-BEA8K_rq.cjs.map} +1 -1
- package/dist/themes.cjs +1 -1
- package/dist/{trust-score-card-glass-2rjz00d_.cjs → trust-score-card-glass-DTS1RdIt.cjs} +172 -181
- package/dist/trust-score-card-glass-DTS1RdIt.cjs.map +1 -0
- package/dist/{trust-score-card-glass-zjkx4OC2.js → trust-score-card-glass-Dg4_b_g_.js} +158 -167
- package/dist/trust-score-card-glass-Dg4_b_g_.js.map +1 -0
- package/dist/{use-focus-DbpBEuee.cjs → use-focus-CdoUzFQ8.cjs} +2 -2
- package/dist/{use-focus-DbpBEuee.cjs.map → use-focus-CdoUzFQ8.cjs.map} +1 -1
- package/dist/{use-wallpaper-tint-DbawS9zh.cjs → use-wallpaper-tint-Rq5UgY9L.cjs} +2 -2
- package/dist/{use-wallpaper-tint-DbawS9zh.cjs.map → use-wallpaper-tint-Rq5UgY9L.cjs.map} +1 -1
- package/dist/{utils-XlyXIhuP.cjs → utils-NLnOCttr.cjs} +2 -2
- package/dist/{utils-XlyXIhuP.cjs.map → utils-NLnOCttr.cjs.map} +1 -1
- package/dist/utils.cjs +1 -1
- package/docs/ADVANCED_PATTERNS.md +7 -5
- package/docs/AI_USAGE.md +0 -1
- package/docs/BEST_PRACTICES.md +0 -2
- package/docs/BREAKING_CHANGES.md +0 -1
- package/docs/COMPONENTS_CATALOG.md +1 -4
- package/docs/COMPONENT_PATTERNS.md +325 -0
- package/docs/GETTING_STARTED.md +52 -28
- package/docs/api/README.md +0 -2
- package/docs/api/variables/ModalGlass.md +5 -4
- package/package.json +1 -1
- package/dist/trust-score-card-glass-2rjz00d_.cjs.map +0 -1
- package/dist/trust-score-card-glass-zjkx4OC2.js.map +0 -1
package/README.md
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
[](https://bundlephobia.com/package/shadcn-glass-ui)
|
|
7
7
|
[](docs/AI_USAGE.md)
|
|
8
8
|
|
|
9
|
-
**Glassmorphism components for React** — drop-in compatible with shadcn/ui.
|
|
9
|
+
**Glassmorphism components for React** — drop-in compatible with shadcn/ui. 59 components, 3 themes,
|
|
10
10
|
zero migration.
|
|
11
11
|
|
|
12
12
|
<div align="center">
|
|
@@ -74,7 +74,7 @@ npx shadcn@latest add @shadcn-glass-ui/button-glass
|
|
|
74
74
|
| ----------------- | ------------------------------- | ------------ |
|
|
75
75
|
| **Themes** | 3 built-in (Glass/Light/Aurora) | 1 base |
|
|
76
76
|
| **Glass effects** | Native blur, glow, transparency | Manual CSS |
|
|
77
|
-
| **Components** |
|
|
77
|
+
| **Components** | 59 specialized | ~40 base |
|
|
78
78
|
| **Custom theme** | 15 lines CSS | Full rewrite |
|
|
79
79
|
| **AI docs** | Context7, Claude Code, Copilot | Basic |
|
|
80
80
|
|
|
@@ -94,14 +94,13 @@ import { ButtonGlass } from '@/components/glass/ui/button-glass'; // Glass vari
|
|
|
94
94
|
|
|
95
95
|
| Category | Count | Examples |
|
|
96
96
|
| --------------- | ----- | -------------------------------------------------- |
|
|
97
|
-
| **Core UI** |
|
|
97
|
+
| **Core UI** | 22 | ButtonGlass, InputGlass, ModalGlass, SidebarGlass |
|
|
98
98
|
| **Composite** | 14 | MetricCardGlass, SplitLayoutGlass, AICardGlass |
|
|
99
|
-
| **Specialized** |
|
|
99
|
+
| **Specialized** | 9 | StepperGlass, SparklineGlass, RainbowProgressGlass |
|
|
100
100
|
| **Sections** | 7 | HeaderNavGlass, ProfileHeaderGlass |
|
|
101
101
|
| **Atomic** | 7 | SearchBoxGlass, ThemeToggleGlass |
|
|
102
|
-
| **Primitives** | 3 | TouchTarget, FormFieldWrapper |
|
|
103
102
|
|
|
104
|
-
[**Browse all
|
|
103
|
+
[**Browse all 59 components →**](https://yhooi2.github.io/shadcn-glass-ui-library/)
|
|
105
104
|
|
|
106
105
|
---
|
|
107
106
|
|
package/context7.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://context7.com/schema/context7.json",
|
|
3
3
|
"projectTitle": "shadcn-glass-ui",
|
|
4
|
-
"description": "Glassmorphism UI library for React - AI-friendly with
|
|
4
|
+
"description": "Glassmorphism UI library for React - AI-friendly with 59 components, strict TypeScript, and comprehensive docs",
|
|
5
5
|
"branch": "main",
|
|
6
6
|
"folders": ["docs"],
|
|
7
7
|
"includeFiles": ["README.md", "CLAUDE.md", "CHANGELOG.md"],
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
"Always wrap components with ThemeProvider from 'shadcn-glass-ui'",
|
|
14
14
|
"Import CSS: '@import \"shadcn-glass-ui/styles.css\"' in main CSS file",
|
|
15
15
|
"Use TypeScript strict mode - no 'any' types allowed",
|
|
16
|
-
"ModalGlass and TabsGlass use compound component API (e.g., ModalGlass.Root, ModalGlass.Content)",
|
|
16
|
+
"ModalGlass and TabsGlass use compound component API (e.g., ModalGlass.Root, ModalGlass.Content) - ModalGlass.Content automatically includes Overlay, do NOT add <ModalGlass.Overlay /> separately",
|
|
17
17
|
"Three themes available: 'glass' (dark), 'light', 'aurora' (gradient)",
|
|
18
18
|
"WCAG 2.1 AA accessibility compliance required",
|
|
19
19
|
"Use asChild prop on ButtonGlass for polymorphic rendering: <ButtonGlass asChild><Link href='/'>Home</Link></ButtonGlass>",
|
package/dist/cli/index.cjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
const require_trust_score_card_glass = require("../trust-score-card-glass-
|
|
2
|
+
const require_trust_score_card_glass = require("../trust-score-card-glass-DTS1RdIt.cjs");
|
|
3
3
|
let node_util = require("node:util");
|
|
4
4
|
let node_fs = require("node:fs");
|
|
5
5
|
let node_path = require("node:path");
|
package/dist/components.cjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
const require_trust_score_card_glass = require("./trust-score-card-glass-
|
|
2
|
-
require("./utils-
|
|
3
|
-
require("./use-focus-
|
|
4
|
-
require("./theme-context-
|
|
1
|
+
const require_trust_score_card_glass = require("./trust-score-card-glass-DTS1RdIt.cjs");
|
|
2
|
+
require("./utils-NLnOCttr.cjs");
|
|
3
|
+
require("./use-focus-CdoUzFQ8.cjs");
|
|
4
|
+
require("./theme-context-BEA8K_rq.cjs");
|
|
5
5
|
exports.AICardGlass = require_trust_score_card_glass.AICardGlass;
|
|
6
6
|
exports.AlertGlass = require_trust_score_card_glass.AlertGlass;
|
|
7
7
|
exports.AvatarGlass = require_trust_score_card_glass.AvatarGlass;
|
package/dist/components.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import * as AvatarPrimitive from '@radix-ui/react-avatar';
|
|
|
2
2
|
import { ButtonHTMLAttributes } from 'react';
|
|
3
3
|
import { ClassProp } from 'class-variance-authority/types';
|
|
4
4
|
import { ComponentPropsWithoutRef } from 'react';
|
|
5
|
-
import
|
|
5
|
+
import * as DialogPrimitive from '@radix-ui/react-dialog';
|
|
6
6
|
import { FC } from 'react';
|
|
7
7
|
import { ForwardRefExoticComponent } from 'react';
|
|
8
8
|
import { HTMLAttributes } from 'react';
|
|
@@ -1128,177 +1128,112 @@ declare interface MetricTrend {
|
|
|
1128
1128
|
*/
|
|
1129
1129
|
declare type MetricVariant = 'default' | 'secondary' | 'success' | 'warning' | 'destructive';
|
|
1130
1130
|
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
declare
|
|
1137
|
-
className?: string;
|
|
1138
|
-
}
|
|
1139
|
-
|
|
1140
|
-
declare interface ModalContentProps {
|
|
1141
|
-
children: ReactNode;
|
|
1142
|
-
className?: string;
|
|
1143
|
-
}
|
|
1144
|
-
|
|
1145
|
-
declare interface ModalDescriptionProps {
|
|
1146
|
-
children: ReactNode;
|
|
1147
|
-
className?: string;
|
|
1148
|
-
}
|
|
1149
|
-
|
|
1150
|
-
declare interface ModalFooterProps {
|
|
1151
|
-
children: ReactNode;
|
|
1152
|
-
className?: string;
|
|
1153
|
-
}
|
|
1131
|
+
/**
|
|
1132
|
+
* ModalGlass.Body - Main content area
|
|
1133
|
+
*
|
|
1134
|
+
* Note: shadcn/ui Dialog doesn't have DialogBody, but we keep it for convenience.
|
|
1135
|
+
*/
|
|
1136
|
+
declare function ModalBody({ className, ...props }: React_2.ComponentProps<'div'>): JSX.Element;
|
|
1154
1137
|
|
|
1155
1138
|
/**
|
|
1156
|
-
* ModalGlass -
|
|
1139
|
+
* ModalGlass.Close - Closes the modal when clicked
|
|
1140
|
+
*
|
|
1141
|
+
* Use `asChild` to render as the child element.
|
|
1157
1142
|
*
|
|
1158
1143
|
* @example
|
|
1159
1144
|
* ```tsx
|
|
1160
|
-
* <ModalGlass.
|
|
1161
|
-
* <
|
|
1162
|
-
*
|
|
1163
|
-
* <ModalGlass.Header>
|
|
1164
|
-
* <ModalGlass.Title>Confirm</ModalGlass.Title>
|
|
1165
|
-
* <ModalGlass.Description>Are you sure?</ModalGlass.Description>
|
|
1166
|
-
* <ModalGlass.Close />
|
|
1167
|
-
* </ModalGlass.Header>
|
|
1168
|
-
* <ModalGlass.Body>
|
|
1169
|
-
* <p>Body content</p>
|
|
1170
|
-
* </ModalGlass.Body>
|
|
1171
|
-
* <ModalGlass.Footer>
|
|
1172
|
-
* <ButtonGlass>Cancel</ButtonGlass>
|
|
1173
|
-
* </ModalGlass.Footer>
|
|
1174
|
-
* </ModalGlass.Content>
|
|
1175
|
-
* </ModalGlass.Root>
|
|
1145
|
+
* <ModalGlass.Close asChild>
|
|
1146
|
+
* <ButtonGlass variant="ghost">Cancel</ButtonGlass>
|
|
1147
|
+
* </ModalGlass.Close>
|
|
1176
1148
|
* ```
|
|
1177
1149
|
*/
|
|
1178
|
-
|
|
1179
|
-
Root: default_2.FC<ModalRootProps>;
|
|
1180
|
-
Overlay: default_2.FC<ModalOverlayProps>;
|
|
1181
|
-
Content: default_2.ForwardRefExoticComponent<ModalContentProps & default_2.RefAttributes<HTMLDivElement>>;
|
|
1182
|
-
Header: default_2.FC<ModalHeaderProps>;
|
|
1183
|
-
Body: default_2.FC<ModalBodyProps>;
|
|
1184
|
-
Footer: default_2.FC<ModalFooterProps>;
|
|
1185
|
-
Title: default_2.FC<ModalTitleProps>;
|
|
1186
|
-
Description: default_2.FC<ModalDescriptionProps>;
|
|
1187
|
-
Close: default_2.FC<ModalCloseProps>;
|
|
1188
|
-
};
|
|
1150
|
+
declare function ModalClose({ ...props }: React_2.ComponentProps<typeof DialogPrimitive.Close>): JSX.Element;
|
|
1189
1151
|
|
|
1190
|
-
declare interface
|
|
1191
|
-
|
|
1192
|
-
|
|
1152
|
+
declare interface ModalContentProps extends React_2.ComponentPropsWithoutRef<typeof DialogPrimitive.Content> {
|
|
1153
|
+
/** Show close button in top-right corner */
|
|
1154
|
+
showCloseButton?: boolean;
|
|
1155
|
+
/** Override size from Root */
|
|
1156
|
+
size?: ModalSize;
|
|
1193
1157
|
}
|
|
1194
1158
|
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1159
|
+
/**
|
|
1160
|
+
* ModalGlass.Footer - Footer section with flex layout for actions
|
|
1161
|
+
*/
|
|
1162
|
+
declare function ModalFooter({ className, ...props }: React_2.ComponentProps<'div'>): JSX.Element;
|
|
1198
1163
|
|
|
1199
1164
|
/**
|
|
1200
|
-
*
|
|
1165
|
+
* ModalGlass - Glass-themed Dialog with shadcn/ui API compatibility
|
|
1201
1166
|
*
|
|
1202
|
-
*
|
|
1203
|
-
* Handles keyboard events, body scroll lock, and accessibility attributes.
|
|
1204
|
-
*
|
|
1205
|
-
* @accessibility
|
|
1206
|
-
* - **Keyboard Navigation:** Escape key closes modal, Tab key traps focus within modal content
|
|
1207
|
-
* - **Focus Management:** Focus automatically moved to modal on open, returned to trigger on close (WCAG 2.4.3)
|
|
1208
|
-
* - **Screen Readers:** Uses `role="dialog"` and `aria-modal="true"` for proper modal semantics (WCAG 4.1.3)
|
|
1209
|
-
* - **Title Association:** Modal title automatically linked via `aria-labelledby="modal-title"`
|
|
1210
|
-
* - **Description Association:** Optional description linked via `aria-describedby="modal-description"`
|
|
1211
|
-
* - **Body Scroll Lock:** Prevents background scrolling when modal is open (improves UX and focus management)
|
|
1212
|
-
* - **Touch Targets:** All interactive elements (close button, action buttons) meet 44x44px minimum (WCAG 2.5.5)
|
|
1213
|
-
* - **Color Contrast:** Modal content and overlay meet WCAG AA contrast requirements
|
|
1214
|
-
* - **Motion:** Open/close animations respect `prefers-reduced-motion` settings
|
|
1167
|
+
* Built on @radix-ui/react-dialog for full accessibility support.
|
|
1215
1168
|
*
|
|
1216
|
-
* @example
|
|
1169
|
+
* @example Uncontrolled (with Trigger)
|
|
1217
1170
|
* ```tsx
|
|
1218
|
-
*
|
|
1219
|
-
*
|
|
1220
|
-
*
|
|
1171
|
+
* <ModalGlass.Root>
|
|
1172
|
+
* <ModalGlass.Trigger asChild>
|
|
1173
|
+
* <ButtonGlass>Open</ButtonGlass>
|
|
1174
|
+
* </ModalGlass.Trigger>
|
|
1221
1175
|
* <ModalGlass.Content>
|
|
1222
1176
|
* <ModalGlass.Header>
|
|
1223
|
-
* <ModalGlass.Title>
|
|
1224
|
-
* <ModalGlass.Description>
|
|
1225
|
-
* This action cannot be undone.
|
|
1226
|
-
* </ModalGlass.Description>
|
|
1227
|
-
* <ModalGlass.Close />
|
|
1177
|
+
* <ModalGlass.Title>Title</ModalGlass.Title>
|
|
1228
1178
|
* </ModalGlass.Header>
|
|
1229
|
-
* <ModalGlass.Body>
|
|
1230
|
-
* <p>Are you sure you want to proceed?</p>
|
|
1231
|
-
* </ModalGlass.Body>
|
|
1179
|
+
* <ModalGlass.Body>Content</ModalGlass.Body>
|
|
1232
1180
|
* <ModalGlass.Footer>
|
|
1233
|
-
* <
|
|
1234
|
-
*
|
|
1235
|
-
* </
|
|
1236
|
-
* <ButtonGlass variant="destructive" onClick={handleConfirm}>
|
|
1237
|
-
* Confirm
|
|
1238
|
-
* </ButtonGlass>
|
|
1181
|
+
* <ModalGlass.Close asChild>
|
|
1182
|
+
* <ButtonGlass>Close</ButtonGlass>
|
|
1183
|
+
* </ModalGlass.Close>
|
|
1239
1184
|
* </ModalGlass.Footer>
|
|
1240
1185
|
* </ModalGlass.Content>
|
|
1241
1186
|
* </ModalGlass.Root>
|
|
1187
|
+
* ```
|
|
1242
1188
|
*
|
|
1243
|
-
*
|
|
1244
|
-
*
|
|
1245
|
-
* {// Small modal content}
|
|
1246
|
-
* </ModalGlass.Root>
|
|
1247
|
-
* <ModalGlass.Root open={open} onOpenChange={setOpen} size="lg">
|
|
1248
|
-
* {// Large modal content}
|
|
1249
|
-
* </ModalGlass.Root>
|
|
1250
|
-
*
|
|
1251
|
-
* // Form modal with proper focus management
|
|
1189
|
+
* @example Controlled
|
|
1190
|
+
* ```tsx
|
|
1252
1191
|
* <ModalGlass.Root open={open} onOpenChange={setOpen}>
|
|
1253
|
-
* <ModalGlass.
|
|
1254
|
-
* <ModalGlass.Content>
|
|
1192
|
+
* <ModalGlass.Content showCloseButton={false}>
|
|
1255
1193
|
* <ModalGlass.Header>
|
|
1256
|
-
* <ModalGlass.Title>
|
|
1257
|
-
* <ModalGlass.Close />
|
|
1258
|
-
* </ModalGlass.Header>
|
|
1259
|
-
* <ModalGlass.Body>
|
|
1260
|
-
* <form id="signup-form" onSubmit={handleSubmit}>
|
|
1261
|
-
* <InputGlass label="Email" type="email" required />
|
|
1262
|
-
* <InputGlass label="Password" type="password" required />
|
|
1263
|
-
* </form>
|
|
1264
|
-
* </ModalGlass.Body>
|
|
1265
|
-
* <ModalGlass.Footer>
|
|
1266
|
-
* <ButtonGlass variant="ghost" onClick={() => setOpen(false)}>
|
|
1267
|
-
* Cancel
|
|
1268
|
-
* </ButtonGlass>
|
|
1269
|
-
* <ButtonGlass type="submit" form="signup-form">
|
|
1270
|
-
* Sign Up
|
|
1271
|
-
* </ButtonGlass>
|
|
1272
|
-
* </ModalGlass.Footer>
|
|
1273
|
-
* </ModalGlass.Content>
|
|
1274
|
-
* </ModalGlass.Root>
|
|
1275
|
-
*
|
|
1276
|
-
* // Alert modal (no close button)
|
|
1277
|
-
* <ModalGlass.Root open={showAlert} onOpenChange={setShowAlert}>
|
|
1278
|
-
* <ModalGlass.Overlay />
|
|
1279
|
-
* <ModalGlass.Content>
|
|
1280
|
-
* <ModalGlass.Header>
|
|
1281
|
-
* <ModalGlass.Title>Session Expired</ModalGlass.Title>
|
|
1194
|
+
* <ModalGlass.Title>Confirm</ModalGlass.Title>
|
|
1282
1195
|
* </ModalGlass.Header>
|
|
1283
|
-
* <ModalGlass.Body>
|
|
1284
|
-
* Your session has expired. Please log in again.
|
|
1285
|
-
* </ModalGlass.Body>
|
|
1286
1196
|
* <ModalGlass.Footer>
|
|
1287
|
-
* <ButtonGlass onClick={
|
|
1197
|
+
* <ButtonGlass onClick={() => setOpen(false)}>OK</ButtonGlass>
|
|
1288
1198
|
* </ModalGlass.Footer>
|
|
1289
1199
|
* </ModalGlass.Content>
|
|
1290
1200
|
* </ModalGlass.Root>
|
|
1291
1201
|
* ```
|
|
1292
1202
|
*/
|
|
1293
|
-
declare
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1203
|
+
export declare const ModalGlass: {
|
|
1204
|
+
Root: typeof ModalRoot;
|
|
1205
|
+
Trigger: typeof ModalTrigger;
|
|
1206
|
+
Portal: typeof ModalPortal;
|
|
1207
|
+
Overlay: React_2.ForwardRefExoticComponent<Omit<DialogPrimitive.DialogOverlayProps & React_2.RefAttributes<HTMLDivElement>, "ref"> & React_2.RefAttributes<HTMLDivElement>>;
|
|
1208
|
+
Content: React_2.ForwardRefExoticComponent<ModalContentProps & React_2.RefAttributes<HTMLDivElement>>;
|
|
1209
|
+
Header: typeof ModalHeader;
|
|
1210
|
+
Body: typeof ModalBody;
|
|
1211
|
+
Footer: typeof ModalFooter;
|
|
1212
|
+
Title: React_2.ForwardRefExoticComponent<Omit<DialogPrimitive.DialogTitleProps & React_2.RefAttributes<HTMLHeadingElement>, "ref"> & React_2.RefAttributes<HTMLHeadingElement>>;
|
|
1213
|
+
Description: React_2.ForwardRefExoticComponent<Omit<DialogPrimitive.DialogDescriptionProps & React_2.RefAttributes<HTMLParagraphElement>, "ref"> & React_2.RefAttributes<HTMLParagraphElement>>;
|
|
1214
|
+
Close: typeof ModalClose;
|
|
1215
|
+
};
|
|
1216
|
+
|
|
1217
|
+
/**
|
|
1218
|
+
* ModalGlass.Header - Header section with flex layout
|
|
1219
|
+
*/
|
|
1220
|
+
declare function ModalHeader({ className, ...props }: React_2.ComponentProps<'div'>): JSX.Element;
|
|
1221
|
+
|
|
1222
|
+
/**
|
|
1223
|
+
* ModalGlass.Portal - Renders children into a portal
|
|
1224
|
+
*/
|
|
1225
|
+
declare function ModalPortal({ ...props }: React_2.ComponentProps<typeof DialogPrimitive.Portal>): JSX.Element;
|
|
1226
|
+
|
|
1227
|
+
/**
|
|
1228
|
+
* ModalGlass.Root - Dialog root component
|
|
1229
|
+
*
|
|
1230
|
+
* Supports both controlled (open/onOpenChange) and uncontrolled (with Trigger) modes.
|
|
1231
|
+
*/
|
|
1232
|
+
declare function ModalRoot({ size, children, ...props }: ModalRootProps): JSX.Element;
|
|
1233
|
+
|
|
1234
|
+
declare interface ModalRootProps extends React_2.ComponentProps<typeof DialogPrimitive.Root> {
|
|
1235
|
+
/** Size variant for the modal */
|
|
1299
1236
|
size?: ModalSize;
|
|
1300
|
-
/** Child components */
|
|
1301
|
-
children: ReactNode;
|
|
1302
1237
|
}
|
|
1303
1238
|
|
|
1304
1239
|
/**
|
|
@@ -1307,10 +1242,12 @@ declare interface ModalRootProps extends default_2.HTMLAttributes<HTMLDivElement
|
|
|
1307
1242
|
*/
|
|
1308
1243
|
declare type ModalSize = 'sm' | 'md' | 'lg' | 'xl' | 'full';
|
|
1309
1244
|
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1245
|
+
/**
|
|
1246
|
+
* ModalGlass.Trigger - Opens the modal when clicked
|
|
1247
|
+
*
|
|
1248
|
+
* Use `asChild` to render as the child element instead of a button.
|
|
1249
|
+
*/
|
|
1250
|
+
declare function ModalTrigger({ ...props }: React_2.ComponentProps<typeof DialogPrimitive.Trigger>): JSX.Element;
|
|
1314
1251
|
|
|
1315
1252
|
export declare const NotificationGlass: ForwardRefExoticComponent<NotificationGlassProps & RefAttributes<HTMLDivElement>>;
|
|
1316
1253
|
|
|
@@ -1820,7 +1757,13 @@ declare const toggleSizes: (props?: ({
|
|
|
1820
1757
|
variant?: "default" | "outline" | null | undefined;
|
|
1821
1758
|
} & ClassProp) | undefined) => string;
|
|
1822
1759
|
|
|
1823
|
-
export declare const TooltipGlass:
|
|
1760
|
+
export declare const TooltipGlass: typeof TooltipGlassRoot;
|
|
1761
|
+
|
|
1762
|
+
/**
|
|
1763
|
+
* TooltipGlassRoot - Individual tooltip instance
|
|
1764
|
+
* Wraps Radix TooltipPrimitive.Root with auto-included Provider (shadcn/ui pattern)
|
|
1765
|
+
*/
|
|
1766
|
+
declare function TooltipGlassRoot({ ...props }: React_2.ComponentPropsWithoutRef<typeof TooltipPrimitive.Root>): JSX.Element;
|
|
1824
1767
|
|
|
1825
1768
|
/**
|
|
1826
1769
|
* TouchTarget wrapper component
|
package/dist/components.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { $ as BaseProgressGlass, Dt as NotificationGlass, G as SegmentedControlGlass, K as RainbowProgressGlass, Mt as GlassCard, Pt as DropdownGlass, Q as StatusIndicatorGlass, St as PopoverGlass, X as LanguageBarGlass, Xt as ComboBoxGlass, Y as ProfileAvatarGlass, Z as FlagAlertGlass, _ as ContributionMetricsGlass, _t as SliderGlass, a as HeaderBrandingGlass, an as ButtonGlass, b as AICardGlass, bn as TouchTarget, bt as SkeletonGlass, c as YearCardGlass, ct as ExpandableHeaderGlass, d as TrustScoreDisplayGlass, et as ThemeToggleGlass, f as RepositoryMetadataGlass, g as MetricCardGlass, gt as TabsGlass, h as MetricsGridGlass, hn as AlertGlass, i as HeaderNavGlass, in as CheckboxGlass, jt as InputGlass, kt as ModalGlass, l as UserStatsLineGlass, ln as AvatarGlass, lt as TooltipGlass, m as RepositoryCardGlass, mt as ToggleGlass, n as ProjectsListGlass, nt as SortDropdownGlass, o as FlagsSectionGlass, p as RepositoryHeaderGlass, q as ProgressGlass, r as ProfileHeaderGlass, rn as CircularProgressGlass, rt as SearchBoxGlass, s as CareerStatsGlass, sn as BadgeGlass, st as IconButtonGlass, t as TrustScoreCardGlass, tt as StatItemGlass, u as UserInfoGlass, v as CircularMetricGlass, vn as InteractiveCard, y as CareerStatsHeaderGlass, yn as FormFieldWrapper } from "./trust-score-card-glass-
|
|
1
|
+
import { $ as BaseProgressGlass, Dt as NotificationGlass, G as SegmentedControlGlass, K as RainbowProgressGlass, Mt as GlassCard, Pt as DropdownGlass, Q as StatusIndicatorGlass, St as PopoverGlass, X as LanguageBarGlass, Xt as ComboBoxGlass, Y as ProfileAvatarGlass, Z as FlagAlertGlass, _ as ContributionMetricsGlass, _t as SliderGlass, a as HeaderBrandingGlass, an as ButtonGlass, b as AICardGlass, bn as TouchTarget, bt as SkeletonGlass, c as YearCardGlass, ct as ExpandableHeaderGlass, d as TrustScoreDisplayGlass, et as ThemeToggleGlass, f as RepositoryMetadataGlass, g as MetricCardGlass, gt as TabsGlass, h as MetricsGridGlass, hn as AlertGlass, i as HeaderNavGlass, in as CheckboxGlass, jt as InputGlass, kt as ModalGlass, l as UserStatsLineGlass, ln as AvatarGlass, lt as TooltipGlass, m as RepositoryCardGlass, mt as ToggleGlass, n as ProjectsListGlass, nt as SortDropdownGlass, o as FlagsSectionGlass, p as RepositoryHeaderGlass, q as ProgressGlass, r as ProfileHeaderGlass, rn as CircularProgressGlass, rt as SearchBoxGlass, s as CareerStatsGlass, sn as BadgeGlass, st as IconButtonGlass, t as TrustScoreCardGlass, tt as StatItemGlass, u as UserInfoGlass, v as CircularMetricGlass, vn as InteractiveCard, y as CareerStatsHeaderGlass, yn as FormFieldWrapper } from "./trust-score-card-glass-Dg4_b_g_.js";
|
|
2
2
|
import "./utils-CcyeqpKQ.js";
|
|
3
3
|
import "./use-focus-CX0TJJIj.js";
|
|
4
4
|
import "./theme-context-_T5r1KG4.js";
|
package/dist/hooks.cjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
const require_use_focus = require("./use-focus-
|
|
2
|
-
const require_use_wallpaper_tint = require("./use-wallpaper-tint-
|
|
1
|
+
const require_use_focus = require("./use-focus-CdoUzFQ8.cjs");
|
|
2
|
+
const require_use_wallpaper_tint = require("./use-wallpaper-tint-Rq5UgY9L.cjs");
|
|
3
3
|
exports.useFocus = require_use_focus.useFocus;
|
|
4
4
|
exports.useHover = require_use_focus.useHover;
|
|
5
5
|
exports.useResponsive = require_use_wallpaper_tint.useResponsive;
|
package/dist/index.cjs
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
const require_trust_score_card_glass = require("./trust-score-card-glass-
|
|
2
|
-
const require_utils = require("./utils-
|
|
3
|
-
const require_use_focus = require("./use-focus-
|
|
4
|
-
const require_theme_context = require("./theme-context-
|
|
5
|
-
const require_use_wallpaper_tint = require("./use-wallpaper-tint-
|
|
1
|
+
const require_trust_score_card_glass = require("./trust-score-card-glass-DTS1RdIt.cjs");
|
|
2
|
+
const require_utils = require("./utils-NLnOCttr.cjs");
|
|
3
|
+
const require_use_focus = require("./use-focus-CdoUzFQ8.cjs");
|
|
4
|
+
const require_theme_context = require("./theme-context-BEA8K_rq.cjs");
|
|
5
|
+
const require_use_wallpaper_tint = require("./use-wallpaper-tint-Rq5UgY9L.cjs");
|
|
6
6
|
let react = require("react");
|
|
7
7
|
react = require_trust_score_card_glass.__toESM(react);
|
|
8
8
|
let lucide_react = require("lucide-react");
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { $ as BaseProgressGlass, $t as useLayoutEffect2, A as useChartHeight, At as modalSizes, B as adaptEventsOfChild, Bt as DropdownMenuGlassLabel, C as sparklineContainerVariants, Ct as PopoverGlassAnchor, D as Tooltip, Dt as NotificationGlass, E as Cell, Et as PopoverGlassTrigger, F as selectLegendPayload, Ft as DropdownMenuGlass, G as SegmentedControlGlass, Gt as DropdownMenuGlassShortcut, H as isNumber, Ht as DropdownMenuGlassRadioGroup, I as useAppDispatch, It as DropdownMenuGlassCheckboxItem, J as progressSizes, Jt as DropdownMenuGlassSubTrigger, K as RainbowProgressGlass, Kt as DropdownMenuGlassSub, L as useAppSelector, Lt as DropdownMenuGlassContent, M as useMargin, Mt as GlassCard, N as ResponsiveContainer, Nt as cardIntensity, O as setLegendSettings, Ot as notificationVariants, P as useElementOffset, Pt as DropdownGlass, Q as StatusIndicatorGlass, Qt as Presence, R as getUniqPayload, Rt as DropdownMenuGlassGroup, S as sparklineBarVariants, St as PopoverGlass, T as Bar, Tt as PopoverGlassLegacy, U as useLegendPortal, Ut as DropdownMenuGlassRadioItem, V as Symbols, Vt as DropdownMenuGlassPortal, W as Surface, Wt as DropdownMenuGlassSeparator, X as LanguageBarGlass, Xt as ComboBoxGlass, Y as ProfileAvatarGlass, Yt as DropdownMenuGlassTrigger, Z as FlagAlertGlass, Zt as inputVariants, _ as ContributionMetricsGlass, _n as AlertGlassTitle, _t as SliderGlass, a as HeaderBrandingGlass, an as ButtonGlass, at as insightCardVariants, b as AICardGlass, bn as TouchTarget, bt as SkeletonGlass, c as YearCardGlass, cn as badgeVariants, ct as ExpandableHeaderGlass, d as TrustScoreDisplayGlass, dn as AvatarGlassImage, dt as TooltipGlassProvider, en as useCallbackRef, et as ThemeToggleGlass, f as RepositoryMetadataGlass, fn as AvatarGlassSimple, ft as TooltipGlassSimple, g as MetricCardGlass, gn as AlertGlassDescription, gt as TabsGlass, h as MetricsGridGlass, hn as AlertGlass, ht as toggleSizes, i as HeaderNavGlass, in as CheckboxGlass, it as InsightCardGlass, j as useChartWidth, jt as InputGlass, k as setLegendSize, kt as ModalGlass, l as UserStatsLineGlass, ln as AvatarGlass, lt as TooltipGlass, m as RepositoryCardGlass, mn as statusSizes, mt as ToggleGlass, n as ProjectsListGlass, nn as composeEventHandlers, nt as SortDropdownGlass, o as FlagsSectionGlass, on as buttonGlassVariants, ot as insightVariantConfig, p as RepositoryHeaderGlass, pn as avatarSizes, pt as TooltipGlassTrigger, q as ProgressGlass, qt as DropdownMenuGlassSubContent, r as ProfileHeaderGlass, rn as CircularProgressGlass, rt as SearchBoxGlass, s as CareerStatsGlass, sn as BadgeGlass, st as IconButtonGlass, t as TrustScoreCardGlass, tn as useComposedRefs, tt as StatItemGlass, u as UserInfoGlass, un as AvatarGlassFallback, ut as TooltipGlassContent, v as CircularMetricGlass, vn as InteractiveCard, vt as useDirection, w as BarChart, wt as PopoverGlassContent, x as SparklineGlass, xn as alertVariants, xt as skeletonVariants, y as CareerStatsHeaderGlass, yn as FormFieldWrapper, yt as clamp, z as resolveDefaultProps, zt as DropdownMenuGlassItem } from "./trust-score-card-glass-
|
|
1
|
+
import { $ as BaseProgressGlass, $t as useLayoutEffect2, A as useChartHeight, At as modalSizes, B as adaptEventsOfChild, Bt as DropdownMenuGlassLabel, C as sparklineContainerVariants, Ct as PopoverGlassAnchor, D as Tooltip, Dt as NotificationGlass, E as Cell, Et as PopoverGlassTrigger, F as selectLegendPayload, Ft as DropdownMenuGlass, G as SegmentedControlGlass, Gt as DropdownMenuGlassShortcut, H as isNumber, Ht as DropdownMenuGlassRadioGroup, I as useAppDispatch, It as DropdownMenuGlassCheckboxItem, J as progressSizes, Jt as DropdownMenuGlassSubTrigger, K as RainbowProgressGlass, Kt as DropdownMenuGlassSub, L as useAppSelector, Lt as DropdownMenuGlassContent, M as useMargin, Mt as GlassCard, N as ResponsiveContainer, Nt as cardIntensity, O as setLegendSettings, Ot as notificationVariants, P as useElementOffset, Pt as DropdownGlass, Q as StatusIndicatorGlass, Qt as Presence, R as getUniqPayload, Rt as DropdownMenuGlassGroup, S as sparklineBarVariants, St as PopoverGlass, T as Bar, Tt as PopoverGlassLegacy, U as useLegendPortal, Ut as DropdownMenuGlassRadioItem, V as Symbols, Vt as DropdownMenuGlassPortal, W as Surface, Wt as DropdownMenuGlassSeparator, X as LanguageBarGlass, Xt as ComboBoxGlass, Y as ProfileAvatarGlass, Yt as DropdownMenuGlassTrigger, Z as FlagAlertGlass, Zt as inputVariants, _ as ContributionMetricsGlass, _n as AlertGlassTitle, _t as SliderGlass, a as HeaderBrandingGlass, an as ButtonGlass, at as insightCardVariants, b as AICardGlass, bn as TouchTarget, bt as SkeletonGlass, c as YearCardGlass, cn as badgeVariants, ct as ExpandableHeaderGlass, d as TrustScoreDisplayGlass, dn as AvatarGlassImage, dt as TooltipGlassProvider, en as useCallbackRef, et as ThemeToggleGlass, f as RepositoryMetadataGlass, fn as AvatarGlassSimple, ft as TooltipGlassSimple, g as MetricCardGlass, gn as AlertGlassDescription, gt as TabsGlass, h as MetricsGridGlass, hn as AlertGlass, ht as toggleSizes, i as HeaderNavGlass, in as CheckboxGlass, it as InsightCardGlass, j as useChartWidth, jt as InputGlass, k as setLegendSize, kt as ModalGlass, l as UserStatsLineGlass, ln as AvatarGlass, lt as TooltipGlass, m as RepositoryCardGlass, mn as statusSizes, mt as ToggleGlass, n as ProjectsListGlass, nn as composeEventHandlers, nt as SortDropdownGlass, o as FlagsSectionGlass, on as buttonGlassVariants, ot as insightVariantConfig, p as RepositoryHeaderGlass, pn as avatarSizes, pt as TooltipGlassTrigger, q as ProgressGlass, qt as DropdownMenuGlassSubContent, r as ProfileHeaderGlass, rn as CircularProgressGlass, rt as SearchBoxGlass, s as CareerStatsGlass, sn as BadgeGlass, st as IconButtonGlass, t as TrustScoreCardGlass, tn as useComposedRefs, tt as StatItemGlass, u as UserInfoGlass, un as AvatarGlassFallback, ut as TooltipGlassContent, v as CircularMetricGlass, vn as InteractiveCard, vt as useDirection, w as BarChart, wt as PopoverGlassContent, x as SparklineGlass, xn as alertVariants, xt as skeletonVariants, y as CareerStatsHeaderGlass, yn as FormFieldWrapper, yt as clamp, z as resolveDefaultProps, zt as DropdownMenuGlassItem } from "./trust-score-card-glass-Dg4_b_g_.js";
|
|
2
2
|
import { t as cn } from "./utils-CcyeqpKQ.js";
|
|
3
3
|
import { n as useHover, t as useFocus } from "./use-focus-CX0TJJIj.js";
|
|
4
4
|
import { a as getThemeConfig, i as getNextTheme, n as THEME_CONFIG, o as useTheme, r as ThemeProvider, t as THEMES } from "./theme-context-_T5r1KG4.js";
|
package/dist/r/alert-glass.json
CHANGED
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
{
|
|
19
19
|
"path": "components/glass/ui/alert-glass.tsx",
|
|
20
20
|
"type": "registry:component",
|
|
21
|
-
"content": "/**\n * AlertGlass Component\n *\n * Glass-themed alert with:\n * - Theme-aware styling via CSS variables (glass/light/aurora)\n * - shadcn/ui compatible variants (default, destructive)\n * - Extended Glass UI variants (success, warning)\n * - Compound component API for flexible composition\n * - Dismissible option\n * - Backdrop blur effect\n *\n * @example Compound API (recommended)\n * ```tsx\n * <AlertGlass variant=\"default\">\n * <AlertGlassTitle>Heads up!</AlertGlassTitle>\n * <AlertGlassDescription>\n * You can add components to your app using the cli.\n * </AlertGlassDescription>\n * </AlertGlass>\n * ```\n *\n * @example With dismiss button\n * ```tsx\n * <AlertGlass variant=\"destructive\" dismissible onDismiss={() => setShow(false)}>\n * <AlertGlassTitle>Error</AlertGlassTitle>\n * <AlertGlassDescription>\n * Your session has expired.\n * </AlertGlassDescription>\n * </AlertGlass>\n * ```\n */\n\n'use client';\n\nimport { forwardRef, type CSSProperties } from 'react';\nimport { type VariantProps } from 'class-variance-authority';\nimport { Info, CheckCircle, AlertTriangle, AlertCircle, X } from 'lucide-react';\nimport { cn } from '@/lib/utils';\nimport { alertVariants } from '@/lib/variants/alert-glass-variants';\nimport { ICON_SIZES } from '@/components/glass/primitives';\nimport '@/glass-theme.css';\n\nimport type { AlertVariant } from '@/lib/variants/alert-glass-variants';\n\n// ========================================\n// ICON MAP\n// ========================================\n\nconst iconMap: Record<AlertVariant, typeof Info> = {\n default: Info,\n destructive: AlertCircle,\n success: CheckCircle,\n warning: AlertTriangle,\n // Aliases\n info: Info,\n error: AlertCircle,\n};\n\n// ========================================\n// CSS VARIABLE HELPERS\n// ========================================\n\ntype AlertStyleVars = { bg: string; border: string; text: string };\n\nconst variantStyles: Record<AlertVariant, AlertStyleVars> = {\n // shadcn/ui compatible variants\n default: {\n bg: 'var(--alert-default-bg)',\n border: 'var(--alert-default-border)',\n text: 'var(--alert-default-text)',\n },\n destructive: {\n bg: 'var(--alert-destructive-bg)',\n border: 'var(--alert-destructive-border)',\n text: 'var(--alert-destructive-text)',\n },\n // Glass UI extended variants\n success: {\n bg: 'var(--alert-success-bg)',\n border: 'var(--alert-success-border)',\n text: 'var(--alert-success-text)',\n },\n warning: {\n bg: 'var(--alert-warning-bg)',\n border: 'var(--alert-warning-border)',\n text: 'var(--alert-warning-text)',\n },\n // Backward compatibility aliases\n info: {\n bg: 'var(--alert-default-bg)',\n border: 'var(--alert-default-border)',\n text: 'var(--alert-default-text)',\n },\n error: {\n bg: 'var(--alert-destructive-bg)',\n border: 'var(--alert-destructive-border)',\n text: 'var(--alert-destructive-text)',\n },\n};\n\nconst getAlertStyles = (variant: AlertVariant): CSSProperties => {\n const config = variantStyles[variant];\n return {\n background: config.bg,\n border: `1px solid ${config.border}`,\n color: config.text,\n };\n};\n\n// ========================================\n// COMPOUND COMPONENT: ROOT\n// ========================================\n\nexport interface AlertGlassProps\n extends Omit<React.HTMLAttributes<HTMLDivElement>, 'style'>, VariantProps<typeof alertVariants> {\n dismissible?: boolean;\n onDismiss?: () => void;\n}\n\nconst AlertGlassRoot = forwardRef<HTMLDivElement, AlertGlassProps>(\n ({ className, variant = 'default', dismissible, onDismiss, children, ...props }, ref) => {\n const effectiveVariant: AlertVariant = variant ?? 'default';\n const Icon = iconMap[effectiveVariant];\n const config = variantStyles[effectiveVariant];\n\n return (\n <div\n ref={ref}\n className={cn(alertVariants({ variant: effectiveVariant }), className)}\n style={getAlertStyles(effectiveVariant)}\n role=\"alert\"\n {...props}\n >\n <Icon\n className=\"w-4 h-4 md:w-5 md:h-5 shrink-0 mt-0.5\"\n style={{ color: config.text }}\n aria-hidden=\"true\"\n />\n <div className=\"flex-1\">{children}</div>\n {dismissible && (\n <button\n onClick={onDismiss}\n className=\"p-0.5 md:p-1 rounded transition-colors duration-200 hover:bg-black/5 shrink-0\"\n aria-label=\"Dismiss alert\"\n >\n <X className={ICON_SIZES.md} style={{ color: config.text }} />\n </button>\n )}\n </div>\n );\n }\n);\n\nAlertGlassRoot.displayName = 'AlertGlass';\n\n// ========================================\n// COMPOUND COMPONENT: TITLE\n// ========================================\n\nexport type AlertGlassTitleProps = React.HTMLAttributes<
|
|
21
|
+
"content": "/**\n * AlertGlass Component\n *\n * Glass-themed alert with:\n * - Theme-aware styling via CSS variables (glass/light/aurora)\n * - shadcn/ui compatible variants (default, destructive)\n * - Extended Glass UI variants (success, warning)\n * - Compound component API for flexible composition\n * - Dismissible option\n * - Backdrop blur effect\n *\n * @example Compound API (recommended)\n * ```tsx\n * <AlertGlass variant=\"default\">\n * <AlertGlassTitle>Heads up!</AlertGlassTitle>\n * <AlertGlassDescription>\n * You can add components to your app using the cli.\n * </AlertGlassDescription>\n * </AlertGlass>\n * ```\n *\n * @example With dismiss button\n * ```tsx\n * <AlertGlass variant=\"destructive\" dismissible onDismiss={() => setShow(false)}>\n * <AlertGlassTitle>Error</AlertGlassTitle>\n * <AlertGlassDescription>\n * Your session has expired.\n * </AlertGlassDescription>\n * </AlertGlass>\n * ```\n */\n\n'use client';\n\nimport { forwardRef, type CSSProperties } from 'react';\nimport { type VariantProps } from 'class-variance-authority';\nimport { Info, CheckCircle, AlertTriangle, AlertCircle, X } from 'lucide-react';\nimport { cn } from '@/lib/utils';\nimport { alertVariants } from '@/lib/variants/alert-glass-variants';\nimport { ICON_SIZES } from '@/components/glass/primitives';\nimport '@/glass-theme.css';\n\nimport type { AlertVariant } from '@/lib/variants/alert-glass-variants';\n\n// ========================================\n// ICON MAP\n// ========================================\n\nconst iconMap: Record<AlertVariant, typeof Info> = {\n default: Info,\n destructive: AlertCircle,\n success: CheckCircle,\n warning: AlertTriangle,\n // Aliases\n info: Info,\n error: AlertCircle,\n};\n\n// ========================================\n// CSS VARIABLE HELPERS\n// ========================================\n\ntype AlertStyleVars = { bg: string; border: string; text: string };\n\nconst variantStyles: Record<AlertVariant, AlertStyleVars> = {\n // shadcn/ui compatible variants\n default: {\n bg: 'var(--alert-default-bg)',\n border: 'var(--alert-default-border)',\n text: 'var(--alert-default-text)',\n },\n destructive: {\n bg: 'var(--alert-destructive-bg)',\n border: 'var(--alert-destructive-border)',\n text: 'var(--alert-destructive-text)',\n },\n // Glass UI extended variants\n success: {\n bg: 'var(--alert-success-bg)',\n border: 'var(--alert-success-border)',\n text: 'var(--alert-success-text)',\n },\n warning: {\n bg: 'var(--alert-warning-bg)',\n border: 'var(--alert-warning-border)',\n text: 'var(--alert-warning-text)',\n },\n // Backward compatibility aliases\n info: {\n bg: 'var(--alert-default-bg)',\n border: 'var(--alert-default-border)',\n text: 'var(--alert-default-text)',\n },\n error: {\n bg: 'var(--alert-destructive-bg)',\n border: 'var(--alert-destructive-border)',\n text: 'var(--alert-destructive-text)',\n },\n};\n\nconst getAlertStyles = (variant: AlertVariant): CSSProperties => {\n const config = variantStyles[variant];\n return {\n background: config.bg,\n border: `1px solid ${config.border}`,\n color: config.text,\n };\n};\n\n// ========================================\n// COMPOUND COMPONENT: ROOT\n// ========================================\n\nexport interface AlertGlassProps\n extends Omit<React.HTMLAttributes<HTMLDivElement>, 'style'>, VariantProps<typeof alertVariants> {\n dismissible?: boolean;\n onDismiss?: () => void;\n}\n\nconst AlertGlassRoot = forwardRef<HTMLDivElement, AlertGlassProps>(\n ({ className, variant = 'default', dismissible, onDismiss, children, ...props }, ref) => {\n const effectiveVariant: AlertVariant = variant ?? 'default';\n const Icon = iconMap[effectiveVariant];\n const config = variantStyles[effectiveVariant];\n\n return (\n <div\n ref={ref}\n data-slot=\"alert\"\n className={cn(alertVariants({ variant: effectiveVariant }), className)}\n style={getAlertStyles(effectiveVariant)}\n role=\"alert\"\n {...props}\n >\n <Icon\n className=\"w-4 h-4 md:w-5 md:h-5 shrink-0 mt-0.5\"\n style={{ color: config.text }}\n aria-hidden=\"true\"\n />\n <div className=\"flex-1\">{children}</div>\n {dismissible && (\n <button\n onClick={onDismiss}\n className=\"p-0.5 md:p-1 rounded transition-colors duration-200 hover:bg-black/5 shrink-0\"\n aria-label=\"Dismiss alert\"\n >\n <X className={ICON_SIZES.md} style={{ color: config.text }} />\n </button>\n )}\n </div>\n );\n }\n);\n\nAlertGlassRoot.displayName = 'AlertGlass';\n\n// ========================================\n// COMPOUND COMPONENT: TITLE\n// ========================================\n\nexport type AlertGlassTitleProps = React.HTMLAttributes<HTMLDivElement>;\n\nconst AlertGlassTitle = forwardRef<HTMLDivElement, AlertGlassTitleProps>(\n ({ className, style, ...props }, ref) => {\n return (\n <div\n ref={ref}\n data-slot=\"alert-title\"\n className={cn('font-medium text-xs md:text-sm mb-0.5 md:mb-1', className)}\n style={{ color: 'inherit', ...style }}\n {...props}\n />\n );\n }\n);\n\nAlertGlassTitle.displayName = 'AlertGlassTitle';\n\n// ========================================\n// COMPOUND COMPONENT: DESCRIPTION\n// ========================================\n\nexport type AlertGlassDescriptionProps = React.HTMLAttributes<HTMLDivElement>;\n\nconst AlertGlassDescription = forwardRef<HTMLDivElement, AlertGlassDescriptionProps>(\n ({ className, style, ...props }, ref) => {\n return (\n <div\n ref={ref}\n data-slot=\"alert-description\"\n className={cn('text-xs md:text-sm opacity-80', className)}\n style={{ color: 'inherit', ...style }}\n {...props}\n />\n );\n }\n);\n\nAlertGlassDescription.displayName = 'AlertGlassDescription';\n\n// ========================================\n// EXPORTS\n// ========================================\n\n// Compound API (shadcn/ui pattern)\nexport const AlertGlass = AlertGlassRoot;\nexport { AlertGlassTitle, AlertGlassDescription };\n"
|
|
22
22
|
}
|
|
23
23
|
],
|
|
24
24
|
"categories": [
|
package/dist/r/badge-glass.json
CHANGED
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
{
|
|
17
17
|
"path": "components/glass/ui/badge-glass.tsx",
|
|
18
18
|
"type": "registry:component",
|
|
19
|
-
"content": "/**\n * BadgeGlass Component\n *\n * Glass-themed badge with:\n * - Theme-aware styling via CSS variables (glass/light/aurora)\n * - shadcn/ui compatible variants (default, secondary, destructive, outline)\n * - Extended Glass UI variants (success, warning, info)\n * - Size options\n * - Optional animated dot\n */\n\nimport { forwardRef, type ReactNode, type CSSProperties } from 'react';\nimport { type VariantProps } from 'class-variance-authority';\nimport { cn } from '@/lib/utils';\nimport { badgeVariants, type BadgeVariant } from '@/lib/variants/badge-glass-variants';\nimport '@/glass-theme.css';\n\n// ========================================\n// CSS VARIABLE HELPERS\n// ========================================\n\ntype BadgeStyleVars = { bg: string; text: string; border: string };\n\nconst variantStyles: Record<BadgeVariant, BadgeStyleVars> = {\n // shadcn/ui compatible variants\n default: {\n bg: 'var(--badge-default-bg)',\n text: 'var(--badge-default-text)',\n border: 'var(--badge-default-border)',\n },\n secondary: {\n bg: 'var(--badge-secondary-bg)',\n text: 'var(--badge-secondary-text)',\n border: 'var(--badge-secondary-border)',\n },\n destructive: {\n bg: 'var(--badge-destructive-bg)',\n text: 'var(--badge-destructive-text)',\n border: 'var(--badge-destructive-border)',\n },\n outline: {\n bg: 'var(--badge-outline-bg)',\n text: 'var(--badge-outline-text)',\n border: 'var(--badge-outline-border)',\n },\n // Glass UI extended variants\n success: {\n bg: 'var(--badge-success-bg)',\n text: 'var(--badge-success-text)',\n border: 'var(--badge-success-border)',\n },\n warning: {\n bg: 'var(--badge-warning-bg)',\n text: 'var(--badge-warning-text)',\n border: 'var(--badge-warning-border)',\n },\n info: {\n bg: 'var(--badge-info-bg)',\n text: 'var(--badge-info-text)',\n border: 'var(--badge-info-border)',\n },\n};\n\nconst getBadgeStyles = (variant: BadgeVariant): CSSProperties => {\n const v = variantStyles[variant] || variantStyles.default;\n return {\n background: v.bg,\n color: v.text,\n border: `1px solid ${v.border}`,\n };\n};\n\n// ========================================\n// PROPS INTERFACE\n// ========================================\n\n/**\n * Props for the BadgeGlass component\n *\n * A glass-themed badge with semantic variants and optional animated status dot.\n * Features shadcn/ui compatible variants plus extended Glass UI variants.\n *\n * @accessibility\n * - **Keyboard Navigation:** Badges are non-interactive by default (display-only)\n * - **Focus Management:** N/A - badges do not receive focus unless wrapped in interactive elements\n * - **Screen Readers:** Semantic `<span>` element, content announced naturally\n * - **Status Indicators:** Use `aria-label` to provide context for status badges (e.g., \"Status: Active\")\n * - **Animated Dot:** Pulse animation respects `prefers-reduced-motion` settings\n * - **Touch Targets:** N/A for display badges, ensure 44x44px if wrapping in button/link (WCAG 2.5.5)\n * - **Color Contrast:** All variant text meets WCAG AA contrast ratio 4.5:1 against badge background\n * - **Motion:** Dot pulse animation can be disabled for users with motion sensitivity\n *\n * @example\n * ```tsx\n * // Basic badge with variant\n * <BadgeGlass variant=\"default\">New</BadgeGlass>\n *\n * // Status badge with aria-label for screen readers\n * <BadgeGlass variant=\"success\" aria-label=\"Status: Active\">\n * Active\n * </BadgeGlass>\n *\n * // Different variants (shadcn/ui compatible)\n * <BadgeGlass variant=\"default\">Default</BadgeGlass>\n * <BadgeGlass variant=\"secondary\">Secondary</BadgeGlass>\n * <BadgeGlass variant=\"destructive\">Error</BadgeGlass>\n * <BadgeGlass variant=\"outline\">Outline</BadgeGlass>\n *\n * // Extended Glass UI variants\n * <BadgeGlass variant=\"success\">Success</BadgeGlass>\n * <BadgeGlass variant=\"warning\">Warning</BadgeGlass>\n * <BadgeGlass variant=\"info\">Info</BadgeGlass>\n *\n * // With animated status dot\n * <BadgeGlass variant=\"success\" dot aria-label=\"Status: Online\">\n * Online\n * </BadgeGlass>\n * <BadgeGlass variant=\"destructive\" dot aria-label=\"Status: Offline\">\n * Offline\n * </BadgeGlass>\n *\n * // Size variants\n * <BadgeGlass size=\"sm\">Small</BadgeGlass>\n * <BadgeGlass size=\"default\">Medium</BadgeGlass>\n * <BadgeGlass size=\"lg\">Large</BadgeGlass>\n *\n * // Inside interactive elements (ensure accessible labels)\n * <button aria-label=\"Filter by active status\">\n * Filter: <BadgeGlass variant=\"success\">Active</BadgeGlass>\n * </button>\n *\n * // Count badge with semantic meaning\n * <div>\n * <span>Notifications</span>\n * <BadgeGlass variant=\"destructive\" aria-label=\"3 unread notifications\">\n * 3\n * </BadgeGlass>\n * </div>\n * ```\n */\nexport interface BadgeGlassProps\n extends Omit<React.HTMLAttributes<HTMLSpanElement>, 'style'>, VariantProps<typeof badgeVariants> {\n readonly children: ReactNode;\n readonly variant?: BadgeVariant;\n readonly dot?: boolean;\n}\n\n// ========================================\n// COMPONENT\n// ========================================\n\nexport const BadgeGlass = forwardRef<HTMLSpanElement, BadgeGlassProps>(\n ({ children, className, variant = 'default', size = 'md', dot, ...props }, ref) => {\n const v = variantStyles[variant];\n\n return (\n <span\n ref={ref}\n className={cn(badgeVariants({ size }), className)}\n style={getBadgeStyles(variant)}\n {...props}\n >\n {dot && (\n <span\n className=\"w-1 h-1 md:w-1.5 md:h-1.5 rounded-full animate-pulse\"\n style={{ background: v.text }}\n />\n )}\n {children}\n </span>\n );\n }\n);\n\nBadgeGlass.displayName = 'BadgeGlass';\n"
|
|
19
|
+
"content": "/**\n * BadgeGlass Component\n *\n * Glass-themed badge with:\n * - Theme-aware styling via CSS variables (glass/light/aurora)\n * - shadcn/ui compatible variants (default, secondary, destructive, outline)\n * - Extended Glass UI variants (success, warning, info)\n * - Size options\n * - Optional animated dot\n */\n\nimport { forwardRef, type ReactNode, type CSSProperties } from 'react';\nimport { type VariantProps } from 'class-variance-authority';\nimport { cn } from '@/lib/utils';\nimport { badgeVariants, type BadgeVariant } from '@/lib/variants/badge-glass-variants';\nimport '@/glass-theme.css';\n\n// ========================================\n// CSS VARIABLE HELPERS\n// ========================================\n\ntype BadgeStyleVars = { bg: string; text: string; border: string };\n\nconst variantStyles: Record<BadgeVariant, BadgeStyleVars> = {\n // shadcn/ui compatible variants\n default: {\n bg: 'var(--badge-default-bg)',\n text: 'var(--badge-default-text)',\n border: 'var(--badge-default-border)',\n },\n secondary: {\n bg: 'var(--badge-secondary-bg)',\n text: 'var(--badge-secondary-text)',\n border: 'var(--badge-secondary-border)',\n },\n destructive: {\n bg: 'var(--badge-destructive-bg)',\n text: 'var(--badge-destructive-text)',\n border: 'var(--badge-destructive-border)',\n },\n outline: {\n bg: 'var(--badge-outline-bg)',\n text: 'var(--badge-outline-text)',\n border: 'var(--badge-outline-border)',\n },\n // Glass UI extended variants\n success: {\n bg: 'var(--badge-success-bg)',\n text: 'var(--badge-success-text)',\n border: 'var(--badge-success-border)',\n },\n warning: {\n bg: 'var(--badge-warning-bg)',\n text: 'var(--badge-warning-text)',\n border: 'var(--badge-warning-border)',\n },\n info: {\n bg: 'var(--badge-info-bg)',\n text: 'var(--badge-info-text)',\n border: 'var(--badge-info-border)',\n },\n};\n\nconst getBadgeStyles = (variant: BadgeVariant): CSSProperties => {\n const v = variantStyles[variant] || variantStyles.default;\n return {\n background: v.bg,\n color: v.text,\n border: `1px solid ${v.border}`,\n };\n};\n\n// ========================================\n// PROPS INTERFACE\n// ========================================\n\n/**\n * Props for the BadgeGlass component\n *\n * A glass-themed badge with semantic variants and optional animated status dot.\n * Features shadcn/ui compatible variants plus extended Glass UI variants.\n *\n * @accessibility\n * - **Keyboard Navigation:** Badges are non-interactive by default (display-only)\n * - **Focus Management:** N/A - badges do not receive focus unless wrapped in interactive elements\n * - **Screen Readers:** Semantic `<span>` element, content announced naturally\n * - **Status Indicators:** Use `aria-label` to provide context for status badges (e.g., \"Status: Active\")\n * - **Animated Dot:** Pulse animation respects `prefers-reduced-motion` settings\n * - **Touch Targets:** N/A for display badges, ensure 44x44px if wrapping in button/link (WCAG 2.5.5)\n * - **Color Contrast:** All variant text meets WCAG AA contrast ratio 4.5:1 against badge background\n * - **Motion:** Dot pulse animation can be disabled for users with motion sensitivity\n *\n * @example\n * ```tsx\n * // Basic badge with variant\n * <BadgeGlass variant=\"default\">New</BadgeGlass>\n *\n * // Status badge with aria-label for screen readers\n * <BadgeGlass variant=\"success\" aria-label=\"Status: Active\">\n * Active\n * </BadgeGlass>\n *\n * // Different variants (shadcn/ui compatible)\n * <BadgeGlass variant=\"default\">Default</BadgeGlass>\n * <BadgeGlass variant=\"secondary\">Secondary</BadgeGlass>\n * <BadgeGlass variant=\"destructive\">Error</BadgeGlass>\n * <BadgeGlass variant=\"outline\">Outline</BadgeGlass>\n *\n * // Extended Glass UI variants\n * <BadgeGlass variant=\"success\">Success</BadgeGlass>\n * <BadgeGlass variant=\"warning\">Warning</BadgeGlass>\n * <BadgeGlass variant=\"info\">Info</BadgeGlass>\n *\n * // With animated status dot\n * <BadgeGlass variant=\"success\" dot aria-label=\"Status: Online\">\n * Online\n * </BadgeGlass>\n * <BadgeGlass variant=\"destructive\" dot aria-label=\"Status: Offline\">\n * Offline\n * </BadgeGlass>\n *\n * // Size variants\n * <BadgeGlass size=\"sm\">Small</BadgeGlass>\n * <BadgeGlass size=\"default\">Medium</BadgeGlass>\n * <BadgeGlass size=\"lg\">Large</BadgeGlass>\n *\n * // Inside interactive elements (ensure accessible labels)\n * <button aria-label=\"Filter by active status\">\n * Filter: <BadgeGlass variant=\"success\">Active</BadgeGlass>\n * </button>\n *\n * // Count badge with semantic meaning\n * <div>\n * <span>Notifications</span>\n * <BadgeGlass variant=\"destructive\" aria-label=\"3 unread notifications\">\n * 3\n * </BadgeGlass>\n * </div>\n * ```\n */\nexport interface BadgeGlassProps\n extends Omit<React.HTMLAttributes<HTMLSpanElement>, 'style'>, VariantProps<typeof badgeVariants> {\n readonly children: ReactNode;\n readonly variant?: BadgeVariant;\n readonly dot?: boolean;\n}\n\n// ========================================\n// COMPONENT\n// ========================================\n\nexport const BadgeGlass = forwardRef<HTMLSpanElement, BadgeGlassProps>(\n ({ children, className, variant = 'default', size = 'md', dot, ...props }, ref) => {\n const v = variantStyles[variant];\n\n return (\n <span\n ref={ref}\n data-slot=\"badge\"\n className={cn(badgeVariants({ size }), className)}\n style={getBadgeStyles(variant)}\n {...props}\n >\n {dot && (\n <span\n className=\"w-1 h-1 md:w-1.5 md:h-1.5 rounded-full animate-pulse\"\n style={{ background: v.text }}\n />\n )}\n {children}\n </span>\n );\n }\n);\n\nBadgeGlass.displayName = 'BadgeGlass';\n"
|
|
20
20
|
}
|
|
21
21
|
],
|
|
22
22
|
"categories": [
|
package/dist/r/button-glass.json
CHANGED
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
{
|
|
21
21
|
"path": "components/glass/ui/button-glass.tsx",
|
|
22
22
|
"type": "registry:component",
|
|
23
|
-
"content": "/**\n * ButtonGlass Component\n *\n * Glass-themed button with:\n * - Theme-aware styling via CSS variables (glass/light/aurora)\n * - Glow effects on hover\n * - Ripple effect on click (JS)\n * - Shine animation for primary variant (JS)\n * - Loading state with spinner\n * - Icon support (left/right position)\n */\n\nimport {\n forwardRef,\n useState,\n useCallback,\n useEffect,\n useRef,\n type MouseEvent,\n type CSSProperties,\n} from 'react';\nimport { Slot } from '@radix-ui/react-slot';\nimport { type VariantProps } from 'class-variance-authority';\nimport { RefreshCw, type LucideIcon } from 'lucide-react';\nimport { cn } from '@/lib/utils';\nimport { useHover } from '@/lib/hooks/use-hover';\nimport { useFocus } from '@/lib/hooks/use-focus';\nimport { buttonGlassVariants, type ButtonGlassVariant } from '@/lib/variants/button-glass-variants';\nimport { ICON_SIZES } from '@/components/glass/primitives';\nimport '@/glass-theme.css';\n\n// ========================================\n// CSS VARIABLE STYLE MAPS\n// ========================================\n\nconst getVariantStyles = (\n variant: ButtonGlassVariant,\n isHovered: boolean,\n isFocusVisible: boolean\n): CSSProperties => {\n const baseStyles: Record<ButtonGlassVariant, CSSProperties> = {\n default: {\n background: isHovered ? 'var(--btn-primary-hover-bg)' : 'var(--btn-primary-bg)',\n color: 'var(--btn-primary-text)',\n border: 'none',\n boxShadow: isFocusVisible\n ? 'var(--focus-glow)'\n : isHovered\n ? 'var(--btn-primary-glow)'\n : 'var(--btn-primary-shadow)',\n },\n secondary: {\n background: isHovered ? 'var(--btn-secondary-hover-bg)' : 'var(--btn-secondary-bg)',\n color: 'var(--btn-secondary-text)',\n border: '1px solid var(--btn-secondary-border)',\n boxShadow: isFocusVisible\n ? 'var(--focus-glow)'\n : isHovered\n ? 'var(--btn-secondary-glow)'\n : 'none',\n },\n ghost: {\n background: isHovered ? 'var(--btn-ghost-hover-bg)' : 'var(--btn-ghost-bg)',\n color: 'var(--btn-ghost-text)',\n border: 'none',\n boxShadow: isFocusVisible ? 'var(--focus-glow)' : 'none',\n },\n destructive: {\n background: 'var(--btn-destructive-bg)',\n color: 'var(--btn-destructive-text)',\n border: 'none',\n boxShadow: isFocusVisible\n ? 'var(--focus-glow)'\n : isHovered\n ? 'var(--btn-destructive-glow)'\n : 'var(--btn-destructive-shadow)',\n },\n outline: {\n background: isHovered ? 'var(--btn-outline-hover-bg)' : 'transparent',\n color: 'var(--btn-outline-text)',\n border: '1px solid var(--btn-outline-border)',\n boxShadow: isFocusVisible\n ? 'var(--focus-glow)'\n : isHovered\n ? 'var(--btn-outline-glow)'\n : 'none',\n },\n success: {\n background: 'var(--btn-success-bg)',\n color: 'var(--btn-success-text)',\n border: 'none',\n boxShadow: isFocusVisible\n ? 'var(--focus-glow)'\n : isHovered\n ? 'var(--btn-success-glow)'\n : 'var(--btn-success-shadow)',\n },\n link: {\n background: 'transparent',\n color: 'var(--btn-link-text)',\n border: 'none',\n boxShadow: isFocusVisible ? 'var(--focus-glow)' : 'none',\n textDecoration: isHovered ? 'underline' : 'none',\n },\n };\n\n return baseStyles[variant];\n};\n\n// ========================================\n// PROPS INTERFACE\n// ========================================\n\n/**\n * Props for the ButtonGlass component\n *\n * A glass-themed button with ripple effects, loading states, and icon support.\n * Features theme-aware styling and hover animations.\n *\n * **shadcn/ui compatible variants:**\n * - `default` - Primary action button with glow effects\n * - `secondary` - Secondary action with border\n * - `ghost` - Minimal visual presence\n * - `destructive` - Dangerous/delete actions (red)\n * - `outline` - Border with transparent background\n * - `link` - Text-only button with underline on hover\n * - `success` - Positive feedback (glass-ui extension)\n *\n * @accessibility\n * - **Keyboard Navigation:** Fully keyboard accessible with native `<button>` element\n * - **Focus Management:** Visible focus ring using `--focus-glow` CSS variable (WCAG 2.4.7)\n * - **Screen Readers:** Semantic `<button>` element, disabled state announced automatically\n * - **Loading State:** When loading=true, button is disabled and loading spinner is visible\n * - **Touch Targets:** Minimum 44x44px touch target (WCAG 2.5.5) via size variants\n * - **Color Contrast:** All variants meet WCAG AA contrast ratio 4.5:1 minimum\n * - **Motion:** Respects `prefers-reduced-motion` for ripple/shine animations\n *\n * @example\n * ```tsx\n * // Basic button (default variant)\n * <ButtonGlass>Click me</ButtonGlass>\n * <ButtonGlass variant=\"default\">Primary action</ButtonGlass>\n *\n * // With icon and aria-label for icon-only buttons\n * <ButtonGlass icon={Check} iconPosition=\"left\">Save</ButtonGlass>\n * <ButtonGlass icon={X} size=\"icon\" aria-label=\"Close dialog\" />\n *\n * // Loading state (automatically disables and shows spinner)\n * <ButtonGlass loading aria-live=\"polite\">Processing...</ButtonGlass>\n *\n * // Different variants (shadcn/ui compatible)\n * <ButtonGlass variant=\"secondary\">Secondary</ButtonGlass>\n * <ButtonGlass variant=\"ghost\">Cancel</ButtonGlass>\n * <ButtonGlass variant=\"outline\">Outline</ButtonGlass>\n * <ButtonGlass variant=\"destructive\">Delete</ButtonGlass>\n * <ButtonGlass variant=\"link\">Learn more</ButtonGlass>\n * <ButtonGlass variant=\"success\">Confirm</ButtonGlass>\n *\n * // As a link (asChild pattern) - maintains semantic HTML\n * <ButtonGlass asChild>\n * <a href=\"/dashboard\">Go to Dashboard</a>\n * </ButtonGlass>\n *\n * // With Next.js Link\n * <ButtonGlass asChild variant=\"ghost\">\n * <Link href=\"/settings\">Settings</Link>\n * </ButtonGlass>\n *\n * // Form submit button\n * <ButtonGlass type=\"submit\">\n * Submit Form\n * </ButtonGlass>\n * ```\n */\nexport interface ButtonGlassProps\n extends\n Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, 'style'>,\n VariantProps<typeof buttonGlassVariants> {\n /**\n * Render as child element instead of button (polymorphic rendering).\n * Useful for rendering buttons as links or other interactive elements.\n *\n * **Note:** When using `asChild`, decorative effects (ripple, shine, glow)\n * are disabled to maintain compatibility with Radix UI Slot.\n * Only styles and event handlers are passed to the child element.\n *\n * @default false\n * @example\n * ```tsx\n * <ButtonGlass asChild>\n * <a href=\"/about\">About Us</a>\n * </ButtonGlass>\n * ```\n */\n readonly asChild?: boolean;\n\n /**\n * Visual style variant of the button (shadcn/ui compatible)\n * @default \"default\"\n */\n readonly variant?: ButtonGlassVariant;\n\n /**\n * Show loading spinner and disable interactions\n * @default false\n */\n readonly loading?: boolean;\n\n /**\n * Icon component from lucide-react to display\n * @example icon={Check}\n */\n readonly icon?: LucideIcon;\n\n /**\n * Position of the icon relative to button text\n * @default \"left\"\n */\n readonly iconPosition?: 'left' | 'right';\n\n /**\n * Size variant of the button (shadcn/ui compatible)\n * @default \"default\"\n */\n readonly size?: 'default' | 'sm' | 'lg' | 'xl' | 'icon';\n}\n\n// ========================================\n// COMPONENT\n// ========================================\n\nexport const ButtonGlass = forwardRef<HTMLButtonElement, ButtonGlassProps>(\n (\n {\n asChild = false,\n className,\n variant = 'default',\n size = 'default',\n children,\n loading = false,\n disabled,\n icon: Icon,\n iconPosition = 'left',\n onClick,\n ...props\n },\n ref\n ) => {\n const { isHovered, hoverProps } = useHover();\n const { isFocusVisible, focusProps } = useFocus({ focusVisible: true });\n const [ripple, setRipple] = useState<{ x: number; y: number } | null>(null);\n\n const isDisabled = disabled || loading;\n const rippleTimeoutRef = useRef<NodeJS.Timeout | null>(null);\n\n // Cleanup ripple timeout on unmount\n useEffect(() => {\n return () => {\n if (rippleTimeoutRef.current) {\n clearTimeout(rippleTimeoutRef.current);\n }\n };\n }, []);\n\n // Ripple effect handler\n const handleClick = useCallback(\n (e: MouseEvent<HTMLButtonElement>) => {\n if (isDisabled) return;\n\n // Create ripple effect\n const rect = e.currentTarget.getBoundingClientRect();\n const x = e.clientX - rect.left;\n const y = e.clientY - rect.top;\n setRipple({ x, y });\n\n // Clear previous timeout if exists\n if (rippleTimeoutRef.current) {\n clearTimeout(rippleTimeoutRef.current);\n }\n\n rippleTimeoutRef.current = setTimeout(() => {\n setRipple(null);\n rippleTimeoutRef.current = null;\n }, 600);\n\n onClick?.(e);\n },\n [isDisabled, onClick]\n );\n\n // Polymorphic component - render as Slot when asChild is true\n const Comp = asChild ? Slot : 'button';\n\n return (\n <Comp\n ref={ref}\n className={cn(\n buttonGlassVariants({ variant, size }),\n isHovered && !isDisabled && 'scale-[1.02]',\n className\n )}\n style={{\n ...getVariantStyles(variant, isHovered && !isDisabled, isFocusVisible && !isDisabled),\n outline: 'none',\n }}\n type={asChild ? undefined : 'button'}\n disabled={isDisabled}\n onClick={handleClick}\n onMouseEnter={hoverProps.onMouseEnter}\n onMouseLeave={hoverProps.onMouseLeave}\n onFocus={focusProps.onFocus}\n onBlur={focusProps.onBlur}\n {...props}\n >\n {/* When asChild is true, only render children (Slot expects a single child) */}\n {asChild ? (\n children\n ) : (\n <>\n {/* Shine effect on hover for default variant */}\n {isHovered && variant === 'default' && !isDisabled && (\n <div\n className=\"absolute inset-0 overflow-hidden pointer-events-none\"\n style={{ borderRadius: 'inherit' }}\n >\n <div\n className=\"absolute top-0 h-full w-1/3 bg-linear-to-r from-transparent via-white/20 to-transparent\"\n style={{ animation: 'btn-shine 1.5s ease-in-out infinite' }}\n />\n </div>\n )}\n\n {/* Ripple effect */}\n {ripple && (\n <span\n className=\"absolute rounded-full bg-white/30 pointer-events-none\"\n style={{\n left: ripple.x,\n top: ripple.y,\n width: 10,\n height: 10,\n transform: 'translate(-50%, -50%)',\n animation: 'ripple 0.6s ease-out',\n }}\n />\n )}\n\n {/* Pulsing glow on hover */}\n {isHovered && variant === 'default' && !isDisabled && (\n <div\n className=\"absolute inset-0 rounded-xl animate-glow-pulse pointer-events-none\"\n style={{\n background: 'var(--btn-glow-radial)',\n }}\n />\n )}\n\n {/* Loading spinner */}\n {loading && <RefreshCw className={cn(ICON_SIZES.md, 'animate-spin')} />}\n\n {/* Icon left */}\n {!loading && Icon && iconPosition === 'left' && <Icon className={ICON_SIZES.md} />}\n\n {/* Content */}\n {!loading && children}\n\n {/* Icon right */}\n {!loading && Icon && iconPosition === 'right' && <Icon className={ICON_SIZES.md} />}\n </>\n )}\n </Comp>\n );\n }\n);\n\nButtonGlass.displayName = 'ButtonGlass';\n"
|
|
23
|
+
"content": "/**\n * ButtonGlass Component\n *\n * Glass-themed button with:\n * - Theme-aware styling via CSS variables (glass/light/aurora)\n * - Glow effects on hover\n * - Ripple effect on click (JS)\n * - Shine animation for primary variant (JS)\n * - Loading state with spinner\n * - Icon support (left/right position)\n */\n\nimport {\n forwardRef,\n useState,\n useCallback,\n useEffect,\n useRef,\n type MouseEvent,\n type CSSProperties,\n} from 'react';\nimport { Slot } from '@radix-ui/react-slot';\nimport { type VariantProps } from 'class-variance-authority';\nimport { RefreshCw, type LucideIcon } from 'lucide-react';\nimport { cn } from '@/lib/utils';\nimport { useHover } from '@/lib/hooks/use-hover';\nimport { useFocus } from '@/lib/hooks/use-focus';\nimport { buttonGlassVariants, type ButtonGlassVariant } from '@/lib/variants/button-glass-variants';\nimport { ICON_SIZES } from '@/components/glass/primitives';\nimport '@/glass-theme.css';\n\n// ========================================\n// CSS VARIABLE STYLE MAPS\n// ========================================\n\nconst getVariantStyles = (\n variant: ButtonGlassVariant,\n isHovered: boolean,\n isFocusVisible: boolean\n): CSSProperties => {\n const baseStyles: Record<ButtonGlassVariant, CSSProperties> = {\n default: {\n background: isHovered ? 'var(--btn-primary-hover-bg)' : 'var(--btn-primary-bg)',\n color: 'var(--btn-primary-text)',\n border: 'none',\n boxShadow: isFocusVisible\n ? 'var(--focus-glow)'\n : isHovered\n ? 'var(--btn-primary-glow)'\n : 'var(--btn-primary-shadow)',\n },\n secondary: {\n background: isHovered ? 'var(--btn-secondary-hover-bg)' : 'var(--btn-secondary-bg)',\n color: 'var(--btn-secondary-text)',\n border: '1px solid var(--btn-secondary-border)',\n boxShadow: isFocusVisible\n ? 'var(--focus-glow)'\n : isHovered\n ? 'var(--btn-secondary-glow)'\n : 'none',\n },\n ghost: {\n background: isHovered ? 'var(--btn-ghost-hover-bg)' : 'var(--btn-ghost-bg)',\n color: 'var(--btn-ghost-text)',\n border: 'none',\n boxShadow: isFocusVisible ? 'var(--focus-glow)' : 'none',\n },\n destructive: {\n background: 'var(--btn-destructive-bg)',\n color: 'var(--btn-destructive-text)',\n border: 'none',\n boxShadow: isFocusVisible\n ? 'var(--focus-glow)'\n : isHovered\n ? 'var(--btn-destructive-glow)'\n : 'var(--btn-destructive-shadow)',\n },\n outline: {\n background: isHovered ? 'var(--btn-outline-hover-bg)' : 'transparent',\n color: 'var(--btn-outline-text)',\n border: '1px solid var(--btn-outline-border)',\n boxShadow: isFocusVisible\n ? 'var(--focus-glow)'\n : isHovered\n ? 'var(--btn-outline-glow)'\n : 'none',\n },\n success: {\n background: 'var(--btn-success-bg)',\n color: 'var(--btn-success-text)',\n border: 'none',\n boxShadow: isFocusVisible\n ? 'var(--focus-glow)'\n : isHovered\n ? 'var(--btn-success-glow)'\n : 'var(--btn-success-shadow)',\n },\n link: {\n background: 'transparent',\n color: 'var(--btn-link-text)',\n border: 'none',\n boxShadow: isFocusVisible ? 'var(--focus-glow)' : 'none',\n textDecoration: isHovered ? 'underline' : 'none',\n },\n };\n\n return baseStyles[variant];\n};\n\n// ========================================\n// PROPS INTERFACE\n// ========================================\n\n/**\n * Props for the ButtonGlass component\n *\n * A glass-themed button with ripple effects, loading states, and icon support.\n * Features theme-aware styling and hover animations.\n *\n * **shadcn/ui compatible variants:**\n * - `default` - Primary action button with glow effects\n * - `secondary` - Secondary action with border\n * - `ghost` - Minimal visual presence\n * - `destructive` - Dangerous/delete actions (red)\n * - `outline` - Border with transparent background\n * - `link` - Text-only button with underline on hover\n * - `success` - Positive feedback (glass-ui extension)\n *\n * @accessibility\n * - **Keyboard Navigation:** Fully keyboard accessible with native `<button>` element\n * - **Focus Management:** Visible focus ring using `--focus-glow` CSS variable (WCAG 2.4.7)\n * - **Screen Readers:** Semantic `<button>` element, disabled state announced automatically\n * - **Loading State:** When loading=true, button is disabled and loading spinner is visible\n * - **Touch Targets:** Minimum 44x44px touch target (WCAG 2.5.5) via size variants\n * - **Color Contrast:** All variants meet WCAG AA contrast ratio 4.5:1 minimum\n * - **Motion:** Respects `prefers-reduced-motion` for ripple/shine animations\n *\n * @example\n * ```tsx\n * // Basic button (default variant)\n * <ButtonGlass>Click me</ButtonGlass>\n * <ButtonGlass variant=\"default\">Primary action</ButtonGlass>\n *\n * // With icon and aria-label for icon-only buttons\n * <ButtonGlass icon={Check} iconPosition=\"left\">Save</ButtonGlass>\n * <ButtonGlass icon={X} size=\"icon\" aria-label=\"Close dialog\" />\n *\n * // Loading state (automatically disables and shows spinner)\n * <ButtonGlass loading aria-live=\"polite\">Processing...</ButtonGlass>\n *\n * // Different variants (shadcn/ui compatible)\n * <ButtonGlass variant=\"secondary\">Secondary</ButtonGlass>\n * <ButtonGlass variant=\"ghost\">Cancel</ButtonGlass>\n * <ButtonGlass variant=\"outline\">Outline</ButtonGlass>\n * <ButtonGlass variant=\"destructive\">Delete</ButtonGlass>\n * <ButtonGlass variant=\"link\">Learn more</ButtonGlass>\n * <ButtonGlass variant=\"success\">Confirm</ButtonGlass>\n *\n * // As a link (asChild pattern) - maintains semantic HTML\n * <ButtonGlass asChild>\n * <a href=\"/dashboard\">Go to Dashboard</a>\n * </ButtonGlass>\n *\n * // With Next.js Link\n * <ButtonGlass asChild variant=\"ghost\">\n * <Link href=\"/settings\">Settings</Link>\n * </ButtonGlass>\n *\n * // Form submit button\n * <ButtonGlass type=\"submit\">\n * Submit Form\n * </ButtonGlass>\n * ```\n */\nexport interface ButtonGlassProps\n extends\n Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, 'style'>,\n VariantProps<typeof buttonGlassVariants> {\n /**\n * Render as child element instead of button (polymorphic rendering).\n * Useful for rendering buttons as links or other interactive elements.\n *\n * **Note:** When using `asChild`, decorative effects (ripple, shine, glow)\n * are disabled to maintain compatibility with Radix UI Slot.\n * Only styles and event handlers are passed to the child element.\n *\n * @default false\n * @example\n * ```tsx\n * <ButtonGlass asChild>\n * <a href=\"/about\">About Us</a>\n * </ButtonGlass>\n * ```\n */\n readonly asChild?: boolean;\n\n /**\n * Visual style variant of the button (shadcn/ui compatible)\n * @default \"default\"\n */\n readonly variant?: ButtonGlassVariant;\n\n /**\n * Show loading spinner and disable interactions\n * @default false\n */\n readonly loading?: boolean;\n\n /**\n * Icon component from lucide-react to display\n * @example icon={Check}\n */\n readonly icon?: LucideIcon;\n\n /**\n * Position of the icon relative to button text\n * @default \"left\"\n */\n readonly iconPosition?: 'left' | 'right';\n\n /**\n * Size variant of the button (shadcn/ui compatible)\n * @default \"default\"\n */\n readonly size?: 'default' | 'sm' | 'lg' | 'xl' | 'icon';\n}\n\n// ========================================\n// COMPONENT\n// ========================================\n\nexport const ButtonGlass = forwardRef<HTMLButtonElement, ButtonGlassProps>(\n (\n {\n asChild = false,\n className,\n variant = 'default',\n size = 'default',\n children,\n loading = false,\n disabled,\n icon: Icon,\n iconPosition = 'left',\n onClick,\n ...props\n },\n ref\n ) => {\n const { isHovered, hoverProps } = useHover();\n const { isFocusVisible, focusProps } = useFocus({ focusVisible: true });\n const [ripple, setRipple] = useState<{ x: number; y: number } | null>(null);\n\n const isDisabled = disabled || loading;\n const rippleTimeoutRef = useRef<NodeJS.Timeout | null>(null);\n\n // Cleanup ripple timeout on unmount\n useEffect(() => {\n return () => {\n if (rippleTimeoutRef.current) {\n clearTimeout(rippleTimeoutRef.current);\n }\n };\n }, []);\n\n // Ripple effect handler\n const handleClick = useCallback(\n (e: MouseEvent<HTMLButtonElement>) => {\n if (isDisabled) return;\n\n // Create ripple effect\n const rect = e.currentTarget.getBoundingClientRect();\n const x = e.clientX - rect.left;\n const y = e.clientY - rect.top;\n setRipple({ x, y });\n\n // Clear previous timeout if exists\n if (rippleTimeoutRef.current) {\n clearTimeout(rippleTimeoutRef.current);\n }\n\n rippleTimeoutRef.current = setTimeout(() => {\n setRipple(null);\n rippleTimeoutRef.current = null;\n }, 600);\n\n onClick?.(e);\n },\n [isDisabled, onClick]\n );\n\n // Polymorphic component - render as Slot when asChild is true\n const Comp = asChild ? Slot : 'button';\n\n return (\n <Comp\n ref={ref}\n data-slot=\"button\"\n className={cn(\n buttonGlassVariants({ variant, size }),\n isHovered && !isDisabled && 'scale-[1.02]',\n className\n )}\n style={{\n ...getVariantStyles(variant, isHovered && !isDisabled, isFocusVisible && !isDisabled),\n outline: 'none',\n }}\n type={asChild ? undefined : 'button'}\n disabled={isDisabled}\n onClick={handleClick}\n onMouseEnter={hoverProps.onMouseEnter}\n onMouseLeave={hoverProps.onMouseLeave}\n onFocus={focusProps.onFocus}\n onBlur={focusProps.onBlur}\n {...props}\n >\n {/* When asChild is true, only render children (Slot expects a single child) */}\n {asChild ? (\n children\n ) : (\n <>\n {/* Shine effect on hover for default variant */}\n {isHovered && variant === 'default' && !isDisabled && (\n <div\n className=\"absolute inset-0 overflow-hidden pointer-events-none\"\n style={{ borderRadius: 'inherit' }}\n >\n <div\n className=\"absolute top-0 h-full w-1/3 bg-linear-to-r from-transparent via-white/20 to-transparent\"\n style={{ animation: 'btn-shine 1.5s ease-in-out infinite' }}\n />\n </div>\n )}\n\n {/* Ripple effect */}\n {ripple && (\n <span\n className=\"absolute rounded-full bg-white/30 pointer-events-none\"\n style={{\n left: ripple.x,\n top: ripple.y,\n width: 10,\n height: 10,\n transform: 'translate(-50%, -50%)',\n animation: 'ripple 0.6s ease-out',\n }}\n />\n )}\n\n {/* Pulsing glow on hover */}\n {isHovered && variant === 'default' && !isDisabled && (\n <div\n className=\"absolute inset-0 rounded-xl animate-glow-pulse pointer-events-none\"\n style={{\n background: 'var(--btn-glow-radial)',\n }}\n />\n )}\n\n {/* Loading spinner */}\n {loading && <RefreshCw className={cn(ICON_SIZES.md, 'animate-spin')} />}\n\n {/* Icon left */}\n {!loading && Icon && iconPosition === 'left' && <Icon className={ICON_SIZES.md} />}\n\n {/* Content */}\n {!loading && children}\n\n {/* Icon right */}\n {!loading && Icon && iconPosition === 'right' && <Icon className={ICON_SIZES.md} />}\n </>\n )}\n </Comp>\n );\n }\n);\n\nButtonGlass.displayName = 'ButtonGlass';\n"
|
|
24
24
|
}
|
|
25
25
|
],
|
|
26
26
|
"categories": [
|