@konce-pt/react 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +58 -0
- package/dist/accordion/accordion.d.ts +45 -0
- package/dist/accordion/accordion.js +69 -0
- package/dist/alert/alert.d.ts +25 -0
- package/dist/alert/alert.js +31 -0
- package/dist/app-shell/app-shell.d.ts +94 -0
- package/dist/app-shell/app-shell.js +105 -0
- package/dist/auth/auth-types.d.ts +44 -0
- package/dist/auth/auth-types.js +2 -0
- package/dist/auth/auth.d.ts +76 -0
- package/dist/auth/auth.js +184 -0
- package/dist/autocomplete/autocomplete.d.ts +18 -0
- package/dist/autocomplete/autocomplete.js +72 -0
- package/dist/avatar/avatar.d.ts +33 -0
- package/dist/avatar/avatar.js +30 -0
- package/dist/avatar-group/avatar-group.d.ts +21 -0
- package/dist/avatar-group/avatar-group.js +15 -0
- package/dist/badge/badge.d.ts +25 -0
- package/dist/badge/badge.js +14 -0
- package/dist/bottom-sheet/bottom-sheet.d.ts +21 -0
- package/dist/bottom-sheet/bottom-sheet.js +22 -0
- package/dist/breadcrumb/breadcrumb.d.ts +19 -0
- package/dist/breadcrumb/breadcrumb.js +20 -0
- package/dist/button/button.d.ts +27 -0
- package/dist/button/button.js +49 -0
- package/dist/button-group/button-group.d.ts +25 -0
- package/dist/button-group/button-group.js +30 -0
- package/dist/card/card.d.ts +66 -0
- package/dist/card/card.js +96 -0
- package/dist/carousel/carousel.d.ts +20 -0
- package/dist/carousel/carousel.js +24 -0
- package/dist/charts/chart-legend.d.ts +23 -0
- package/dist/charts/chart-legend.js +9 -0
- package/dist/charts/chart-tooltip.d.ts +21 -0
- package/dist/charts/chart-tooltip.js +13 -0
- package/dist/charts/chart.d.ts +18 -0
- package/dist/charts/chart.js +231 -0
- package/dist/charts-entry/public-api.d.ts +4 -0
- package/dist/charts-entry/public-api.js +7 -0
- package/dist/checkbox/checkbox.d.ts +33 -0
- package/dist/checkbox/checkbox.js +29 -0
- package/dist/chip/chip.d.ts +22 -0
- package/dist/chip/chip.js +16 -0
- package/dist/chips-input/chips-input.d.ts +25 -0
- package/dist/chips-input/chips-input.js +54 -0
- package/dist/clock/clock.d.ts +17 -0
- package/dist/clock/clock.js +57 -0
- package/dist/color-picker/color-picker.d.ts +23 -0
- package/dist/color-picker/color-picker.js +28 -0
- package/dist/confirm/confirm-container.d.ts +13 -0
- package/dist/confirm/confirm-container.js +26 -0
- package/dist/confirm/confirm-store.d.ts +29 -0
- package/dist/confirm/confirm-store.js +52 -0
- package/dist/context-menu/context-menu.d.ts +21 -0
- package/dist/context-menu/context-menu.js +36 -0
- package/dist/data-table/data-table-types.d.ts +67 -0
- package/dist/data-table/data-table-types.js +1 -0
- package/dist/data-table/data-table.d.ts +62 -0
- package/dist/data-table/data-table.js +453 -0
- package/dist/data-table/export-csv.d.ts +7 -0
- package/dist/data-table/export-csv.js +19 -0
- package/dist/data-view/data-view.d.ts +21 -0
- package/dist/data-view/data-view.js +25 -0
- package/dist/date-range/date-range.d.ts +30 -0
- package/dist/date-range/date-range.js +155 -0
- package/dist/datepicker/datepicker.d.ts +39 -0
- package/dist/datepicker/datepicker.js +202 -0
- package/dist/dialog/dialog.d.ts +35 -0
- package/dist/dialog/dialog.js +59 -0
- package/dist/divider/divider.d.ts +16 -0
- package/dist/divider/divider.js +13 -0
- package/dist/drawer/drawer.d.ts +25 -0
- package/dist/drawer/drawer.js +25 -0
- package/dist/empty/empty.d.ts +18 -0
- package/dist/empty/empty.js +14 -0
- package/dist/fab/fab.d.ts +22 -0
- package/dist/fab/fab.js +17 -0
- package/dist/fieldset/fieldset.d.ts +22 -0
- package/dist/fieldset/fieldset.js +24 -0
- package/dist/file-upload/file-upload.d.ts +22 -0
- package/dist/file-upload/file-upload.js +50 -0
- package/dist/form-field/form-field-context.d.ts +23 -0
- package/dist/form-field/form-field-context.js +17 -0
- package/dist/form-field/form-field.d.ts +39 -0
- package/dist/form-field/form-field.js +41 -0
- package/dist/galleria/galleria.d.ts +22 -0
- package/dist/galleria/galleria.js +21 -0
- package/dist/grid/col.d.ts +39 -0
- package/dist/grid/col.js +32 -0
- package/dist/grid/flex.d.ts +45 -0
- package/dist/grid/flex.js +35 -0
- package/dist/grid/grid.d.ts +47 -0
- package/dist/grid/grid.js +38 -0
- package/dist/grid/layout.d.ts +18 -0
- package/dist/grid/layout.js +32 -0
- package/dist/grid-entry/public-api.d.ts +6 -0
- package/dist/grid-entry/public-api.js +8 -0
- package/dist/i18n/i18n-context.d.ts +45 -0
- package/dist/i18n/i18n-context.js +65 -0
- package/dist/icon/icon-registry.d.ts +16 -0
- package/dist/icon/icon-registry.js +43 -0
- package/dist/icon/icon.d.ts +17 -0
- package/dist/icon/icon.js +23 -0
- package/dist/icon-button/icon-button.d.ts +23 -0
- package/dist/icon-button/icon-button.js +14 -0
- package/dist/icons-entry/public-api.d.ts +12 -0
- package/dist/icons-entry/public-api.js +20 -0
- package/dist/image/image.d.ts +17 -0
- package/dist/image/image.js +16 -0
- package/dist/input/input.d.ts +41 -0
- package/dist/input/input.js +36 -0
- package/dist/input-mask/input-mask.d.ts +19 -0
- package/dist/input-mask/input-mask.js +65 -0
- package/dist/input-number/input-number.d.ts +28 -0
- package/dist/input-number/input-number.js +52 -0
- package/dist/input-otp/input-otp.d.ts +21 -0
- package/dist/input-otp/input-otp.js +59 -0
- package/dist/internal/cn.d.ts +9 -0
- package/dist/internal/cn.js +19 -0
- package/dist/internal/compose-refs.d.ts +6 -0
- package/dist/internal/compose-refs.js +16 -0
- package/dist/internal/overlay-container.d.ts +3 -0
- package/dist/internal/overlay-container.js +19 -0
- package/dist/internal/overlay.d.ts +26 -0
- package/dist/internal/overlay.js +64 -0
- package/dist/internal/slot.d.ts +23 -0
- package/dist/internal/slot.js +49 -0
- package/dist/internal/types.d.ts +25 -0
- package/dist/internal/types.js +1 -0
- package/dist/internal/use-breakpoint.d.ts +18 -0
- package/dist/internal/use-breakpoint.js +52 -0
- package/dist/internal/use-controllable-state.d.ts +11 -0
- package/dist/internal/use-controllable-state.js +18 -0
- package/dist/internal/use-id.d.ts +9 -0
- package/dist/internal/use-id.js +13 -0
- package/dist/knob/knob.d.ts +27 -0
- package/dist/knob/knob.js +86 -0
- package/dist/listbox/listbox.d.ts +28 -0
- package/dist/listbox/listbox.js +43 -0
- package/dist/map/map-create-dialog.d.ts +21 -0
- package/dist/map/map-create-dialog.js +196 -0
- package/dist/map/map-hours-field.d.ts +22 -0
- package/dist/map/map-hours-field.js +90 -0
- package/dist/map/map-image-field.d.ts +24 -0
- package/dist/map/map-image-field.js +61 -0
- package/dist/map/map-legend.d.ts +29 -0
- package/dist/map/map-legend.js +41 -0
- package/dist/map/map-poi-card.d.ts +42 -0
- package/dist/map/map-poi-card.js +152 -0
- package/dist/map/map-search.d.ts +37 -0
- package/dist/map/map-search.js +201 -0
- package/dist/map/map.d.ts +113 -0
- package/dist/map/map.js +425 -0
- package/dist/map/ports.d.ts +76 -0
- package/dist/map/ports.js +174 -0
- package/dist/map-entry/public-api.d.ts +20 -0
- package/dist/map-entry/public-api.js +19 -0
- package/dist/megamenu/megamenu.d.ts +17 -0
- package/dist/megamenu/megamenu.js +28 -0
- package/dist/menu/menu-item.d.ts +33 -0
- package/dist/menu/menu-item.js +1 -0
- package/dist/menu/menu-rows.d.ts +9 -0
- package/dist/menu/menu-rows.js +15 -0
- package/dist/menu/menu.d.ts +22 -0
- package/dist/menu/menu.js +31 -0
- package/dist/menubar/menubar.d.ts +16 -0
- package/dist/menubar/menubar.js +39 -0
- package/dist/meter-group/meter-group.d.ts +20 -0
- package/dist/meter-group/meter-group.js +24 -0
- package/dist/order-list/order-list.d.ts +18 -0
- package/dist/order-list/order-list.js +37 -0
- package/dist/paginator/paginator.d.ts +29 -0
- package/dist/paginator/paginator.js +45 -0
- package/dist/panel/panel.d.ts +31 -0
- package/dist/panel/panel.js +36 -0
- package/dist/password/password.d.ts +28 -0
- package/dist/password/password.js +37 -0
- package/dist/pick-list/pick-list.d.ts +28 -0
- package/dist/pick-list/pick-list.js +65 -0
- package/dist/popover/popover.d.ts +23 -0
- package/dist/popover/popover.js +27 -0
- package/dist/progress/progress.d.ts +19 -0
- package/dist/progress/progress.js +21 -0
- package/dist/public-api.d.ts +181 -0
- package/dist/public-api.js +105 -0
- package/dist/radio-group/radio-group.d.ts +24 -0
- package/dist/radio-group/radio-group.js +23 -0
- package/dist/rating/rating.d.ts +22 -0
- package/dist/rating/rating.js +30 -0
- package/dist/rich-text/lists.d.ts +17 -0
- package/dist/rich-text/lists.js +144 -0
- package/dist/rich-text/rich-text.d.ts +28 -0
- package/dist/rich-text/rich-text.js +654 -0
- package/dist/rich-text/sanitize.d.ts +10 -0
- package/dist/rich-text/sanitize.js +85 -0
- package/dist/rich-text/tables.d.ts +44 -0
- package/dist/rich-text/tables.js +268 -0
- package/dist/roadmap/roadmap.d.ts +37 -0
- package/dist/roadmap/roadmap.js +271 -0
- package/dist/roadmap-entry/public-api.d.ts +4 -0
- package/dist/roadmap-entry/public-api.js +7 -0
- package/dist/scroll-top/scroll-top.d.ts +16 -0
- package/dist/scroll-top/scroll-top.js +38 -0
- package/dist/select/select.d.ts +37 -0
- package/dist/select/select.js +117 -0
- package/dist/shared/types.d.ts +8 -0
- package/dist/shared/types.js +1 -0
- package/dist/sidenav/sidenav.d.ts +26 -0
- package/dist/sidenav/sidenav.js +41 -0
- package/dist/skeleton/skeleton.d.ts +20 -0
- package/dist/skeleton/skeleton.js +15 -0
- package/dist/slider/slider.d.ts +28 -0
- package/dist/slider/slider.js +30 -0
- package/dist/speed-dial/speed-dial.d.ts +20 -0
- package/dist/speed-dial/speed-dial.js +23 -0
- package/dist/spinner/spinner.d.ts +15 -0
- package/dist/spinner/spinner.js +14 -0
- package/dist/split-button/split-button.d.ts +28 -0
- package/dist/split-button/split-button.js +34 -0
- package/dist/splitter/splitter.d.ts +39 -0
- package/dist/splitter/splitter.js +80 -0
- package/dist/stepper/stepper.d.ts +51 -0
- package/dist/stepper/stepper.js +71 -0
- package/dist/switch/switch.d.ts +39 -0
- package/dist/switch/switch.js +30 -0
- package/dist/switch-group/switch-group.d.ts +29 -0
- package/dist/switch-group/switch-group.js +47 -0
- package/dist/tabs/tabs.d.ts +38 -0
- package/dist/tabs/tabs.js +74 -0
- package/dist/textarea/textarea.d.ts +28 -0
- package/dist/textarea/textarea.js +44 -0
- package/dist/timeline/timeline.d.ts +19 -0
- package/dist/timeline/timeline.js +12 -0
- package/dist/toast/toast-container.d.ts +12 -0
- package/dist/toast/toast-container.js +23 -0
- package/dist/toast/toast-store.d.ts +26 -0
- package/dist/toast/toast-store.js +51 -0
- package/dist/toolbar/toolbar.d.ts +29 -0
- package/dist/toolbar/toolbar.js +24 -0
- package/dist/tooltip/tooltip.d.ts +26 -0
- package/dist/tooltip/tooltip.js +113 -0
- package/dist/tree/tree.d.ts +31 -0
- package/dist/tree/tree.js +62 -0
- package/package.json +91 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 konce.pt
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="https://ui.konce.pt/images/koncept_ui_lib.png" alt="Koncept UI — component library" width="100%" />
|
|
3
|
+
</p>
|
|
4
|
+
|
|
5
|
+
# @konce-pt/react
|
|
6
|
+
|
|
7
|
+
Komponenty React 19 systemu projektowego [Koncept UI](https://gitlab.com/konce-pt/koncept-ui).
|
|
8
|
+
Ta sama warstwa CSS co port Angulara — te same klasy `kpt-*`, te same tokeny `--kpt-*` —
|
|
9
|
+
więc oba frameworki wyglądają identycznie. **Zero zależności runtime.**
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npm i @konce-pt/react @konce-pt/styles @konce-pt/tokens
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
CSS ładujesz raz, w wejściu aplikacji (pakiet wysyła wyłącznie JavaScript):
|
|
16
|
+
|
|
17
|
+
```ts
|
|
18
|
+
import '@konce-pt/tokens/css';
|
|
19
|
+
import '@konce-pt/tokens/css/dark';
|
|
20
|
+
import '@konce-pt/styles'; // reset, warstwy, motyw
|
|
21
|
+
import '@konce-pt/styles/components'; // warstwa komponentów — wymagane
|
|
22
|
+
import '@konce-pt/grid'; // opcjonalnie — klasy układu
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
```tsx
|
|
26
|
+
import { KptI18nProvider, useKptI18n } from '@konce-pt/react';
|
|
27
|
+
|
|
28
|
+
export function App() {
|
|
29
|
+
return (
|
|
30
|
+
<KptI18nProvider locale="pl">
|
|
31
|
+
<Toolbar />
|
|
32
|
+
</KptI18nProvider>
|
|
33
|
+
);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function Toolbar() {
|
|
37
|
+
const { t } = useKptI18n();
|
|
38
|
+
return <span>{t('paginator.range', { start: 1, end: 10, total: 42 })}</span>;
|
|
39
|
+
}
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Zasady portu
|
|
43
|
+
|
|
44
|
+
- Drzewo DOM odpowiada wersji Angulara węzeł w węzeł — host jest odtwarzany jako wrapper
|
|
45
|
+
(`<span class="kpt-button-host">` wokół `<button class="kpt-button">`), dzięki czemu SCSS
|
|
46
|
+
jest reużyty bez zmian.
|
|
47
|
+
- `ref` i `className` trafiają na element wewnętrzny; wrapper konfiguruje `hostProps`.
|
|
48
|
+
- Warianty i rozmiary przez atrybuty `data-*`, nie przez klasy modyfikatorów.
|
|
49
|
+
- React 19: `ref` jest zwykłym propem — bez `forwardRef`.
|
|
50
|
+
- Kontrolki formularza działają kontrolowane i niekontrolowane, z natywnym `name`/`form`
|
|
51
|
+
(React 19 Actions i React Hook Form bez adaptera).
|
|
52
|
+
- Tłumaczenia pochodzą z `@konce-pt/i18n`, wspólnego z portem Angulara.
|
|
53
|
+
|
|
54
|
+
Pełna dokumentacja dla modeli: [`llms.txt`](./llms.txt) (EN) i [`llms-pl.txt`](./llms-pl.txt) (PL).
|
|
55
|
+
|
|
56
|
+
## Licencja
|
|
57
|
+
|
|
58
|
+
MIT © konce.pt
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { type ComponentPropsWithRef, type ReactNode } from 'react';
|
|
2
|
+
export interface KptAccordionProps extends ComponentPropsWithRef<'div'> {
|
|
3
|
+
/** Pozwala trzymać otwartych wiele paneli naraz. */
|
|
4
|
+
multi?: boolean;
|
|
5
|
+
animated?: boolean;
|
|
6
|
+
animationDuration?: number;
|
|
7
|
+
/** Indeksy otwartych paneli. */
|
|
8
|
+
openIndexes?: number[];
|
|
9
|
+
defaultOpenIndexes?: number[];
|
|
10
|
+
onOpenIndexesChange?: (indexes: number[]) => void;
|
|
11
|
+
children?: ReactNode;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Akordeon — grupa rozwijanych paneli. `multi` pozwala otworzyć wiele naraz.
|
|
15
|
+
*
|
|
16
|
+
* Stan otwarcia trzyma akordeon, a panele dostają swój indeks przez klonowanie — inaczej
|
|
17
|
+
* pojedynczy tryb nie miałby jak zamknąć rodzeństwa. Panel użyty samodzielnie, poza akordeonem,
|
|
18
|
+
* zarządza sobą sam.
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* <KptAccordion>
|
|
22
|
+
* <KptAccordion.Panel title="Sekcja 1">…</KptAccordion.Panel>
|
|
23
|
+
* <KptAccordion.Panel title="Sekcja 2">…</KptAccordion.Panel>
|
|
24
|
+
* </KptAccordion>
|
|
25
|
+
*/
|
|
26
|
+
export declare function KptAccordion({ multi, animated, animationDuration, openIndexes, defaultOpenIndexes, onOpenIndexesChange, className, children, ...rest }: Readonly<KptAccordionProps>): import("react").JSX.Element;
|
|
27
|
+
export declare namespace KptAccordion {
|
|
28
|
+
var Panel: typeof KptAccordionPanel;
|
|
29
|
+
}
|
|
30
|
+
export interface KptAccordionPanelProps extends Omit<ComponentPropsWithRef<'div'>, 'title'> {
|
|
31
|
+
title: string;
|
|
32
|
+
disabled?: boolean;
|
|
33
|
+
/** Używane, gdy panel stoi poza akordeonem. */
|
|
34
|
+
expanded?: boolean;
|
|
35
|
+
defaultExpanded?: boolean;
|
|
36
|
+
onExpandedChange?: (expanded: boolean) => void;
|
|
37
|
+
/** Wstawiany przez akordeon — nie podawaj ręcznie. */
|
|
38
|
+
index?: number;
|
|
39
|
+
children?: ReactNode;
|
|
40
|
+
}
|
|
41
|
+
/** Panel akordeonu. Umieszczaj w `<KptAccordion>` albo używaj samodzielnie. */
|
|
42
|
+
export declare function KptAccordionPanel({ title, disabled, expanded, defaultExpanded, onExpandedChange, index, className, style, children, ...rest }: Readonly<KptAccordionPanelProps>): import("react").JSX.Element;
|
|
43
|
+
export declare namespace KptAccordionPanel {
|
|
44
|
+
var kptAccordionSlot: "panel";
|
|
45
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Children, cloneElement, createContext, isValidElement, useContext, useState, } from 'react';
|
|
3
|
+
import { cn } from "../internal/cn.js";
|
|
4
|
+
import { useControllableState } from "../internal/use-controllable-state.js";
|
|
5
|
+
import { KptIcon } from "../icon/icon.js";
|
|
6
|
+
const AccordionContext = createContext(null);
|
|
7
|
+
/**
|
|
8
|
+
* Akordeon — grupa rozwijanych paneli. `multi` pozwala otworzyć wiele naraz.
|
|
9
|
+
*
|
|
10
|
+
* Stan otwarcia trzyma akordeon, a panele dostają swój indeks przez klonowanie — inaczej
|
|
11
|
+
* pojedynczy tryb nie miałby jak zamknąć rodzeństwa. Panel użyty samodzielnie, poza akordeonem,
|
|
12
|
+
* zarządza sobą sam.
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* <KptAccordion>
|
|
16
|
+
* <KptAccordion.Panel title="Sekcja 1">…</KptAccordion.Panel>
|
|
17
|
+
* <KptAccordion.Panel title="Sekcja 2">…</KptAccordion.Panel>
|
|
18
|
+
* </KptAccordion>
|
|
19
|
+
*/
|
|
20
|
+
export function KptAccordion({ multi = false, animated = true, animationDuration = 500, openIndexes, defaultOpenIndexes = [], onOpenIndexesChange, className, children, ...rest }) {
|
|
21
|
+
const [open, setOpen] = useControllableState({
|
|
22
|
+
value: openIndexes,
|
|
23
|
+
defaultValue: defaultOpenIndexes,
|
|
24
|
+
onChange: onOpenIndexesChange,
|
|
25
|
+
});
|
|
26
|
+
const context = {
|
|
27
|
+
isOpen: (index) => open.includes(index),
|
|
28
|
+
toggle: (index, willOpen) => {
|
|
29
|
+
if (!willOpen)
|
|
30
|
+
setOpen(open.filter((i) => i !== index));
|
|
31
|
+
else
|
|
32
|
+
setOpen(multi ? [...open, index] : [index]);
|
|
33
|
+
},
|
|
34
|
+
animMs: `${animated ? animationDuration : 0}ms`,
|
|
35
|
+
};
|
|
36
|
+
let index = -1;
|
|
37
|
+
const panels = Children.map(children, (child) => {
|
|
38
|
+
if (!isValidElement(child) || child.type?.kptAccordionSlot !== 'panel') {
|
|
39
|
+
return child;
|
|
40
|
+
}
|
|
41
|
+
index += 1;
|
|
42
|
+
return cloneElement(child, { index });
|
|
43
|
+
});
|
|
44
|
+
return (_jsx(AccordionContext.Provider, { value: context, children: _jsx("div", { className: cn('kpt-accordion-host', className), ...rest, children: panels }) }));
|
|
45
|
+
}
|
|
46
|
+
/** Panel akordeonu. Umieszczaj w `<KptAccordion>` albo używaj samodzielnie. */
|
|
47
|
+
export function KptAccordionPanel({ title, disabled = false, expanded, defaultExpanded = false, onExpandedChange, index, className, style, children, ...rest }) {
|
|
48
|
+
const accordion = useContext(AccordionContext);
|
|
49
|
+
const [standalone, setStandalone] = useControllableState({
|
|
50
|
+
value: expanded,
|
|
51
|
+
defaultValue: defaultExpanded,
|
|
52
|
+
onChange: onExpandedChange,
|
|
53
|
+
});
|
|
54
|
+
const managed = accordion !== null && index !== undefined;
|
|
55
|
+
const isOpen = managed ? accordion.isOpen(index) : standalone;
|
|
56
|
+
const toggle = () => {
|
|
57
|
+
if (disabled)
|
|
58
|
+
return;
|
|
59
|
+
const willOpen = !isOpen;
|
|
60
|
+
if (managed)
|
|
61
|
+
accordion.toggle(index, willOpen);
|
|
62
|
+
else
|
|
63
|
+
setStandalone(willOpen);
|
|
64
|
+
onExpandedChange?.(willOpen);
|
|
65
|
+
};
|
|
66
|
+
return (_jsx("div", { className: cn('kpt-accordion-panel-host', className), style: { ['--kpt-anim-duration']: accordion?.animMs ?? '500ms', ...style }, ...rest, children: _jsxs("div", { className: cn('kpt-accordion-panel', isOpen && 'is-open'), children: [_jsxs("button", { type: "button", className: "kpt-accordion-panel__header", "aria-expanded": isOpen, disabled: disabled, onClick: toggle, children: [_jsx("span", { className: "kpt-accordion-panel__title", children: title }), _jsx(KptIcon, { name: "chevron-down", className: cn('kpt-accordion-panel__chevron', isOpen && 'is-open') })] }), _jsx("div", { className: cn('kpt-accordion-panel__collapse', isOpen && 'is-open'), inert: !isOpen, "aria-hidden": !isOpen, children: _jsx("div", { className: "kpt-accordion-panel__collapse-inner", children: _jsx("div", { className: "kpt-accordion-panel__body", children: children }) }) })] }) }));
|
|
67
|
+
}
|
|
68
|
+
KptAccordionPanel.kptAccordionSlot = 'panel';
|
|
69
|
+
KptAccordion.Panel = KptAccordionPanel;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { type ComponentPropsWithRef, type ReactNode } from 'react';
|
|
2
|
+
import { type KptI18nOverrides } from '../i18n/i18n-context.tsx';
|
|
3
|
+
import type { KptAlertVariant } from '../shared/types.ts';
|
|
4
|
+
export type { KptAlertVariant };
|
|
5
|
+
export interface KptAlertProps extends Omit<ComponentPropsWithRef<'div'>, 'title'>, KptI18nOverrides {
|
|
6
|
+
variant?: KptAlertVariant;
|
|
7
|
+
title?: string;
|
|
8
|
+
/** Dokłada przycisk zamykania. */
|
|
9
|
+
dismissible?: boolean;
|
|
10
|
+
/** Wywoływane po zamknięciu przez użytkownika. */
|
|
11
|
+
onClosed?: () => void;
|
|
12
|
+
children?: ReactNode;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Komunikat inline (alert). Warianty info/success/warning/danger, opcjonalny tytuł i zamykanie.
|
|
16
|
+
*
|
|
17
|
+
* Zamknięcie chowa komunikat atrybutem `hidden` (tak samo jak port Angulara), a nie odmontowuje
|
|
18
|
+
* go — dzięki temu ten sam alert da się pokazać ponownie bez przebudowy drzewa. Gdy wolisz nim
|
|
19
|
+
* sterować z zewnątrz, po prostu nie renderuj komponentu.
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* <KptAlert variant="success" title="Zapisano">Zmiany zostały zapisane.</KptAlert>
|
|
23
|
+
* <KptAlert variant="warning" dismissible onClosed={onClosed}>Uwaga…</KptAlert>
|
|
24
|
+
*/
|
|
25
|
+
export declare function KptAlert({ variant, title, dismissible, onClosed, locale, dictionary, className, children, ...rest }: Readonly<KptAlertProps>): import("react").JSX.Element;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useState } from 'react';
|
|
3
|
+
import { cn } from "../internal/cn.js";
|
|
4
|
+
import { useKptMessages } from "../i18n/i18n-context.js";
|
|
5
|
+
import { KptIcon } from "../icon/icon.js";
|
|
6
|
+
const ICONS = {
|
|
7
|
+
info: 'info',
|
|
8
|
+
success: 'circle-check',
|
|
9
|
+
warning: 'alert-triangle',
|
|
10
|
+
danger: 'circle-x',
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* Komunikat inline (alert). Warianty info/success/warning/danger, opcjonalny tytuł i zamykanie.
|
|
14
|
+
*
|
|
15
|
+
* Zamknięcie chowa komunikat atrybutem `hidden` (tak samo jak port Angulara), a nie odmontowuje
|
|
16
|
+
* go — dzięki temu ten sam alert da się pokazać ponownie bez przebudowy drzewa. Gdy wolisz nim
|
|
17
|
+
* sterować z zewnątrz, po prostu nie renderuj komponentu.
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* <KptAlert variant="success" title="Zapisano">Zmiany zostały zapisane.</KptAlert>
|
|
21
|
+
* <KptAlert variant="warning" dismissible onClosed={onClosed}>Uwaga…</KptAlert>
|
|
22
|
+
*/
|
|
23
|
+
export function KptAlert({ variant = 'info', title = '', dismissible = false, onClosed, locale, dictionary, className, children, ...rest }) {
|
|
24
|
+
const { t } = useKptMessages({ locale, dictionary });
|
|
25
|
+
const [visible, setVisible] = useState(true);
|
|
26
|
+
const dismiss = () => {
|
|
27
|
+
setVisible(false);
|
|
28
|
+
onClosed?.();
|
|
29
|
+
};
|
|
30
|
+
return (_jsx("div", { className: cn('kpt-alert-host', className), hidden: !visible, ...rest, children: _jsxs("div", { className: "kpt-alert", "data-variant": variant, role: "alert", children: [_jsx(KptIcon, { className: "kpt-alert__icon", name: ICONS[variant] }), _jsxs("div", { className: "kpt-alert__content", children: [title ? _jsx("div", { className: "kpt-alert__title", children: title }) : null, _jsx("div", { className: "kpt-alert__message", children: children })] }), dismissible ? (_jsx("button", { className: "kpt-alert__close", type: "button", onClick: dismiss, "aria-label": t('common.close'), children: _jsx(KptIcon, { name: "x" }) })) : null] }) }));
|
|
31
|
+
}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { type ComponentPropsWithRef, type ReactNode } from 'react';
|
|
2
|
+
import { type KptBreakpoint } from '../internal/use-breakpoint.ts';
|
|
3
|
+
import { type KptI18nOverrides } from '../i18n/i18n-context.tsx';
|
|
4
|
+
/**
|
|
5
|
+
* Zachowanie panelu bocznego:
|
|
6
|
+
* - `auto` — zależne od szerokości okna (domyślne),
|
|
7
|
+
* - `side` — zawsze zadokowany, rozpycha treść,
|
|
8
|
+
* - `over` — zawsze nakładka nad treścią.
|
|
9
|
+
*/
|
|
10
|
+
export type KptSidenavMode = 'side' | 'over' | 'auto';
|
|
11
|
+
export interface KptAppShellProps extends Omit<ComponentPropsWithRef<'div'>, 'children'>, KptI18nOverrides {
|
|
12
|
+
/** Slot górnego paska — renderowany nad obszarem treści (zwykle `<KptToolbar>`). */
|
|
13
|
+
toolbar?: ReactNode;
|
|
14
|
+
/** Slot panelu bocznego (zwykle `<KptSidenav>`). */
|
|
15
|
+
sidenav?: ReactNode;
|
|
16
|
+
/** Treść aplikacji. */
|
|
17
|
+
children?: ReactNode;
|
|
18
|
+
/** Czy panel jest otwarty w układzie zadokowanym (oraz w wymuszonym trybie `over`). */
|
|
19
|
+
sidenavOpen?: boolean;
|
|
20
|
+
defaultSidenavOpen?: boolean;
|
|
21
|
+
onSidenavOpenChange?: (open: boolean) => void;
|
|
22
|
+
/**
|
|
23
|
+
* Czy nakładka jest wysunięta w trybie `auto` poniżej `sidenavBreakpoint`.
|
|
24
|
+
*
|
|
25
|
+
* Celowo osobny od `sidenavOpen`: gdyby oba układy dzieliły jeden stan, wejście na wąski
|
|
26
|
+
* ekran musiałoby nadpisać stan konsumenta, a powrót na szeroki nie miałby czego przywrócić.
|
|
27
|
+
*/
|
|
28
|
+
sidenavCompactOpen?: boolean;
|
|
29
|
+
defaultSidenavCompactOpen?: boolean;
|
|
30
|
+
onSidenavCompactOpenChange?: (open: boolean) => void;
|
|
31
|
+
/** `auto` przełącza układ na breakpoincie; `side`/`over` wymuszają go niezależnie od szerokości. */
|
|
32
|
+
sidenavMode?: KptSidenavMode;
|
|
33
|
+
/** Od tego breakpointa w górę tryb `auto` dokuje panel; poniżej robi z niego nakładkę. */
|
|
34
|
+
sidenavBreakpoint?: KptBreakpoint;
|
|
35
|
+
/**
|
|
36
|
+
* Włącza szynę ikon w paśmie od `sidenavBreakpoint` do tego breakpointa: zamknięty panel
|
|
37
|
+
* nie chowa się wtedy całkowicie, tylko zwęża do `--kpt-sidenav-rail-width`. Wartość musi
|
|
38
|
+
* być wyższa niż `sidenavBreakpoint`. `null` (domyślnie) wyłącza szynę.
|
|
39
|
+
*/
|
|
40
|
+
sidenavRailBreakpoint?: KptBreakpoint | null;
|
|
41
|
+
/** Etykieta dostępności panelu; puste = `appShell.navigation` ze słownika. */
|
|
42
|
+
sidenavLabel?: string;
|
|
43
|
+
}
|
|
44
|
+
/** Kontrakt kontekstu shella — czytany przez `useKptAppShell()` i przełącznik panelu. */
|
|
45
|
+
export interface KptAppShellContextValue {
|
|
46
|
+
/** Efektywny stan otwarcia — ten, który obowiązuje w bieżącym układzie. */
|
|
47
|
+
isSidenavOpen: boolean;
|
|
48
|
+
/** Czy panel zachowuje się TERAZ jak nakładka nad treścią. */
|
|
49
|
+
isOverlay: boolean;
|
|
50
|
+
/** Identyfikator panelu dla `aria-controls`. */
|
|
51
|
+
sidenavId: string;
|
|
52
|
+
toggleSidenav: () => void;
|
|
53
|
+
openSidenav: () => void;
|
|
54
|
+
closeSidenav: () => void;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Szkielet aplikacji: pasek u góry, panel boczny i treść.
|
|
58
|
+
*
|
|
59
|
+
* Domyślny tryb `auto` jest responsywny bez konfiguracji: od `sidenavBreakpoint` w górę panel
|
|
60
|
+
* jest zadokowany, poniżej zachowuje się jak nakładka ze scrimem i startuje zamknięty.
|
|
61
|
+
*
|
|
62
|
+
* O układzie decyduje wyłącznie CSS — nic nie migocze przed hydracją i nic nie zależy od
|
|
63
|
+
* `matchMedia`. JavaScript odpowiada tylko za to, KTÓRY stan przełącza przycisk.
|
|
64
|
+
*
|
|
65
|
+
* @example
|
|
66
|
+
* <KptAppShell
|
|
67
|
+
* toolbar={<KptToolbar>…</KptToolbar>}
|
|
68
|
+
* sidenav={<KptSidenav>…</KptSidenav>}
|
|
69
|
+
* >
|
|
70
|
+
* <Routes />
|
|
71
|
+
* </KptAppShell>
|
|
72
|
+
*/
|
|
73
|
+
export declare function KptAppShell({ toolbar, sidenav, children, sidenavOpen, defaultSidenavOpen, onSidenavOpenChange, sidenavCompactOpen, defaultSidenavCompactOpen, onSidenavCompactOpenChange, sidenavMode, sidenavBreakpoint, sidenavRailBreakpoint, sidenavLabel, locale, dictionary, className, ...rest }: Readonly<KptAppShellProps>): import("react").JSX.Element;
|
|
74
|
+
/** Dostęp do stanu shella. Poza `KptAppShell` rzuca — to zawsze błąd użycia. */
|
|
75
|
+
export declare function useKptAppShell(): KptAppShellContextValue;
|
|
76
|
+
/**
|
|
77
|
+
* Propsy przycisku przełączającego panel boczny. Rozłóż je na natywnym `<button>`
|
|
78
|
+
* (albo na `<KptButton>`, który przekazuje je do swojego wewnętrznego `<button>`) —
|
|
79
|
+
* atrybuty ARIA muszą wylądować na elemencie z rolą, nie na opakowaniu.
|
|
80
|
+
*
|
|
81
|
+
* Trafia w stan właściwy dla bieżącego układu, więc jeden przycisk obsługuje desktop
|
|
82
|
+
* i wąski ekran.
|
|
83
|
+
*
|
|
84
|
+
* @example
|
|
85
|
+
* <KptButton variant="text" {...useKptShellNavToggle()}>Menu</KptButton>
|
|
86
|
+
*/
|
|
87
|
+
export declare function useKptShellNavToggle(options?: {
|
|
88
|
+
label?: string;
|
|
89
|
+
} & KptI18nOverrides): {
|
|
90
|
+
readonly 'aria-expanded': boolean;
|
|
91
|
+
readonly 'aria-controls': string;
|
|
92
|
+
readonly 'aria-label': string;
|
|
93
|
+
readonly onClick: () => void;
|
|
94
|
+
};
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { createContext, useCallback, useContext, useEffect, useMemo, } from 'react';
|
|
3
|
+
import { cn } from "../internal/cn.js";
|
|
4
|
+
import { useControllableState } from "../internal/use-controllable-state.js";
|
|
5
|
+
import { useKptId } from "../internal/use-id.js";
|
|
6
|
+
import { useKptBreakpointUp } from "../internal/use-breakpoint.js";
|
|
7
|
+
import { useKptMessages } from "../i18n/i18n-context.js";
|
|
8
|
+
const KptAppShellContext = createContext(null);
|
|
9
|
+
/**
|
|
10
|
+
* Szkielet aplikacji: pasek u góry, panel boczny i treść.
|
|
11
|
+
*
|
|
12
|
+
* Domyślny tryb `auto` jest responsywny bez konfiguracji: od `sidenavBreakpoint` w górę panel
|
|
13
|
+
* jest zadokowany, poniżej zachowuje się jak nakładka ze scrimem i startuje zamknięty.
|
|
14
|
+
*
|
|
15
|
+
* O układzie decyduje wyłącznie CSS — nic nie migocze przed hydracją i nic nie zależy od
|
|
16
|
+
* `matchMedia`. JavaScript odpowiada tylko za to, KTÓRY stan przełącza przycisk.
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* <KptAppShell
|
|
20
|
+
* toolbar={<KptToolbar>…</KptToolbar>}
|
|
21
|
+
* sidenav={<KptSidenav>…</KptSidenav>}
|
|
22
|
+
* >
|
|
23
|
+
* <Routes />
|
|
24
|
+
* </KptAppShell>
|
|
25
|
+
*/
|
|
26
|
+
export function KptAppShell({ toolbar, sidenav, children, sidenavOpen, defaultSidenavOpen = true, onSidenavOpenChange, sidenavCompactOpen, defaultSidenavCompactOpen = false, onSidenavCompactOpenChange, sidenavMode = 'auto', sidenavBreakpoint = 'lg', sidenavRailBreakpoint = null, sidenavLabel = '', locale, dictionary, className, ...rest }) {
|
|
27
|
+
const { t } = useKptMessages({ locale, dictionary });
|
|
28
|
+
const sidenavId = useKptId(undefined, 'kpt-app-shell-nav');
|
|
29
|
+
const [dockedOpen, setDockedOpen] = useControllableState({
|
|
30
|
+
value: sidenavOpen,
|
|
31
|
+
defaultValue: defaultSidenavOpen,
|
|
32
|
+
onChange: onSidenavOpenChange,
|
|
33
|
+
});
|
|
34
|
+
const [compactOpen, setCompactOpen] = useControllableState({
|
|
35
|
+
value: sidenavCompactOpen,
|
|
36
|
+
defaultValue: defaultSidenavCompactOpen,
|
|
37
|
+
onChange: onSidenavCompactOpenChange,
|
|
38
|
+
});
|
|
39
|
+
const isWide = useKptBreakpointUp(sidenavBreakpoint);
|
|
40
|
+
const isOverlay = sidenavMode === 'over' ? true : sidenavMode === 'side' ? false : !isWide;
|
|
41
|
+
const usesCompactState = sidenavMode === 'auto' && isOverlay;
|
|
42
|
+
const isSidenavOpen = usesCompactState ? compactOpen : dockedOpen;
|
|
43
|
+
const setSidenavOpen = useCallback((open) => {
|
|
44
|
+
if (usesCompactState)
|
|
45
|
+
setCompactOpen(open);
|
|
46
|
+
else
|
|
47
|
+
setDockedOpen(open);
|
|
48
|
+
}, [usesCompactState, setCompactOpen, setDockedOpen]);
|
|
49
|
+
// Wyjście z nakładki chowa ją na wejściu: inaczej wróciłaby otwarta przy kolejnym
|
|
50
|
+
// zwężeniu okna, mimo że użytkownik jej wtedy nie otwierał.
|
|
51
|
+
useEffect(() => {
|
|
52
|
+
if (!isOverlay)
|
|
53
|
+
setCompactOpen(false);
|
|
54
|
+
}, [isOverlay, setCompactOpen]);
|
|
55
|
+
const closeSidenav = useCallback(() => setSidenavOpen(false), [setSidenavOpen]);
|
|
56
|
+
useEffect(() => {
|
|
57
|
+
if (!isOverlay || !isSidenavOpen)
|
|
58
|
+
return;
|
|
59
|
+
const onKeyDown = (event) => {
|
|
60
|
+
if (event.key === 'Escape')
|
|
61
|
+
closeSidenav();
|
|
62
|
+
};
|
|
63
|
+
document.addEventListener('keydown', onKeyDown);
|
|
64
|
+
return () => document.removeEventListener('keydown', onKeyDown);
|
|
65
|
+
}, [isOverlay, isSidenavOpen, closeSidenav]);
|
|
66
|
+
const context = useMemo(() => ({
|
|
67
|
+
isSidenavOpen,
|
|
68
|
+
isOverlay,
|
|
69
|
+
sidenavId,
|
|
70
|
+
toggleSidenav: () => setSidenavOpen(!isSidenavOpen),
|
|
71
|
+
openSidenav: () => setSidenavOpen(true),
|
|
72
|
+
closeSidenav,
|
|
73
|
+
}), [isSidenavOpen, isOverlay, sidenavId, setSidenavOpen, closeSidenav]);
|
|
74
|
+
// Scrim blokuje wskaźnik, ale nie klawiaturę — treść pod nakładką nie może łapać fokusu.
|
|
75
|
+
const contentInert = isOverlay && isSidenavOpen;
|
|
76
|
+
return (_jsx(KptAppShellContext.Provider, { value: context, children: _jsxs("div", { className: cn('kpt-app-shell', dockedOpen && 'kpt-app-shell--nav-open', compactOpen && 'kpt-app-shell--nav-compact-open', className), "data-sidenav-mode": sidenavMode, "data-sidenav-breakpoint": sidenavBreakpoint, "data-sidenav-rail": sidenavRailBreakpoint ?? undefined, ...rest, children: [toolbar, _jsxs("div", { className: "kpt-app-shell__body", children: [_jsx("aside", { className: "kpt-app-shell__sidenav", role: "navigation", tabIndex: -1, id: sidenavId, "aria-label": sidenavLabel || t('appShell.navigation'), children: sidenav }), _jsx("div", { className: "kpt-app-shell__scrim", "aria-hidden": "true", onClick: closeSidenav }), _jsx("main", { className: "kpt-app-shell__content", inert: contentInert, children: children })] })] }) }));
|
|
77
|
+
}
|
|
78
|
+
/** Dostęp do stanu shella. Poza `KptAppShell` rzuca — to zawsze błąd użycia. */
|
|
79
|
+
export function useKptAppShell() {
|
|
80
|
+
const context = useContext(KptAppShellContext);
|
|
81
|
+
if (!context)
|
|
82
|
+
throw new Error('useKptAppShell() wymaga otaczajacego <KptAppShell>.');
|
|
83
|
+
return context;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Propsy przycisku przełączającego panel boczny. Rozłóż je na natywnym `<button>`
|
|
87
|
+
* (albo na `<KptButton>`, który przekazuje je do swojego wewnętrznego `<button>`) —
|
|
88
|
+
* atrybuty ARIA muszą wylądować na elemencie z rolą, nie na opakowaniu.
|
|
89
|
+
*
|
|
90
|
+
* Trafia w stan właściwy dla bieżącego układu, więc jeden przycisk obsługuje desktop
|
|
91
|
+
* i wąski ekran.
|
|
92
|
+
*
|
|
93
|
+
* @example
|
|
94
|
+
* <KptButton variant="text" {...useKptShellNavToggle()}>Menu</KptButton>
|
|
95
|
+
*/
|
|
96
|
+
export function useKptShellNavToggle(options) {
|
|
97
|
+
const { isSidenavOpen, sidenavId, toggleSidenav } = useKptAppShell();
|
|
98
|
+
const { t } = useKptMessages({ locale: options?.locale, dictionary: options?.dictionary });
|
|
99
|
+
return {
|
|
100
|
+
'aria-expanded': isSidenavOpen,
|
|
101
|
+
'aria-controls': sidenavId,
|
|
102
|
+
'aria-label': options?.label || t('appShell.toggleNavigation'),
|
|
103
|
+
onClick: toggleSidenav,
|
|
104
|
+
};
|
|
105
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/** Tryb ekranu — logowanie, rejestracja, odzyskiwanie hasła. */
|
|
2
|
+
export type KptAuthMode = 'signIn' | 'signUp' | 'forgot';
|
|
3
|
+
/**
|
|
4
|
+
* Układ ekranu:
|
|
5
|
+
* - `slider` — panel promo przesuwa się nad formularzami przy zmianie trybu,
|
|
6
|
+
* - `split` — panel promo stoi w miejscu, zmienia się tylko formularz.
|
|
7
|
+
*/
|
|
8
|
+
export type KptAuthLayout = 'slider' | 'split';
|
|
9
|
+
/** Układ przycisków dostawców: pełnowymiarowa lista albo siatka ikon z podpisami. */
|
|
10
|
+
export type KptAuthProviderLayout = 'list' | 'grid';
|
|
11
|
+
/** Dostawca logowania zewnętrznego (OAuth/SSO/dowolny własny). */
|
|
12
|
+
export interface KptAuthProvider {
|
|
13
|
+
/** Identyfikator zwracany w `onProviderSelect`. */
|
|
14
|
+
id: string;
|
|
15
|
+
/** Widoczna etykieta — jednocześnie nazwa dostępna przycisku. */
|
|
16
|
+
label: string;
|
|
17
|
+
/** Nazwa ikony z rejestru `KptIcon` (np. `brand-google` z pełnego zestawu Tabler). */
|
|
18
|
+
icon?: string;
|
|
19
|
+
/** Alternatywa dla `icon`: adres obrazka (wierne, wielokolorowe logo marki). */
|
|
20
|
+
iconUrl?: string;
|
|
21
|
+
/** Drugi wiersz opisu — tylko w układzie `list`. */
|
|
22
|
+
description?: string;
|
|
23
|
+
}
|
|
24
|
+
/** Wartość formularza logowania. */
|
|
25
|
+
export interface KptAuthSignInValue {
|
|
26
|
+
email: string;
|
|
27
|
+
password: string;
|
|
28
|
+
remember: boolean;
|
|
29
|
+
}
|
|
30
|
+
/** Wartość formularza rejestracji. */
|
|
31
|
+
export interface KptAuthSignUpValue {
|
|
32
|
+
name: string;
|
|
33
|
+
email: string;
|
|
34
|
+
password: string;
|
|
35
|
+
terms: boolean;
|
|
36
|
+
}
|
|
37
|
+
/** Wartość formularza odzyskiwania hasła. */
|
|
38
|
+
export interface KptAuthResetValue {
|
|
39
|
+
email: string;
|
|
40
|
+
}
|
|
41
|
+
/** Rodzaj błędu pola — komunikat składamy z niego dopiero przy renderowaniu. */
|
|
42
|
+
export type KptAuthErrorKind = 'required' | 'email' | 'minLength' | 'mismatch';
|
|
43
|
+
/** Minimalna długość hasła w rejestracji. */
|
|
44
|
+
export declare const KPT_AUTH_MIN_PASSWORD = 8;
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { type ComponentPropsWithRef, type ReactNode } from 'react';
|
|
2
|
+
import { type KptI18nOverrides } from '../i18n/i18n-context.tsx';
|
|
3
|
+
import { type KptAuthLayout, type KptAuthMode, type KptAuthProvider, type KptAuthProviderLayout, type KptAuthResetValue, type KptAuthSignInValue, type KptAuthSignUpValue } from './auth-types.ts';
|
|
4
|
+
type SlotName = 'brand' | 'promo' | 'sso' | 'fields' | 'footer';
|
|
5
|
+
interface SlotProps {
|
|
6
|
+
children?: ReactNode;
|
|
7
|
+
}
|
|
8
|
+
export interface KptAuthProps extends Omit<ComponentPropsWithRef<'div'>, 'onSubmit' | 'children'>, KptI18nOverrides {
|
|
9
|
+
mode?: KptAuthMode;
|
|
10
|
+
defaultMode?: KptAuthMode;
|
|
11
|
+
onModeChange?: (mode: KptAuthMode) => void;
|
|
12
|
+
layout?: KptAuthLayout;
|
|
13
|
+
providers?: KptAuthProvider[];
|
|
14
|
+
providerLayout?: KptAuthProviderLayout;
|
|
15
|
+
showName?: boolean;
|
|
16
|
+
requireTerms?: boolean;
|
|
17
|
+
showRemember?: boolean;
|
|
18
|
+
/** Operacja w toku — przyciski w stanie ładowania, dostawcy zablokowani. */
|
|
19
|
+
busy?: boolean;
|
|
20
|
+
error?: string | null;
|
|
21
|
+
notice?: string | null;
|
|
22
|
+
/** `null` = tekst z i18n zależny od trybu, `''` = brak (miejsce dla slotu `KptAuth.Promo`). */
|
|
23
|
+
promoTitle?: string | null;
|
|
24
|
+
promoText?: string | null;
|
|
25
|
+
animated?: boolean;
|
|
26
|
+
animationDuration?: number;
|
|
27
|
+
onSignIn?: (value: KptAuthSignInValue) => void;
|
|
28
|
+
onSignUp?: (value: KptAuthSignUpValue) => void;
|
|
29
|
+
onResetPassword?: (value: KptAuthResetValue) => void;
|
|
30
|
+
onProviderSelect?: (provider: KptAuthProvider) => void;
|
|
31
|
+
/** Własny wygląd pojedynczego dostawcy; `select` zgłasza wybór. */
|
|
32
|
+
renderProvider?: (provider: KptAuthProvider, select: () => void) => ReactNode;
|
|
33
|
+
children?: ReactNode;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Ekran uwierzytelniania: logowanie, rejestracja i odzyskiwanie hasła w jednym komponencie,
|
|
37
|
+
* z panelem promocyjnym i listą dostawców zewnętrznych.
|
|
38
|
+
*
|
|
39
|
+
* Komponent jest prezentacyjny — nie woła API ani nie nawiguje. Wywołania backendu podpina
|
|
40
|
+
* aplikacja pod `onSignIn` / `onSignUp` / `onResetPassword` / `onProviderSelect`, a stan
|
|
41
|
+
* operacji podaje z powrotem przez `busy`, `error` i `notice`.
|
|
42
|
+
*
|
|
43
|
+
* @example
|
|
44
|
+
* <KptAuth providers={providers} busy={loading} error={serverError} onSignIn={login}>
|
|
45
|
+
* <KptAuth.Brand><img src="/logo.svg" alt="Konce" /></KptAuth.Brand>
|
|
46
|
+
* </KptAuth>
|
|
47
|
+
*/
|
|
48
|
+
export declare function KptAuth({ mode, defaultMode, onModeChange, layout, providers, providerLayout, showName, requireTerms, showRemember, busy, error, notice, promoTitle, promoText, animated, animationDuration, onSignIn, onSignUp, onResetPassword, onProviderSelect, renderProvider, locale, dictionary, className, style, children, ...rest }: Readonly<KptAuthProps>): import("react").JSX.Element;
|
|
49
|
+
export declare namespace KptAuth {
|
|
50
|
+
var Brand: {
|
|
51
|
+
(_props: Readonly<SlotProps>): ReactNode;
|
|
52
|
+
kptAuthSlot: SlotName;
|
|
53
|
+
displayName: string;
|
|
54
|
+
};
|
|
55
|
+
var Promo: {
|
|
56
|
+
(_props: Readonly<SlotProps>): ReactNode;
|
|
57
|
+
kptAuthSlot: SlotName;
|
|
58
|
+
displayName: string;
|
|
59
|
+
};
|
|
60
|
+
var Sso: {
|
|
61
|
+
(_props: Readonly<SlotProps>): ReactNode;
|
|
62
|
+
kptAuthSlot: SlotName;
|
|
63
|
+
displayName: string;
|
|
64
|
+
};
|
|
65
|
+
var Fields: {
|
|
66
|
+
(_props: Readonly<SlotProps>): ReactNode;
|
|
67
|
+
kptAuthSlot: SlotName;
|
|
68
|
+
displayName: string;
|
|
69
|
+
};
|
|
70
|
+
var Footer: {
|
|
71
|
+
(_props: Readonly<SlotProps>): ReactNode;
|
|
72
|
+
kptAuthSlot: SlotName;
|
|
73
|
+
displayName: string;
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
export {};
|