@konce-pt/react 0.8.1 → 0.8.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +381 -27
- package/dist/accordion/llms.txt +56 -0
- package/dist/alert/llms.txt +45 -0
- package/dist/app-shell/app-shell.d.ts +20 -0
- package/dist/app-shell/app-shell.js +24 -0
- package/dist/app-shell/llms.txt +59 -0
- package/dist/auth/auth.d.ts +1 -1
- package/dist/auth/llms.txt +65 -0
- package/dist/autocomplete/autocomplete.d.ts +1 -1
- package/dist/autocomplete/llms.txt +44 -0
- package/dist/avatar/llms.txt +42 -0
- package/dist/avatar-group/avatar-group.d.ts +1 -1
- package/dist/avatar-group/llms.txt +38 -0
- package/dist/badge/llms.txt +38 -0
- package/dist/bottom-sheet/llms.txt +43 -0
- package/dist/breadcrumb/breadcrumb.d.ts +1 -1
- package/dist/breadcrumb/llms.txt +35 -0
- package/dist/button/llms.txt +56 -0
- package/dist/button-group/button-group.d.ts +1 -1
- package/dist/button-group/llms.txt +40 -0
- package/dist/card/llms.txt +60 -0
- package/dist/carousel/carousel.d.ts +1 -1
- package/dist/carousel/llms.txt +47 -0
- package/dist/charts/chart-legend.d.ts +1 -1
- package/dist/charts/llms.txt +57 -0
- package/dist/checkbox/llms.txt +39 -0
- package/dist/chip/llms.txt +41 -0
- package/dist/chips-input/llms.txt +40 -0
- package/dist/clock/llms.txt +50 -0
- package/dist/color-picker/color-picker.d.ts +1 -1
- package/dist/color-picker/llms.txt +40 -0
- package/dist/confirm/llms.txt +44 -0
- package/dist/context-menu/context-menu.d.ts +1 -1
- package/dist/context-menu/llms.txt +39 -0
- package/dist/data-table/data-table-types.d.ts +1 -1
- package/dist/data-table/data-table.d.ts +2 -10
- package/dist/data-table/data-table.js +17 -9
- package/dist/data-table/llms.txt +79 -0
- package/dist/data-view/data-view.d.ts +1 -1
- package/dist/data-view/llms.txt +49 -0
- package/dist/date-range/llms.txt +54 -0
- package/dist/datepicker/llms.txt +74 -0
- package/dist/dialog/llms.txt +51 -0
- package/dist/divider/llms.txt +28 -0
- package/dist/drawer/llms.txt +47 -0
- package/dist/empty/llms.txt +35 -0
- package/dist/fab/llms.txt +37 -0
- package/dist/fieldset/llms.txt +43 -0
- package/dist/file-upload/llms.txt +48 -0
- package/dist/form-field/llms.txt +55 -0
- package/dist/galleria/galleria.d.ts +1 -1
- package/dist/galleria/llms.txt +46 -0
- package/dist/grid/llms.txt +110 -0
- package/dist/icon/icon-registry.d.ts +5 -2
- package/dist/icon/icon-registry.js +5 -3
- package/dist/icon/llms.txt +66 -0
- package/dist/icon-button/llms.txt +38 -0
- package/dist/icons-entry/public-api.d.ts +5 -1
- package/dist/icons-entry/public-api.js +7 -1
- package/dist/image/llms.txt +46 -0
- package/dist/input/llms.txt +54 -0
- package/dist/input-mask/llms.txt +37 -0
- package/dist/input-number/llms.txt +44 -0
- package/dist/input-otp/llms.txt +43 -0
- package/dist/internal/use-breakpoint.js +18 -10
- package/dist/knob/llms.txt +46 -0
- package/dist/listbox/listbox.d.ts +1 -1
- package/dist/listbox/llms.txt +39 -0
- package/dist/map/llms.txt +108 -0
- package/dist/megamenu/llms.txt +48 -0
- package/dist/megamenu/megamenu.d.ts +1 -1
- package/dist/menu/llms.txt +56 -0
- package/dist/menu/menu-item.d.ts +1 -1
- package/dist/menu/menu-rows.d.ts +1 -1
- package/dist/menu/menu.d.ts +1 -1
- package/dist/menu/menu.js +12 -1
- package/dist/menubar/llms.txt +45 -0
- package/dist/menubar/menubar.d.ts +1 -1
- package/dist/meter-group/llms.txt +47 -0
- package/dist/meter-group/meter-group.d.ts +1 -1
- package/dist/order-list/llms.txt +41 -0
- package/dist/paginator/llms.txt +48 -0
- package/dist/paginator/paginator.d.ts +1 -1
- package/dist/paginator/paginator.js +7 -1
- package/dist/panel/llms.txt +55 -0
- package/dist/password/llms.txt +45 -0
- package/dist/pick-list/llms.txt +52 -0
- package/dist/popover/llms.txt +42 -0
- package/dist/progress/llms.txt +47 -0
- package/dist/public-api.d.ts +2 -1
- package/dist/public-api.js +1 -1
- package/dist/radio-group/llms.txt +40 -0
- package/dist/radio-group/radio-group.d.ts +1 -1
- package/dist/rating/llms.txt +43 -0
- package/dist/rich-text/llms.txt +61 -0
- package/dist/rich-text/rich-text.d.ts +1 -1
- package/dist/roadmap/llms.txt +82 -0
- package/dist/scroll-top/llms.txt +41 -0
- package/dist/select/llms.txt +56 -0
- package/dist/select/select.d.ts +1 -1
- package/dist/sidenav/llms.txt +53 -0
- package/dist/skeleton/llms.txt +33 -0
- package/dist/slider/llms.txt +50 -0
- package/dist/speed-dial/llms.txt +46 -0
- package/dist/speed-dial/speed-dial.d.ts +1 -1
- package/dist/spinner/llms.txt +33 -0
- package/dist/split-button/llms.txt +54 -0
- package/dist/split-button/split-button.d.ts +1 -1
- package/dist/splitter/llms.txt +44 -0
- package/dist/stepper/llms.txt +64 -0
- package/dist/switch/llms.txt +42 -0
- package/dist/switch-group/llms.txt +43 -0
- package/dist/switch-group/switch-group.d.ts +1 -1
- package/dist/tabs/llms.txt +48 -0
- package/dist/textarea/llms.txt +40 -0
- package/dist/timeline/llms.txt +53 -0
- package/dist/timeline/timeline.d.ts +1 -1
- package/dist/toast/llms.txt +52 -0
- package/dist/toolbar/llms.txt +45 -0
- package/dist/tooltip/llms.txt +42 -0
- package/dist/tree/llms.txt +45 -0
- package/dist/tree/tree.d.ts +2 -2
- package/package.json +11 -11
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# KptSplitButton (@konce-pt/react)
|
|
2
|
+
|
|
3
|
+
A split button — a primary action plus a dropdown of further actions.
|
|
4
|
+
Import: `import { KptSplitButton } from '@konce-pt/react';`
|
|
5
|
+
|
|
6
|
+
## DOM
|
|
7
|
+
<span class="kpt-split-button-host">
|
|
8
|
+
<div class="kpt-split-button" data-variant="filled">
|
|
9
|
+
<button class="kpt-split-button__main" type="button">Save</button>
|
|
10
|
+
<button class="kpt-split-button__toggle" type="button" aria-label="More actions">…chevron…</button>
|
|
11
|
+
</div>
|
|
12
|
+
</span>
|
|
13
|
+
<!-- while open, in a portal: -->
|
|
14
|
+
<div class="kpt-split-button__panel" role="menu">…rows…</div>
|
|
15
|
+
|
|
16
|
+
## Props
|
|
17
|
+
- `variant`: the same union as `KptButton` (default 'filled')
|
|
18
|
+
- `items`: `KptMenuItem<T>[]` — the same shape as `KptMenu`
|
|
19
|
+
- `disabled`: boolean — disables both buttons
|
|
20
|
+
- `onPrimaryClick()` — the main action
|
|
21
|
+
- `onSelect(item)` — a pick from the menu
|
|
22
|
+
- `open` / `defaultOpen` / `onOpenChange` — the panel state
|
|
23
|
+
- `children` — the content of the main action
|
|
24
|
+
- `locale`, `dictionary` — i18n overrides for this component only
|
|
25
|
+
|
|
26
|
+
## The panel aligns to the right
|
|
27
|
+
The toggle sits on the right-hand side of the control, so the panel is anchored by its RIGHT edge
|
|
28
|
+
(`align="end"` on the overlay). Anchored to the left it would hang off the control instead of under
|
|
29
|
+
it — the same reasoning the Angular port encodes in its CDK position list.
|
|
30
|
+
|
|
31
|
+
## Shared rows
|
|
32
|
+
The panel renders the same rows as `KptMenu` — icons, descriptions, badges, separators, headers and
|
|
33
|
+
the `danger` modifier all behave identically, only the BEM block differs.
|
|
34
|
+
|
|
35
|
+
## i18n
|
|
36
|
+
The toggle's label comes from `splitButton.more` in the dictionary.
|
|
37
|
+
|
|
38
|
+
## Examples
|
|
39
|
+
<KptSplitButton items={items} onPrimaryClick={save} onSelect={onItem}>Save</KptSplitButton>
|
|
40
|
+
|
|
41
|
+
const items: KptMenuItem[] = [
|
|
42
|
+
{ label: 'Save as draft', value: 'draft' },
|
|
43
|
+
{ label: 'Save and publish', value: 'publish' },
|
|
44
|
+
{ separator: true },
|
|
45
|
+
{ label: 'Discard', value: 'discard', danger: true },
|
|
46
|
+
];
|
|
47
|
+
|
|
48
|
+
## Tokens
|
|
49
|
+
The `--kpt-button-*` tokens of the chosen variant, plus `--kpt-color-surface-raised` and
|
|
50
|
+
`--kpt-elevation-3` for the panel.
|
|
51
|
+
|
|
52
|
+
## Accessibility
|
|
53
|
+
Two native buttons; the toggle carries `aria-label`, the panel is `role="menu"` with
|
|
54
|
+
`role="menuitem"` rows.
|
|
@@ -4,7 +4,7 @@ import type { KptMenuItem } from '../menu/menu-item.ts';
|
|
|
4
4
|
import type { KptButtonVariant } from '../button/button.tsx';
|
|
5
5
|
export interface KptSplitButtonProps<T> extends Omit<ComponentPropsWithRef<'span'>, 'onSelect'>, KptI18nOverrides {
|
|
6
6
|
variant?: KptButtonVariant;
|
|
7
|
-
items?: KptMenuItem<T>[];
|
|
7
|
+
items?: readonly KptMenuItem<T>[];
|
|
8
8
|
disabled?: boolean;
|
|
9
9
|
/** Kliknięcie akcji głównej. */
|
|
10
10
|
onPrimaryClick?: () => void;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# KptSplitter (@konce-pt/react)
|
|
2
|
+
|
|
3
|
+
Two panes with a draggable handle.
|
|
4
|
+
Import: `import { KptSplitter } from '@konce-pt/react';`
|
|
5
|
+
|
|
6
|
+
## DOM
|
|
7
|
+
<div class="kpt-splitter-host">
|
|
8
|
+
<div class="kpt-splitter" data-orientation="horizontal">
|
|
9
|
+
<div class="kpt-splitter__pane" style="flex-basis:40%">…</div>
|
|
10
|
+
<div class="kpt-splitter__gutter" role="separator" tabindex="0" aria-valuenow="40"></div>
|
|
11
|
+
<div class="kpt-splitter__pane" style="flex-basis:60%">…</div>
|
|
12
|
+
</div>
|
|
13
|
+
</div>
|
|
14
|
+
|
|
15
|
+
## Props
|
|
16
|
+
- `orientation`: `'horizontal'` (default) | `'vertical'`
|
|
17
|
+
- `startSize` / `defaultStartSize` / `onStartSizeChange` — the first pane's size in percent
|
|
18
|
+
- `minSize`: number (percent, default 10) — neither pane goes below it
|
|
19
|
+
- `className`, `ref` and every other `<div>` prop go to the host
|
|
20
|
+
|
|
21
|
+
## Panes
|
|
22
|
+
`<KptSplitter.Start>` and `<KptSplitter.End>` replace Angular's `[kptSplitStart]` / `[kptSplitEnd]`
|
|
23
|
+
slots. They render nothing themselves: the splitter reads their children and wraps them in
|
|
24
|
+
`__pane`, because it is the splitter that owns the size.
|
|
25
|
+
|
|
26
|
+
## Dragging listens on the window
|
|
27
|
+
`pointermove` and `pointerup` are attached to `window`, not to the handle: on a quick drag the
|
|
28
|
+
pointer outruns a 6px strip, and a handle-bound listener would drop the drag after a few pixels.
|
|
29
|
+
|
|
30
|
+
## Examples
|
|
31
|
+
<KptSplitter startSize={size} onStartSizeChange={setSize}>
|
|
32
|
+
<KptSplitter.Start>Left</KptSplitter.Start>
|
|
33
|
+
<KptSplitter.End>Right</KptSplitter.End>
|
|
34
|
+
</KptSplitter>
|
|
35
|
+
|
|
36
|
+
<KptSplitter orientation="vertical" defaultStartSize={30} minSize={20}>…</KptSplitter>
|
|
37
|
+
|
|
38
|
+
## Tokens
|
|
39
|
+
The handle `--kpt-color-border` → `--kpt-color-primary` on hover and focus; the frame
|
|
40
|
+
`--kpt-color-border` with `--kpt-radius-md`.
|
|
41
|
+
|
|
42
|
+
## Accessibility
|
|
43
|
+
The handle is `role="separator"` with `aria-orientation` and `aria-valuenow`, reachable with Tab;
|
|
44
|
+
the arrow keys resize by 2% a press, clamped by `minSize`.
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# KptStepper + KptStep (@konce-pt/react)
|
|
2
|
+
|
|
3
|
+
A step wizard — a header of numbered steps plus the active step's content.
|
|
4
|
+
Import: `import { KptStepper, useKptStepper } from '@konce-pt/react';`
|
|
5
|
+
|
|
6
|
+
## DOM
|
|
7
|
+
<div class="kpt-stepper-host" style="--kpt-anim-duration:500ms; --kpt-anim-dir:1">
|
|
8
|
+
<ol class="kpt-stepper__header">
|
|
9
|
+
<li class="kpt-stepper__step is-done">
|
|
10
|
+
<button class="kpt-stepper__marker">✓</button>
|
|
11
|
+
<span class="kpt-stepper__label">Account</span>
|
|
12
|
+
<span class="kpt-stepper__connector"></span>
|
|
13
|
+
</li>
|
|
14
|
+
…
|
|
15
|
+
</ol>
|
|
16
|
+
<div class="kpt-stepper__body"><div class="kpt-stepper__panel">…</div></div>
|
|
17
|
+
</div>
|
|
18
|
+
|
|
19
|
+
## KptStepper props
|
|
20
|
+
- `activeIndex` / `defaultActiveIndex` / `onActiveIndexChange`
|
|
21
|
+
- `animated`: boolean (default true), `animationDuration`: ms (default 500)
|
|
22
|
+
- `className`, `ref` and every other `<div>` prop go to the host
|
|
23
|
+
|
|
24
|
+
## KptStepper.Step props
|
|
25
|
+
- `label`: string (required); `children` — the step's content
|
|
26
|
+
|
|
27
|
+
## useKptStepper()
|
|
28
|
+
`{ activeIndex, count, next, prev, goTo }` — the replacement for Angular's `#s` + `s.next()`.
|
|
29
|
+
It reads a context the stepper provides around the panel, so it works only in a component
|
|
30
|
+
rendered inside a step (a hook cannot be called in the parent's body) and throws elsewhere.
|
|
31
|
+
`count` lets a step hide "Next" on the last one.
|
|
32
|
+
|
|
33
|
+
## The step is a config carrier
|
|
34
|
+
`KptStep` renders `null`; `KptStepper` reads its props and decides what to show, so only the
|
|
35
|
+
active step's content is ever mounted — the same laziness as the `kpt-step` template in Angular.
|
|
36
|
+
|
|
37
|
+
## The panel is keyed by index
|
|
38
|
+
`key={active}` forces a remount on every change, otherwise the enter animation would have nothing
|
|
39
|
+
to start from. The slide direction rides on `--kpt-anim-dir` (1 forward, -1 back), so jumping to
|
|
40
|
+
an earlier step animates from the other side.
|
|
41
|
+
|
|
42
|
+
## Examples
|
|
43
|
+
<KptStepper>
|
|
44
|
+
<KptStepper.Step label="Account"><StepNav /></KptStepper.Step>
|
|
45
|
+
<KptStepper.Step label="Profile">…</KptStepper.Step>
|
|
46
|
+
</KptStepper>
|
|
47
|
+
|
|
48
|
+
function StepNav() {
|
|
49
|
+
const { activeIndex, count, next, prev } = useKptStepper();
|
|
50
|
+
return (
|
|
51
|
+
<>
|
|
52
|
+
{activeIndex > 0 && <KptButton size="sm" variant="text" onClick={prev}>Back</KptButton>}
|
|
53
|
+
{activeIndex < count - 1 && <KptButton size="sm" onClick={next}>Next</KptButton>}
|
|
54
|
+
</>
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
## Tokens
|
|
59
|
+
The active and completed step: `--kpt-color-primary` (marker, connector); the rest
|
|
60
|
+
`--kpt-color-border-strong` and `--kpt-color-on-surface-muted`.
|
|
61
|
+
|
|
62
|
+
## Accessibility
|
|
63
|
+
The header is an `<ol>` of real buttons — every step is reachable with the keyboard; the active
|
|
64
|
+
marker carries `aria-current="step"`.
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# KptSwitch (@konce-pt/react)
|
|
2
|
+
|
|
3
|
+
A switch / toggle. Underneath it is a native `<input type="checkbox" role="switch">`, so the
|
|
4
|
+
keyboard and screen readers work with no extra handling.
|
|
5
|
+
Import: `import { KptSwitch } from '@konce-pt/react';`
|
|
6
|
+
|
|
7
|
+
## DOM
|
|
8
|
+
<span class="kpt-switch-host">
|
|
9
|
+
<label class="kpt-switch">
|
|
10
|
+
<input type="checkbox" role="switch" class="kpt-switch__input">
|
|
11
|
+
<span class="kpt-switch__track" aria-hidden="true"><span class="kpt-switch__thumb"></span></span>
|
|
12
|
+
<span class="kpt-switch__label">Notifications</span>
|
|
13
|
+
<span class="kpt-switch__state kpt-switch__state--on">On</span>
|
|
14
|
+
</label>
|
|
15
|
+
</span>
|
|
16
|
+
|
|
17
|
+
## Props
|
|
18
|
+
- `label`: string, `labelPosition`: 'start' | 'end' (default 'end')
|
|
19
|
+
- `onLabel`, `offLabel`: string — the state text, swapped on toggle
|
|
20
|
+
- `checked` / `defaultChecked`, `onCheckedChange(checked)`, `onTouch()`
|
|
21
|
+
- `required`, `invalid`, `touched` — as in `KptCheckbox`
|
|
22
|
+
- `hostProps` — props for the `.kpt-switch-host` wrapper
|
|
23
|
+
- `className` goes to the `.kpt-switch` block; the rest to the native `<input>`
|
|
24
|
+
|
|
25
|
+
## The state text needs a controlled value
|
|
26
|
+
`onLabel` and `offLabel` read `checked`, so they only follow the switch in controlled mode.
|
|
27
|
+
Uncontrolled, the value belongs to the DOM and React never learns about a toggle, which would
|
|
28
|
+
freeze the state text on its initial value — use `checked` with `onCheckedChange` whenever you
|
|
29
|
+
show one.
|
|
30
|
+
|
|
31
|
+
## Examples
|
|
32
|
+
<KptSwitch name="notifications" label="Notifications" />
|
|
33
|
+
<KptSwitch checked={on} onCheckedChange={setOn} onLabel="On" offLabel="Off" />
|
|
34
|
+
<KptSwitch checked={on} onCheckedChange={setOn} label="Dark mode" labelPosition="start" />
|
|
35
|
+
|
|
36
|
+
## Tokens
|
|
37
|
+
`--kpt-color-primary` (the on track), `--kpt-color-muted` (the off track), `--kpt-color-surface`
|
|
38
|
+
(the thumb), `--kpt-motion-duration-fast`.
|
|
39
|
+
|
|
40
|
+
## Accessibility
|
|
41
|
+
`role="switch"` on a native checkbox — a screen reader announces on/off instead of
|
|
42
|
+
checked/unchecked. The track and the thumb are `aria-hidden`.
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# KptSwitchGroup (@konce-pt/react)
|
|
2
|
+
|
|
3
|
+
A group of switches — mutually exclusive by default, multi-select with `multiple`.
|
|
4
|
+
Import: `import { KptSwitchGroup } from '@konce-pt/react';`
|
|
5
|
+
|
|
6
|
+
## DOM
|
|
7
|
+
<div class="kpt-switch-group-host">
|
|
8
|
+
<div class="kpt-switch-group" role="group">
|
|
9
|
+
<span class="kpt-switch-host kpt-switch-group__item">…KptSwitch…</span>
|
|
10
|
+
…one per option…
|
|
11
|
+
</div>
|
|
12
|
+
</div>
|
|
13
|
+
|
|
14
|
+
## Props
|
|
15
|
+
- `options`: `KptOption<T>[]` — `{ label, value, disabled? }`
|
|
16
|
+
- `value` / `defaultValue` / `onValueChange` — single select: the option's value or `null`;
|
|
17
|
+
with `multiple`: an array of the selected values
|
|
18
|
+
- `multiple`: boolean (default false)
|
|
19
|
+
- `orientation`: `'vertical'` (default) | `'horizontal'`
|
|
20
|
+
- `allowDeselect`: boolean (default true) — single select only; in `multiple` mode turning an
|
|
21
|
+
option off is always allowed
|
|
22
|
+
- `disabled`, `invalid`, `touched`, `onTouch()`
|
|
23
|
+
- `className`, `ref` and every other `<div>` prop go to the host
|
|
24
|
+
|
|
25
|
+
## Single select comes out of the value, not out of the switches
|
|
26
|
+
Every entry is a `KptSwitch` whose `checked` is derived from the group value, so turning one on
|
|
27
|
+
turns the rest off by itself — there is no per-switch state to keep in sync.
|
|
28
|
+
|
|
29
|
+
That is also why `allowDeselect={false}` needs no code: the handler writes nothing, so React
|
|
30
|
+
re-applies the controlled `checked` and the switch snaps back on.
|
|
31
|
+
|
|
32
|
+
## Examples
|
|
33
|
+
<KptSwitchGroup value={mode} onValueChange={setMode} options={options} />
|
|
34
|
+
<KptSwitchGroup multiple value={channels} onValueChange={setChannels} options={options} />
|
|
35
|
+
<KptSwitchGroup orientation="horizontal" value={mode} onValueChange={setMode} options={options} />
|
|
36
|
+
|
|
37
|
+
## Tokens
|
|
38
|
+
Layout only: `--kpt-space-2` (vertical gap) and `--kpt-space-4` (horizontal). The look comes from
|
|
39
|
+
`KptSwitch` and its tokens.
|
|
40
|
+
|
|
41
|
+
## Accessibility
|
|
42
|
+
`role="group"` with `aria-invalid` once the field is touched; every entry keeps the native
|
|
43
|
+
checkbox of `KptSwitch`, so keyboard and screen readers work with no extra handling.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { ComponentPropsWithRef } from 'react';
|
|
2
2
|
import type { KptOption } from '../shared/types.ts';
|
|
3
3
|
export interface KptSwitchGroupProps<T> extends Omit<ComponentPropsWithRef<'div'>, 'onChange' | 'defaultValue'> {
|
|
4
|
-
options?: KptOption<T>[];
|
|
4
|
+
options?: readonly KptOption<T>[];
|
|
5
5
|
/** Pojedynczy wybór: wartość opcji albo `null`. Tryb `multiple`: tablica wartości. */
|
|
6
6
|
value?: T | T[] | null;
|
|
7
7
|
defaultValue?: T | T[] | null;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# KptTabs (@konce-pt/react)
|
|
2
|
+
|
|
3
|
+
Tabs — switching views, with the content rendered lazily.
|
|
4
|
+
Import: `import { KptTabs } from '@konce-pt/react';`
|
|
5
|
+
|
|
6
|
+
## DOM
|
|
7
|
+
<div class="kpt-tabs-host" style="--kpt-anim-duration: 500ms; --kpt-anim-dir: 1">
|
|
8
|
+
<div class="kpt-tabs__header" role="tablist">
|
|
9
|
+
<button class="kpt-tabs__tab is-active" role="tab" aria-selected="true">General</button>
|
|
10
|
+
<button class="kpt-tabs__tab" role="tab" aria-selected="false">Advanced</button>
|
|
11
|
+
<span class="kpt-tabs__ink" style="width: 95px; transform: translateX(85px)"></span>
|
|
12
|
+
</div>
|
|
13
|
+
<div class="kpt-tabs__body" role="tabpanel">
|
|
14
|
+
<div class="kpt-tabs__panel">…active tab content…</div>
|
|
15
|
+
</div>
|
|
16
|
+
</div>
|
|
17
|
+
|
|
18
|
+
## Props
|
|
19
|
+
- `activeIndex` / `defaultActiveIndex` / `onActiveIndexChange` — controlled or uncontrolled
|
|
20
|
+
- `animated`: boolean (default true), `animationDuration`: number (ms, default 500)
|
|
21
|
+
- `children` — `<KptTabs.Tab>` elements
|
|
22
|
+
|
|
23
|
+
## KptTabs.Tab
|
|
24
|
+
`label` (required), `disabled`, `children`. The tab component never renders itself — `KptTabs`
|
|
25
|
+
reads its props and decides what to show, exactly as the Angular version reads the `kpt-tab`
|
|
26
|
+
template. Only the active tab's content is in the DOM.
|
|
27
|
+
|
|
28
|
+
## The underline is measured, not computed
|
|
29
|
+
`__ink` takes its width and offset from the active button in the DOM, not from the index: tabs have
|
|
30
|
+
different widths and the labels change with the language. The measurement runs after every render,
|
|
31
|
+
and the state is only replaced when the numbers actually change — otherwise each measurement would
|
|
32
|
+
schedule another render and the component would loop.
|
|
33
|
+
|
|
34
|
+
## Examples
|
|
35
|
+
<KptTabs>
|
|
36
|
+
<KptTabs.Tab label="General">…</KptTabs.Tab>
|
|
37
|
+
<KptTabs.Tab label="Advanced">…</KptTabs.Tab>
|
|
38
|
+
</KptTabs>
|
|
39
|
+
|
|
40
|
+
<KptTabs activeIndex={tab} onActiveIndexChange={setTab} animated={false}>…</KptTabs>
|
|
41
|
+
|
|
42
|
+
## Tokens
|
|
43
|
+
`--kpt-color-primary` (the active tab and the ink), `--kpt-color-on-surface-muted`,
|
|
44
|
+
`--kpt-color-border`, `--kpt-motion-easing-standard`.
|
|
45
|
+
|
|
46
|
+
## Accessibility
|
|
47
|
+
The header is `role="tablist"` with `role="tab"` buttons carrying `aria-selected`; the body is
|
|
48
|
+
`role="tabpanel"`. A disabled tab is a disabled button, so the keyboard skips it.
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# KptTextarea (@konce-pt/react)
|
|
2
|
+
|
|
3
|
+
A multi-line field, with optional auto-resize. It renders a native `<textarea>` inside a
|
|
4
|
+
`.kpt-textarea-host` wrapper. Import: `import { KptTextarea } from '@konce-pt/react';`
|
|
5
|
+
|
|
6
|
+
## DOM
|
|
7
|
+
<span class="kpt-textarea-host">
|
|
8
|
+
<textarea class="kpt-textarea__field" rows="3"></textarea>
|
|
9
|
+
</span>
|
|
10
|
+
|
|
11
|
+
## Props
|
|
12
|
+
- `autoResize`: boolean — matches the height to the content on every change
|
|
13
|
+
- `rows`: number (default 3) — the starting height
|
|
14
|
+
- `value` / `defaultValue` — controlled or uncontrolled, like a native textarea
|
|
15
|
+
- `onValueChange(value)`, `onTouch()` — the value alone, and the blur moment
|
|
16
|
+
- `required`: boolean — set as `aria-required`, not as the native attribute
|
|
17
|
+
- `invalid`, `touched` — the error state, gated the same way as in `KptInput`
|
|
18
|
+
- `hostProps` — props for the wrapper
|
|
19
|
+
- `className`, `ref`, `name`, `placeholder` and every other `<textarea>` prop go to the textarea
|
|
20
|
+
|
|
21
|
+
## Auto-resize
|
|
22
|
+
The height is read straight from the DOM (`scrollHeight`), so it is right for a controlled field, an
|
|
23
|
+
uncontrolled one, and a prefilled initial value alike. The measurement resets the height to `auto`
|
|
24
|
+
first — without that a field can only ever grow, since `scrollHeight` never drops below the current
|
|
25
|
+
height.
|
|
26
|
+
|
|
27
|
+
## Examples
|
|
28
|
+
<KptTextarea name="notes" placeholder="Notes…" autoResize />
|
|
29
|
+
<KptTextarea value={note} onValueChange={setNote} rows={6} />
|
|
30
|
+
<KptFormField label="Notes" error={err}>
|
|
31
|
+
<KptTextarea invalid={!!err} onTouch={markTouched} />
|
|
32
|
+
</KptFormField>
|
|
33
|
+
|
|
34
|
+
## Tokens
|
|
35
|
+
`--kpt-form-field-{bg,text,placeholder,border,border-hover,border-focus,border-error,radius}` —
|
|
36
|
+
the same set as the text field, so both controls stay in step.
|
|
37
|
+
|
|
38
|
+
## Accessibility
|
|
39
|
+
A native `<textarea>`. Inside `KptFormField` it takes its `id` from the wrapper, so `label[for]`
|
|
40
|
+
is wired with no configuration.
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# KptTimeline (@konce-pt/react)
|
|
2
|
+
|
|
3
|
+
A timeline — a vertical list of events with markers.
|
|
4
|
+
Import: `import { KptTimeline } from '@konce-pt/react';`
|
|
5
|
+
|
|
6
|
+
## DOM
|
|
7
|
+
<div class="kpt-timeline-host">
|
|
8
|
+
<ol class="kpt-timeline">
|
|
9
|
+
<li class="kpt-timeline__item">
|
|
10
|
+
<div class="kpt-timeline__marker" data-variant="success">…icon…</div>
|
|
11
|
+
<div class="kpt-timeline__content">
|
|
12
|
+
<div class="kpt-timeline__header">
|
|
13
|
+
<span class="kpt-timeline__title">Order created</span>
|
|
14
|
+
<span class="kpt-timeline__time">10:02</span>
|
|
15
|
+
</div>
|
|
16
|
+
<p class="kpt-timeline__desc">…</p>
|
|
17
|
+
</div>
|
|
18
|
+
</li>
|
|
19
|
+
</ol>
|
|
20
|
+
</div>
|
|
21
|
+
|
|
22
|
+
## Props
|
|
23
|
+
- `items`: `KptTimelineItem[]`
|
|
24
|
+
- `className`, `ref` and every other `<div>` prop go to the host
|
|
25
|
+
|
|
26
|
+
### KptTimelineItem
|
|
27
|
+
- `title`: string (required)
|
|
28
|
+
- `description?`, `time?`: string; `icon?`: an icon name from the registry
|
|
29
|
+
- `variant?`: `'neutral' | 'primary' | 'success' | 'danger' | 'warning' | 'info'` (default `'primary'`)
|
|
30
|
+
|
|
31
|
+
## The variant is an attribute, not a class
|
|
32
|
+
The marker carries `data-variant`, and the SCSS maps it to `--_color` — the same contract as every
|
|
33
|
+
other component in the library, so a new variant is a token, not a new class.
|
|
34
|
+
|
|
35
|
+
## The connecting line is a pseudo-element
|
|
36
|
+
`::before` on every item but the last, so the line is drawn between markers without an extra node
|
|
37
|
+
and needs no knowledge of the list's length.
|
|
38
|
+
|
|
39
|
+
## Examples
|
|
40
|
+
<KptTimeline items={events} />
|
|
41
|
+
|
|
42
|
+
const events: KptTimelineItem[] = [
|
|
43
|
+
{ title: 'Order created', time: '10:02', variant: 'success', icon: 'check' },
|
|
44
|
+
{ title: 'Shipped', time: '12:30', variant: 'info' },
|
|
45
|
+
];
|
|
46
|
+
|
|
47
|
+
## Tokens
|
|
48
|
+
The marker follows the variant (`--kpt-color-{variant}`), the line `--kpt-color-border`, the
|
|
49
|
+
description `--kpt-color-on-surface-muted`.
|
|
50
|
+
|
|
51
|
+
## Accessibility
|
|
52
|
+
An ordered list (`<ol>`), so the sequence of events is conveyed by the markup itself; markers are
|
|
53
|
+
decorative and carry no text of their own.
|
|
@@ -8,7 +8,7 @@ export interface KptTimelineItem {
|
|
|
8
8
|
variant?: 'neutral' | 'primary' | 'success' | 'danger' | 'warning' | 'info';
|
|
9
9
|
}
|
|
10
10
|
export interface KptTimelineProps extends ComponentPropsWithRef<'div'> {
|
|
11
|
-
items?: KptTimelineItem[];
|
|
11
|
+
items?: readonly KptTimelineItem[];
|
|
12
12
|
}
|
|
13
13
|
/**
|
|
14
14
|
* Oś czasu — pionowa lista zdarzeń z markerami.
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# Toast (@konce-pt/react)
|
|
2
|
+
|
|
3
|
+
Notifications. `kptToast` raises them, `<KptToastContainer />` renders them.
|
|
4
|
+
Import: `import { kptToast, KptToastContainer } from '@konce-pt/react';`
|
|
5
|
+
|
|
6
|
+
## DOM
|
|
7
|
+
<div class="kpt-toast-container-host">
|
|
8
|
+
<div class="kpt-toast-container" aria-live="polite" aria-atomic="false">
|
|
9
|
+
<div class="kpt-toast" data-variant="success" role="status">
|
|
10
|
+
<span class="kpt-icon-host kpt-toast__icon">…</span>
|
|
11
|
+
<div class="kpt-toast__content">
|
|
12
|
+
<div class="kpt-toast__title">Saved</div>
|
|
13
|
+
<div class="kpt-toast__message">Your changes are stored.</div>
|
|
14
|
+
</div>
|
|
15
|
+
<button class="kpt-toast__close" type="button" aria-label="Close">…</button>
|
|
16
|
+
</div>
|
|
17
|
+
</div>
|
|
18
|
+
</div>
|
|
19
|
+
|
|
20
|
+
## kptToast
|
|
21
|
+
- `show(message, options?)` — returns the toast id
|
|
22
|
+
- `info` / `success` / `warning` / `error` — the same, with the variant preset
|
|
23
|
+
- `dismiss(id)`, `clear()`
|
|
24
|
+
- options: `title`, `variant`, `duration` (ms, default 4000; `0` disables auto-dismiss)
|
|
25
|
+
|
|
26
|
+
## A module singleton, not a provider
|
|
27
|
+
The store lives in the module, which is the closest equivalent of Angular's
|
|
28
|
+
`providedIn: 'root'`. `kptToast.error(...)` therefore works from anywhere — including outside the
|
|
29
|
+
React tree, in a data-layer error handler or an HTTP interceptor — with no provider wrapping the
|
|
30
|
+
application. `useKptToasts()` exposes the current list when you want to render them yourself.
|
|
31
|
+
|
|
32
|
+
## Placement
|
|
33
|
+
Render `<KptToastContainer />` once, near the root of the application. Toasts raised before it
|
|
34
|
+
mounts are kept in the store and appear as soon as it does.
|
|
35
|
+
|
|
36
|
+
## Examples
|
|
37
|
+
// once in the app
|
|
38
|
+
<KptToastContainer />
|
|
39
|
+
|
|
40
|
+
kptToast.success('Saved', { title: 'Saved' });
|
|
41
|
+
kptToast.error('Could not connect to the server.', { title: 'Error', duration: 0 });
|
|
42
|
+
const id = kptToast.info('Uploading…', { duration: 0 });
|
|
43
|
+
kptToast.dismiss(id);
|
|
44
|
+
|
|
45
|
+
## Tokens
|
|
46
|
+
The semantic colour pairs of each variant (`--kpt-color-info` / `-success` / `-warning` /
|
|
47
|
+
`-danger` with their `-subtle` and `on-` counterparts), `--kpt-elevation-3`, `--kpt-z-overlay`.
|
|
48
|
+
|
|
49
|
+
## Accessibility
|
|
50
|
+
The container is `aria-live="polite"` with `aria-atomic="false"`, and each toast is
|
|
51
|
+
`role="status"`, so a screen reader announces new ones without interrupting the current task.
|
|
52
|
+
The close button gets its label from `common.close`.
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# KptToolbar (@konce-pt/react)
|
|
2
|
+
|
|
3
|
+
The top bar — a horizontal strip for application content (logo, actions).
|
|
4
|
+
Import: `import { KptToolbar, KptToolbarSpacer } from '@konce-pt/react';`
|
|
5
|
+
|
|
6
|
+
## DOM
|
|
7
|
+
<div class="kpt-toolbar kpt-toolbar--elevated">
|
|
8
|
+
…children…
|
|
9
|
+
<span kpttoolbarspacer=""></span>
|
|
10
|
+
…children…
|
|
11
|
+
</div>
|
|
12
|
+
|
|
13
|
+
## Props
|
|
14
|
+
- `elevated`: boolean — adds a shadow under the bar
|
|
15
|
+
- `wrap`: boolean — lets the content wrap onto further rows when it runs out of room
|
|
16
|
+
- `className`, `ref` and every other `<div>` prop go to the bar itself
|
|
17
|
+
|
|
18
|
+
`wrap` is opt-in because wrapping changes what `<KptToolbarSpacer>` does: in a single-row bar it
|
|
19
|
+
pushes content apart, in a wrapping one it can shove the rest onto a new row.
|
|
20
|
+
|
|
21
|
+
## KptToolbarSpacer
|
|
22
|
+
A flexible gap that pushes the bar's content apart. It carries the `kpttoolbarspacer` attribute the
|
|
23
|
+
shared SCSS targets (attribute names in CSS selectors are case-insensitive in HTML, so one rule
|
|
24
|
+
serves both ports).
|
|
25
|
+
|
|
26
|
+
## Examples
|
|
27
|
+
<KptToolbar elevated>
|
|
28
|
+
<strong>Koncept UI</strong>
|
|
29
|
+
<KptToolbarSpacer />
|
|
30
|
+
<KptButton variant="text">Sign out</KptButton>
|
|
31
|
+
</KptToolbar>
|
|
32
|
+
|
|
33
|
+
<KptAppShell toolbar={<KptToolbar elevated>…</KptToolbar>} sidenav={…}>…</KptAppShell>
|
|
34
|
+
|
|
35
|
+
## Responsiveness
|
|
36
|
+
Below the `sm` breakpoint the bar shrinks on its own — a lower height
|
|
37
|
+
(`--kpt-toolbar-height-compact`), narrower inline padding and a smaller gap. No props involved.
|
|
38
|
+
|
|
39
|
+
## Tokens
|
|
40
|
+
`--kpt-toolbar-height` (3.5rem), `--kpt-toolbar-height-compact` (3rem), `--kpt-toolbar-bg`,
|
|
41
|
+
`--kpt-toolbar-fg`, `--kpt-toolbar-border`, `--kpt-elevation-1` for the elevated variant.
|
|
42
|
+
|
|
43
|
+
## Accessibility
|
|
44
|
+
A plain container with no role of its own. Give it `role="banner"` or wrap it in a `<header>`
|
|
45
|
+
when it is the page's main bar.
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# KptTooltip (@konce-pt/react)
|
|
2
|
+
|
|
3
|
+
A tooltip shown on hover and focus. Light — the element is appended to `body` and positioned
|
|
4
|
+
against the child. Import: `import { KptTooltip } from '@konce-pt/react';`
|
|
5
|
+
|
|
6
|
+
## DOM
|
|
7
|
+
The component renders NO wrapper of its own — it clones the child and attaches the handlers and a
|
|
8
|
+
ref to it, so the tree stays exactly as it would be without the tooltip. This is the port of the
|
|
9
|
+
`[kptTooltip]` directive, which likewise added nothing to the DOM.
|
|
10
|
+
|
|
11
|
+
<!-- while visible, appended to body: -->
|
|
12
|
+
<div class="kpt-tooltip" role="tooltip" style="position: fixed; …">Save changes</div>
|
|
13
|
+
|
|
14
|
+
## Props
|
|
15
|
+
- `text`: string — the bubble content; empty text disables the tooltip
|
|
16
|
+
- `position`: 'top' | 'bottom' | 'left' | 'right' (default 'top')
|
|
17
|
+
- `onlyWhenTruncated`: boolean — show it only when the content does not fit
|
|
18
|
+
- `children` — exactly one element, the one that gets hover and focus
|
|
19
|
+
|
|
20
|
+
## onlyWhenTruncated
|
|
21
|
+
The check runs at hover time, not at render, so the result is always current after a width or zoom
|
|
22
|
+
change, with no observers. It measures the host AND its direct children, because
|
|
23
|
+
`text-overflow: ellipsis` usually sits on an inner element — and such an element shrinks to the
|
|
24
|
+
available width instead of stretching its parent, so measuring the host alone would find nothing.
|
|
25
|
+
|
|
26
|
+
## Styling
|
|
27
|
+
The bubble carries inline styles built from tokens rather than a class from the shared stylesheet,
|
|
28
|
+
exactly like the Angular directive — it is created outside React's tree, so there is nothing to
|
|
29
|
+
attach a stylesheet rule to reliably.
|
|
30
|
+
|
|
31
|
+
## Examples
|
|
32
|
+
<KptTooltip text="Save changes" position="bottom"><KptButton>Save</KptButton></KptTooltip>
|
|
33
|
+
<KptTooltip text={name} onlyWhenTruncated><span className="ellipsis">{name}</span></KptTooltip>
|
|
34
|
+
|
|
35
|
+
## Tokens
|
|
36
|
+
`--kpt-color-on-surface` (the background), `--kpt-color-surface` (the text), `--kpt-radius-sm`,
|
|
37
|
+
`--kpt-font-size-xs`, `--kpt-elevation-2`.
|
|
38
|
+
|
|
39
|
+
## Accessibility
|
|
40
|
+
The bubble is `role="tooltip"` and appears on focus as well as hover, so it is reachable from the
|
|
41
|
+
keyboard. It is `pointer-events: none`, so it never steals a click. It does NOT replace an
|
|
42
|
+
accessible name — for an icon-only button give the button its own `aria-label`.
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# KptTree (@konce-pt/react)
|
|
2
|
+
|
|
3
|
+
A hierarchical tree: expanding, selection, icons.
|
|
4
|
+
Import: `import { KptTree, type KptTreeNode } from '@konce-pt/react';`
|
|
5
|
+
|
|
6
|
+
## DOM
|
|
7
|
+
<div class="kpt-tree-host">
|
|
8
|
+
<ul class="kpt-tree" role="tree">
|
|
9
|
+
<li class="kpt-tree__node" role="treeitem" aria-expanded="true">
|
|
10
|
+
<div class="kpt-tree__row is-selected">
|
|
11
|
+
<button class="kpt-tree__toggle">…chevron…</button>
|
|
12
|
+
<span class="kpt-tree__icon">…</span>
|
|
13
|
+
<span class="kpt-tree__label">src</span>
|
|
14
|
+
</div>
|
|
15
|
+
<ul role="group">…</ul>
|
|
16
|
+
</li>
|
|
17
|
+
</ul>
|
|
18
|
+
</div>
|
|
19
|
+
|
|
20
|
+
## Props
|
|
21
|
+
- `nodes`: `KptTreeNode<T>[]` — `{ label, value?, icon?, children?, expanded?, disabled? }`
|
|
22
|
+
- `selectable`: boolean — a row click selects instead of expanding
|
|
23
|
+
- `selected` / `defaultSelected` / `onSelectedChange` — the node object, or `null`
|
|
24
|
+
- `onNodeClick(node)`
|
|
25
|
+
- `className`, `ref` and every other `<div>` prop go to the host
|
|
26
|
+
|
|
27
|
+
## Expansion is component state, not data
|
|
28
|
+
The Angular port flips `node.expanded` in place and bumps a version signal. In React that would be
|
|
29
|
+
a side effect on someone else's array during render, so the open branches live in a `Set` of node
|
|
30
|
+
references instead — and `expanded` in the data goes back to being what it should be: the initial
|
|
31
|
+
state, read once on mount.
|
|
32
|
+
|
|
33
|
+
## Examples
|
|
34
|
+
<KptTree nodes={tree} />
|
|
35
|
+
<KptTree nodes={tree} selectable selected={node} onSelectedChange={setNode} />
|
|
36
|
+
|
|
37
|
+
## i18n
|
|
38
|
+
The toggle is labelled from `tree.expand` / `tree.collapse`.
|
|
39
|
+
|
|
40
|
+
## Tokens
|
|
41
|
+
The selected row `--kpt-color-primary`, the hover `--kpt-color-surface-variant`.
|
|
42
|
+
|
|
43
|
+
## Accessibility
|
|
44
|
+
`role="tree"` / `role="treeitem"` with `aria-expanded` on branches only; the indentation is
|
|
45
|
+
`padding-inline-start`, so it follows the writing direction.
|
package/dist/tree/tree.d.ts
CHANGED
|
@@ -4,13 +4,13 @@ export interface KptTreeNode<T = unknown> {
|
|
|
4
4
|
label: string;
|
|
5
5
|
value?: T;
|
|
6
6
|
icon?: string;
|
|
7
|
-
children?: KptTreeNode<T>[];
|
|
7
|
+
children?: readonly KptTreeNode<T>[];
|
|
8
8
|
/** Stan początkowy gałęzi; dalej rozwijaniem steruje już komponent. */
|
|
9
9
|
expanded?: boolean;
|
|
10
10
|
disabled?: boolean;
|
|
11
11
|
}
|
|
12
12
|
export interface KptTreeProps<T> extends Omit<ComponentPropsWithRef<'div'>, 'onSelect' | 'children'>, KptI18nOverrides {
|
|
13
|
-
nodes?: KptTreeNode<T>[];
|
|
13
|
+
nodes?: readonly KptTreeNode<T>[];
|
|
14
14
|
/** Klik w wiersz zaznacza gałąź zamiast ją rozwijać. */
|
|
15
15
|
selectable?: boolean;
|
|
16
16
|
selected?: KptTreeNode<T> | null;
|