@pihanga2/shadcn 0.2.19 → 0.2.21
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.using-cards.md +2 -2
- package/cards/button/button.component.js +56 -54
- package/cards/button/button.component.js.map +1 -1
- package/cards/button/button.types.d.ts +24 -0
- package/cards/button/button.types.js.map +1 -1
- package/cards/checkbox/checkbox.types.d.ts +2 -7
- package/cards/checkbox/checkbox.types.js.map +1 -1
- package/cards/field/field.component.js +1 -1
- package/cards/field/field.component.js.map +1 -1
- package/cards/form/form.component.js +57 -32
- package/cards/form/form.component.js.map +1 -1
- package/cards/form/form.context.d.ts +11 -0
- package/cards/form/form.context.js +1 -0
- package/cards/form/form.context.js.map +1 -1
- package/cards/form/form.types.d.ts +75 -0
- package/cards/form/form.types.js +6 -2
- package/cards/form/form.types.js.map +1 -1
- package/cards/form/index.js +5 -5
- package/cards/input/index.js +6 -6
- package/cards/input/input.component.js +34 -28
- package/cards/input/input.component.js.map +1 -1
- package/cards/input/input.types.d.ts +14 -7
- package/cards/input/input.types.js +2 -2
- package/cards/input/input.types.js.map +1 -1
- package/cards/pageWithNavbarMeta/index.js +35 -25
- package/cards/pageWithNavbarMeta/index.js.map +1 -1
- package/cards/pageWithNavbarMeta/pageWithNavbarMeta.types.d.ts +1 -4
- package/cards/select/select.types.d.ts +2 -7
- package/cards/select/select.types.js.map +1 -1
- package/cards/switch/switch.types.d.ts +2 -7
- package/cards/switch/switch.types.js.map +1 -1
- package/cards/textArea/textArea.component.js +1 -1
- package/cards/textArea/textArea.component.js.map +1 -1
- package/cards/textArea/textArea.types.d.ts +15 -11
- package/cards/textArea/textArea.types.js.map +1 -1
- package/cards/textField/textField.component.js +13 -9
- package/cards/textField/textField.component.js.map +1 -1
- package/cards/textField/textField.types.d.ts +12 -7
- package/cards/textField/textField.types.js.map +1 -1
- package/cards/toggleGroup/toggleGroup.types.d.ts +2 -7
- package/cards/toggleGroup/toggleGroup.types.js.map +1 -1
- package/package.json +2 -3
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { CSSProperties } from 'react';
|
|
2
|
+
import { FormFieldProps } from '../form/form.types';
|
|
2
3
|
export declare const PI_TEXT_AREA_CARD = "pi/text-area";
|
|
3
4
|
export declare const TextArea: <S extends import('@pihanga2/core').ReduxState>(p: import('@pihanga2/core').PiMapProps<PiTextAreaProps, S, PiTextAreaEvents>) => import('@pihanga2/core').PiCardDef;
|
|
4
5
|
export declare const PI_TEXT_AREA_ACTION: {
|
|
5
|
-
CHANGED: string;
|
|
6
6
|
SUBMITTED: string;
|
|
7
|
+
CHANGED: string;
|
|
7
8
|
};
|
|
8
9
|
export declare const onTextAreaChanged: <S extends import('@pihanga2/core').ReduxState>(register: import('@pihanga2/core/types').PiRegisterMinimal, f: import('@pihanga2/core').ReduceF<S, import('@pihanga2/core').ReduxAction & {
|
|
9
10
|
cardID: string;
|
|
@@ -25,13 +26,7 @@ export type CssLength = number | string;
|
|
|
25
26
|
*/
|
|
26
27
|
export type PiTextAreaFieldSizing = "fixed" | "content";
|
|
27
28
|
export type PiTextAreaResize = "none" | "vertical" | "horizontal" | "both";
|
|
28
|
-
export type PiTextAreaProps = {
|
|
29
|
-
/**
|
|
30
|
-
* Field name used to bind to FormContext when inside a pi/form card.
|
|
31
|
-
* When provided the component reads its value from form state and writes
|
|
32
|
-
* back via form.handleChange.
|
|
33
|
-
*/
|
|
34
|
-
name?: string;
|
|
29
|
+
export type PiTextAreaProps = FormFieldProps & {
|
|
35
30
|
/**
|
|
36
31
|
* Controlled value used in standalone mode (outside a Form).
|
|
37
32
|
* Ignored when `name` is set and the component is inside a pi/form.
|
|
@@ -81,9 +76,18 @@ export type PiTextAreaProps = {
|
|
|
81
76
|
*/
|
|
82
77
|
writingMode?: "horizontal-tb" | "vertical-rl" | "vertical-lr";
|
|
83
78
|
/**
|
|
84
|
-
* When true, pressing Enter (without Shift/Ctrl/Meta/Alt)
|
|
85
|
-
*
|
|
86
|
-
*
|
|
79
|
+
* When true, pressing Enter (without Shift/Ctrl/Meta/Alt) submits instead
|
|
80
|
+
* of inserting a newline. Shift+Enter (etc.) still inserts a newline.
|
|
81
|
+
*
|
|
82
|
+
* - Inside a `pi/form` (i.e. `name` is set and a `pi/form` ancestor is
|
|
83
|
+
* present): requests the form's submit action
|
|
84
|
+
* (`FormContext.requestAction("submit")`) — equivalent to clicking a
|
|
85
|
+
* `Button` with `formAction: "submit"`, and consistent with
|
|
86
|
+
* `pi/input`'s / `pi/text-field`'s `submitOnEnter`.
|
|
87
|
+
* - Standalone: fires this card's own `onSubmitted` event with the
|
|
88
|
+
* current text.
|
|
89
|
+
*
|
|
90
|
+
* Default: `false`.
|
|
87
91
|
*/
|
|
88
92
|
submitOnEnter?: boolean;
|
|
89
93
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"textArea.types.js","names":[],"sources":["../../../src/cards/textArea/textArea.types.ts"],"sourcesContent":["import type {CSSProperties} from \"react\";\nimport {\n createCardDeclaration,\n createOnAction,\n registerActions,\n} from \"@pihanga2/core\";\n\nexport const PI_TEXT_AREA_CARD = \"pi/text-area\";\n\nexport const TextArea = createCardDeclaration<\n PiTextAreaProps,\n PiTextAreaEvents\n>(PI_TEXT_AREA_CARD);\n\nexport const PI_TEXT_AREA_ACTION = registerActions(PI_TEXT_AREA_CARD, [\n \"changed\",\n \"submitted\",\n]);\n\nexport const onTextAreaChanged = createOnAction<PiTextAreaChangedEvent>(\n PI_TEXT_AREA_ACTION.CHANGED,\n);\n\nexport const onTextAreaSubmitted = createOnAction<PiTextAreaSubmittedEvent>(\n PI_TEXT_AREA_ACTION.SUBMITTED,\n);\n\n/** A CSS length. Numbers are treated as pixels, strings are used verbatim. */\nexport type CssLength = number | string;\n\n/**\n * How the textarea sizes itself:\n * - \"fixed\" (default) — plain `<textarea>` behaviour. Size is governed by\n * `rows`/`cols` (and any explicit `width`/`height`); the user\n * may resize it per the `resize` prop. Never grows with content.\n * - \"content\" — uses the CSS `field-sizing: content` behaviour: the box\n * grows/shrinks to fit its content, clamped by any\n * `minHeight`/`maxHeight`/`width`/`height`/`maxWidth` you set.\n * `rows`/`cols` are ignored by the browser once this is active.\n */\nexport type PiTextAreaFieldSizing = \"fixed\" | \"content\";\n\nexport type PiTextAreaResize = \"none\" | \"vertical\" | \"horizontal\" | \"both\";\n\nexport type PiTextAreaProps =
|
|
1
|
+
{"version":3,"file":"textArea.types.js","names":[],"sources":["../../../src/cards/textArea/textArea.types.ts"],"sourcesContent":["import type {CSSProperties} from \"react\";\nimport {\n createCardDeclaration,\n createOnAction,\n registerActions,\n} from \"@pihanga2/core\";\nimport type {FormFieldProps} from \"@/cards/form/form.types\";\n\nexport const PI_TEXT_AREA_CARD = \"pi/text-area\";\n\nexport const TextArea = createCardDeclaration<\n PiTextAreaProps,\n PiTextAreaEvents\n>(PI_TEXT_AREA_CARD);\n\nexport const PI_TEXT_AREA_ACTION = registerActions(PI_TEXT_AREA_CARD, [\n \"changed\",\n \"submitted\",\n]);\n\nexport const onTextAreaChanged = createOnAction<PiTextAreaChangedEvent>(\n PI_TEXT_AREA_ACTION.CHANGED,\n);\n\nexport const onTextAreaSubmitted = createOnAction<PiTextAreaSubmittedEvent>(\n PI_TEXT_AREA_ACTION.SUBMITTED,\n);\n\n/** A CSS length. Numbers are treated as pixels, strings are used verbatim. */\nexport type CssLength = number | string;\n\n/**\n * How the textarea sizes itself:\n * - \"fixed\" (default) — plain `<textarea>` behaviour. Size is governed by\n * `rows`/`cols` (and any explicit `width`/`height`); the user\n * may resize it per the `resize` prop. Never grows with content.\n * - \"content\" — uses the CSS `field-sizing: content` behaviour: the box\n * grows/shrinks to fit its content, clamped by any\n * `minHeight`/`maxHeight`/`width`/`height`/`maxWidth` you set.\n * `rows`/`cols` are ignored by the browser once this is active.\n */\nexport type PiTextAreaFieldSizing = \"fixed\" | \"content\";\n\nexport type PiTextAreaResize = \"none\" | \"vertical\" | \"horizontal\" | \"both\";\n\nexport type PiTextAreaProps = FormFieldProps & {\n /**\n * Controlled value used in standalone mode (outside a Form).\n * Ignored when `name` is set and the component is inside a pi/form.\n */\n value?: string;\n\n /** Placeholder text shown when the box is empty. May contain `\\n`. */\n placeholder?: string;\n\n /** When true, the textarea is disabled and non-interactive. */\n disabled?: boolean;\n\n /** When true, the textarea's value cannot be edited by the user. */\n readOnly?: boolean;\n\n /**\n * Number of visible text lines. Only meaningful when `fieldSizing` is\n * `\"fixed\"` — browsers ignore `rows`/`cols` once `field-sizing: content`\n * is active. Default: `4`.\n */\n rows?: number;\n\n /** Number of visible character columns. See `rows` for caveats. */\n cols?: number;\n\n /** See `PiTextAreaFieldSizing`. Default: `\"fixed\"`. */\n fieldSizing?: PiTextAreaFieldSizing;\n\n /**\n * CSS `resize` behaviour — whether/how the user can drag-resize the box.\n * Default: `\"vertical\"` when `fieldSizing` is `\"fixed\"`, `\"none\"` when\n * `fieldSizing` is `\"content\"` (dragging would otherwise permanently\n * defeat the content-based sizing by writing an inline width/height).\n */\n resize?: PiTextAreaResize;\n\n /** Minimum height. Accepts CSS units like `\"2lh\"`, `\"4rem\"`, or a number of px. */\n minHeight?: CssLength;\n\n /** Maximum height. Once reached, content scrolls instead of growing further. */\n maxHeight?: CssLength;\n\n /** Explicit width. Freezes the inline axis even when `fieldSizing=\"content\"`. */\n width?: CssLength;\n\n /** Explicit height. Freezes the block axis even when `fieldSizing=\"content\"`. */\n height?: CssLength;\n\n /**\n * Maximum width — a guard against an unconstrained `fieldSizing=\"content\"`\n * box escaping its parent container.\n */\n maxWidth?: CssLength;\n\n /** Text direction. Default: inherited from the document. */\n dir?: \"ltr\" | \"rtl\";\n\n /**\n * CSS `writing-mode`. With `\"vertical-rl\"` the sizing axes swap: content\n * growth under `fieldSizing=\"content\"` runs horizontally, not vertically.\n */\n writingMode?: \"horizontal-tb\" | \"vertical-rl\" | \"vertical-lr\";\n\n /**\n * When true, pressing Enter (without Shift/Ctrl/Meta/Alt) submits instead\n * of inserting a newline. Shift+Enter (etc.) still inserts a newline.\n *\n * - Inside a `pi/form` (i.e. `name` is set and a `pi/form` ancestor is\n * present): requests the form's submit action\n * (`FormContext.requestAction(\"submit\")`) — equivalent to clicking a\n * `Button` with `formAction: \"submit\"`, and consistent with\n * `pi/input`'s / `pi/text-field`'s `submitOnEnter`.\n * - Standalone: fires this card's own `onSubmitted` event with the\n * current text.\n *\n * Default: `false`.\n */\n submitOnEnter?: boolean;\n\n /**\n * **Standalone mode only** (ignored when used inside a `pi/form` card —\n * see below). When true, the textarea keeps its own internal text state\n * so the visible text always updates immediately as the user types, but\n * the outgoing `onChanged` event is only dispatched at a \"commit\" point\n * instead of on every keystroke:\n *\n * - always on blur,\n * - and, if `debounceMs > 0`, also after that many ms of typing\n * inactivity (a trailing debounce), so the value is committed even if\n * the user never blurs the field (e.g. drives an autosave / API call).\n *\n * Use this to avoid flooding the host app / reducer with an event per\n * keystroke for a card whose `onChanged` handler is expensive.\n *\n * When the card is used inside a `pi/form` (i.e. `name` is set and a\n * `pi/form` ancestor is present), this prop has no effect: form fields\n * always write back to form state on every keystroke via\n * `form.handleChange`, exactly like `pi/input` and `pi/text-field` — the\n * form's own submit action is the natural \"commit\" point in that case.\n *\n * Default: `false` (dispatches `onChanged` on every keystroke, as\n * before).\n */\n selfManaged?: boolean;\n\n /**\n * Trailing-debounce window (ms) for committing changes while\n * `selfManaged` is true (standalone mode only). `0` (default) means no\n * debounce — the value is only committed on blur. Ignored when\n * `selfManaged` is `false`, or when the card is inside a `pi/form`.\n */\n debounceMs?: number;\n\n /** Additional class names merged onto the root `<textarea>`. */\n className?: string;\n\n /** Additional inline styles merged onto the root `<textarea>` (highest precedence). */\n style?: CSSProperties;\n\n /**\n * When true, the textarea grabs keyboard focus the first time it is\n * mounted/shown (e.g. when a dialog or drawer opens). Only applies once,\n * on mount — it does not re-focus on subsequent re-renders.\n */\n autoFocus?: boolean;\n};\n\nexport type PiTextAreaChangedEvent = {\n /** Field name, mirrors the `name` prop if provided. */\n name?: string;\n /** New value after the change. */\n value: string;\n};\n\nexport type PiTextAreaSubmittedEvent = {\n /** Field name, mirrors the `name` prop if provided. */\n name?: string;\n /** The current text at the time Enter was pressed. */\n value: string;\n};\n\nexport type PiTextAreaEvents = {\n onChanged: PiTextAreaChangedEvent;\n onSubmitted: PiTextAreaSubmittedEvent;\n};\n"],"mappings":";;AAQA,IAAa,IAAoB,gBAEpB,IAAW,EAGtB,CAAiB,GAEN,IAAsB,EAAgB,GAAmB,CACpE,WACA,WACF,CAAC,GAEY,IAAoB,EAC/B,EAAoB,OACtB,GAEa,IAAsB,EACjC,EAAoB,SACtB"}
|
|
@@ -5,24 +5,28 @@ import "@pihanga2/core";
|
|
|
5
5
|
import { jsx as n } from "react/jsx-runtime";
|
|
6
6
|
//#region src/cards/textField/textField.component.tsx
|
|
7
7
|
var r = (r) => {
|
|
8
|
-
let { name: i, value: a = "", type: o = "text", placeholder: s, disabled: c,
|
|
9
|
-
function
|
|
8
|
+
let { name: i, value: a = "", type: o = "text", placeholder: s, disabled: c, submitOnEnter: l, cardName: u, onChanged: d } = r, f = r.id, p = !!r.invalid, m = e(), h = m.isInForm && !!i, g = h ? m.formData[i] ?? "" : a;
|
|
9
|
+
function _(e) {
|
|
10
10
|
let t = e.target.value;
|
|
11
|
-
|
|
11
|
+
h ? m.handleChange(i, t) : d({
|
|
12
12
|
name: i,
|
|
13
13
|
value: t
|
|
14
14
|
});
|
|
15
15
|
}
|
|
16
|
-
|
|
16
|
+
function v(e) {
|
|
17
|
+
l && h && e.key === "Enter" && m.requestAction("submit");
|
|
18
|
+
}
|
|
19
|
+
let y = `${u}-${i ?? "field"}`;
|
|
17
20
|
return /* @__PURE__ */ n(t, {
|
|
18
|
-
id:
|
|
21
|
+
id: f ?? y,
|
|
19
22
|
type: o,
|
|
20
|
-
value:
|
|
21
|
-
onChange:
|
|
23
|
+
value: g,
|
|
24
|
+
onChange: _,
|
|
25
|
+
onKeyDown: v,
|
|
22
26
|
placeholder: s,
|
|
23
27
|
disabled: c,
|
|
24
|
-
"aria-invalid":
|
|
25
|
-
"data-pihanga":
|
|
28
|
+
"aria-invalid": p || void 0,
|
|
29
|
+
"data-pihanga": u
|
|
26
30
|
});
|
|
27
31
|
};
|
|
28
32
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"textField.component.js","names":[],"sources":["../../../src/cards/textField/textField.component.tsx"],"sourcesContent":["import React from \"react\";\nimport {type PiCardProps} from \"@pihanga2/core\";\nimport {Input} from \"@/components/ui/input\";\nimport {useFormContext} from \"@/cards/form/form.context\";\nimport type {PiTextFieldEvents, PiTextFieldProps} from \"./textField.types\";\n\nexport const TextFieldComponent = (\n props: PiCardProps<PiTextFieldProps, PiTextFieldEvents>,\n): React.ReactNode => {\n const {\n name,\n value: propValue = \"\",\n type = \"text\",\n placeholder,\n disabled,\n cardName,\n onChanged,\n } = props;\n\n // `id` and `invalid` may be injected by a parent pi/field card via\n // Pihanga's extra-prop forwarding. They are not in the official type so\n // we read them through an escape hatch.\n const injectedId = (props as {id?: string}).id;\n const invalid = Boolean((props as {invalid?: boolean}).invalid);\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 const value = useFormData\n ? ((form.formData[name!] as string | undefined) ?? \"\")\n : propValue;\n\n function handleChange(e: React.ChangeEvent<HTMLInputElement>) {\n const newValue = e.target.value;\n if (useFormData) {\n form.handleChange(name!, newValue);\n } else {\n onChanged({name, value: newValue});\n }\n }\n\n // Use the id injected by pi/field (for label↔control linking); fall back\n // to a locally-generated id when used standalone.\n const selfId = `${cardName}-${name ?? \"field\"}`;\n const fieldId = injectedId ?? selfId;\n\n return (\n <Input\n id={fieldId}\n type={type}\n value={value}\n onChange={handleChange}\n placeholder={placeholder}\n disabled={disabled}\n aria-invalid={invalid || undefined}\n data-pihanga={cardName}\n />\n );\n};\n"],"mappings":";;;;;;AAMA,IAAa,KACX,MACoB;CACpB,IAAM,EACJ,SACA,OAAO,IAAY,IACnB,UAAO,QACP,gBACA,aACA,aACA,iBACE,GAKE,IAAc,EAAwB,IACtC,IAAU,EAAS,EAA8B,SAGjD,IAAO,EAAe,GACtB,IAAc,EAAK,YAAY,EAAQ,GAEvC,IAAQ,IACR,EAAK,SAAS,MAAiC,KACjD;CAEJ,SAAS,EAAa,GAAwC;EAC5D,IAAM,IAAW,EAAE,OAAO;EAC1B,AAAI,IACF,EAAK,aAAa,GAAO,CAAQ,IAEjC,EAAU;GAAC;GAAM,OAAO;EAAQ,CAAC;CAErC;CAIA,IAAM,IAAS,GAAG,EAAS,GAAG,KAAQ;CAGtC,OACE,kBAAC,GAAD;EACE,IAJY,KAAc;EAKpB;EACC;EACP,UAAU;
|
|
1
|
+
{"version":3,"file":"textField.component.js","names":[],"sources":["../../../src/cards/textField/textField.component.tsx"],"sourcesContent":["import React from \"react\";\nimport {type PiCardProps} from \"@pihanga2/core\";\nimport {Input} from \"@/components/ui/input\";\nimport {useFormContext} from \"@/cards/form/form.context\";\nimport type {PiTextFieldEvents, PiTextFieldProps} from \"./textField.types\";\n\nexport const TextFieldComponent = (\n props: PiCardProps<PiTextFieldProps, PiTextFieldEvents>,\n): React.ReactNode => {\n const {\n name,\n value: propValue = \"\",\n type = \"text\",\n placeholder,\n disabled,\n submitOnEnter,\n cardName,\n onChanged,\n } = props;\n\n // `id` and `invalid` may be injected by a parent pi/field card via\n // Pihanga's extra-prop forwarding. They are not in the official type so\n // we read them through an escape hatch.\n const injectedId = (props as {id?: string}).id;\n const invalid = Boolean((props as {invalid?: boolean}).invalid);\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 const value = useFormData\n ? ((form.formData[name!] as string | undefined) ?? \"\")\n : propValue;\n\n function handleChange(e: React.ChangeEvent<HTMLInputElement>) {\n const newValue = e.target.value;\n if (useFormData) {\n form.handleChange(name!, newValue);\n } else {\n onChanged({name, value: newValue});\n }\n }\n\n function handleKeyDown(e: React.KeyboardEvent<HTMLInputElement>) {\n if (submitOnEnter && useFormData && e.key === \"Enter\") {\n form.requestAction(\"submit\");\n }\n }\n\n // Use the id injected by pi/field (for label↔control linking); fall back\n // to a locally-generated id when used standalone.\n const selfId = `${cardName}-${name ?? \"field\"}`;\n const fieldId = injectedId ?? selfId;\n\n return (\n <Input\n id={fieldId}\n type={type}\n value={value}\n onChange={handleChange}\n onKeyDown={handleKeyDown}\n placeholder={placeholder}\n disabled={disabled}\n aria-invalid={invalid || undefined}\n data-pihanga={cardName}\n />\n );\n};\n"],"mappings":";;;;;;AAMA,IAAa,KACX,MACoB;CACpB,IAAM,EACJ,SACA,OAAO,IAAY,IACnB,UAAO,QACP,gBACA,aACA,kBACA,aACA,iBACE,GAKE,IAAc,EAAwB,IACtC,IAAU,EAAS,EAA8B,SAGjD,IAAO,EAAe,GACtB,IAAc,EAAK,YAAY,EAAQ,GAEvC,IAAQ,IACR,EAAK,SAAS,MAAiC,KACjD;CAEJ,SAAS,EAAa,GAAwC;EAC5D,IAAM,IAAW,EAAE,OAAO;EAC1B,AAAI,IACF,EAAK,aAAa,GAAO,CAAQ,IAEjC,EAAU;GAAC;GAAM,OAAO;EAAQ,CAAC;CAErC;CAEA,SAAS,EAAc,GAA0C;EAC/D,AAAI,KAAiB,KAAe,EAAE,QAAQ,WAC5C,EAAK,cAAc,QAAQ;CAE/B;CAIA,IAAM,IAAS,GAAG,EAAS,GAAG,KAAQ;CAGtC,OACE,kBAAC,GAAD;EACE,IAJY,KAAc;EAKpB;EACC;EACP,UAAU;EACV,WAAW;EACE;EACH;EACV,gBAAc,KAAW,KAAA;EACzB,gBAAc;CACf,CAAA;AAEL"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { FormFieldProps } from '../form/form.types';
|
|
1
2
|
export declare const PI_TEXT_FIELD_CARD = "pi/text-field";
|
|
2
3
|
export declare const TextField: <S extends import('@pihanga2/core').ReduxState>(p: import('@pihanga2/core').PiMapProps<PiTextFieldProps, S, PiTextFieldEvents>) => import('@pihanga2/core').PiCardDef;
|
|
3
4
|
export declare const PI_TEXT_FIELD_ACTION: {
|
|
@@ -10,13 +11,7 @@ export declare const onTextFieldChanged: <S extends import('@pihanga2/core').Red
|
|
|
10
11
|
export declare const onPiTextFieldChanged: <S extends import('@pihanga2/core').ReduxState>(register: import('@pihanga2/core/types').PiRegisterMinimal, f: import('@pihanga2/core').ReduceF<S, import('@pihanga2/core').ReduxAction & {
|
|
11
12
|
cardID: string;
|
|
12
13
|
} & PiTextFieldChangedEvent>) => void;
|
|
13
|
-
export type PiTextFieldProps = {
|
|
14
|
-
/**
|
|
15
|
-
* Field name used to bind to FormContext when inside a pi/form card.
|
|
16
|
-
* When provided the component reads its value from form state and writes
|
|
17
|
-
* back via form.handleChange.
|
|
18
|
-
*/
|
|
19
|
-
name?: string;
|
|
14
|
+
export type PiTextFieldProps = FormFieldProps & {
|
|
20
15
|
/**
|
|
21
16
|
* Controlled value used in standalone mode (outside a Form).
|
|
22
17
|
* Ignored when `name` is set and the component is inside a pi/form.
|
|
@@ -28,6 +23,16 @@ export type PiTextFieldProps = {
|
|
|
28
23
|
placeholder?: string;
|
|
29
24
|
/** When true, the input is disabled and non-interactive. */
|
|
30
25
|
disabled?: boolean;
|
|
26
|
+
/**
|
|
27
|
+
* When true and this field is rendered inside a `pi/form` card, pressing
|
|
28
|
+
* Enter requests the form's submit action
|
|
29
|
+
* (`FormContext.requestAction("submit")`) — equivalent to clicking a
|
|
30
|
+
* `Button` with `formAction: "submit"`.
|
|
31
|
+
*
|
|
32
|
+
* Has no effect outside a `pi/form`.
|
|
33
|
+
* @default false
|
|
34
|
+
*/
|
|
35
|
+
submitOnEnter?: boolean;
|
|
31
36
|
};
|
|
32
37
|
export type PiTextFieldChangedEvent = {
|
|
33
38
|
/** Field name, mirrors the `name` prop if provided. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"textField.types.js","names":[],"sources":["../../../src/cards/textField/textField.types.ts"],"sourcesContent":["import {\n createCardDeclaration,\n createOnAction,\n registerActions,\n} from \"@pihanga2/core\";\n\nexport const PI_TEXT_FIELD_CARD = \"pi/text-field\";\n\nexport const TextField = createCardDeclaration<\n PiTextFieldProps,\n PiTextFieldEvents\n>(PI_TEXT_FIELD_CARD);\n\nexport const PI_TEXT_FIELD_ACTION = registerActions(PI_TEXT_FIELD_CARD, [\n \"changed\",\n]);\n\nexport const onTextFieldChanged = createOnAction<PiTextFieldChangedEvent>(\n PI_TEXT_FIELD_ACTION.CHANGED,\n);\n\n/** @deprecated Use `onTextFieldChanged` instead. */\nexport const onPiTextFieldChanged = onTextFieldChanged;\n\nexport type PiTextFieldProps =
|
|
1
|
+
{"version":3,"file":"textField.types.js","names":[],"sources":["../../../src/cards/textField/textField.types.ts"],"sourcesContent":["import {\n createCardDeclaration,\n createOnAction,\n registerActions,\n} from \"@pihanga2/core\";\nimport type {FormFieldProps} from \"@/cards/form/form.types\";\n\nexport const PI_TEXT_FIELD_CARD = \"pi/text-field\";\n\nexport const TextField = createCardDeclaration<\n PiTextFieldProps,\n PiTextFieldEvents\n>(PI_TEXT_FIELD_CARD);\n\nexport const PI_TEXT_FIELD_ACTION = registerActions(PI_TEXT_FIELD_CARD, [\n \"changed\",\n]);\n\nexport const onTextFieldChanged = createOnAction<PiTextFieldChangedEvent>(\n PI_TEXT_FIELD_ACTION.CHANGED,\n);\n\n/** @deprecated Use `onTextFieldChanged` instead. */\nexport const onPiTextFieldChanged = onTextFieldChanged;\n\nexport type PiTextFieldProps = FormFieldProps & {\n /**\n * Controlled value used in standalone mode (outside a Form).\n * Ignored when `name` is set and the component is inside a pi/form.\n */\n value?: string;\n\n /** HTML input type (e.g. \"text\", \"email\", \"password\", \"number\"). */\n type?: string;\n\n /** Placeholder text shown when the input is empty. */\n placeholder?: string;\n\n /** When true, the input is disabled and non-interactive. */\n disabled?: boolean;\n\n /**\n * When true and this field is rendered inside a `pi/form` card, pressing\n * Enter requests the form's submit action\n * (`FormContext.requestAction(\"submit\")`) — equivalent to clicking a\n * `Button` with `formAction: \"submit\"`.\n *\n * Has no effect outside a `pi/form`.\n * @default false\n */\n submitOnEnter?: boolean;\n};\n\nexport type PiTextFieldChangedEvent = {\n /** Field name, mirrors the `name` prop if provided. */\n name?: string;\n /** New value after the change. */\n value: string;\n};\n\nexport type PiTextFieldEvents = {\n onChanged: PiTextFieldChangedEvent;\n};\n"],"mappings":";;AAOA,IAAa,IAAqB,iBAErB,IAAY,EAGvB,CAAkB,GAEP,IAAuB,EAAgB,GAAoB,CACtE,SACF,CAAC,GAEY,IAAqB,EAChC,EAAqB,OACvB,GAGa,IAAuB"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { FormFieldProps } from '../form/form.types';
|
|
1
2
|
export declare const PI_TOGGLE_GROUP_CARD = "pi/toggle-group";
|
|
2
3
|
export declare const ToggleGroup: <S extends import('@pihanga2/core').ReduxState>(p: import('@pihanga2/core').PiMapProps<PiToggleGroupProps, S, PiToggleGroupEvents>) => import('@pihanga2/core').PiCardDef;
|
|
3
4
|
export declare const PI_TOGGLE_GROUP_ACTION: {
|
|
@@ -18,13 +19,7 @@ export type PiToggleGroupItem = {
|
|
|
18
19
|
/** When true, this individual item is disabled. */
|
|
19
20
|
disabled?: boolean;
|
|
20
21
|
};
|
|
21
|
-
export type PiToggleGroupProps = {
|
|
22
|
-
/**
|
|
23
|
-
* Field name used to bind to FormContext when inside a pi/form card.
|
|
24
|
-
* When provided the component reads its selected value from form data and
|
|
25
|
-
* writes back via form.handleChange.
|
|
26
|
-
*/
|
|
27
|
-
name?: string;
|
|
22
|
+
export type PiToggleGroupProps = FormFieldProps & {
|
|
28
23
|
/**
|
|
29
24
|
* The list of toggle items to display.
|
|
30
25
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"toggleGroup.types.js","names":[],"sources":["../../../src/cards/toggleGroup/toggleGroup.types.ts"],"sourcesContent":["import {\n createCardDeclaration,\n createOnAction,\n registerActions,\n} from \"@pihanga2/core\";\n\nexport const PI_TOGGLE_GROUP_CARD = \"pi/toggle-group\";\n\nexport const ToggleGroup = createCardDeclaration<\n PiToggleGroupProps,\n PiToggleGroupEvents\n>(PI_TOGGLE_GROUP_CARD);\n\nexport const PI_TOGGLE_GROUP_ACTION = registerActions(PI_TOGGLE_GROUP_CARD, [\n \"changed\",\n]);\n\nexport const onToggleGroupChanged = createOnAction<PiToggleGroupChangedEvent>(\n PI_TOGGLE_GROUP_ACTION.CHANGED,\n);\n\n/** @deprecated Use `onToggleGroupChanged` instead. */\nexport const onPiToggleGroupChanged = onToggleGroupChanged;\n\n// ---------------------------------------------------------------------------\n// Item type\n// ---------------------------------------------------------------------------\n\nexport type PiToggleGroupItem = {\n /** The value associated with this toggle item. */\n value: string;\n /** Human-readable label rendered inside the toggle button. */\n label: string;\n /** When true, this individual item is disabled. */\n disabled?: boolean;\n};\n\n// ---------------------------------------------------------------------------\n// Props & Events\n// ---------------------------------------------------------------------------\n\nexport type PiToggleGroupProps =
|
|
1
|
+
{"version":3,"file":"toggleGroup.types.js","names":[],"sources":["../../../src/cards/toggleGroup/toggleGroup.types.ts"],"sourcesContent":["import {\n createCardDeclaration,\n createOnAction,\n registerActions,\n} from \"@pihanga2/core\";\nimport type {FormFieldProps} from \"@/cards/form/form.types\";\n\nexport const PI_TOGGLE_GROUP_CARD = \"pi/toggle-group\";\n\nexport const ToggleGroup = createCardDeclaration<\n PiToggleGroupProps,\n PiToggleGroupEvents\n>(PI_TOGGLE_GROUP_CARD);\n\nexport const PI_TOGGLE_GROUP_ACTION = registerActions(PI_TOGGLE_GROUP_CARD, [\n \"changed\",\n]);\n\nexport const onToggleGroupChanged = createOnAction<PiToggleGroupChangedEvent>(\n PI_TOGGLE_GROUP_ACTION.CHANGED,\n);\n\n/** @deprecated Use `onToggleGroupChanged` instead. */\nexport const onPiToggleGroupChanged = onToggleGroupChanged;\n\n// ---------------------------------------------------------------------------\n// Item type\n// ---------------------------------------------------------------------------\n\nexport type PiToggleGroupItem = {\n /** The value associated with this toggle item. */\n value: string;\n /** Human-readable label rendered inside the toggle button. */\n label: string;\n /** When true, this individual item is disabled. */\n disabled?: boolean;\n};\n\n// ---------------------------------------------------------------------------\n// Props & Events\n// ---------------------------------------------------------------------------\n\nexport type PiToggleGroupProps = FormFieldProps & {\n /**\n * The list of toggle items to display.\n */\n items: PiToggleGroupItem[];\n\n /**\n * Selection mode.\n * - `\"single\"` — at most one item can be active at a time.\n * - `\"multiple\"` — any number of items can be active simultaneously.\n *\n * @default \"single\"\n */\n type?: \"single\" | \"multiple\";\n\n /**\n * Controlled selected value(s).\n * - In `\"single\"` mode: a `string` (or `undefined` for nothing selected).\n * - In `\"multiple\"` mode: an array of `string`.\n *\n * Ignored when `name` is set and the component is inside a pi/form.\n * Also ignored when `selfManaged` is `true`.\n */\n value?: string | string[];\n\n /**\n * When `true`, the component manages its own selection state internally\n * using `React.useState`. The `value` prop is used only as the initial\n * value (i.e. `defaultValue`) and subsequent changes do not require an\n * external state update. `onChanged` is still fired so callers can\n * observe changes without owning the state.\n *\n * Has no effect when inside a pi/form (form context always takes\n * precedence).\n *\n * @default false\n */\n selfManaged?: boolean;\n\n /**\n * Visual style variant of the toggle buttons.\n * - `\"default\"` — transparent background, highlights on active.\n * - `\"outline\"` — bordered buttons, grouped or spaced.\n * - `\"pill\"` — segmented-control style: muted rounded-full container with a\n * filled foreground pill on the active item.\n *\n * @default \"default\"\n */\n variant?: \"default\" | \"outline\" | \"pill\";\n\n /**\n * Size of each toggle button.\n * @default \"default\"\n */\n size?: \"default\" | \"sm\" | \"lg\";\n\n /**\n * Gap between toggle buttons (in Tailwind spacing units).\n * `0` = buttons are joined (no gap, rounded ends only).\n * Positive values add space between each button.\n *\n * @default 0\n */\n spacing?: number;\n\n /** When true, the entire group is disabled and non-interactive. */\n disabled?: boolean;\n\n /** Extra Tailwind / CSS classes forwarded to the root element. */\n className?: string;\n};\n\nexport type PiToggleGroupChangedEvent = {\n /** Field name, mirrors the `name` prop if provided. */\n name?: string;\n /**\n * New selected value(s).\n * - In `\"single\"` mode: a `string` (empty string when nothing selected).\n * - In `\"multiple\"` mode: an array of `string`.\n */\n value: string | string[];\n};\n\nexport type PiToggleGroupEvents = {\n onChanged: PiToggleGroupChangedEvent;\n};\n"],"mappings":";;AAOA,IAAa,IAAuB,mBAEvB,IAAc,EAGzB,CAAoB,GAET,IAAyB,EAAgB,GAAsB,CAC1E,SACF,CAAC,GAEY,IAAuB,EAClC,EAAuB,OACzB,GAGa,IAAyB"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pihanga2/shadcn",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.21",
|
|
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": {
|
|
@@ -295,11 +295,10 @@
|
|
|
295
295
|
"peerDependencies": {
|
|
296
296
|
"react": "^19.1.0",
|
|
297
297
|
"react-dom": "^19.1.0",
|
|
298
|
-
"@pihanga2/core": "0.3.
|
|
298
|
+
"@pihanga2/core": "^0.3.40",
|
|
299
299
|
"@pihanga2/cards": "*"
|
|
300
300
|
},
|
|
301
301
|
"dependencies": {
|
|
302
|
-
"@pihanga2/shadcn": "UNKNOWN - add to root package.json",
|
|
303
302
|
"@radix-ui/react-collapsible": "^1.1.20",
|
|
304
303
|
"@radix-ui/react-dialog": "^1.1.15",
|
|
305
304
|
"@radix-ui/react-dropdown-menu": "^2.1.16",
|