@pihanga2/shadcn 0.2.6 → 0.2.8
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/AGENT.building-cards.md +118 -0
- package/README.md +3 -1
- package/cards/collapsibleCard/collapsibleCard.component.d.ts +4 -0
- package/cards/collapsibleCard/collapsibleCard.component.js +61 -0
- package/cards/collapsibleCard/collapsibleCard.component.js.map +1 -0
- package/cards/collapsibleCard/collapsibleCard.types.d.ts +91 -0
- package/cards/collapsibleCard/collapsibleCard.types.js +7 -0
- package/cards/collapsibleCard/collapsibleCard.types.js.map +1 -0
- package/cards/collapsibleCard/index.d.ts +1 -0
- package/cards/collapsibleCard/index.js +13 -0
- package/cards/collapsibleCard/index.js.map +1 -0
- package/cards/collapsibleCard.d.ts +1 -0
- package/cards/emptyCard/emptyCard.component.d.ts +4 -0
- package/cards/emptyCard/emptyCard.types.d.ts +36 -0
- package/cards/emptyCard/index.d.ts +1 -7
- package/cards/emptyCard.d.ts +1 -7
- package/cards/flexGrid/flexGrid.types.d.ts +1 -2
- package/cards/flexGrid/flexGrid.types.js.map +1 -1
- package/cards/graphin/eventDispatcher.component.d.ts +1 -0
- package/cards/infoCard/index.d.ts +1 -0
- package/cards/infoCard/index.js +12 -0
- package/cards/infoCard/index.js.map +1 -0
- package/cards/infoCard/infoCard.component.d.ts +4 -0
- package/cards/infoCard/infoCard.component.js +55 -0
- package/cards/infoCard/infoCard.component.js.map +1 -0
- package/cards/infoCard/infoCard.types.d.ts +65 -0
- package/cards/infoCard/infoCard.types.js +7 -0
- package/cards/infoCard/infoCard.types.js.map +1 -0
- package/cards/infoCard.d.ts +1 -0
- package/cards/toggleGroup/toggleGroup.component.js +1 -1
- package/cards/toggleGroup/toggleGroup.component.js.map +1 -1
- package/components/ui/card.js +50 -0
- package/components/ui/card.js.map +1 -0
- package/package.json +15 -1
- package/theme.css +102 -0
package/AGENT.building-cards.md
CHANGED
|
@@ -703,3 +703,121 @@ Rules:
|
|
|
703
703
|
- `src/cards/BUILDING_CARDS_HOWTO.md` — human-oriented narrative version of this guide
|
|
704
704
|
- `scripts/gen-card-dependencies.mjs` — dependency scanner
|
|
705
705
|
- `scripts/gen-registry.mjs` — registry builder
|
|
706
|
+
|
|
707
|
+
---
|
|
708
|
+
|
|
709
|
+
## Theme-aware cards — working with CSS variables
|
|
710
|
+
|
|
711
|
+
shadcn/ui components (and therefore pihanga-shadcn cards built on top of them)
|
|
712
|
+
use **CSS custom properties** for all semantic colours, radii, and shadows.
|
|
713
|
+
Understanding the token system is essential for cards that carry their own
|
|
714
|
+
visual chrome (borders, backgrounds, elevation).
|
|
715
|
+
|
|
716
|
+
### How the token system works
|
|
717
|
+
|
|
718
|
+
`src/theme.css` (shipped as `@pihanga2/shadcn/theme.css`) defines three layers:
|
|
719
|
+
|
|
720
|
+
| Layer | Purpose | Example |
|
|
721
|
+
|---|---|---|
|
|
722
|
+
| `:root { --card: oklch(...) }` | **Palette** — raw colour values | `--card`, `--border`, `--radius` |
|
|
723
|
+
| `@theme inline { --color-card: var(--card) }` | **Tailwind mapping** — wires vars to utility classes | `bg-card`, `border-border`, `rounded-xl` |
|
|
724
|
+
| `.dark { --card: oklch(...) }` | **Dark-mode overrides** | Same tokens, different values |
|
|
725
|
+
|
|
726
|
+
A consumer who overrides `:root { --card: oklch(0.9 0 0); }` in their own CSS
|
|
727
|
+
automatically rethemes every card that uses `bg-card` — no card code changes
|
|
728
|
+
needed.
|
|
729
|
+
|
|
730
|
+
### Using theme tokens in a new card
|
|
731
|
+
|
|
732
|
+
**Prefer shadcn semantic tokens over hardcoded colours.** This makes the card
|
|
733
|
+
rethemable by the consumer:
|
|
734
|
+
|
|
735
|
+
```tsx
|
|
736
|
+
// ✅ Rethemable — uses CSS variable tokens
|
|
737
|
+
<div className="bg-card text-card-foreground border border-border rounded-xl shadow-sm">
|
|
738
|
+
|
|
739
|
+
// ❌ Hard-wired — ignores consumer theme
|
|
740
|
+
<div className="bg-white text-gray-900 border border-gray-200 rounded-xl shadow-sm">
|
|
741
|
+
```
|
|
742
|
+
|
|
743
|
+
Standard shadcn tokens available as Tailwind utilities:
|
|
744
|
+
|
|
745
|
+
| Tailwind class | CSS variable | Default (light) |
|
|
746
|
+
|---|---|---|
|
|
747
|
+
| `bg-card` | `--card` | white |
|
|
748
|
+
| `text-card-foreground` | `--card-foreground` | near-black |
|
|
749
|
+
| `bg-background` | `--background` | white |
|
|
750
|
+
| `text-foreground` | `--foreground` | near-black |
|
|
751
|
+
| `bg-muted` | `--muted` | light gray |
|
|
752
|
+
| `text-muted-foreground` | `--muted-foreground` | medium gray |
|
|
753
|
+
| `bg-primary` | `--primary` | dark |
|
|
754
|
+
| `text-primary-foreground` | `--primary-foreground` | near-white |
|
|
755
|
+
| `border-border` | `--border` | light gray |
|
|
756
|
+
| `rounded-xl` | `--radius-xl` = `--radius + 4px` | ~14px |
|
|
757
|
+
| `rounded-lg` | `--radius-lg` = `--radius` | 10px |
|
|
758
|
+
| `shadow-sm` | Tailwind built-in | subtle shadow |
|
|
759
|
+
|
|
760
|
+
### Adding a new theme token for a card
|
|
761
|
+
|
|
762
|
+
When a card needs a design token consumers can override (e.g. a brand-specific
|
|
763
|
+
colour or radius), add it to **`src/theme.css`** following the same pattern:
|
|
764
|
+
|
|
765
|
+
```css
|
|
766
|
+
/* In src/theme.css — @theme inline block */
|
|
767
|
+
@theme inline {
|
|
768
|
+
/* … existing tokens … */
|
|
769
|
+
--color-my-card-accent: var(--my-card-accent);
|
|
770
|
+
}
|
|
771
|
+
|
|
772
|
+
/* default in :root */
|
|
773
|
+
:root {
|
|
774
|
+
--my-card-accent: oklch(0.5 0.2 260); /* a blue */
|
|
775
|
+
}
|
|
776
|
+
```
|
|
777
|
+
|
|
778
|
+
Then use `bg-my-card-accent` / `text-my-card-accent` in your component.
|
|
779
|
+
Consumers override by setting `--my-card-accent` in their own `:root`.
|
|
780
|
+
|
|
781
|
+
> **Do not** add tokens that are only useful for a single card to the global
|
|
782
|
+
> `theme.css`. For card-local defaults, prefer explicit Tailwind colour classes
|
|
783
|
+
> or a `className` prop.
|
|
784
|
+
|
|
785
|
+
### The `@container` gotcha with shadcn composites
|
|
786
|
+
|
|
787
|
+
shadcn's `<CardHeader>` applies `@container/card-header`
|
|
788
|
+
(`container-type: inline-size`). CSS containment makes the element's
|
|
789
|
+
intrinsic inline size appear as **0** to its parent for `min-width` / `max-content`
|
|
790
|
+
calculations — your card will collapse to a tiny width if it relies on `min-w-max`.
|
|
791
|
+
|
|
792
|
+
**Fix:** replace `<CardHeader>` with a plain `<div data-slot="card-header">` that
|
|
793
|
+
carries the same Tailwind classes but without the `@container` prefix:
|
|
794
|
+
|
|
795
|
+
```tsx
|
|
796
|
+
// ❌ @container breaks min-w-max on the parent Card
|
|
797
|
+
<CardHeader className={headerClassName}>
|
|
798
|
+
|
|
799
|
+
// ✅ Same visual styles, no CSS containment
|
|
800
|
+
<div
|
|
801
|
+
data-slot="card-header"
|
|
802
|
+
className={cn(
|
|
803
|
+
"grid auto-rows-min grid-rows-[auto_auto] items-start gap-2 px-6",
|
|
804
|
+
"has-data-[slot=card-action]:grid-cols-[1fr_auto] [.border-b]:pb-6",
|
|
805
|
+
headerClassName,
|
|
806
|
+
)}
|
|
807
|
+
>
|
|
808
|
+
```
|
|
809
|
+
|
|
810
|
+
This is safe because the `has-data-[slot=card-action]` selector is a CSS `:has()`
|
|
811
|
+
rule, not a container query — it doesn't require `@container` to function.
|
|
812
|
+
|
|
813
|
+
### Consumer setup (reminder)
|
|
814
|
+
|
|
815
|
+
Cards in this library render correctly only when the consuming app's CSS
|
|
816
|
+
includes `@import "@pihanga2/shadcn/theme.css"`. That single import:
|
|
817
|
+
|
|
818
|
+
1. Defines the CSS custom property palette (`:root`, `.dark`)
|
|
819
|
+
2. Maps them to Tailwind v4 utility tokens (`@theme inline`)
|
|
820
|
+
3. Tells Tailwind to scan the library's compiled files (`@source "."`)
|
|
821
|
+
|
|
822
|
+
Apps that already use shadcn/ui with their own theme setup do not need the
|
|
823
|
+
import — their `:root` variables cascade over the defaults.
|
package/README.md
CHANGED
|
@@ -62,13 +62,14 @@ import "@pihanga2/shadcn/cards/dataTable";
|
|
|
62
62
|
|
|
63
63
|
---
|
|
64
64
|
|
|
65
|
-
## Included cards (
|
|
65
|
+
## Included cards (41)
|
|
66
66
|
|
|
67
67
|
- `avatar`
|
|
68
68
|
- `badge`
|
|
69
69
|
- `box`
|
|
70
70
|
- `button`
|
|
71
71
|
- `checkbox`
|
|
72
|
+
- `collapsibleCard`
|
|
72
73
|
- `conditional`
|
|
73
74
|
- `dataTable`
|
|
74
75
|
- `dialog`
|
|
@@ -79,6 +80,7 @@ import "@pihanga2/shadcn/cards/dataTable";
|
|
|
79
80
|
- `flexGrid`
|
|
80
81
|
- `form`
|
|
81
82
|
- `framework`
|
|
83
|
+
- `infoCard`
|
|
82
84
|
- `input`
|
|
83
85
|
- `jsonViewer`
|
|
84
86
|
- `list`
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { PiCardProps } from '@pihanga2/core';
|
|
2
|
+
import { CollapsibleCardProps, CollapsibleCardEvents } from './collapsibleCard.types';
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
export declare const CollapsibleCardComponent: (props: PiCardProps<CollapsibleCardProps, CollapsibleCardEvents>) => React.ReactNode;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { getIcon as e } from "../icons.js";
|
|
2
|
+
import { cn as t } from "../../lib/utils.js";
|
|
3
|
+
import * as n from "react";
|
|
4
|
+
import { Card as r } from "@pihanga2/core";
|
|
5
|
+
import { jsx as i, jsxs as a } from "react/jsx-runtime";
|
|
6
|
+
import * as o from "@radix-ui/react-collapsible";
|
|
7
|
+
import { ChevronsUpDown as s } from "lucide-react";
|
|
8
|
+
//#region src/cards/collapsibleCard/collapsibleCard.component.tsx
|
|
9
|
+
var c = {
|
|
10
|
+
h1: "scroll-m-20 text-4xl font-extrabold tracking-tight",
|
|
11
|
+
h2: "scroll-m-20 text-3xl font-semibold tracking-tight",
|
|
12
|
+
h3: "scroll-m-20 text-2xl font-semibold tracking-tight",
|
|
13
|
+
h4: "scroll-m-20 text-xl font-semibold tracking-tight",
|
|
14
|
+
p: "leading-7",
|
|
15
|
+
lead: "text-xl text-muted-foreground",
|
|
16
|
+
large: "text-lg font-semibold",
|
|
17
|
+
small: "text-sm font-medium leading-none",
|
|
18
|
+
muted: "text-sm text-muted-foreground"
|
|
19
|
+
}, l = (l) => {
|
|
20
|
+
let { title: u, titleLevel: d = "h4", titleCard: f, icon: p, contentCard: m, defaultOpen: h = !1, open: g, onOpenChanged: _, className: v, headerClassName: y, contentClassName: b, style: x, cardName: S } = l, [C, w] = n.useState(h), T = g === void 0 ? C : g;
|
|
21
|
+
function E(e) {
|
|
22
|
+
w(e), _?.({ open: e });
|
|
23
|
+
}
|
|
24
|
+
let D = p ? e(p) : /* @__PURE__ */ i(s, { className: "h-4 w-4" });
|
|
25
|
+
return /* @__PURE__ */ a(o.Root, {
|
|
26
|
+
open: T,
|
|
27
|
+
onOpenChange: E,
|
|
28
|
+
className: t("w-full", v),
|
|
29
|
+
style: x,
|
|
30
|
+
"data-pihanga": S,
|
|
31
|
+
children: [/* @__PURE__ */ a("div", {
|
|
32
|
+
className: t("flex items-center justify-between space-x-4 py-2", y),
|
|
33
|
+
children: [f ? /* @__PURE__ */ i(r, {
|
|
34
|
+
cardName: f,
|
|
35
|
+
parentCard: S
|
|
36
|
+
}) : /* @__PURE__ */ i("span", {
|
|
37
|
+
className: c[d],
|
|
38
|
+
children: u
|
|
39
|
+
}), /* @__PURE__ */ i(o.Trigger, {
|
|
40
|
+
asChild: !0,
|
|
41
|
+
children: /* @__PURE__ */ i("button", {
|
|
42
|
+
type: "button",
|
|
43
|
+
className: "shrink-0 rounded-sm p-1 transition-colors hover:bg-accent hover:text-accent-foreground",
|
|
44
|
+
"aria-expanded": T,
|
|
45
|
+
"aria-label": T ? "Collapse" : "Expand",
|
|
46
|
+
children: D
|
|
47
|
+
})
|
|
48
|
+
})]
|
|
49
|
+
}), /* @__PURE__ */ i(o.Content, {
|
|
50
|
+
className: t("overflow-hidden", b),
|
|
51
|
+
children: m && /* @__PURE__ */ i(r, {
|
|
52
|
+
cardName: m,
|
|
53
|
+
parentCard: S
|
|
54
|
+
})
|
|
55
|
+
})]
|
|
56
|
+
});
|
|
57
|
+
};
|
|
58
|
+
//#endregion
|
|
59
|
+
export { l as CollapsibleCardComponent };
|
|
60
|
+
|
|
61
|
+
//# sourceMappingURL=collapsibleCard.component.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"collapsibleCard.component.js","names":[],"sources":["../../../src/cards/collapsibleCard/collapsibleCard.component.tsx"],"sourcesContent":["import * as React from \"react\";\nimport * as CollapsiblePrimitive from \"@radix-ui/react-collapsible\";\nimport {ChevronsUpDown} from \"lucide-react\";\nimport {Card, type PiCardProps} from \"@pihanga2/core\";\nimport {cn} from \"@/lib/utils\";\nimport {getIcon} from \"@/cards/icons\";\nimport type {\n CollapsibleCardProps,\n CollapsibleCardEvents,\n CollapsibleTitleLevel,\n} from \"./collapsibleCard.types\";\n\nconst TITLE_CLASSES: Record<CollapsibleTitleLevel, string> = {\n h1: \"scroll-m-20 text-4xl font-extrabold tracking-tight\",\n h2: \"scroll-m-20 text-3xl font-semibold tracking-tight\",\n h3: \"scroll-m-20 text-2xl font-semibold tracking-tight\",\n h4: \"scroll-m-20 text-xl font-semibold tracking-tight\",\n p: \"leading-7\",\n lead: \"text-xl text-muted-foreground\",\n large: \"text-lg font-semibold\",\n small: \"text-sm font-medium leading-none\",\n muted: \"text-sm text-muted-foreground\",\n};\n\nexport const CollapsibleCardComponent = (\n props: PiCardProps<CollapsibleCardProps, CollapsibleCardEvents>,\n): React.ReactNode => {\n const {\n title,\n titleLevel = \"h4\",\n titleCard,\n icon,\n contentCard,\n defaultOpen = false,\n open,\n onOpenChanged,\n className,\n headerClassName,\n contentClassName,\n style,\n cardName,\n } = props;\n\n const [localOpen, setLocalOpen] = React.useState(defaultOpen);\n const openState = open !== undefined ? open : localOpen;\n\n function handleOpenChange(next: boolean): void {\n setLocalOpen(next);\n onOpenChanged?.({open: next});\n }\n\n const triggerIcon = icon ? (\n getIcon(icon)\n ) : (\n <ChevronsUpDown className=\"h-4 w-4\" />\n );\n\n return (\n <CollapsiblePrimitive.Root\n open={openState}\n onOpenChange={handleOpenChange}\n className={cn(\"w-full\", className)}\n style={style}\n data-pihanga={cardName}\n >\n <div\n className={cn(\n \"flex items-center justify-between space-x-4 py-2\",\n headerClassName,\n )}\n >\n {titleCard ? (\n <Card cardName={titleCard} parentCard={cardName} />\n ) : (\n <span className={TITLE_CLASSES[titleLevel]}>{title}</span>\n )}\n <CollapsiblePrimitive.Trigger asChild>\n <button\n type=\"button\"\n className=\"shrink-0 rounded-sm p-1 transition-colors hover:bg-accent hover:text-accent-foreground\"\n aria-expanded={openState}\n aria-label={openState ? \"Collapse\" : \"Expand\"}\n >\n {triggerIcon}\n </button>\n </CollapsiblePrimitive.Trigger>\n </div>\n <CollapsiblePrimitive.Content\n className={cn(\"overflow-hidden\", contentClassName)}\n >\n {contentCard && <Card cardName={contentCard} parentCard={cardName} />}\n </CollapsiblePrimitive.Content>\n </CollapsiblePrimitive.Root>\n );\n};\n"],"mappings":";;;;;;;;AAYA,IAAM,IAAuD;CAC3D,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,GAAG;CACH,MAAM;CACN,OAAO;CACP,OAAO;CACP,OAAO;AACT,GAEa,KACX,MACoB;CACpB,IAAM,EACJ,UACA,gBAAa,MACb,cACA,SACA,gBACA,iBAAc,IACd,SACA,kBACA,cACA,oBACA,qBACA,UACA,gBACE,GAEE,CAAC,GAAW,KAAgB,EAAM,SAAS,CAAW,GACtD,IAAY,MAAS,KAAA,IAAmB,IAAP;CAEvC,SAAS,EAAiB,GAAqB;EAE7C,AADA,EAAa,CAAI,GACjB,IAAgB,EAAC,MAAM,EAAI,CAAC;CAC9B;CAEA,IAAM,IAAc,IAClB,EAAQ,CAAI,IAEZ,kBAAC,GAAD,EAAgB,WAAU,UAAW,CAAA;CAGvC,OACE,kBAAC,EAAqB,MAAtB;EACE,MAAM;EACN,cAAc;EACd,WAAW,EAAG,UAAU,CAAS;EAC1B;EACP,gBAAc;YALhB,CAOE,kBAAC,OAAD;GACE,WAAW,EACT,oDACA,CACF;aAJF,CAMG,IACC,kBAAC,GAAD;IAAM,UAAU;IAAW,YAAY;GAAW,CAAA,IAElD,kBAAC,QAAD;IAAM,WAAW,EAAc;cAAc;GAAY,CAAA,GAE3D,kBAAC,EAAqB,SAAtB;IAA8B,SAAA;cAC5B,kBAAC,UAAD;KACE,MAAK;KACL,WAAU;KACV,iBAAe;KACf,cAAY,IAAY,aAAa;eAEpC;IACK,CAAA;GACoB,CAAA,CAC3B;MACL,kBAAC,EAAqB,SAAtB;GACE,WAAW,EAAG,mBAAmB,CAAgB;aAEhD,KAAe,kBAAC,GAAD;IAAM,UAAU;IAAa,YAAY;GAAW,CAAA;EACxC,CAAA,CACL;;AAE/B"}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { PiCardRef } from '@pihanga2/core';
|
|
2
|
+
import { default as React } from 'react';
|
|
3
|
+
export declare const COLLAPSIBLE_CARD = "shad/collapsible";
|
|
4
|
+
export declare const COLLAPSIBLE_CARD_ACTION: {
|
|
5
|
+
OPENCHANGED: string;
|
|
6
|
+
};
|
|
7
|
+
export type CollapsibleCardOpenChangedEvent = {
|
|
8
|
+
open: boolean;
|
|
9
|
+
};
|
|
10
|
+
export declare const onCollapsibleCardOpenChanged: <S extends import('@pihanga2/core').ReduxState>(register: import('@pihanga2/core').PiRegister, f: import('@pihanga2/core').ReduceF<S, import('@pihanga2/core').ReduxAction & {
|
|
11
|
+
cardID: string;
|
|
12
|
+
} & CollapsibleCardOpenChangedEvent>) => void;
|
|
13
|
+
export type CollapsibleCardEvents = {
|
|
14
|
+
onOpenChanged: CollapsibleCardOpenChangedEvent;
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* Subset of shadcn/ui typography levels supported for the built-in title slot.
|
|
18
|
+
*/
|
|
19
|
+
export type CollapsibleTitleLevel = "h1" | "h2" | "h3" | "h4" | "p" | "lead" | "large" | "small" | "muted";
|
|
20
|
+
export type CollapsibleCardProps = {
|
|
21
|
+
/**
|
|
22
|
+
* Plain-text title rendered in the trigger row using the built-in
|
|
23
|
+
* Typography styles. Use `titleCard` instead to supply a full Pihanga card.
|
|
24
|
+
*/
|
|
25
|
+
title?: string;
|
|
26
|
+
/**
|
|
27
|
+
* Typography level applied to `title`.
|
|
28
|
+
* @default "h4"
|
|
29
|
+
*/
|
|
30
|
+
titleLevel?: CollapsibleTitleLevel;
|
|
31
|
+
/**
|
|
32
|
+
* Alternative to `title` — any Pihanga card reference rendered as the
|
|
33
|
+
* header (e.g. a `shad/typography` or `shad/badge` card).
|
|
34
|
+
* When provided, `title` and `titleLevel` are ignored.
|
|
35
|
+
*/
|
|
36
|
+
titleCard?: PiCardRef;
|
|
37
|
+
/**
|
|
38
|
+
* Icon name from the Pihanga icon registry, shown inside the toggle button.
|
|
39
|
+
* Falls back to the built-in `ChevronsUpDown` icon when omitted.
|
|
40
|
+
*
|
|
41
|
+
* @example
|
|
42
|
+
* import {registerIcon} from "@/cards/icons";
|
|
43
|
+
* import {ChevronDown} from "lucide-react";
|
|
44
|
+
* registerIcon("chevron-down", ChevronDown);
|
|
45
|
+
* CollapsibleCard({ icon: "chevron-down", ... });
|
|
46
|
+
*/
|
|
47
|
+
icon?: string;
|
|
48
|
+
/**
|
|
49
|
+
* Pihanga card reference rendered inside the collapsible body.
|
|
50
|
+
*/
|
|
51
|
+
contentCard?: PiCardRef;
|
|
52
|
+
/**
|
|
53
|
+
* Whether the panel is open on first render (uncontrolled mode).
|
|
54
|
+
* @default false
|
|
55
|
+
*/
|
|
56
|
+
defaultOpen?: boolean;
|
|
57
|
+
/**
|
|
58
|
+
* Controlled open state. When provided, the component delegates all open
|
|
59
|
+
* state management to the consumer — update this via `onOpenChanged`.
|
|
60
|
+
*/
|
|
61
|
+
open?: boolean;
|
|
62
|
+
/** CSS classes applied to the root `<div>`. */
|
|
63
|
+
className?: string;
|
|
64
|
+
/** CSS classes applied to the trigger row (title + toggle button). */
|
|
65
|
+
headerClassName?: string;
|
|
66
|
+
/** CSS classes applied to the collapsible content wrapper `<div>`. */
|
|
67
|
+
contentClassName?: string;
|
|
68
|
+
/** Inline styles on the root element. */
|
|
69
|
+
style?: React.CSSProperties;
|
|
70
|
+
};
|
|
71
|
+
/**
|
|
72
|
+
* Factory function for declaring a `shad/collapsible` card instance.
|
|
73
|
+
*
|
|
74
|
+
* ```ts
|
|
75
|
+
* import {registerCard} from "@pihanga2/core";
|
|
76
|
+
* import {CollapsibleCard} from "@/cards/collapsibleCard";
|
|
77
|
+
* import {Typography} from "@/cards/typography";
|
|
78
|
+
*
|
|
79
|
+
* registerCard("myApp/details", CollapsibleCard({
|
|
80
|
+
* title: "Advanced options",
|
|
81
|
+
* titleLevel: "h4",
|
|
82
|
+
* contentCard: "myApp/detailsBody",
|
|
83
|
+
* }));
|
|
84
|
+
*
|
|
85
|
+
* registerCard("myApp/detailsBody", Typography({
|
|
86
|
+
* text: "Hidden content revealed when expanded.",
|
|
87
|
+
* level: "p",
|
|
88
|
+
* }));
|
|
89
|
+
* ```
|
|
90
|
+
*/
|
|
91
|
+
export declare const CollapsibleCard: <S extends import('@pihanga2/core').ReduxState>(p: import('@pihanga2/core').PiMapProps<CollapsibleCardProps, S, CollapsibleCardEvents>) => import('@pihanga2/core').PiCardDef;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { createCardDeclaration as e, createOnAction as t, registerActions as n } from "@pihanga2/core";
|
|
2
|
+
//#region src/cards/collapsibleCard/collapsibleCard.types.ts
|
|
3
|
+
var r = "shad/collapsible", i = n(r, ["openChanged"]), a = t(i.OPENCHANGED), o = e(r);
|
|
4
|
+
//#endregion
|
|
5
|
+
export { r as COLLAPSIBLE_CARD, i as COLLAPSIBLE_CARD_ACTION, o as CollapsibleCard, a as onCollapsibleCardOpenChanged };
|
|
6
|
+
|
|
7
|
+
//# sourceMappingURL=collapsibleCard.types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"collapsibleCard.types.js","names":[],"sources":["../../../src/cards/collapsibleCard/collapsibleCard.types.ts"],"sourcesContent":["import {\n createCardDeclaration,\n createOnAction,\n registerActions,\n type PiCardRef,\n} from \"@pihanga2/core\";\nimport type React from \"react\";\n\nexport const COLLAPSIBLE_CARD = \"shad/collapsible\";\n\nexport const COLLAPSIBLE_CARD_ACTION = registerActions(COLLAPSIBLE_CARD, [\n \"openChanged\",\n]);\n\nexport type CollapsibleCardOpenChangedEvent = {open: boolean};\n\nexport const onCollapsibleCardOpenChanged =\n createOnAction<CollapsibleCardOpenChangedEvent>(\n COLLAPSIBLE_CARD_ACTION.OPENCHANGED,\n );\n\nexport type CollapsibleCardEvents = {\n onOpenChanged: CollapsibleCardOpenChangedEvent;\n};\n\n/**\n * Subset of shadcn/ui typography levels supported for the built-in title slot.\n */\nexport type CollapsibleTitleLevel =\n | \"h1\"\n | \"h2\"\n | \"h3\"\n | \"h4\"\n | \"p\"\n | \"lead\"\n | \"large\"\n | \"small\"\n | \"muted\";\n\nexport type CollapsibleCardProps = {\n /**\n * Plain-text title rendered in the trigger row using the built-in\n * Typography styles. Use `titleCard` instead to supply a full Pihanga card.\n */\n title?: string;\n\n /**\n * Typography level applied to `title`.\n * @default \"h4\"\n */\n titleLevel?: CollapsibleTitleLevel;\n\n /**\n * Alternative to `title` — any Pihanga card reference rendered as the\n * header (e.g. a `shad/typography` or `shad/badge` card).\n * When provided, `title` and `titleLevel` are ignored.\n */\n titleCard?: PiCardRef;\n\n /**\n * Icon name from the Pihanga icon registry, shown inside the toggle button.\n * Falls back to the built-in `ChevronsUpDown` icon when omitted.\n *\n * @example\n * import {registerIcon} from \"@/cards/icons\";\n * import {ChevronDown} from \"lucide-react\";\n * registerIcon(\"chevron-down\", ChevronDown);\n * CollapsibleCard({ icon: \"chevron-down\", ... });\n */\n icon?: string;\n\n /**\n * Pihanga card reference rendered inside the collapsible body.\n */\n contentCard?: PiCardRef;\n\n /**\n * Whether the panel is open on first render (uncontrolled mode).\n * @default false\n */\n defaultOpen?: boolean;\n\n /**\n * Controlled open state. When provided, the component delegates all open\n * state management to the consumer — update this via `onOpenChanged`.\n */\n open?: boolean;\n\n /** CSS classes applied to the root `<div>`. */\n className?: string;\n\n /** CSS classes applied to the trigger row (title + toggle button). */\n headerClassName?: string;\n\n /** CSS classes applied to the collapsible content wrapper `<div>`. */\n contentClassName?: string;\n\n /** Inline styles on the root element. */\n style?: React.CSSProperties;\n};\n\n/**\n * Factory function for declaring a `shad/collapsible` card instance.\n *\n * ```ts\n * import {registerCard} from \"@pihanga2/core\";\n * import {CollapsibleCard} from \"@/cards/collapsibleCard\";\n * import {Typography} from \"@/cards/typography\";\n *\n * registerCard(\"myApp/details\", CollapsibleCard({\n * title: \"Advanced options\",\n * titleLevel: \"h4\",\n * contentCard: \"myApp/detailsBody\",\n * }));\n *\n * registerCard(\"myApp/detailsBody\", Typography({\n * text: \"Hidden content revealed when expanded.\",\n * level: \"p\",\n * }));\n * ```\n */\nexport const CollapsibleCard = createCardDeclaration<\n CollapsibleCardProps,\n CollapsibleCardEvents\n>(COLLAPSIBLE_CARD);\n"],"mappings":";;AAQA,IAAa,IAAmB,oBAEnB,IAA0B,EAAgB,GAAkB,CACvE,aACF,CAAC,GAIY,IACX,EACE,EAAwB,WAC1B,GAsGW,IAAkB,EAG7B,CAAgB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './collapsibleCard.types';
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { CollapsibleCardComponent as e } from "./collapsibleCard.component.js";
|
|
2
|
+
import { COLLAPSIBLE_CARD as t, COLLAPSIBLE_CARD_ACTION as n, CollapsibleCard as r, onCollapsibleCardOpenChanged as i } from "./collapsibleCard.types.js";
|
|
3
|
+
import { actionTypesToEvents as a, registerCardComponent as o } from "@pihanga2/core";
|
|
4
|
+
//#region src/cards/collapsibleCard/index.tsx
|
|
5
|
+
o({
|
|
6
|
+
name: t,
|
|
7
|
+
component: e,
|
|
8
|
+
events: a(n)
|
|
9
|
+
});
|
|
10
|
+
//#endregion
|
|
11
|
+
export { t as COLLAPSIBLE_CARD, n as COLLAPSIBLE_CARD_ACTION, r as CollapsibleCard, i as onCollapsibleCardOpenChanged };
|
|
12
|
+
|
|
13
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../../src/cards/collapsibleCard/index.tsx"],"sourcesContent":["import {actionTypesToEvents, registerCardComponent} from \"@pihanga2/core\";\n\nimport {CollapsibleCardComponent} from \"./collapsibleCard.component\";\nimport {\n COLLAPSIBLE_CARD,\n COLLAPSIBLE_CARD_ACTION,\n} from \"./collapsibleCard.types\";\n\nexport * from \"./collapsibleCard.types\";\n\nregisterCardComponent({\n name: COLLAPSIBLE_CARD,\n component: CollapsibleCardComponent,\n events: actionTypesToEvents(COLLAPSIBLE_CARD_ACTION),\n});\n"],"mappings":";;;;AAUA,EAAsB;CACpB,MAAM;CACN,WAAW;CACX,QAAQ,EAAoB,CAAuB;AACrD,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './collapsibleCard/index';
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { PiCardRef } from '@pihanga2/core';
|
|
2
|
+
import { default as React } from 'react';
|
|
3
|
+
export declare const EMPTY_CARD = "empty-card";
|
|
4
|
+
export type EmptyCardProps = {
|
|
5
|
+
/**
|
|
6
|
+
* Icon name from the pihanga icon registry.
|
|
7
|
+
* When provided, renders an `EmptyMedia` slot with `variant="icon"`.
|
|
8
|
+
*/
|
|
9
|
+
icon?: string;
|
|
10
|
+
/**
|
|
11
|
+
* Pihanga card reference rendered inside `EmptyContent`.
|
|
12
|
+
* Use this to show a call-to-action button, form, or any other card.
|
|
13
|
+
*/
|
|
14
|
+
content?: PiCardRef;
|
|
15
|
+
/** Additional Tailwind / CSS classes forwarded to the root `Empty` element. */
|
|
16
|
+
className?: string;
|
|
17
|
+
/** Inline styles forwarded to the root `Empty` element. */
|
|
18
|
+
style?: React.CSSProperties;
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* Factory function for declaring an `empty-card` instance.
|
|
22
|
+
*
|
|
23
|
+
* ```ts
|
|
24
|
+
* import {registerCard} from "@pihanga2/core";
|
|
25
|
+
* import {EmptyCard} from "@/cards/emptyCard";
|
|
26
|
+
* import {Button} from "@/cards/button";
|
|
27
|
+
*
|
|
28
|
+
* registerCard("myApp/noResults", EmptyCard({
|
|
29
|
+
* icon: "search",
|
|
30
|
+
* content: "myApp/createButton",
|
|
31
|
+
* }));
|
|
32
|
+
*
|
|
33
|
+
* registerCard("myApp/createButton", Button({label: "Create new"}));
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
36
|
+
export declare const EmptyCard: <S extends import('@pihanga2/core').ReduxState>(p: import('@pihanga2/core').PiMapProps<EmptyCardProps, S, {}>) => import('@pihanga2/core').PiCardDef;
|
|
@@ -1,7 +1 @@
|
|
|
1
|
-
|
|
2
|
-
import * as React from "react";
|
|
3
|
-
export declare const EmptyCard: <S extends import('@pihanga2/core').ReduxState>(p: import('@pihanga2/core').PiMapProps<EmptyProps, S, {}>) => import('@pihanga2/core').PiCardDef;
|
|
4
|
-
export type EmptyProps = {
|
|
5
|
-
style?: React.CSSProperties;
|
|
6
|
-
};
|
|
7
|
-
export declare const EmptyComponent: (props: PiCardProps<EmptyProps>) => React.ReactNode;
|
|
1
|
+
export * from './emptyCard.types';
|
package/cards/emptyCard.d.ts
CHANGED
|
@@ -1,7 +1 @@
|
|
|
1
|
-
|
|
2
|
-
import * as React from "react";
|
|
3
|
-
export declare const EmptyCard: <S extends import('@pihanga2/core').ReduxState>(p: import('@pihanga2/core').PiMapProps<EmptyProps, S, {}>) => import('@pihanga2/core').PiCardDef;
|
|
4
|
-
export type EmptyProps = {
|
|
5
|
-
style?: React.CSSProperties;
|
|
6
|
-
};
|
|
7
|
-
export declare const EmptyComponent: (props: PiCardProps<EmptyProps>) => React.ReactNode;
|
|
1
|
+
export * from './emptyCard/index';
|
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
import { PiCardRef } from '@pihanga2/core';
|
|
2
1
|
export declare const FLEX_GRID_CARD = "flex_grid";
|
|
3
2
|
export declare const FlexGrid: <S extends import('@pihanga2/core').ReduxState>(p: import('@pihanga2/core').PiMapProps<FlexGridProps, S, {}>) => import('@pihanga2/core').PiCardDef;
|
|
4
3
|
export type FlexGridProps = {
|
|
5
4
|
cards: {
|
|
6
|
-
[name: string]:
|
|
5
|
+
[name: string]: string;
|
|
7
6
|
};
|
|
8
7
|
template: TemplateT;
|
|
9
8
|
height?: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"flexGrid.types.js","names":[],"sources":["../../../src/cards/flexGrid/flexGrid.types.ts"],"sourcesContent":["import {createCardDeclaration
|
|
1
|
+
{"version":3,"file":"flexGrid.types.js","names":[],"sources":["../../../src/cards/flexGrid/flexGrid.types.ts"],"sourcesContent":["import {createCardDeclaration} from \"@pihanga2/core\";\n\nexport const FLEX_GRID_CARD = \"flex_grid\";\nexport const FlexGrid = createCardDeclaration<FlexGridProps>(FLEX_GRID_CARD);\n\nexport type FlexGridProps = {\n cards: {[name: string]: string}; // anonymous cards are not supported\n template: TemplateT;\n height?: string;\n margin?: string;\n overflow?: string;\n\n style?: {\n root?: React.CSSProperties;\n item?: React.CSSProperties;\n };\n className?: string;\n};\n\n// body {\n// display: grid;\n// grid-template-areas:\n// \"header header header\"\n// \"nav article ads\"\n// \"footer footer footer\";\n// grid-template-rows: 60px 1fr 60px;\n// grid-template-columns: 20% 1fr 15%;\n// grid-gap: 10px;\n// height: 100vh;\n// margin: 0;\n// }\n\n// https://css-tricks.com/snippets/css/complete-guide-grid/\nexport type TemplateT = {\n area?: string[][]; // name of card dict\n rows?: string[]; // grid-template-rows (e.g [\"min-content\", \"1fr\", \"min-content\"])\n columns?: string[]; // grid-template-cols (e.g. [\"1fr\", \"50px\", \"1fr\", \"1fr\"])\n gap?: string;\n};\n"],"mappings":";;AAEA,IAAa,IAAiB,aACjB,IAAW,EAAqC,CAAc"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { GraphinAfterLayoutContext, GraphinNodeEventContext } from './graphin.types';
|
|
2
2
|
export type GraphinEventDispatcherProps = {
|
|
3
|
+
cardName: string;
|
|
3
4
|
onNodeHovered?: (ctx: GraphinNodeEventContext) => void;
|
|
4
5
|
onNodeHoverEnd?: (ctx: GraphinNodeEventContext) => void;
|
|
5
6
|
onNodeClicked?: (ctx: GraphinNodeEventContext) => void;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './infoCard.types';
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { InfoCardComponent as e } from "./infoCard.component.js";
|
|
2
|
+
import { INFO_CARD as t, InfoCard as n } from "./infoCard.types.js";
|
|
3
|
+
import { registerCardComponent as r } from "@pihanga2/core";
|
|
4
|
+
//#region src/cards/infoCard/index.tsx
|
|
5
|
+
r({
|
|
6
|
+
name: t,
|
|
7
|
+
component: e
|
|
8
|
+
});
|
|
9
|
+
//#endregion
|
|
10
|
+
export { t as INFO_CARD, n as InfoCard };
|
|
11
|
+
|
|
12
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../../src/cards/infoCard/index.tsx"],"sourcesContent":["import {registerCardComponent} from \"@pihanga2/core\";\n\nimport {InfoCardComponent} from \"./infoCard.component\";\nimport {INFO_CARD} from \"./infoCard.types\";\n\nexport * from \"./infoCard.types\";\n\nregisterCardComponent({\n name: INFO_CARD,\n component: InfoCardComponent,\n});\n"],"mappings":";;;;AAOA,EAAsB;CACpB,MAAM;CACN,WAAW;AACb,CAAC"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { cn as e } from "../../lib/utils.js";
|
|
2
|
+
import { Card as t, CardAction as n, CardContent as r, CardDescription as i, CardFooter as a, CardTitle as o } from "../../components/ui/card.js";
|
|
3
|
+
import "react";
|
|
4
|
+
import { Card as s } from "@pihanga2/core";
|
|
5
|
+
import { jsx as c, jsxs as l } from "react/jsx-runtime";
|
|
6
|
+
//#region src/cards/infoCard/infoCard.component.tsx
|
|
7
|
+
var u = (u) => {
|
|
8
|
+
let { title: d, description: f, actionCard: p, contentCard: m, footerCard: h, className: g, headerClassName: _, titleClassName: v, descriptionClassName: y, actionClassName: b, contentClassName: x, footerClassName: S, style: C, cardName: w } = u, T = d || f || p;
|
|
9
|
+
return /* @__PURE__ */ l(t, {
|
|
10
|
+
className: e("min-w-max", g),
|
|
11
|
+
style: C,
|
|
12
|
+
"data-pihanga": w,
|
|
13
|
+
children: [
|
|
14
|
+
T && /* @__PURE__ */ l("div", {
|
|
15
|
+
"data-slot": "card-header",
|
|
16
|
+
className: e("grid auto-rows-min grid-rows-[auto_auto] items-start gap-2 px-6", "has-data-[slot=card-action]:grid-cols-[1fr_auto] [.border-b]:pb-6", _),
|
|
17
|
+
children: [
|
|
18
|
+
d && /* @__PURE__ */ c(o, {
|
|
19
|
+
className: v,
|
|
20
|
+
children: d
|
|
21
|
+
}),
|
|
22
|
+
f && /* @__PURE__ */ c(i, {
|
|
23
|
+
className: y,
|
|
24
|
+
children: f
|
|
25
|
+
}),
|
|
26
|
+
p && /* @__PURE__ */ c(n, {
|
|
27
|
+
className: b,
|
|
28
|
+
children: /* @__PURE__ */ c(s, {
|
|
29
|
+
cardName: p,
|
|
30
|
+
parentCard: w
|
|
31
|
+
})
|
|
32
|
+
})
|
|
33
|
+
]
|
|
34
|
+
}),
|
|
35
|
+
m && /* @__PURE__ */ c(r, {
|
|
36
|
+
className: x,
|
|
37
|
+
children: /* @__PURE__ */ c(s, {
|
|
38
|
+
cardName: m,
|
|
39
|
+
parentCard: w
|
|
40
|
+
})
|
|
41
|
+
}),
|
|
42
|
+
h && /* @__PURE__ */ c(a, {
|
|
43
|
+
className: S,
|
|
44
|
+
children: /* @__PURE__ */ c(s, {
|
|
45
|
+
cardName: h,
|
|
46
|
+
parentCard: w
|
|
47
|
+
})
|
|
48
|
+
})
|
|
49
|
+
]
|
|
50
|
+
});
|
|
51
|
+
};
|
|
52
|
+
//#endregion
|
|
53
|
+
export { u as InfoCardComponent };
|
|
54
|
+
|
|
55
|
+
//# sourceMappingURL=infoCard.component.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"infoCard.component.js","names":[],"sources":["../../../src/cards/infoCard/infoCard.component.tsx"],"sourcesContent":["import * as React from \"react\";\nimport {Card as PiCard, type PiCardProps} from \"@pihanga2/core\";\nimport {cn} from \"@/lib/utils\";\nimport {\n Card,\n CardTitle,\n CardDescription,\n CardAction,\n CardContent,\n CardFooter,\n} from \"@/components/ui/card\";\nimport type {InfoCardProps} from \"./infoCard.types\";\n\nexport const InfoCardComponent = (\n props: PiCardProps<InfoCardProps>,\n): React.ReactNode => {\n const {\n title,\n description,\n actionCard,\n contentCard,\n footerCard,\n className,\n headerClassName,\n titleClassName,\n descriptionClassName,\n actionClassName,\n contentClassName,\n footerClassName,\n style,\n cardName,\n } = props;\n\n const hasHeader = title || description || actionCard;\n\n return (\n <Card\n className={cn(\"min-w-max\", className)}\n style={style}\n data-pihanga={cardName}\n >\n {hasHeader && (\n // Plain <div> instead of shadcn <CardHeader> — avoids @container/card-header\n // (container-type:inline-size) which zeroes out intrinsic inline size and\n // breaks min-w-max on the parent Card. Visual classes are identical.\n <div\n data-slot=\"card-header\"\n className={cn(\n \"grid auto-rows-min grid-rows-[auto_auto] items-start gap-2 px-6\",\n \"has-data-[slot=card-action]:grid-cols-[1fr_auto] [.border-b]:pb-6\",\n headerClassName,\n )}\n >\n {title && <CardTitle className={titleClassName}>{title}</CardTitle>}\n {description && (\n <CardDescription className={descriptionClassName}>\n {description}\n </CardDescription>\n )}\n {actionCard && (\n <CardAction className={actionClassName}>\n <PiCard cardName={actionCard} parentCard={cardName} />\n </CardAction>\n )}\n </div>\n )}\n {contentCard && (\n <CardContent className={contentClassName}>\n <PiCard cardName={contentCard} parentCard={cardName} />\n </CardContent>\n )}\n {footerCard && (\n <CardFooter className={footerClassName}>\n <PiCard cardName={footerCard} parentCard={cardName} />\n </CardFooter>\n )}\n </Card>\n );\n};\n"],"mappings":";;;;;;AAaA,IAAa,KACX,MACoB;CACpB,IAAM,EACJ,UACA,gBACA,eACA,gBACA,eACA,cACA,oBACA,mBACA,yBACA,oBACA,qBACA,oBACA,UACA,gBACE,GAEE,IAAY,KAAS,KAAe;CAE1C,OACE,kBAAC,GAAD;EACE,WAAW,EAAG,aAAa,CAAS;EAC7B;EACP,gBAAc;YAHhB;GAKG,KAIC,kBAAC,OAAD;IACE,aAAU;IACV,WAAW,EACT,mEACA,qEACA,CACF;cANF;KAQG,KAAS,kBAAC,GAAD;MAAW,WAAW;gBAAiB;KAAiB,CAAA;KACjE,KACC,kBAAC,GAAD;MAAiB,WAAW;gBACzB;KACc,CAAA;KAElB,KACC,kBAAC,GAAD;MAAY,WAAW;gBACrB,kBAAC,GAAD;OAAQ,UAAU;OAAY,YAAY;MAAW,CAAA;KAC3C,CAAA;IAEX;;GAEN,KACC,kBAAC,GAAD;IAAa,WAAW;cACtB,kBAAC,GAAD;KAAQ,UAAU;KAAa,YAAY;IAAW,CAAA;GAC3C,CAAA;GAEd,KACC,kBAAC,GAAD;IAAY,WAAW;cACrB,kBAAC,GAAD;KAAQ,UAAU;KAAY,YAAY;IAAW,CAAA;GAC3C,CAAA;EAEV;;AAEV"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { PiCardRef } from '@pihanga2/core';
|
|
2
|
+
import { default as React } from 'react';
|
|
3
|
+
export declare const INFO_CARD = "shad/info-card";
|
|
4
|
+
export type InfoCardProps = {
|
|
5
|
+
/**
|
|
6
|
+
* Text rendered inside `CardTitle`.
|
|
7
|
+
* Leave unset to omit the title element entirely.
|
|
8
|
+
*/
|
|
9
|
+
title?: string;
|
|
10
|
+
/**
|
|
11
|
+
* Text rendered inside `CardDescription`.
|
|
12
|
+
* Leave unset to omit the description element entirely.
|
|
13
|
+
*/
|
|
14
|
+
description?: string;
|
|
15
|
+
/**
|
|
16
|
+
* Pihanga card reference rendered inside the `CardAction` slot.
|
|
17
|
+
* Positioned at the top-right of the header (e.g. a button, badge, or icon).
|
|
18
|
+
*/
|
|
19
|
+
actionCard?: PiCardRef;
|
|
20
|
+
/**
|
|
21
|
+
* Pihanga card reference rendered inside `CardContent`.
|
|
22
|
+
* Main body of the card — use any layout or display card.
|
|
23
|
+
*/
|
|
24
|
+
contentCard?: PiCardRef;
|
|
25
|
+
/**
|
|
26
|
+
* Pihanga card reference rendered inside `CardFooter`.
|
|
27
|
+
* Typically a row of actions or a status line.
|
|
28
|
+
*/
|
|
29
|
+
footerCard?: PiCardRef;
|
|
30
|
+
/** Extra CSS classes applied to the root `<div data-slot="card">`. */
|
|
31
|
+
className?: string;
|
|
32
|
+
/** Extra CSS classes applied to `<div data-slot="card-header">`. */
|
|
33
|
+
headerClassName?: string;
|
|
34
|
+
/** Extra CSS classes applied to `<div data-slot="card-title">`. */
|
|
35
|
+
titleClassName?: string;
|
|
36
|
+
/** Extra CSS classes applied to `<div data-slot="card-description">`. */
|
|
37
|
+
descriptionClassName?: string;
|
|
38
|
+
/** Extra CSS classes applied to `<div data-slot="card-action">`. */
|
|
39
|
+
actionClassName?: string;
|
|
40
|
+
/** Extra CSS classes applied to `<div data-slot="card-content">`. */
|
|
41
|
+
contentClassName?: string;
|
|
42
|
+
/** Extra CSS classes applied to `<div data-slot="card-footer">`. */
|
|
43
|
+
footerClassName?: string;
|
|
44
|
+
/** Inline styles applied to the root card element. */
|
|
45
|
+
style?: React.CSSProperties;
|
|
46
|
+
};
|
|
47
|
+
/**
|
|
48
|
+
* Factory function for declaring a `shad/info-card` instance.
|
|
49
|
+
*
|
|
50
|
+
* ```ts
|
|
51
|
+
* import {registerCard} from "@pihanga2/core";
|
|
52
|
+
* import {InfoCard} from "@/cards/infoCard";
|
|
53
|
+
* import {Typography} from "@/cards/typography";
|
|
54
|
+
* import {Button} from "@/cards/button";
|
|
55
|
+
*
|
|
56
|
+
* registerCard("myApp/userCard", InfoCard({
|
|
57
|
+
* title: "John Doe",
|
|
58
|
+
* description: "Software Engineer",
|
|
59
|
+
* actionCard: "myApp/editButton",
|
|
60
|
+
* contentCard: "myApp/userDetails",
|
|
61
|
+
* footerCard: "myApp/userActions",
|
|
62
|
+
* }));
|
|
63
|
+
* ```
|
|
64
|
+
*/
|
|
65
|
+
export declare const InfoCard: <S extends import('@pihanga2/core').ReduxState>(p: import('@pihanga2/core').PiMapProps<InfoCardProps, S, {}>) => import('@pihanga2/core').PiCardDef;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"infoCard.types.js","names":[],"sources":["../../../src/cards/infoCard/infoCard.types.ts"],"sourcesContent":["import {createCardDeclaration, type PiCardRef} from \"@pihanga2/core\";\nimport type React from \"react\";\n\nexport const INFO_CARD = \"shad/info-card\";\n\nexport type InfoCardProps = {\n /**\n * Text rendered inside `CardTitle`.\n * Leave unset to omit the title element entirely.\n */\n title?: string;\n\n /**\n * Text rendered inside `CardDescription`.\n * Leave unset to omit the description element entirely.\n */\n description?: string;\n\n /**\n * Pihanga card reference rendered inside the `CardAction` slot.\n * Positioned at the top-right of the header (e.g. a button, badge, or icon).\n */\n actionCard?: PiCardRef;\n\n /**\n * Pihanga card reference rendered inside `CardContent`.\n * Main body of the card — use any layout or display card.\n */\n contentCard?: PiCardRef;\n\n /**\n * Pihanga card reference rendered inside `CardFooter`.\n * Typically a row of actions or a status line.\n */\n footerCard?: PiCardRef;\n\n // ── Per-element className overrides ────────────────────────────────────────\n\n /** Extra CSS classes applied to the root `<div data-slot=\"card\">`. */\n className?: string;\n\n /** Extra CSS classes applied to `<div data-slot=\"card-header\">`. */\n headerClassName?: string;\n\n /** Extra CSS classes applied to `<div data-slot=\"card-title\">`. */\n titleClassName?: string;\n\n /** Extra CSS classes applied to `<div data-slot=\"card-description\">`. */\n descriptionClassName?: string;\n\n /** Extra CSS classes applied to `<div data-slot=\"card-action\">`. */\n actionClassName?: string;\n\n /** Extra CSS classes applied to `<div data-slot=\"card-content\">`. */\n contentClassName?: string;\n\n /** Extra CSS classes applied to `<div data-slot=\"card-footer\">`. */\n footerClassName?: string;\n\n /** Inline styles applied to the root card element. */\n style?: React.CSSProperties;\n};\n\n/**\n * Factory function for declaring a `shad/info-card` instance.\n *\n * ```ts\n * import {registerCard} from \"@pihanga2/core\";\n * import {InfoCard} from \"@/cards/infoCard\";\n * import {Typography} from \"@/cards/typography\";\n * import {Button} from \"@/cards/button\";\n *\n * registerCard(\"myApp/userCard\", InfoCard({\n * title: \"John Doe\",\n * description: \"Software Engineer\",\n * actionCard: \"myApp/editButton\",\n * contentCard: \"myApp/userDetails\",\n * footerCard: \"myApp/userActions\",\n * }));\n * ```\n */\nexport const InfoCard = createCardDeclaration<InfoCardProps>(INFO_CARD);\n"],"mappings":";;AAGA,IAAa,IAAY,kBA8EZ,IAAW,EAAqC,CAAS"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './infoCard/index';
|
|
@@ -5,7 +5,7 @@ import "@pihanga2/core";
|
|
|
5
5
|
import { jsx as i } from "react/jsx-runtime";
|
|
6
6
|
//#region src/cards/toggleGroup/toggleGroup.component.tsx
|
|
7
7
|
var a = (a) => {
|
|
8
|
-
let { name: o, items: s, type: c = "single", value: l, selfManaged: u = !1, variant: d = "default", size: f = "default", spacing: p = 0, disabled: m, className: h, cardName: g, onChanged: _ } = a, v = e(), y = v.isInForm && !!o, b = c === "multiple" ? Array.isArray(l) ? l : l == null ? [] : [String(l)] : typeof l == "string" ? l : "", [x, S] = r.useState(b), C = y ? v.formData[o] : void 0, w = y ? c === "multiple" ? Array.isArray(C) ? C : C == null ? [] : [String(C)] : C == null ? "" : String(C) : u ? x : l ?? (c === "multiple" ? [] : "");
|
|
8
|
+
let { name: o, items: s = [], type: c = "single", value: l, selfManaged: u = !1, variant: d = "default", size: f = "default", spacing: p = 0, disabled: m, className: h, cardName: g, onChanged: _ } = a, v = e(), y = v.isInForm && !!o, b = c === "multiple" ? Array.isArray(l) ? l : l == null ? [] : [String(l)] : typeof l == "string" ? l : "", [x, S] = r.useState(b), C = y ? v.formData[o] : void 0, w = y ? c === "multiple" ? Array.isArray(C) ? C : C == null ? [] : [String(C)] : C == null ? "" : String(C) : u ? x : l ?? (c === "multiple" ? [] : "");
|
|
9
9
|
function T(e) {
|
|
10
10
|
y ? v.handleChange(o, e) : (u && S(e), _({
|
|
11
11
|
name: o ?? g,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"toggleGroup.component.js","names":[],"sources":["../../../src/cards/toggleGroup/toggleGroup.component.tsx"],"sourcesContent":["import React from \"react\";\nimport {type PiCardProps} from \"@pihanga2/core\";\nimport {\n ToggleGroup as ToggleGroupUI,\n ToggleGroupItem,\n} from \"@/components/ui/toggle-group\";\nimport {useFormContext} from \"@/cards/form/form.context\";\nimport type {\n PiToggleGroupEvents,\n PiToggleGroupProps,\n} from \"./toggleGroup.types\";\n\nexport const ToggleGroupComponent = (\n props: PiCardProps<PiToggleGroupProps, PiToggleGroupEvents>,\n): React.ReactNode => {\n const {\n name,\n items,\n type = \"single\",\n value: propValue,\n selfManaged = false,\n variant = \"default\",\n size = \"default\",\n spacing = 0,\n disabled,\n className,\n cardName,\n onChanged,\n } = props;\n\n // Detect if we are inside a pi/form card via React context.\n const form = useFormContext();\n const useFormData = form.isInForm && Boolean(name);\n\n // ---------------------------------------------------------------------------\n // Self-managed (internal) state — only active when selfManaged=true and we\n // are NOT inside a pi/form card.\n // ---------------------------------------------------------------------------\n const initialSelfValue: string | string[] =\n type === \"multiple\"\n ? Array.isArray(propValue)\n ? propValue\n : propValue != null\n ? [String(propValue)]\n : []\n : typeof propValue === \"string\"\n ? propValue\n : \"\";\n\n const [internalValue, setInternalValue] = React.useState<string | string[]>(\n initialSelfValue,\n );\n\n // ---------------------------------------------------------------------------\n // Derive the effective value from the appropriate source.\n // 1. Form context (highest priority)\n // 2. Self-managed internal state\n // 3. Externally controlled prop value\n // ---------------------------------------------------------------------------\n const formRawValue = useFormData ? form.formData[name!] : undefined;\n const value: string | string[] = useFormData\n ? type === \"multiple\"\n ? Array.isArray(formRawValue)\n ? (formRawValue as string[])\n : formRawValue != null\n ? [String(formRawValue)]\n : []\n : formRawValue != null\n ? String(formRawValue)\n : \"\"\n : selfManaged\n ? internalValue\n : (propValue ?? (type === \"multiple\" ? [] : \"\"));\n\n function handleSingleChange(newValue: string) {\n if (useFormData) {\n form.handleChange(name!, newValue);\n } else {\n if (selfManaged) {\n setInternalValue(newValue);\n }\n onChanged({name: name ?? cardName, value: newValue});\n }\n }\n\n function handleMultipleChange(newValue: string[]) {\n if (useFormData) {\n form.handleChange(name!, newValue);\n } else {\n if (selfManaged) {\n setInternalValue(newValue);\n }\n onChanged({name: name ?? cardName, value: newValue});\n }\n }\n\n // Render single-selection group\n if (type === \"single\") {\n return (\n <ToggleGroupUI\n data-pihanga={cardName}\n type=\"single\"\n value={typeof value === \"string\" ? value : \"\"}\n onValueChange={handleSingleChange}\n variant={variant}\n size={size}\n spacing={spacing}\n disabled={disabled}\n className={className}\n >\n {items.map((item) => (\n <ToggleGroupItem\n key={item.value}\n value={item.value}\n disabled={item.disabled}\n >\n {item.label}\n </ToggleGroupItem>\n ))}\n </ToggleGroupUI>\n );\n }\n\n // Render multiple-selection group\n return (\n <ToggleGroupUI\n data-pihanga={cardName}\n type=\"multiple\"\n value={Array.isArray(value) ? value : value ? [value] : []}\n onValueChange={handleMultipleChange}\n variant={variant}\n size={size}\n spacing={spacing}\n disabled={disabled}\n className={className}\n >\n {items.map((item) => (\n <ToggleGroupItem\n key={item.value}\n value={item.value}\n disabled={item.disabled}\n >\n {item.label}\n </ToggleGroupItem>\n ))}\n </ToggleGroupUI>\n );\n};\n"],"mappings":";;;;;;AAYA,IAAa,KACX,MACoB;CACpB,IAAM,EACJ,SACA,
|
|
1
|
+
{"version":3,"file":"toggleGroup.component.js","names":[],"sources":["../../../src/cards/toggleGroup/toggleGroup.component.tsx"],"sourcesContent":["import React from \"react\";\nimport {type PiCardProps} from \"@pihanga2/core\";\nimport {\n ToggleGroup as ToggleGroupUI,\n ToggleGroupItem,\n} from \"@/components/ui/toggle-group\";\nimport {useFormContext} from \"@/cards/form/form.context\";\nimport type {\n PiToggleGroupEvents,\n PiToggleGroupProps,\n} from \"./toggleGroup.types\";\n\nexport const ToggleGroupComponent = (\n props: PiCardProps<PiToggleGroupProps, PiToggleGroupEvents>,\n): React.ReactNode => {\n const {\n name,\n items = [],\n type = \"single\",\n value: propValue,\n selfManaged = false,\n variant = \"default\",\n size = \"default\",\n spacing = 0,\n disabled,\n className,\n cardName,\n onChanged,\n } = props;\n\n // Detect if we are inside a pi/form card via React context.\n const form = useFormContext();\n const useFormData = form.isInForm && Boolean(name);\n\n // ---------------------------------------------------------------------------\n // Self-managed (internal) state — only active when selfManaged=true and we\n // are NOT inside a pi/form card.\n // ---------------------------------------------------------------------------\n const initialSelfValue: string | string[] =\n type === \"multiple\"\n ? Array.isArray(propValue)\n ? propValue\n : propValue != null\n ? [String(propValue)]\n : []\n : typeof propValue === \"string\"\n ? propValue\n : \"\";\n\n const [internalValue, setInternalValue] = React.useState<string | string[]>(\n initialSelfValue,\n );\n\n // ---------------------------------------------------------------------------\n // Derive the effective value from the appropriate source.\n // 1. Form context (highest priority)\n // 2. Self-managed internal state\n // 3. Externally controlled prop value\n // ---------------------------------------------------------------------------\n const formRawValue = useFormData ? form.formData[name!] : undefined;\n const value: string | string[] = useFormData\n ? type === \"multiple\"\n ? Array.isArray(formRawValue)\n ? (formRawValue as string[])\n : formRawValue != null\n ? [String(formRawValue)]\n : []\n : formRawValue != null\n ? String(formRawValue)\n : \"\"\n : selfManaged\n ? internalValue\n : (propValue ?? (type === \"multiple\" ? [] : \"\"));\n\n function handleSingleChange(newValue: string) {\n if (useFormData) {\n form.handleChange(name!, newValue);\n } else {\n if (selfManaged) {\n setInternalValue(newValue);\n }\n onChanged({name: name ?? cardName, value: newValue});\n }\n }\n\n function handleMultipleChange(newValue: string[]) {\n if (useFormData) {\n form.handleChange(name!, newValue);\n } else {\n if (selfManaged) {\n setInternalValue(newValue);\n }\n onChanged({name: name ?? cardName, value: newValue});\n }\n }\n\n // Render single-selection group\n if (type === \"single\") {\n return (\n <ToggleGroupUI\n data-pihanga={cardName}\n type=\"single\"\n value={typeof value === \"string\" ? value : \"\"}\n onValueChange={handleSingleChange}\n variant={variant}\n size={size}\n spacing={spacing}\n disabled={disabled}\n className={className}\n >\n {items.map((item) => (\n <ToggleGroupItem\n key={item.value}\n value={item.value}\n disabled={item.disabled}\n >\n {item.label}\n </ToggleGroupItem>\n ))}\n </ToggleGroupUI>\n );\n }\n\n // Render multiple-selection group\n return (\n <ToggleGroupUI\n data-pihanga={cardName}\n type=\"multiple\"\n value={Array.isArray(value) ? value : value ? [value] : []}\n onValueChange={handleMultipleChange}\n variant={variant}\n size={size}\n spacing={spacing}\n disabled={disabled}\n className={className}\n >\n {items.map((item) => (\n <ToggleGroupItem\n key={item.value}\n value={item.value}\n disabled={item.disabled}\n >\n {item.label}\n </ToggleGroupItem>\n ))}\n </ToggleGroupUI>\n );\n};\n"],"mappings":";;;;;;AAYA,IAAa,KACX,MACoB;CACpB,IAAM,EACJ,SACA,WAAQ,CAAC,GACT,UAAO,UACP,OAAO,GACP,iBAAc,IACd,aAAU,WACV,UAAO,WACP,aAAU,GACV,aACA,cACA,aACA,iBACE,GAGE,IAAO,EAAe,GACtB,IAAc,EAAK,YAAY,EAAQ,GAMvC,IACJ,MAAS,aACL,MAAM,QAAQ,CAAS,IACrB,IACA,KAAa,OAEX,CAAC,IADD,CAAC,OAAO,CAAS,CAAC,IAEtB,OAAO,KAAc,WACnB,IACA,IAEF,CAAC,GAAe,KAAoB,EAAM,SAC9C,CACF,GAQM,IAAe,IAAc,EAAK,SAAS,KAAS,KAAA,GACpD,IAA2B,IAC7B,MAAS,aACP,MAAM,QAAQ,CAAY,IACvB,IACD,KAAgB,OAEd,CAAC,IADD,CAAC,OAAO,CAAY,CAAC,IAEzB,KAAgB,OAEd,KADA,OAAO,CAAY,IAEvB,IACE,IACC,MAAc,MAAS,aAAa,CAAC,IAAI;CAEhD,SAAS,EAAmB,GAAkB;EAC5C,AAAI,IACF,EAAK,aAAa,GAAO,CAAQ,KAE7B,KACF,EAAiB,CAAQ,GAE3B,EAAU;GAAC,MAAM,KAAQ;GAAU,OAAO;EAAQ,CAAC;CAEvD;CAEA,SAAS,EAAqB,GAAoB;EAChD,AAAI,IACF,EAAK,aAAa,GAAO,CAAQ,KAE7B,KACF,EAAiB,CAAQ,GAE3B,EAAU;GAAC,MAAM,KAAQ;GAAU,OAAO;EAAQ,CAAC;CAEvD;CA8BA,OA3BI,MAAS,WAET,kBAAC,GAAD;EACE,gBAAc;EACd,MAAK;EACL,OAAO,OAAO,KAAU,WAAW,IAAQ;EAC3C,eAAe;EACN;EACH;EACG;EACC;EACC;YAEV,EAAM,KAAK,MACV,kBAAC,GAAD;GAEE,OAAO,EAAK;GACZ,UAAU,EAAK;aAEd,EAAK;EACS,GALV,EAAK,KAKK,CAClB;CACY,CAAA,IAMjB,kBAAC,GAAD;EACE,gBAAc;EACd,MAAK;EACL,OAAO,MAAM,QAAQ,CAAK,IAAI,IAAQ,IAAQ,CAAC,CAAK,IAAI,CAAC;EACzD,eAAe;EACN;EACH;EACG;EACC;EACC;YAEV,EAAM,KAAK,MACV,kBAAC,GAAD;GAEE,OAAO,EAAK;GACZ,UAAU,EAAK;aAEd,EAAK;EACS,GALV,EAAK,KAKK,CAClB;CACY,CAAA;AAEnB"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { cn as e } from "../../lib/utils.js";
|
|
2
|
+
import "react";
|
|
3
|
+
import { jsx as t } from "react/jsx-runtime";
|
|
4
|
+
//#region src/components/ui/card.tsx
|
|
5
|
+
function n({ className: n, ...r }) {
|
|
6
|
+
return /* @__PURE__ */ t("div", {
|
|
7
|
+
"data-slot": "card",
|
|
8
|
+
className: e("flex flex-col gap-6 rounded-xl border bg-card py-6 text-card-foreground shadow-sm", n),
|
|
9
|
+
...r
|
|
10
|
+
});
|
|
11
|
+
}
|
|
12
|
+
function r({ className: n, ...r }) {
|
|
13
|
+
return /* @__PURE__ */ t("div", {
|
|
14
|
+
"data-slot": "card-title",
|
|
15
|
+
className: e("leading-none font-semibold", n),
|
|
16
|
+
...r
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
function i({ className: n, ...r }) {
|
|
20
|
+
return /* @__PURE__ */ t("div", {
|
|
21
|
+
"data-slot": "card-description",
|
|
22
|
+
className: e("text-sm text-muted-foreground", n),
|
|
23
|
+
...r
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
function a({ className: n, ...r }) {
|
|
27
|
+
return /* @__PURE__ */ t("div", {
|
|
28
|
+
"data-slot": "card-action",
|
|
29
|
+
className: e("col-start-2 row-span-2 row-start-1 self-start justify-self-end", n),
|
|
30
|
+
...r
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
function o({ className: n, ...r }) {
|
|
34
|
+
return /* @__PURE__ */ t("div", {
|
|
35
|
+
"data-slot": "card-content",
|
|
36
|
+
className: e("px-6", n),
|
|
37
|
+
...r
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
function s({ className: n, ...r }) {
|
|
41
|
+
return /* @__PURE__ */ t("div", {
|
|
42
|
+
"data-slot": "card-footer",
|
|
43
|
+
className: e("flex items-center px-6 [.border-t]:pt-6", n),
|
|
44
|
+
...r
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
//#endregion
|
|
48
|
+
export { n as Card, a as CardAction, o as CardContent, i as CardDescription, s as CardFooter, r as CardTitle };
|
|
49
|
+
|
|
50
|
+
//# sourceMappingURL=card.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"card.js","names":[],"sources":["../../../src/components/ui/card.tsx"],"sourcesContent":["import * as React from \"react\"\n\nimport { cn } from \"@/lib/utils\"\n\nfunction Card({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"card\"\n className={cn(\n \"flex flex-col gap-6 rounded-xl border bg-card py-6 text-card-foreground shadow-sm\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction CardHeader({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"card-header\"\n className={cn(\n \"@container/card-header grid auto-rows-min grid-rows-[auto_auto] items-start gap-2 px-6 has-data-[slot=card-action]:grid-cols-[1fr_auto] [.border-b]:pb-6\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction CardTitle({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"card-title\"\n className={cn(\"leading-none font-semibold\", className)}\n {...props}\n />\n )\n}\n\nfunction CardDescription({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"card-description\"\n className={cn(\"text-sm text-muted-foreground\", className)}\n {...props}\n />\n )\n}\n\nfunction CardAction({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"card-action\"\n className={cn(\n \"col-start-2 row-span-2 row-start-1 self-start justify-self-end\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction CardContent({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"card-content\"\n className={cn(\"px-6\", className)}\n {...props}\n />\n )\n}\n\nfunction CardFooter({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"card-footer\"\n className={cn(\"flex items-center px-6 [.border-t]:pt-6\", className)}\n {...props}\n />\n )\n}\n\nexport {\n Card,\n CardHeader,\n CardFooter,\n CardTitle,\n CardAction,\n CardDescription,\n CardContent,\n}\n"],"mappings":";;;;AAIA,SAAS,EAAK,EAAE,cAAW,GAAG,KAAsC;CAClE,OACE,kBAAC,OAAD;EACE,aAAU;EACV,WAAW,EACT,qFACA,CACF;EACA,GAAI;CACL,CAAA;AAEL;AAeA,SAAS,EAAU,EAAE,cAAW,GAAG,KAAsC;CACvE,OACE,kBAAC,OAAD;EACE,aAAU;EACV,WAAW,EAAG,8BAA8B,CAAS;EACrD,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,EAAgB,EAAE,cAAW,GAAG,KAAsC;CAC7E,OACE,kBAAC,OAAD;EACE,aAAU;EACV,WAAW,EAAG,iCAAiC,CAAS;EACxD,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,EAAW,EAAE,cAAW,GAAG,KAAsC;CACxE,OACE,kBAAC,OAAD;EACE,aAAU;EACV,WAAW,EACT,kEACA,CACF;EACA,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,EAAY,EAAE,cAAW,GAAG,KAAsC;CACzE,OACE,kBAAC,OAAD;EACE,aAAU;EACV,WAAW,EAAG,QAAQ,CAAS;EAC/B,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,EAAW,EAAE,cAAW,GAAG,KAAsC;CACxE,OACE,kBAAC,OAAD;EACE,aAAU;EACV,WAAW,EAAG,2CAA2C,CAAS;EAClE,GAAI;CACL,CAAA;AAEL"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pihanga2/shadcn",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.8",
|
|
4
4
|
"description": "Pihanga core card components built on shadcn/ui and Radix UI — the npm distribution of pihanga-shadcn.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -24,6 +24,10 @@
|
|
|
24
24
|
"import": "./cards/checkbox/index.js",
|
|
25
25
|
"types": "./cards/checkbox/index.d.ts"
|
|
26
26
|
},
|
|
27
|
+
"./cards/collapsibleCard": {
|
|
28
|
+
"import": "./cards/collapsibleCard/index.js",
|
|
29
|
+
"types": "./cards/collapsibleCard/index.d.ts"
|
|
30
|
+
},
|
|
27
31
|
"./cards/conditional": {
|
|
28
32
|
"import": "./cards/conditional/index.js",
|
|
29
33
|
"types": "./cards/conditional/index.d.ts"
|
|
@@ -64,6 +68,10 @@
|
|
|
64
68
|
"import": "./cards/framework/index.js",
|
|
65
69
|
"types": "./cards/framework/index.d.ts"
|
|
66
70
|
},
|
|
71
|
+
"./cards/infoCard": {
|
|
72
|
+
"import": "./cards/infoCard/index.js",
|
|
73
|
+
"types": "./cards/infoCard/index.d.ts"
|
|
74
|
+
},
|
|
67
75
|
"./cards/input": {
|
|
68
76
|
"import": "./cards/input/index.js",
|
|
69
77
|
"types": "./cards/input/index.d.ts"
|
|
@@ -171,6 +179,9 @@
|
|
|
171
179
|
"./lib/utils": {
|
|
172
180
|
"import": "./lib/utils.js",
|
|
173
181
|
"types": "./lib/utils.d.ts"
|
|
182
|
+
},
|
|
183
|
+
"./theme": {
|
|
184
|
+
"import": "./theme.css"
|
|
174
185
|
}
|
|
175
186
|
},
|
|
176
187
|
"sideEffects": [
|
|
@@ -179,6 +190,7 @@
|
|
|
179
190
|
"./cards/box/index.js",
|
|
180
191
|
"./cards/button/index.js",
|
|
181
192
|
"./cards/checkbox/index.js",
|
|
193
|
+
"./cards/collapsibleCard/index.js",
|
|
182
194
|
"./cards/conditional/index.js",
|
|
183
195
|
"./cards/dataTable/index.js",
|
|
184
196
|
"./cards/dialog/index.js",
|
|
@@ -189,6 +201,7 @@
|
|
|
189
201
|
"./cards/flexGrid/index.js",
|
|
190
202
|
"./cards/form/index.js",
|
|
191
203
|
"./cards/framework/index.js",
|
|
204
|
+
"./cards/infoCard/index.js",
|
|
192
205
|
"./cards/input/index.js",
|
|
193
206
|
"./cards/jsonViewer/index.js",
|
|
194
207
|
"./cards/list/index.js",
|
|
@@ -236,6 +249,7 @@
|
|
|
236
249
|
"@pihanga2/cards": "*"
|
|
237
250
|
},
|
|
238
251
|
"dependencies": {
|
|
252
|
+
"@radix-ui/react-collapsible": "^1.1.20",
|
|
239
253
|
"@radix-ui/react-dialog": "^1.1.15",
|
|
240
254
|
"@radix-ui/react-dropdown-menu": "^2.1.16",
|
|
241
255
|
"@radix-ui/react-menubar": "^1.1.16",
|
package/theme.css
ADDED
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* pihanga-shadcn — theme.css
|
|
3
|
+
*
|
|
4
|
+
* Add ONE line to your app's main CSS (processed by Tailwind v4):
|
|
5
|
+
*
|
|
6
|
+
* @import "tailwindcss";
|
|
7
|
+
* @import "@pihanga2/shadcn/theme.css";
|
|
8
|
+
*
|
|
9
|
+
* The @source directive below tells Tailwind to scan this package's
|
|
10
|
+
* compiled JS files for utility class names, so you don't need a
|
|
11
|
+
* separate @source line in your own CSS.
|
|
12
|
+
*
|
|
13
|
+
* Skip the import if your app already has a shadcn/ui theme — your
|
|
14
|
+
* :root variables will take precedence over the defaults below.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
/* Scan this package's compiled files for Tailwind utility classes */
|
|
18
|
+
@source ".";
|
|
19
|
+
|
|
20
|
+
/* Map shadcn CSS vars to Tailwind v4 utility tokens */
|
|
21
|
+
@theme inline {
|
|
22
|
+
--color-background: var(--background);
|
|
23
|
+
--color-foreground: var(--foreground);
|
|
24
|
+
--color-card: var(--card);
|
|
25
|
+
--color-card-foreground: var(--card-foreground);
|
|
26
|
+
--color-popover: var(--popover);
|
|
27
|
+
--color-popover-foreground: var(--popover-foreground);
|
|
28
|
+
--color-primary: var(--primary);
|
|
29
|
+
--color-primary-foreground: var(--primary-foreground);
|
|
30
|
+
--color-secondary: var(--secondary);
|
|
31
|
+
--color-secondary-foreground: var(--secondary-foreground);
|
|
32
|
+
--color-muted: var(--muted);
|
|
33
|
+
--color-muted-foreground: var(--muted-foreground);
|
|
34
|
+
--color-accent: var(--accent);
|
|
35
|
+
--color-accent-foreground: var(--accent-foreground);
|
|
36
|
+
--color-destructive: var(--destructive);
|
|
37
|
+
--color-border: var(--border);
|
|
38
|
+
--color-input: var(--input);
|
|
39
|
+
--color-ring: var(--ring);
|
|
40
|
+
--radius-sm: calc(var(--radius) - 4px);
|
|
41
|
+
--radius-md: calc(var(--radius) - 2px);
|
|
42
|
+
--radius-lg: var(--radius);
|
|
43
|
+
--radius-xl: calc(var(--radius) + 4px);
|
|
44
|
+
--color-btn-brand: var(--primary);
|
|
45
|
+
--color-btn-brand-foreground: var(--primary-foreground);
|
|
46
|
+
--radius-btn-brand: var(--radius-md);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/* Light theme (shadcn neutral / new-york) */
|
|
50
|
+
:root {
|
|
51
|
+
--background: oklch(1 0 0);
|
|
52
|
+
--foreground: oklch(0.145 0 0);
|
|
53
|
+
--card: oklch(1 0 0);
|
|
54
|
+
--card-foreground: oklch(0.145 0 0);
|
|
55
|
+
--popover: oklch(1 0 0);
|
|
56
|
+
--popover-foreground: oklch(0.145 0 0);
|
|
57
|
+
--primary: oklch(0.205 0 0);
|
|
58
|
+
--primary-foreground: oklch(0.985 0 0);
|
|
59
|
+
--secondary: oklch(0.97 0 0);
|
|
60
|
+
--secondary-foreground: oklch(0.205 0 0);
|
|
61
|
+
--muted: oklch(0.97 0 0);
|
|
62
|
+
--muted-foreground: oklch(0.556 0 0);
|
|
63
|
+
--accent: oklch(0.97 0 0);
|
|
64
|
+
--accent-foreground: oklch(0.205 0 0);
|
|
65
|
+
--destructive: oklch(0.577 0.245 27.325);
|
|
66
|
+
--border: oklch(0.922 0 0);
|
|
67
|
+
--input: oklch(0.922 0 0);
|
|
68
|
+
--ring: oklch(0.708 0 0);
|
|
69
|
+
--radius: 0.625rem;
|
|
70
|
+
--chart-1: oklch(0.646 0.222 41.116);
|
|
71
|
+
--chart-2: oklch(0.6 0.118 184.704);
|
|
72
|
+
--chart-3: oklch(0.398 0.07 227.392);
|
|
73
|
+
--chart-4: oklch(0.828 0.189 84.429);
|
|
74
|
+
--chart-5: oklch(0.769 0.188 70.08);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/* Dark theme */
|
|
78
|
+
.dark {
|
|
79
|
+
--background: oklch(0.145 0 0);
|
|
80
|
+
--foreground: oklch(0.985 0 0);
|
|
81
|
+
--card: oklch(0.205 0 0);
|
|
82
|
+
--card-foreground: oklch(0.985 0 0);
|
|
83
|
+
--popover: oklch(0.205 0 0);
|
|
84
|
+
--popover-foreground: oklch(0.985 0 0);
|
|
85
|
+
--primary: oklch(0.922 0 0);
|
|
86
|
+
--primary-foreground: oklch(0.205 0 0);
|
|
87
|
+
--secondary: oklch(0.269 0 0);
|
|
88
|
+
--secondary-foreground: oklch(0.985 0 0);
|
|
89
|
+
--muted: oklch(0.269 0 0);
|
|
90
|
+
--muted-foreground: oklch(0.708 0 0);
|
|
91
|
+
--accent: oklch(0.269 0 0);
|
|
92
|
+
--accent-foreground: oklch(0.985 0 0);
|
|
93
|
+
--destructive: oklch(0.704 0.191 22.216);
|
|
94
|
+
--border: oklch(1 0 0 / 10%);
|
|
95
|
+
--input: oklch(1 0 0 / 15%);
|
|
96
|
+
--ring: oklch(0.556 0 0);
|
|
97
|
+
--chart-1: oklch(0.488 0.243 264.376);
|
|
98
|
+
--chart-2: oklch(0.696 0.17 162.48);
|
|
99
|
+
--chart-3: oklch(0.769 0.188 70.08);
|
|
100
|
+
--chart-4: oklch(0.627 0.265 303.9);
|
|
101
|
+
--chart-5: oklch(0.645 0.246 16.439);
|
|
102
|
+
}
|