@inshorts/glint-ui 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,60 @@
1
+ # @inshorts/glint-ui
2
+
3
+ Shared Tailwind 4 UI kit for Inshorts Next panels — the same components that
4
+ ship in `inpix-panel` (`src/lib/ui/`), extracted so every panel can reuse them.
5
+
6
+ Includes Button, Input, Label, Card, Table, Modal, Select, DataTable,
7
+ DateRangePicker, Tabs, ImageUploader (upload handlers injected), and the panel
8
+ theme tokens.
9
+
10
+ ## Install
11
+
12
+ Until this is published to the private registry, link the local checkout that
13
+ sits next to your panel repos:
14
+
15
+ ```bash
16
+ # from inshorts-sales-panel-next (or inpix-panel, users-crm, …)
17
+ pnpm add @inshorts/glint-ui@file:../inshorts-npm-modules/glint/ui
18
+ ```
19
+
20
+ After publish:
21
+
22
+ ```bash
23
+ pnpm add @inshorts/glint-ui
24
+ ```
25
+
26
+ Peer deps: `react` and `react-dom` ^19.3.
27
+
28
+ ## Wire it into a Next + Tailwind 4 panel
29
+
30
+ 1. Depend on the package (see above).
31
+ 2. Add `transpilePackages: ["@inshorts/glint-ui"]` in `next.config.mjs`.
32
+ 3. In `src/styles/globals.css`:
33
+
34
+ ```css
35
+ @import "tailwindcss";
36
+ @plugin "tailwindcss-animate";
37
+ @import "@inshorts/glint-ui/theme.css";
38
+
39
+ /* So Tailwind emits classes used only inside the package. */
40
+ @source "../../node_modules/@inshorts/glint-ui/src";
41
+ ```
42
+
43
+ 4. Import components:
44
+
45
+ ```tsx
46
+ import { Button, Modal, cn } from "@inshorts/glint-ui";
47
+ // or a single file:
48
+ import { Button } from "@inshorts/glint-ui/button";
49
+ ```
50
+
51
+ `ImageUploader` takes `uploadFile` / `uploadFromUrl` props — each panel passes
52
+ its own BFF upload route. Absolute `https://` pastes work without a handler.
53
+
54
+ ## Develop
55
+
56
+ ```bash
57
+ cd glint/ui
58
+ npm install
59
+ npm run typecheck
60
+ ```
package/package.json ADDED
@@ -0,0 +1,56 @@
1
+ {
2
+ "name": "@inshorts/glint-ui",
3
+ "version": "0.3.0",
4
+ "description": "Glint Tailwind 4 UI kit for Inshorts Next panels.",
5
+ "license": "UNLICENSED",
6
+ "type": "module",
7
+ "sideEffects": [
8
+ "**/*.css"
9
+ ],
10
+ "main": "./src/index.ts",
11
+ "types": "./src/index.ts",
12
+ "exports": {
13
+ ".": "./src/index.ts",
14
+ "./theme.css": "./theme.css",
15
+ "./utils": "./src/utils.ts",
16
+ "./clipboard": "./src/clipboard.ts",
17
+ "./dialogLayer": "./src/dialogLayer.ts",
18
+ "./date-range-picker": "./src/date-range-picker/index.tsx",
19
+ "./date-range-picker/dateRange": "./src/date-range-picker/dateRange.ts",
20
+ "./*": "./src/*.tsx",
21
+ "./package.json": "./package.json"
22
+ },
23
+ "files": [
24
+ "src",
25
+ "theme.css",
26
+ "README.md"
27
+ ],
28
+ "engines": {
29
+ "node": ">=22"
30
+ },
31
+ "repository": {
32
+ "type": "git",
33
+ "url": "git+https://github.com/NewsInShorts/inshorts-npm-modules.git",
34
+ "directory": "glint/ui"
35
+ },
36
+ "peerDependencies": {
37
+ "react": "^19.3.0",
38
+ "react-dom": "^19.3.0"
39
+ },
40
+ "dependencies": {
41
+ "@radix-ui/react-slot": "^1.3.3",
42
+ "class-variance-authority": "^0.7.1",
43
+ "clsx": "^2.1.1",
44
+ "lucide-react": "^1.49.0",
45
+ "tailwind-merge": "^3.7.0",
46
+ "@inshorts/glint-theme": "0.3.0"
47
+ },
48
+ "devDependencies": {
49
+ "@types/react": "^19.3.0",
50
+ "@types/react-dom": "^19.3.0",
51
+ "typescript": "^5.9.3"
52
+ },
53
+ "scripts": {
54
+ "typecheck": "tsc --noEmit"
55
+ }
56
+ }
package/src/alert.tsx ADDED
@@ -0,0 +1,74 @@
1
+ import * as React from "react";
2
+ import { cva, type VariantProps } from "class-variance-authority";
3
+
4
+ import { cn } from "./utils";
5
+
6
+ /**
7
+ * The inline message banner — a failed load, a warning above a form, a note.
8
+ *
9
+ * This was the most duplicated markup in the panel: thirty blocks across
10
+ * twenty-eight files, spelled seven different ways. `px-3 py-2` in most places
11
+ * and `px-4 py-3` in others, `text-rose-700` here and `text-destructive`
12
+ * there — all meaning "something went wrong".
13
+ *
14
+ * `role` is derived from the variant rather than left to callers. An error a
15
+ * user needs to act on should interrupt a screen reader; a note should not.
16
+ * Almost none of the hand-rolled copies set either.
17
+ */
18
+ const alertVariants = cva("rounded-lg border px-3 py-2 text-sm", {
19
+ variants: {
20
+ variant: {
21
+ danger: "border-rose-200 bg-rose-50 text-rose-700",
22
+ warning: "border-amber-200 bg-amber-50 text-amber-800",
23
+ success: "border-emerald-200 bg-emerald-50 text-emerald-800",
24
+ info: "border-sky-200 bg-sky-50 text-sky-800",
25
+ /**
26
+ * The quiet state of a banner that also has loud ones — "no default
27
+ * campaign set" next to "this is the default". Without it those callers
28
+ * keep a ternary of raw class strings and the shared component only
29
+ * covers half of what they draw.
30
+ */
31
+ neutral: "border-border bg-muted/40 text-muted-foreground",
32
+ },
33
+ },
34
+ defaultVariants: {
35
+ // Failure is what a banner almost always reports here, and defaulting to
36
+ // it means the noisy case cannot be forgotten.
37
+ variant: "danger",
38
+ },
39
+ });
40
+
41
+ export interface AlertProps
42
+ extends
43
+ React.HTMLAttributes<HTMLDivElement>,
44
+ VariantProps<typeof alertVariants> {
45
+ /**
46
+ * A control belonging to the message, such as Retry. Given one, the banner
47
+ * lays out as a row and keeps the action at its end.
48
+ */
49
+ action?: React.ReactNode;
50
+ }
51
+
52
+ export const Alert = React.forwardRef<HTMLDivElement, AlertProps>(
53
+ ({ className, variant, action, children, ...props }, ref) => (
54
+ <div
55
+ ref={ref}
56
+ role={variant === "danger" || variant == null ? "alert" : "status"}
57
+ className={cn(
58
+ alertVariants({ variant }),
59
+ action && "flex flex-wrap items-center justify-between gap-3",
60
+ className,
61
+ )}
62
+ {...props}
63
+ >
64
+ {/* Wrapped so the action sits opposite the text rather than being
65
+ pushed around by whatever the caller passed as children. */}
66
+ {action ? <span>{children}</span> : children}
67
+ {action}
68
+ </div>
69
+ ),
70
+ );
71
+
72
+ Alert.displayName = "Alert";
73
+
74
+ export { alertVariants };