@lattice-php/lattice 0.1.0 → 0.2.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/dist/_virtual/_rolldown/runtime.js +8 -0
- package/dist/action/components/action-form.d.ts +24 -0
- package/dist/action/components/action-form.js +270 -0
- package/dist/action/components/action-form.js.map +1 -0
- package/dist/action/components/action-group.d.ts +1 -8
- package/dist/action/components/action-group.js +24 -66
- package/dist/action/components/action-group.js.map +1 -1
- package/dist/action/components/action.d.ts +1 -24
- package/dist/action/components/action.js +61 -46
- package/dist/action/components/action.js.map +1 -1
- package/dist/action/effects.d.ts +6 -25
- package/dist/action/effects.js +2 -2
- package/dist/action/effects.js.map +1 -1
- package/dist/action/index.d.ts +1 -1
- package/dist/core/components/badge.d.ts +1 -8
- package/dist/core/components/badge.js +2 -3
- package/dist/core/components/badge.js.map +1 -1
- package/dist/core/components/button.d.ts +4 -12
- package/dist/core/components/button.js +6 -9
- package/dist/core/components/button.js.map +1 -1
- package/dist/core/components/card.d.ts +1 -9
- package/dist/core/components/card.js +1 -3
- package/dist/core/components/card.js.map +1 -1
- package/dist/core/components/confirm-dialog.d.ts +2 -3
- package/dist/core/components/confirm-dialog.js +19 -13
- package/dist/core/components/confirm-dialog.js.map +1 -1
- package/dist/core/components/fragment.d.ts +1 -10
- package/dist/core/components/fragment.js +5 -6
- package/dist/core/components/fragment.js.map +1 -1
- package/dist/core/components/grid.d.ts +1 -8
- package/dist/core/components/grid.js +1 -2
- package/dist/core/components/grid.js.map +1 -1
- package/dist/core/components/heading.d.ts +1 -9
- package/dist/core/components/heading.js +2 -3
- package/dist/core/components/heading.js.map +1 -1
- package/dist/core/components/icon.d.ts +3 -0
- package/dist/core/components/icon.js +30 -0
- package/dist/core/components/icon.js.map +1 -0
- package/dist/core/components/index.d.ts +1 -1
- package/dist/core/components/index.js +4 -0
- package/dist/core/components/index.js.map +1 -1
- package/dist/core/components/link.d.ts +1 -12
- package/dist/core/components/link.js +4 -9
- package/dist/core/components/link.js.map +1 -1
- package/dist/core/components/modal.d.ts +1 -11
- package/dist/core/components/modal.js +27 -31
- package/dist/core/components/modal.js.map +1 -1
- package/dist/core/components/section.d.ts +3 -0
- package/dist/core/components/section.js +79 -0
- package/dist/core/components/section.js.map +1 -0
- package/dist/core/components/segmented-control.d.ts +1 -14
- package/dist/core/components/segmented-control.js +4 -7
- package/dist/core/components/segmented-control.js.map +1 -1
- package/dist/core/components/segmented-pills.d.ts +4 -2
- package/dist/core/components/segmented-pills.js +10 -1
- package/dist/core/components/segmented-pills.js.map +1 -1
- package/dist/core/components/spinner.js +8 -4
- package/dist/core/components/spinner.js.map +1 -1
- package/dist/core/components/stack.d.ts +1 -11
- package/dist/core/components/stack.js +5 -5
- package/dist/core/components/stack.js.map +1 -1
- package/dist/core/components/tabs.d.ts +1 -19
- package/dist/core/components/tabs.js +45 -21
- package/dist/core/components/tabs.js.map +1 -1
- package/dist/core/components/text.d.ts +1 -9
- package/dist/core/components/text.js +2 -3
- package/dist/core/components/text.js.map +1 -1
- package/dist/core/registry.d.ts +9 -3
- package/dist/core/registry.js +21 -5
- package/dist/core/registry.js.map +1 -1
- package/dist/core/renderer.js +7 -13
- package/dist/core/renderer.js.map +1 -1
- package/dist/core/types.d.ts +54 -26
- package/dist/form/components/base/checkbox.js +5 -2
- package/dist/form/components/base/checkbox.js.map +1 -1
- package/dist/form/components/base/field.d.ts +2 -1
- package/dist/form/components/base/field.js +5 -1
- package/dist/form/components/base/field.js.map +1 -1
- package/dist/form/components/base/password-input.js +9 -2
- package/dist/form/components/base/password-input.js.map +1 -1
- package/dist/form/components/base/submit-button.d.ts +4 -4
- package/dist/form/components/base/submit-button.js +2 -2
- package/dist/form/components/base/submit-button.js.map +1 -1
- package/dist/form/components/conditions.d.ts +6 -9
- package/dist/form/components/conditions.js +10 -2
- package/dist/form/components/conditions.js.map +1 -1
- package/dist/form/components/context.d.ts +0 -4
- package/dist/form/components/context.js +1 -5
- package/dist/form/components/context.js.map +1 -1
- package/dist/form/components/field-props.d.ts +24 -0
- package/dist/form/components/field-props.js +15 -0
- package/dist/form/components/field-props.js.map +1 -0
- package/dist/form/components/fields/checkbox.d.ts +1 -15
- package/dist/form/components/fields/checkbox.js +16 -21
- package/dist/form/components/fields/checkbox.js.map +1 -1
- package/dist/form/components/fields/choice.d.ts +1 -13
- package/dist/form/components/fields/choice.js +13 -20
- package/dist/form/components/fields/choice.js.map +1 -1
- package/dist/form/components/fields/date-input.d.ts +1 -19
- package/dist/form/components/fields/date-input.js +11 -16
- package/dist/form/components/fields/date-input.js.map +1 -1
- package/dist/form/components/fields/hidden-input.d.ts +1 -9
- package/dist/form/components/fields/hidden-input.js +2 -3
- package/dist/form/components/fields/hidden-input.js.map +1 -1
- package/dist/form/components/fields/number-input.d.ts +1 -22
- package/dist/form/components/fields/number-input.js +38 -41
- package/dist/form/components/fields/number-input.js.map +1 -1
- package/dist/form/components/fields/password-input.d.ts +1 -28
- package/dist/form/components/fields/password-input.js +15 -24
- package/dist/form/components/fields/password-input.js.map +1 -1
- package/dist/form/components/fields/rich-editor.d.ts +1 -16
- package/dist/form/components/fields/rich-editor.js +57 -47
- package/dist/form/components/fields/rich-editor.js.map +1 -1
- package/dist/form/components/fields/select.d.ts +1 -22
- package/dist/form/components/fields/select.js +85 -74
- package/dist/form/components/fields/select.js.map +1 -1
- package/dist/form/components/fields/simple-field.d.ts +9 -0
- package/dist/form/components/fields/simple-field.js +22 -0
- package/dist/form/components/fields/simple-field.js.map +1 -0
- package/dist/form/components/fields/text-input.d.ts +1 -20
- package/dist/form/components/fields/text-input.js +12 -17
- package/dist/form/components/fields/text-input.js.map +1 -1
- package/dist/form/components/fields/textarea.d.ts +1 -19
- package/dist/form/components/fields/textarea.js +11 -16
- package/dist/form/components/fields/textarea.js.map +1 -1
- package/dist/form/components/form.d.ts +1 -20
- package/dist/form/components/form.js +29 -36
- package/dist/form/components/form.js.map +1 -1
- package/dist/form/components/index.d.ts +0 -1
- package/dist/form/components/index.js +1 -2
- package/dist/form/components/resolved-nodes.d.ts +1 -1
- package/dist/form/components/resolved-nodes.js +2 -2
- package/dist/form/components/resolved-nodes.js.map +1 -1
- package/dist/form/components/types.d.ts +1 -0
- package/dist/form/components/use-controlled-field.d.ts +3 -9
- package/dist/form/components/use-controlled-field.js +5 -9
- package/dist/form/components/use-controlled-field.js.map +1 -1
- package/dist/form/components/use-dependent-field.d.ts +1 -1
- package/dist/form/components/use-dependent-field.js +8 -8
- package/dist/form/components/use-dependent-field.js.map +1 -1
- package/dist/form/components/use-form-resolver.d.ts +1 -1
- package/dist/form/components/use-form-resolver.js +8 -13
- package/dist/form/components/use-form-resolver.js.map +1 -1
- package/dist/form/components/use-seed-default.d.ts +5 -0
- package/dist/form/components/use-seed-default.js +23 -0
- package/dist/form/components/use-seed-default.js.map +1 -0
- package/dist/form/index.d.ts +1 -1
- package/dist/form/index.js +0 -1
- package/dist/form/index.js.map +1 -1
- package/dist/form/skeleton.d.ts +1 -1
- package/dist/form/skeleton.js +1 -1
- package/dist/form/skeleton.js.map +1 -1
- package/dist/i18n/backend.d.ts +24 -0
- package/dist/i18n/backend.js +39 -0
- package/dist/i18n/backend.js.map +1 -0
- package/dist/i18n/index.d.ts +3 -0
- package/dist/i18n/index.js +3 -0
- package/dist/i18n/instance.js +48 -0
- package/dist/i18n/instance.js.map +1 -0
- package/dist/icons/icon-renderer.js +30 -5
- package/dist/icons/icon-renderer.js.map +1 -1
- package/dist/icons/index.d.ts +2 -0
- package/dist/icons/index.js +2 -1
- package/dist/icons/sprite.d.ts +30 -0
- package/dist/icons/sprite.js +40 -0
- package/dist/icons/sprite.js.map +1 -0
- package/dist/index.d.ts +9 -5
- package/dist/index.js +7 -3
- package/dist/inertia.d.ts +1 -6
- package/dist/inertia.js +4 -8
- package/dist/inertia.js.map +1 -1
- package/dist/lattice.css +129 -5
- package/dist/layout/components.d.ts +1 -0
- package/dist/layout/components.js +19 -0
- package/dist/layout/components.js.map +1 -0
- package/dist/layout/context.d.ts +12 -0
- package/dist/layout/context.js +19 -0
- package/dist/layout/context.js.map +1 -0
- package/dist/layout/index.d.ts +3 -0
- package/dist/layout/index.js +4 -0
- package/dist/layout/menu-item.d.ts +3 -0
- package/dist/layout/menu-item.js +130 -0
- package/dist/layout/menu-item.js.map +1 -0
- package/dist/layout/menu.d.ts +3 -0
- package/dist/layout/menu.js +13 -0
- package/dist/layout/menu.js.map +1 -0
- package/dist/layout/outlet.d.ts +6 -0
- package/dist/layout/outlet.js +14 -0
- package/dist/layout/outlet.js.map +1 -0
- package/dist/layout/schema-layout.d.ts +10 -0
- package/dist/layout/schema-layout.js +30 -0
- package/dist/layout/schema-layout.js.map +1 -0
- package/dist/layout/sidebar.d.ts +3 -0
- package/dist/layout/sidebar.js +48 -0
- package/dist/layout/sidebar.js.map +1 -0
- package/dist/lib/utils.d.ts +0 -2
- package/dist/lib/utils.js +1 -4
- package/dist/lib/utils.js.map +1 -1
- package/dist/node_modules/i18next/dist/esm/i18next.js +1982 -0
- package/dist/node_modules/i18next/dist/esm/i18next.js.map +1 -0
- package/dist/node_modules/i18next-http-backend/esm/index.js +352 -0
- package/dist/node_modules/i18next-http-backend/esm/index.js.map +1 -0
- package/dist/node_modules/react-i18next/dist/es/context.js +23 -0
- package/dist/node_modules/react-i18next/dist/es/context.js.map +1 -0
- package/dist/node_modules/react-i18next/dist/es/defaults.js +29 -0
- package/dist/node_modules/react-i18next/dist/es/defaults.js.map +1 -0
- package/dist/node_modules/react-i18next/dist/es/i18nInstance.js +10 -0
- package/dist/node_modules/react-i18next/dist/es/i18nInstance.js.map +1 -0
- package/dist/node_modules/react-i18next/dist/es/initReactI18next.js +14 -0
- package/dist/node_modules/react-i18next/dist/es/initReactI18next.js.map +1 -0
- package/dist/node_modules/react-i18next/dist/es/unescape.js +30 -0
- package/dist/node_modules/react-i18next/dist/es/unescape.js.map +1 -0
- package/dist/node_modules/react-i18next/dist/es/useTranslation.js +157 -0
- package/dist/node_modules/react-i18next/dist/es/useTranslation.js.map +1 -0
- package/dist/node_modules/react-i18next/dist/es/utils.js +58 -0
- package/dist/node_modules/react-i18next/dist/es/utils.js.map +1 -0
- package/dist/node_modules/use-sync-external-store/cjs/use-sync-external-store-shim.development.js +70 -0
- package/dist/node_modules/use-sync-external-store/cjs/use-sync-external-store-shim.development.js.map +1 -0
- package/dist/node_modules/use-sync-external-store/cjs/use-sync-external-store-shim.production.js +61 -0
- package/dist/node_modules/use-sync-external-store/cjs/use-sync-external-store-shim.production.js.map +1 -0
- package/dist/node_modules/use-sync-external-store/shim/index.js +13 -0
- package/dist/node_modules/use-sync-external-store/shim/index.js.map +1 -0
- package/dist/page.d.ts +1 -1
- package/dist/page.js +2 -2
- package/dist/page.js.map +1 -1
- package/dist/provider.d.ts +8 -3
- package/dist/provider.js +17 -9
- package/dist/provider.js.map +1 -1
- package/dist/registry.d.ts +1 -1
- package/dist/registry.js +2 -1
- package/dist/registry.js.map +1 -1
- package/dist/table/bulk.d.ts +6 -10
- package/dist/table/bulk.js +13 -35
- package/dist/table/bulk.js.map +1 -1
- package/dist/table/column-registry.d.ts +9 -0
- package/dist/table/components/bulk-bar.js +34 -3
- package/dist/table/components/bulk-bar.js.map +1 -1
- package/dist/table/components/cells/badge-cell.d.ts +5 -0
- package/dist/table/components/cells/badge-cell.js +16 -0
- package/dist/table/components/cells/badge-cell.js.map +1 -0
- package/dist/table/components/cells/icon-cell.d.ts +5 -0
- package/dist/table/components/cells/icon-cell.js +22 -0
- package/dist/table/components/cells/icon-cell.js.map +1 -0
- package/dist/table/components/cells/image-cell.d.ts +5 -0
- package/dist/table/components/cells/image-cell.js +24 -0
- package/dist/table/components/cells/image-cell.js.map +1 -0
- package/dist/table/components/cells/text-cell.d.ts +6 -0
- package/dist/table/components/cells/text-cell.js +50 -0
- package/dist/table/components/cells/text-cell.js.map +1 -0
- package/dist/table/components/column-filter-control.js +59 -96
- package/dist/table/components/column-filter-control.js.map +1 -1
- package/dist/table/components/column-header.js +22 -11
- package/dist/table/components/column-header.js.map +1 -1
- package/dist/table/components/filter-stack-bar.d.ts +2 -2
- package/dist/table/components/filter-stack-bar.js +10 -8
- package/dist/table/components/filter-stack-bar.js.map +1 -1
- package/dist/table/components/filter-value-input.d.ts +5 -3
- package/dist/table/components/filter-value-input.js +25 -16
- package/dist/table/components/filter-value-input.js.map +1 -1
- package/dist/table/components/pagination.d.ts +1 -1
- package/dist/table/components/pagination.js +20 -8
- package/dist/table/components/pagination.js.map +1 -1
- package/dist/table/components/sort-bar.d.ts +2 -2
- package/dist/table/components/sort-bar.js +12 -10
- package/dist/table/components/sort-bar.js.map +1 -1
- package/dist/table/components/table-action-node.d.ts +1 -1
- package/dist/table/components/table-action-node.js +1 -1
- package/dist/table/components/table-action-node.js.map +1 -1
- package/dist/table/components/table-cell.d.ts +1 -1
- package/dist/table/components/table-cell.js +24 -43
- package/dist/table/components/table-cell.js.map +1 -1
- package/dist/table/components/table.d.ts +6 -2
- package/dist/table/components/table.js +40 -17
- package/dist/table/components/table.js.map +1 -1
- package/dist/table/format.js +5 -3
- package/dist/table/format.js.map +1 -1
- package/dist/table/index.d.ts +1 -1
- package/dist/table/index.js.map +1 -1
- package/dist/table/payload.d.ts +1 -1
- package/dist/table/query.d.ts +0 -1
- package/dist/table/query.js +8 -9
- package/dist/table/query.js.map +1 -1
- package/dist/table/types.d.ts +38 -42
- package/dist/table/use-table.d.ts +3 -4
- package/dist/table/use-table.js +12 -23
- package/dist/table/use-table.js.map +1 -1
- package/dist/test-support.d.ts +14 -0
- package/dist/test-support.js +14 -0
- package/dist/test-support.js.map +1 -0
- package/dist/toast/index.d.ts +1 -0
- package/dist/toast/index.js +2 -0
- package/dist/toast/toaster.d.ts +3 -0
- package/dist/toast/toaster.js +126 -0
- package/dist/toast/toaster.js.map +1 -0
- package/dist/types/generated.d.ts +677 -0
- package/dist/types/generated.js +0 -0
- package/dist/types/index.d.ts +1 -1
- package/package.json +18 -3
- package/resources/icons/align-center.svg +17 -0
- package/resources/icons/align-justify.svg +17 -0
- package/resources/icons/align-left.svg +17 -0
- package/resources/icons/align-right.svg +17 -0
- package/resources/icons/arrow-down.svg +16 -0
- package/resources/icons/arrow-up.svg +16 -0
- package/resources/icons/bold.svg +15 -0
- package/resources/icons/check.svg +15 -0
- package/resources/icons/chevron-down.svg +15 -0
- package/resources/icons/chevron-right.svg +15 -0
- package/resources/icons/chevrons-up-down.svg +16 -0
- package/resources/icons/circle-alert.svg +17 -0
- package/resources/icons/circle-check.svg +16 -0
- package/resources/icons/circle-help.svg +17 -0
- package/resources/icons/circle-x.svg +17 -0
- package/resources/icons/code.svg +16 -0
- package/resources/icons/columns-3.svg +17 -0
- package/resources/icons/copy.svg +16 -0
- package/resources/icons/external-link.svg +17 -0
- package/resources/icons/eye-off.svg +18 -0
- package/resources/icons/eye.svg +16 -0
- package/resources/icons/filter.svg +15 -0
- package/resources/icons/heading-1.svg +18 -0
- package/resources/icons/heading-2.svg +18 -0
- package/resources/icons/heading-3.svg +19 -0
- package/resources/icons/highlighter.svg +16 -0
- package/resources/icons/info.svg +17 -0
- package/resources/icons/italic.svg +17 -0
- package/resources/icons/layout-dashboard.svg +18 -0
- package/resources/icons/link.svg +16 -0
- package/resources/icons/list-ordered.svg +20 -0
- package/resources/icons/list.svg +20 -0
- package/resources/icons/loader-2.svg +15 -0
- package/resources/icons/minus.svg +15 -0
- package/resources/icons/more-horizontal.svg +17 -0
- package/resources/icons/panel-left.svg +16 -0
- package/resources/icons/pencil-line.svg +17 -0
- package/resources/icons/pencil.svg +16 -0
- package/resources/icons/plus.svg +16 -0
- package/resources/icons/quote.svg +16 -0
- package/resources/icons/rows-3.svg +17 -0
- package/resources/icons/search.svg +16 -0
- package/resources/icons/send.svg +16 -0
- package/resources/icons/settings.svg +16 -0
- package/resources/icons/smile.svg +18 -0
- package/resources/icons/strikethrough.svg +17 -0
- package/resources/icons/table.svg +18 -0
- package/resources/icons/trash-2.svg +19 -0
- package/resources/icons/underline.svg +16 -0
- package/resources/icons/x.svg +16 -0
- package/dist/core/props.d.ts +0 -14
- package/dist/core/props.js +0 -30
- package/dist/core/props.js.map +0 -1
- package/dist/form/components/fields/submit-button.d.ts +0 -10
- package/dist/form/components/fields/submit-button.js +0 -14
- package/dist/form/components/fields/submit-button.js.map +0 -1
- package/dist/generated/types.d.ts +0 -17
- package/dist/icons/default-icons.d.ts +0 -3
- package/dist/icons/default-icons.js +0 -44
- package/dist/icons/default-icons.js.map +0 -1
- package/dist/icons/dynamic-lucide-renderer.d.ts +0 -2
- package/dist/icons/dynamic-lucide-renderer.js +0 -18
- package/dist/icons/dynamic-lucide-renderer.js.map +0 -1
- package/dist/menu/index.d.ts +0 -1
- package/dist/menu/index.js +0 -2
- package/dist/menu/use-menu.d.ts +0 -2
- package/dist/menu/use-menu.js +0 -9
- package/dist/menu/use-menu.js.map +0 -1
- /package/dist/{generated/types.js → table/column-registry.js} +0 -0
|
@@ -1,22 +1,4 @@
|
|
|
1
|
-
import { RendererComponent } from '
|
|
2
|
-
declare module '../../../../core/types' {
|
|
3
|
-
interface ComponentProps {
|
|
4
|
-
tab: {
|
|
5
|
-
confirm?: {
|
|
6
|
-
redirectUrl?: string;
|
|
7
|
-
required?: boolean;
|
|
8
|
-
timeout?: number;
|
|
9
|
-
};
|
|
10
|
-
label?: string;
|
|
11
|
-
value?: string;
|
|
12
|
-
};
|
|
13
|
-
tabs: {
|
|
14
|
-
activeValue?: string;
|
|
15
|
-
defaultValue?: string;
|
|
16
|
-
queryKey?: string;
|
|
17
|
-
};
|
|
18
|
-
}
|
|
19
|
-
}
|
|
1
|
+
import { RendererComponent } from '../types';
|
|
20
2
|
export declare const TabsComponent: RendererComponent<"tabs">;
|
|
21
3
|
declare const TabComponent: RendererComponent<"tab">;
|
|
22
4
|
export default TabComponent;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { cn } from "../../lib/utils.js";
|
|
2
|
-
import {
|
|
3
|
-
import { createContext, useContext, useEffect, useMemo, useState } from "react";
|
|
2
|
+
import { useT } from "../../i18n/instance.js";
|
|
3
|
+
import { createContext, useContext, useEffect, useMemo, useRef, useState } from "react";
|
|
4
4
|
import { router } from "@inertiajs/react";
|
|
5
5
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
6
6
|
//#region resources/js/core/components/tabs.tsx
|
|
@@ -14,16 +14,14 @@ function useTabsContext() {
|
|
|
14
14
|
return context;
|
|
15
15
|
}
|
|
16
16
|
function getTabs(node) {
|
|
17
|
-
return (node.
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
if (!confirm || typeof confirm !== "object" || Array.isArray(confirm)) return;
|
|
26
|
-
return { required: confirm.required === true };
|
|
17
|
+
return (node.schema ?? []).filter((child) => child.type === "tab").map((child) => {
|
|
18
|
+
const props = child.props;
|
|
19
|
+
return {
|
|
20
|
+
confirm: props.confirm ? { required: props.confirm.required } : void 0,
|
|
21
|
+
label: props.label,
|
|
22
|
+
value: props.value
|
|
23
|
+
};
|
|
24
|
+
}).filter((tab) => tab.value !== "");
|
|
27
25
|
}
|
|
28
26
|
function queryValue(queryKey, tabs) {
|
|
29
27
|
if (typeof window === "undefined") return null;
|
|
@@ -44,11 +42,15 @@ function queryUrl(queryKey, value) {
|
|
|
44
42
|
return `${url.pathname}${url.search}${url.hash}`;
|
|
45
43
|
}
|
|
46
44
|
var TabsComponent = ({ children, node }) => {
|
|
45
|
+
const { t } = useT("lattice");
|
|
47
46
|
const tabs = useMemo(() => getTabs(node), [node]);
|
|
48
47
|
const firstValue = tabs[0]?.value ?? "";
|
|
49
|
-
const queryKey =
|
|
50
|
-
const
|
|
51
|
-
const
|
|
48
|
+
const queryKey = node.props.queryKey;
|
|
49
|
+
const orientation = node.props.orientation;
|
|
50
|
+
const isVertical = orientation === "vertical";
|
|
51
|
+
const serverActiveValue = node.props.activeValue;
|
|
52
|
+
const defaultValue = node.props.defaultValue ?? firstValue;
|
|
53
|
+
const tablistRef = useRef(null);
|
|
52
54
|
const [activeValue, setActiveTabValue] = useState(() => serverActiveValue || (queryValue(queryKey, tabs) ?? defaultValue) || firstValue);
|
|
53
55
|
function selectTab(tab) {
|
|
54
56
|
if (tab.confirm?.required) {
|
|
@@ -62,33 +64,55 @@ var TabsComponent = ({ children, node }) => {
|
|
|
62
64
|
const tab = tabs.find((item) => item.value === value);
|
|
63
65
|
if (tab) selectTab(tab);
|
|
64
66
|
}
|
|
67
|
+
function onTablistKeyDown(event) {
|
|
68
|
+
const nextKey = isVertical ? "ArrowDown" : "ArrowRight";
|
|
69
|
+
const prevKey = isVertical ? "ArrowUp" : "ArrowLeft";
|
|
70
|
+
if (event.key !== nextKey && event.key !== prevKey && event.key !== "Home" && event.key !== "End") return;
|
|
71
|
+
const buttons = Array.from(tablistRef.current?.querySelectorAll("[role=\"tab\"]") ?? []);
|
|
72
|
+
if (buttons.length === 0) return;
|
|
73
|
+
event.preventDefault();
|
|
74
|
+
const current = buttons.indexOf(document.activeElement);
|
|
75
|
+
let index;
|
|
76
|
+
if (event.key === "Home") index = 0;
|
|
77
|
+
else if (event.key === "End") index = buttons.length - 1;
|
|
78
|
+
else {
|
|
79
|
+
const delta = event.key === nextKey ? 1 : -1;
|
|
80
|
+
index = ((current < 0 ? 0 : current) + delta + buttons.length) % buttons.length;
|
|
81
|
+
}
|
|
82
|
+
buttons[index]?.focus();
|
|
83
|
+
}
|
|
65
84
|
return /* @__PURE__ */ jsx(TabsContext.Provider, {
|
|
66
85
|
value: {
|
|
67
86
|
activeValue,
|
|
68
87
|
setActiveValue: selectTabValue
|
|
69
88
|
},
|
|
70
89
|
children: /* @__PURE__ */ jsxs("div", {
|
|
71
|
-
className: "
|
|
90
|
+
className: cn("gap-6", isVertical ? "flex" : "grid"),
|
|
72
91
|
"data-lattice-tabs": node.key ?? node.id,
|
|
73
92
|
children: [/* @__PURE__ */ jsx("div", {
|
|
74
|
-
"aria-label":
|
|
75
|
-
|
|
93
|
+
"aria-label": t("a11y.tabs", "Tabs"),
|
|
94
|
+
"aria-orientation": orientation,
|
|
95
|
+
className: cn("gap-1 rounded-lt bg-lt-muted p-1", isVertical ? "flex flex-col" : "inline-flex w-fit max-w-full overflow-x-auto"),
|
|
96
|
+
ref: tablistRef,
|
|
76
97
|
role: "tablist",
|
|
77
98
|
children: tabs.map((tab) => {
|
|
78
99
|
const isActive = activeValue === tab.value;
|
|
79
100
|
return /* @__PURE__ */ jsx("button", {
|
|
80
101
|
"aria-controls": `${tab.value}-panel`,
|
|
81
102
|
"aria-selected": isActive,
|
|
82
|
-
|
|
103
|
+
"data-test": `tab-${tab.value}`,
|
|
104
|
+
className: cn("whitespace-nowrap rounded-lt-sm px-3 py-1.5 text-sm font-medium transition-colors", isActive ? "bg-lt-bg text-lt-fg shadow-xs" : "text-lt-muted-fg hover:bg-lt-bg/60 hover:text-lt-fg", isVertical && "text-left"),
|
|
83
105
|
id: `${tab.value}-tab`,
|
|
84
106
|
onClick: () => selectTab(tab),
|
|
107
|
+
onKeyDown: onTablistKeyDown,
|
|
85
108
|
role: "tab",
|
|
109
|
+
tabIndex: isActive ? 0 : -1,
|
|
86
110
|
type: "button",
|
|
87
111
|
children: tab.label
|
|
88
112
|
}, tab.value);
|
|
89
113
|
})
|
|
90
114
|
}), /* @__PURE__ */ jsx("div", {
|
|
91
|
-
className: "min-w-0",
|
|
115
|
+
className: cn("min-w-0", isVertical && "flex-1"),
|
|
92
116
|
children
|
|
93
117
|
})]
|
|
94
118
|
})
|
|
@@ -96,7 +120,7 @@ var TabsComponent = ({ children, node }) => {
|
|
|
96
120
|
};
|
|
97
121
|
var TabComponent = ({ children, node }) => {
|
|
98
122
|
const { activeValue } = useTabsContext();
|
|
99
|
-
const value =
|
|
123
|
+
const value = node.props.value;
|
|
100
124
|
const isActive = activeValue === value;
|
|
101
125
|
const [hasOpened, setHasOpened] = useState(isActive);
|
|
102
126
|
useEffect(() => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tabs.js","names":[],"sources":["../../../resources/js/core/components/tabs.tsx"],"sourcesContent":["import { router } from \"@inertiajs/react\";\nimport { createContext, useContext, useEffect, useMemo, useState } from \"react\";\nimport type { ReactNode } from \"react\";\nimport { getStringProp } from \"@lattice/lattice/core/props\";\nimport type { Node, RendererComponent } from \"@lattice/lattice/core/types\";\nimport { cn } from \"@lattice/lattice/lib/utils\";\n\ntype TabsContextValue = {\n activeValue: string;\n setActiveValue: (value: string) => void;\n};\n\nconst TabsContext = createContext<TabsContextValue | null>(null);\n\nfunction useTabsContext(): TabsContextValue {\n const context = useContext(TabsContext);\n\n if (!context) {\n return {\n activeValue: \"\",\n setActiveValue: () => {},\n };\n }\n\n return context;\n}\n\ntype TabItem = {\n confirm?: {\n required?: boolean;\n };\n label: string;\n value: string;\n};\n\nfunction getTabs(node: Node): TabItem[] {\n return (node.children ?? [])\n .filter((child) => child.type === \"tab\")\n .map((child) => ({\n confirm: getConfirmationProp(child.props),\n label: getStringProp(child.props, \"label\"),\n value: getStringProp(child.props, \"value\"),\n }))\n .filter((tab) => tab.value !== \"\");\n}\n\nfunction getConfirmationProp(props: Node[\"props\"]): TabItem[\"confirm\"] {\n const confirm = props?.confirm;\n\n if (!confirm || typeof confirm !== \"object\" || Array.isArray(confirm)) {\n return undefined;\n }\n\n const confirmation = confirm as Record<string, unknown>;\n\n return {\n required: confirmation.required === true,\n };\n}\n\nfunction queryValue(queryKey: string, tabs: Array<{ value: string }>): string | null {\n if (typeof window === \"undefined\") {\n return null;\n }\n\n const value = new URLSearchParams(window.location.search).get(queryKey);\n\n if (!value || !tabs.some((tab) => tab.value === value)) {\n return null;\n }\n\n return value;\n}\n\nfunction replaceQueryValue(queryKey: string, value: string): void {\n if (typeof window === \"undefined\") {\n return;\n }\n\n const url = new URL(window.location.href);\n url.searchParams.set(queryKey, value);\n window.history.replaceState(window.history.state, \"\", `${url.pathname}${url.search}${url.hash}`);\n}\n\nfunction queryUrl(queryKey: string, value: string): string {\n if (typeof window === \"undefined\") {\n return \"\";\n }\n\n const url = new URL(window.location.href);\n url.searchParams.set(queryKey, value);\n\n return `${url.pathname}${url.search}${url.hash}`;\n}\n\ndeclare module \"@lattice/lattice/core/types\" {\n interface ComponentProps {\n tab: {\n confirm?: {\n redirectUrl?: string;\n required?: boolean;\n timeout?: number;\n };\n label?: string;\n value?: string;\n };\n tabs: {\n activeValue?: string;\n defaultValue?: string;\n queryKey?: string;\n };\n }\n}\n\nexport const TabsComponent: RendererComponent<\"tabs\"> = ({ children, node }) => {\n const tabs = useMemo(() => getTabs(node), [node]);\n const firstValue = tabs[0]?.value ?? \"\";\n const queryKey = getStringProp(node.props, \"queryKey\", \"tabs\");\n const serverActiveValue = getStringProp(node.props, \"activeValue\", \"\");\n const defaultValue = getStringProp(node.props, \"defaultValue\", firstValue);\n const [activeValue, setActiveTabValue] = useState(\n () => serverActiveValue || (queryValue(queryKey, tabs) ?? defaultValue) || firstValue,\n );\n\n function selectTab(tab: TabItem): void {\n if (tab.confirm?.required) {\n router.visit(queryUrl(queryKey, tab.value), {\n preserveScroll: true,\n });\n\n return;\n }\n\n setActiveTabValue(tab.value);\n replaceQueryValue(queryKey, tab.value);\n }\n\n function selectTabValue(value: string): void {\n const tab = tabs.find((item) => item.value === value);\n\n if (tab) {\n selectTab(tab);\n }\n }\n\n return (\n <TabsContext.Provider value={{ activeValue, setActiveValue: selectTabValue }}>\n <div className=\"grid gap-6\" data-lattice-tabs={node.key ?? node.id}>\n <div\n aria-label={getStringProp(node.props, \"label\", \"Tabs\")}\n className=\"inline-flex w-fit max-w-full gap-1 overflow-x-auto rounded-lt bg-lt-muted p-1\"\n role=\"tablist\"\n >\n {tabs.map((tab) => {\n const isActive = activeValue === tab.value;\n\n return (\n <button\n aria-controls={`${tab.value}-panel`}\n aria-selected={isActive}\n className={cn(\n \"whitespace-nowrap rounded-lt-sm px-3 py-1.5 text-sm font-medium transition-colors\",\n isActive\n ? \"bg-lt-bg text-lt-fg shadow-xs\"\n : \"text-lt-muted-fg hover:bg-lt-bg/60 hover:text-lt-fg\",\n )}\n id={`${tab.value}-tab`}\n key={tab.value}\n onClick={() => selectTab(tab)}\n role=\"tab\"\n type=\"button\"\n >\n {tab.label}\n </button>\n );\n })}\n </div>\n\n <div className=\"min-w-0\">{children}</div>\n </div>\n </TabsContext.Provider>\n );\n};\n\nconst TabComponent: RendererComponent<\"tab\"> = ({ children, node }) => {\n const { activeValue } = useTabsContext();\n const value = getStringProp(node.props, \"value\");\n const isActive = activeValue === value;\n const [hasOpened, setHasOpened] = useState(isActive);\n\n useEffect(() => {\n if (isActive) {\n setHasOpened(true);\n }\n }, [isActive]);\n\n return (\n <section\n aria-labelledby={`${value}-tab`}\n className={cn(\"space-y-8\", !isActive && \"hidden\")}\n hidden={!isActive}\n id={`${value}-panel`}\n role=\"tabpanel\"\n tabIndex={0}\n >\n {hasOpened ? (children as ReactNode) : null}\n </section>\n );\n};\n\nexport default TabComponent;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"tabs.js","names":[],"sources":["../../../resources/js/core/components/tabs.tsx"],"sourcesContent":["import { router } from \"@inertiajs/react\";\nimport { createContext, useContext, useEffect, useMemo, useRef, useState } from \"react\";\nimport type { KeyboardEvent, ReactNode } from \"react\";\nimport type { Node, RendererComponent } from \"@lattice/lattice/core/types\";\nimport type { Tab } from \"@lattice/lattice/types/generated\";\nimport { cn } from \"@lattice/lattice/lib/utils\";\nimport { useT } from \"@lattice/lattice/i18n\";\n\ntype TabsContextValue = {\n activeValue: string;\n setActiveValue: (value: string) => void;\n};\n\nconst TabsContext = createContext<TabsContextValue | null>(null);\n\nfunction useTabsContext(): TabsContextValue {\n const context = useContext(TabsContext);\n\n if (!context) {\n return {\n activeValue: \"\",\n setActiveValue: () => {},\n };\n }\n\n return context;\n}\n\ntype TabItem = {\n confirm?: {\n required?: boolean;\n };\n label: string;\n value: string;\n};\n\nfunction getTabs(node: Node): TabItem[] {\n return (node.schema ?? [])\n .filter((child) => child.type === \"tab\")\n .map((child) => {\n const props = child.props as unknown as Tab;\n\n return {\n confirm: props.confirm ? { required: props.confirm.required } : undefined,\n label: props.label,\n value: props.value,\n };\n })\n .filter((tab) => tab.value !== \"\");\n}\n\nfunction queryValue(queryKey: string, tabs: Array<{ value: string }>): string | null {\n if (typeof window === \"undefined\") {\n return null;\n }\n\n const value = new URLSearchParams(window.location.search).get(queryKey);\n\n if (!value || !tabs.some((tab) => tab.value === value)) {\n return null;\n }\n\n return value;\n}\n\nfunction replaceQueryValue(queryKey: string, value: string): void {\n if (typeof window === \"undefined\") {\n return;\n }\n\n const url = new URL(window.location.href);\n url.searchParams.set(queryKey, value);\n window.history.replaceState(window.history.state, \"\", `${url.pathname}${url.search}${url.hash}`);\n}\n\nfunction queryUrl(queryKey: string, value: string): string {\n if (typeof window === \"undefined\") {\n return \"\";\n }\n\n const url = new URL(window.location.href);\n url.searchParams.set(queryKey, value);\n\n return `${url.pathname}${url.search}${url.hash}`;\n}\n\nexport const TabsComponent: RendererComponent<\"tabs\"> = ({ children, node }) => {\n const { t } = useT(\"lattice\");\n const tabs = useMemo(() => getTabs(node), [node]);\n const firstValue = tabs[0]?.value ?? \"\";\n const queryKey = node.props.queryKey;\n const orientation = node.props.orientation;\n const isVertical = orientation === \"vertical\";\n const serverActiveValue = node.props.activeValue;\n const defaultValue = node.props.defaultValue ?? firstValue;\n const tablistRef = useRef<HTMLDivElement>(null);\n const [activeValue, setActiveTabValue] = useState(\n () => serverActiveValue || (queryValue(queryKey, tabs) ?? defaultValue) || firstValue,\n );\n\n function selectTab(tab: TabItem): void {\n if (tab.confirm?.required) {\n router.visit(queryUrl(queryKey, tab.value), {\n preserveScroll: true,\n });\n\n return;\n }\n\n setActiveTabValue(tab.value);\n replaceQueryValue(queryKey, tab.value);\n }\n\n function selectTabValue(value: string): void {\n const tab = tabs.find((item) => item.value === value);\n\n if (tab) {\n selectTab(tab);\n }\n }\n\n function onTablistKeyDown(event: KeyboardEvent<HTMLButtonElement>): void {\n const nextKey = isVertical ? \"ArrowDown\" : \"ArrowRight\";\n const prevKey = isVertical ? \"ArrowUp\" : \"ArrowLeft\";\n\n if (\n event.key !== nextKey &&\n event.key !== prevKey &&\n event.key !== \"Home\" &&\n event.key !== \"End\"\n ) {\n return;\n }\n\n const buttons = Array.from(\n tablistRef.current?.querySelectorAll<HTMLButtonElement>('[role=\"tab\"]') ?? [],\n );\n\n if (buttons.length === 0) {\n return;\n }\n\n event.preventDefault();\n const current = buttons.indexOf(document.activeElement as HTMLButtonElement);\n\n let index: number;\n if (event.key === \"Home\") {\n index = 0;\n } else if (event.key === \"End\") {\n index = buttons.length - 1;\n } else {\n const delta = event.key === nextKey ? 1 : -1;\n const base = current < 0 ? 0 : current;\n index = (base + delta + buttons.length) % buttons.length;\n }\n\n buttons[index]?.focus();\n }\n\n return (\n <TabsContext.Provider value={{ activeValue, setActiveValue: selectTabValue }}>\n <div\n className={cn(\"gap-6\", isVertical ? \"flex\" : \"grid\")}\n data-lattice-tabs={node.key ?? node.id}\n >\n <div\n aria-label={t(\"a11y.tabs\", \"Tabs\")}\n aria-orientation={orientation}\n className={cn(\n \"gap-1 rounded-lt bg-lt-muted p-1\",\n isVertical ? \"flex flex-col\" : \"inline-flex w-fit max-w-full overflow-x-auto\",\n )}\n ref={tablistRef}\n role=\"tablist\"\n >\n {tabs.map((tab) => {\n const isActive = activeValue === tab.value;\n\n return (\n <button\n aria-controls={`${tab.value}-panel`}\n aria-selected={isActive}\n data-test={`tab-${tab.value}`}\n className={cn(\n \"whitespace-nowrap rounded-lt-sm px-3 py-1.5 text-sm font-medium transition-colors\",\n isActive\n ? \"bg-lt-bg text-lt-fg shadow-xs\"\n : \"text-lt-muted-fg hover:bg-lt-bg/60 hover:text-lt-fg\",\n isVertical && \"text-left\",\n )}\n id={`${tab.value}-tab`}\n key={tab.value}\n onClick={() => selectTab(tab)}\n onKeyDown={onTablistKeyDown}\n role=\"tab\"\n tabIndex={isActive ? 0 : -1}\n type=\"button\"\n >\n {tab.label}\n </button>\n );\n })}\n </div>\n\n <div className={cn(\"min-w-0\", isVertical && \"flex-1\")}>{children}</div>\n </div>\n </TabsContext.Provider>\n );\n};\n\nconst TabComponent: RendererComponent<\"tab\"> = ({ children, node }) => {\n const { activeValue } = useTabsContext();\n const value = node.props.value;\n const isActive = activeValue === value;\n const [hasOpened, setHasOpened] = useState(isActive);\n\n useEffect(() => {\n if (isActive) {\n setHasOpened(true);\n }\n }, [isActive]);\n\n return (\n <section\n aria-labelledby={`${value}-tab`}\n className={cn(\"space-y-8\", !isActive && \"hidden\")}\n hidden={!isActive}\n id={`${value}-panel`}\n role=\"tabpanel\"\n tabIndex={0}\n >\n {hasOpened ? (children as ReactNode) : null}\n </section>\n );\n};\n\nexport default TabComponent;\n"],"mappings":"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"}
|
|
@@ -1,11 +1,3 @@
|
|
|
1
|
-
import { RendererComponent } from '
|
|
2
|
-
declare module '../../../../core/types' {
|
|
3
|
-
interface ComponentProps {
|
|
4
|
-
text: {
|
|
5
|
-
align?: string;
|
|
6
|
-
text?: string;
|
|
7
|
-
};
|
|
8
|
-
}
|
|
9
|
-
}
|
|
1
|
+
import { RendererComponent } from '../types';
|
|
10
2
|
declare const TextComponent: RendererComponent<"text">;
|
|
11
3
|
export default TextComponent;
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { cn } from "../../lib/utils.js";
|
|
2
|
-
import { getStringProp } from "../props.js";
|
|
3
2
|
import { jsx } from "react/jsx-runtime";
|
|
4
3
|
//#region resources/js/core/components/text.tsx
|
|
5
4
|
var textAlignments = {
|
|
@@ -8,8 +7,8 @@ var textAlignments = {
|
|
|
8
7
|
};
|
|
9
8
|
var TextComponent = ({ node }) => {
|
|
10
9
|
return /* @__PURE__ */ jsx("p", {
|
|
11
|
-
className: cn("max-w-2xl text-base leading-7 text-lt-muted-fg", textAlignments[
|
|
12
|
-
children:
|
|
10
|
+
className: cn("max-w-2xl text-base leading-7 text-lt-muted-fg", textAlignments[node.props.align ?? "left"] ?? textAlignments.left),
|
|
11
|
+
children: node.props.text
|
|
13
12
|
});
|
|
14
13
|
};
|
|
15
14
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"text.js","names":[],"sources":["../../../resources/js/core/components/text.tsx"],"sourcesContent":["import
|
|
1
|
+
{"version":3,"file":"text.js","names":[],"sources":["../../../resources/js/core/components/text.tsx"],"sourcesContent":["import type { RendererComponent } from \"@lattice/lattice/core/types\";\nimport { cn } from \"@lattice/lattice/lib/utils\";\n\nconst textAlignments: Record<string, string> = {\n center: \"text-center\",\n left: \"text-left\",\n};\n\nconst TextComponent: RendererComponent<\"text\"> = ({ node }) => {\n const align = node.props.align ?? \"left\";\n\n return (\n <p\n className={cn(\n \"max-w-2xl text-base leading-7 text-lt-muted-fg\",\n textAlignments[align] ?? textAlignments.left,\n )}\n >\n {node.props.text}\n </p>\n );\n};\n\nexport default TextComponent;\n"],"mappings":";;;AAGA,IAAM,iBAAyC;CAC7C,QAAQ;CACR,MAAM;AACR;AAEA,IAAM,iBAA4C,EAAE,WAAW;CAG7D,OACE,oBAAC,KAAD;EACE,WAAW,GACT,kDACA,eANQ,KAAK,MAAM,SAAS,WAMH,eAAe,IAC1C;YAEC,KAAK,MAAM;CACX,CAAA;AAEP"}
|
package/dist/core/registry.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { LazyExoticComponent } from 'react';
|
|
2
2
|
import { RendererComponent, RendererComponentModule } from './types';
|
|
3
|
+
import { ColumnRegistry } from '../table/column-registry';
|
|
3
4
|
export type EagerComponentRegistration = {
|
|
4
5
|
component: RendererComponent;
|
|
5
6
|
mode: "eager";
|
|
@@ -13,8 +14,13 @@ export type LazyComponentRegistration = {
|
|
|
13
14
|
export type ComponentRegistration = EagerComponentRegistration | LazyComponentRegistration;
|
|
14
15
|
export type ComponentRegistry = Record<string, ComponentRegistration>;
|
|
15
16
|
export type Plugin = {
|
|
16
|
-
components: ComponentRegistry;
|
|
17
17
|
name: string;
|
|
18
|
+
components?: ComponentRegistry;
|
|
19
|
+
columns?: ColumnRegistry;
|
|
20
|
+
};
|
|
21
|
+
export type Registry = {
|
|
22
|
+
components: ComponentRegistry;
|
|
23
|
+
columns: ColumnRegistry;
|
|
18
24
|
};
|
|
19
25
|
export type LazyComponentOptions<TType extends string> = {
|
|
20
26
|
fallback?: RendererComponent<TType>;
|
|
@@ -22,5 +28,5 @@ export type LazyComponentOptions<TType extends string> = {
|
|
|
22
28
|
export declare function eagerComponent<TType extends string>(component: RendererComponent<TType>): EagerComponentRegistration;
|
|
23
29
|
export declare function lazyComponent<TType extends string>(load: () => Promise<RendererComponentModule<TType>>, options?: LazyComponentOptions<TType>): LazyComponentRegistration;
|
|
24
30
|
export declare function createPlugin(plugin: Plugin): Plugin;
|
|
25
|
-
export declare function createRegistry(...plugins: Plugin[]):
|
|
26
|
-
export declare function extendRegistry(registry:
|
|
31
|
+
export declare function createRegistry(...plugins: Plugin[]): Registry;
|
|
32
|
+
export declare function extendRegistry(registry: Registry, ...plugins: Plugin[]): Registry;
|
package/dist/core/registry.js
CHANGED
|
@@ -20,14 +20,30 @@ function createPlugin(plugin) {
|
|
|
20
20
|
}
|
|
21
21
|
function createRegistry(...plugins) {
|
|
22
22
|
return plugins.reduce((registry, plugin) => ({
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
23
|
+
components: {
|
|
24
|
+
...registry.components,
|
|
25
|
+
...plugin.components
|
|
26
|
+
},
|
|
27
|
+
columns: {
|
|
28
|
+
...registry.columns,
|
|
29
|
+
...plugin.columns
|
|
30
|
+
}
|
|
31
|
+
}), {
|
|
32
|
+
components: {},
|
|
33
|
+
columns: {}
|
|
34
|
+
});
|
|
26
35
|
}
|
|
27
36
|
function extendRegistry(registry, ...plugins) {
|
|
37
|
+
const merged = createRegistry(...plugins);
|
|
28
38
|
return {
|
|
29
|
-
|
|
30
|
-
|
|
39
|
+
components: {
|
|
40
|
+
...registry.components,
|
|
41
|
+
...merged.components
|
|
42
|
+
},
|
|
43
|
+
columns: {
|
|
44
|
+
...registry.columns,
|
|
45
|
+
...merged.columns
|
|
46
|
+
}
|
|
31
47
|
};
|
|
32
48
|
}
|
|
33
49
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registry.js","names":[],"sources":["../../resources/js/core/registry.ts"],"sourcesContent":["import { lazy } from \"react\";\nimport type { LazyExoticComponent } from \"react\";\nimport type { RendererComponent, RendererComponentModule } from \"./types\";\n\nexport type EagerComponentRegistration = {\n component: RendererComponent;\n mode: \"eager\";\n};\n\nexport type LazyComponentRegistration = {\n component: LazyExoticComponent<RendererComponent>;\n fallback?: RendererComponent;\n load: () => Promise<RendererComponentModule>;\n mode: \"lazy\";\n};\n\nexport type ComponentRegistration = EagerComponentRegistration | LazyComponentRegistration;\n\nexport type ComponentRegistry = Record<string, ComponentRegistration>;\n\nexport type Plugin = {\n components: ComponentRegistry;\n
|
|
1
|
+
{"version":3,"file":"registry.js","names":[],"sources":["../../resources/js/core/registry.ts"],"sourcesContent":["import { lazy } from \"react\";\nimport type { LazyExoticComponent } from \"react\";\nimport type { RendererComponent, RendererComponentModule } from \"./types\";\nimport type { ColumnRegistry } from \"../table/column-registry\";\n\nexport type EagerComponentRegistration = {\n component: RendererComponent;\n mode: \"eager\";\n};\n\nexport type LazyComponentRegistration = {\n component: LazyExoticComponent<RendererComponent>;\n fallback?: RendererComponent;\n load: () => Promise<RendererComponentModule>;\n mode: \"lazy\";\n};\n\nexport type ComponentRegistration = EagerComponentRegistration | LazyComponentRegistration;\n\nexport type ComponentRegistry = Record<string, ComponentRegistration>;\n\nexport type Plugin = {\n name: string;\n components?: ComponentRegistry;\n columns?: ColumnRegistry;\n};\n\nexport type Registry = {\n components: ComponentRegistry;\n columns: ColumnRegistry;\n};\n\nexport type LazyComponentOptions<TType extends string> = {\n fallback?: RendererComponent<TType>;\n};\n\nexport function eagerComponent<TType extends string>(\n component: RendererComponent<TType>,\n): EagerComponentRegistration {\n return {\n component: component as unknown as RendererComponent,\n mode: \"eager\",\n };\n}\n\nexport function lazyComponent<TType extends string>(\n load: () => Promise<RendererComponentModule<TType>>,\n options: LazyComponentOptions<TType> = {},\n): LazyComponentRegistration {\n const erasedLoader = load as unknown as () => Promise<RendererComponentModule>;\n\n return {\n component: lazy(erasedLoader),\n fallback: options.fallback as RendererComponent | undefined,\n load: erasedLoader,\n mode: \"lazy\",\n };\n}\n\nexport function createPlugin(plugin: Plugin): Plugin {\n return plugin;\n}\n\nexport function createRegistry(...plugins: Plugin[]): Registry {\n return plugins.reduce<Registry>(\n (registry, plugin) => ({\n components: { ...registry.components, ...plugin.components },\n columns: { ...registry.columns, ...plugin.columns },\n }),\n { components: {}, columns: {} },\n );\n}\n\nexport function extendRegistry(registry: Registry, ...plugins: Plugin[]): Registry {\n const merged = createRegistry(...plugins);\n\n return {\n components: { ...registry.components, ...merged.components },\n columns: { ...registry.columns, ...merged.columns },\n };\n}\n"],"mappings":";;AAoCA,SAAgB,eACd,WAC4B;CAC5B,OAAO;EACM;EACX,MAAM;CACR;AACF;AAEA,SAAgB,cACd,MACA,UAAuC,CAAC,GACb;CAC3B,MAAM,eAAe;CAErB,OAAO;EACL,WAAW,KAAK,YAAY;EAC5B,UAAU,QAAQ;EAClB,MAAM;EACN,MAAM;CACR;AACF;AAEA,SAAgB,aAAa,QAAwB;CACnD,OAAO;AACT;AAEA,SAAgB,eAAe,GAAG,SAA6B;CAC7D,OAAO,QAAQ,QACZ,UAAU,YAAY;EACrB,YAAY;GAAE,GAAG,SAAS;GAAY,GAAG,OAAO;EAAW;EAC3D,SAAS;GAAE,GAAG,SAAS;GAAS,GAAG,OAAO;EAAQ;CACpD,IACA;EAAE,YAAY,CAAC;EAAG,SAAS,CAAC;CAAE,CAChC;AACF;AAEA,SAAgB,eAAe,UAAoB,GAAG,SAA6B;CACjF,MAAM,SAAS,eAAe,GAAG,OAAO;CAExC,OAAO;EACL,YAAY;GAAE,GAAG,SAAS;GAAY,GAAG,OAAO;EAAW;EAC3D,SAAS;GAAE,GAAG,SAAS;GAAS,GAAG,OAAO;EAAQ;CACpD;AACF"}
|
package/dist/core/renderer.js
CHANGED
|
@@ -10,6 +10,9 @@ function useRendererContext() {
|
|
|
10
10
|
if (!context) throw new Error("Renderer context is not available.");
|
|
11
11
|
return context;
|
|
12
12
|
}
|
|
13
|
+
function nodeKey(node, index) {
|
|
14
|
+
return node.key ?? node.id ?? `${node.type}-${index}`;
|
|
15
|
+
}
|
|
13
16
|
function Renderer({ fallback = null, missingComponent: UnknownComponent = MissingComponent, nodes, registry }) {
|
|
14
17
|
const context = useMemo(() => ({
|
|
15
18
|
fallback,
|
|
@@ -22,26 +25,17 @@ function Renderer({ fallback = null, missingComponent: UnknownComponent = Missin
|
|
|
22
25
|
]);
|
|
23
26
|
return /* @__PURE__ */ jsx(RendererContext.Provider, {
|
|
24
27
|
value: context,
|
|
25
|
-
children: nodes.map((node, index) => /* @__PURE__ */ jsx(NodeRenderer, {
|
|
26
|
-
fallback,
|
|
27
|
-
missingComponent: UnknownComponent,
|
|
28
|
-
node,
|
|
29
|
-
registry
|
|
30
|
-
}, node.key ?? node.id ?? `${node.type}-${index}`))
|
|
28
|
+
children: nodes.map((node, index) => /* @__PURE__ */ jsx(NodeRenderer, { node }, nodeKey(node, index)))
|
|
31
29
|
});
|
|
32
30
|
}
|
|
33
|
-
function NodeRenderer({
|
|
31
|
+
function NodeRenderer({ node }) {
|
|
32
|
+
const { fallback, missingComponent: UnknownComponent, registry } = useRendererContext();
|
|
34
33
|
const registration = registry[node.type];
|
|
35
34
|
if (!registration) return /* @__PURE__ */ jsx(UnknownComponent, { node });
|
|
36
35
|
const Component = registration.component;
|
|
37
36
|
const renderedComponent = /* @__PURE__ */ jsx(Component, {
|
|
38
37
|
node,
|
|
39
|
-
children: node.
|
|
40
|
-
fallback,
|
|
41
|
-
missingComponent: UnknownComponent,
|
|
42
|
-
nodes: node.children,
|
|
43
|
-
registry
|
|
44
|
-
}) : null
|
|
38
|
+
children: node.schema?.length ? node.schema.map((child, index) => /* @__PURE__ */ jsx(NodeRenderer, { node: child }, nodeKey(child, index))) : null
|
|
45
39
|
});
|
|
46
40
|
if (registration.mode === "lazy") {
|
|
47
41
|
const FallbackComponent = registration.fallback;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"renderer.js","names":[],"sources":["../../resources/js/core/renderer.tsx"],"sourcesContent":["import { createContext, Suspense, useContext, useMemo } from \"react\";\nimport type { ReactNode } from \"react\";\nimport type { ComponentRegistry } from \"./registry\";\nimport type { Node, UnknownComponent } from \"./types\";\n\nfunction MissingComponent({ node }: { node: Node }) {\n if (!import.meta.env.DEV) {\n return null;\n }\n\n return <div data-lattice-missing-component={node.type}>Missing component: {node.type}</div>;\n}\n\ntype RendererContextValue = {\n fallback: ReactNode;\n missingComponent: UnknownComponent;\n registry: ComponentRegistry;\n};\n\nconst RendererContext = createContext<RendererContextValue | null>(null);\n\nexport function useRendererContext(): RendererContextValue {\n const context = useContext(RendererContext);\n\n if (!context) {\n throw new Error(\"Renderer context is not available.\");\n }\n\n return context;\n}\n\nexport function Renderer({\n fallback = null,\n missingComponent: UnknownComponent = MissingComponent,\n nodes,\n registry,\n}: {\n fallback?: ReactNode;\n missingComponent?: UnknownComponent;\n nodes: Node[];\n registry: ComponentRegistry;\n}) {\n const context = useMemo(\n () => ({\n fallback,\n missingComponent: UnknownComponent,\n registry,\n }),\n [fallback, registry, UnknownComponent],\n );\n\n return (\n <RendererContext.Provider value={context}>\n {nodes.map((node, index) => (\n <NodeRenderer
|
|
1
|
+
{"version":3,"file":"renderer.js","names":[],"sources":["../../resources/js/core/renderer.tsx"],"sourcesContent":["import { createContext, Suspense, useContext, useMemo } from \"react\";\nimport type { ReactNode } from \"react\";\nimport type { ComponentRegistry } from \"./registry\";\nimport type { Node, UnknownComponent } from \"./types\";\n\nfunction MissingComponent({ node }: { node: Node }) {\n if (!import.meta.env.DEV) {\n return null;\n }\n\n return <div data-lattice-missing-component={node.type}>Missing component: {node.type}</div>;\n}\n\ntype RendererContextValue = {\n fallback: ReactNode;\n missingComponent: UnknownComponent;\n registry: ComponentRegistry;\n};\n\nconst RendererContext = createContext<RendererContextValue | null>(null);\n\nexport function useRendererContext(): RendererContextValue {\n const context = useContext(RendererContext);\n\n if (!context) {\n throw new Error(\"Renderer context is not available.\");\n }\n\n return context;\n}\n\nfunction nodeKey(node: Node, index: number): string {\n return node.key ?? node.id ?? `${node.type}-${index}`;\n}\n\nexport function Renderer({\n fallback = null,\n missingComponent: UnknownComponent = MissingComponent,\n nodes,\n registry,\n}: {\n fallback?: ReactNode;\n missingComponent?: UnknownComponent;\n nodes: Node[];\n registry: ComponentRegistry;\n}) {\n const context = useMemo(\n () => ({\n fallback,\n missingComponent: UnknownComponent,\n registry,\n }),\n [fallback, registry, UnknownComponent],\n );\n\n return (\n <RendererContext.Provider value={context}>\n {nodes.map((node, index) => (\n <NodeRenderer key={nodeKey(node, index)} node={node} />\n ))}\n </RendererContext.Provider>\n );\n}\n\nfunction NodeRenderer({ node }: { node: Node }) {\n const { fallback, missingComponent: UnknownComponent, registry } = useRendererContext();\n const registration = registry[node.type];\n\n if (!registration) {\n return <UnknownComponent node={node} />;\n }\n\n const Component = registration.component;\n const children = node.schema?.length\n ? node.schema.map((child, index) => <NodeRenderer key={nodeKey(child, index)} node={child} />)\n : null;\n\n const renderedComponent = <Component node={node}>{children}</Component>;\n\n if (registration.mode === \"lazy\") {\n const FallbackComponent = registration.fallback;\n const suspenseFallback = FallbackComponent ? (\n <FallbackComponent node={node}>{null}</FallbackComponent>\n ) : (\n fallback\n );\n\n return <Suspense fallback={suspenseFallback}>{renderedComponent}</Suspense>;\n }\n\n return renderedComponent;\n}\n"],"mappings":";;;AAKA,SAAS,iBAAiB,EAAE,QAAwB;CAEhD,OAAO;AAIX;AAQA,IAAM,kBAAkB,cAA2C,IAAI;AAEvE,SAAgB,qBAA2C;CACzD,MAAM,UAAU,WAAW,eAAe;CAE1C,IAAI,CAAC,SACH,MAAM,IAAI,MAAM,oCAAoC;CAGtD,OAAO;AACT;AAEA,SAAS,QAAQ,MAAY,OAAuB;CAClD,OAAO,KAAK,OAAO,KAAK,MAAM,GAAG,KAAK,KAAK,GAAG;AAChD;AAEA,SAAgB,SAAS,EACvB,WAAW,MACX,kBAAkB,mBAAmB,kBACrC,OACA,YAMC;CACD,MAAM,UAAU,eACP;EACL;EACA,kBAAkB;EAClB;CACF,IACA;EAAC;EAAU;EAAU;CAAgB,CACvC;CAEA,OACE,oBAAC,gBAAgB,UAAjB;EAA0B,OAAO;YAC9B,MAAM,KAAK,MAAM,UAChB,oBAAC,cAAD,EAA+C,KAAO,GAAnC,QAAQ,MAAM,KAAK,CAAgB,CACvD;CACuB,CAAA;AAE9B;AAEA,SAAS,aAAa,EAAE,QAAwB;CAC9C,MAAM,EAAE,UAAU,kBAAkB,kBAAkB,aAAa,mBAAmB;CACtF,MAAM,eAAe,SAAS,KAAK;CAEnC,IAAI,CAAC,cACH,OAAO,oBAAC,kBAAD,EAAwB,KAAO,CAAA;CAGxC,MAAM,YAAY,aAAa;CAK/B,MAAM,oBAAoB,oBAAC,WAAD;EAAiB;EAAO,UAJjC,KAAK,QAAQ,SAC1B,KAAK,OAAO,KAAK,OAAO,UAAU,oBAAC,cAAD,EAA0C,MAAM,MAAQ,GAArC,QAAQ,OAAO,KAAK,CAAiB,CAAC,IAC3F;CAEkE,CAAA;CAEtE,IAAI,aAAa,SAAS,QAAQ;EAChC,MAAM,oBAAoB,aAAa;EAOvC,OAAO,oBAAC,UAAD;GAAU,UANQ,oBACvB,oBAAC,mBAAD;IAAyB;cAAO;GAAwB,CAAA,IAExD;aAG4C;EAA4B,CAAA;CAC5E;CAEA,OAAO;AACT"}
|
package/dist/core/types.d.ts
CHANGED
|
@@ -1,46 +1,74 @@
|
|
|
1
|
-
import { Method } from '@inertiajs/core';
|
|
2
1
|
import { ComponentType as ReactComponentType, ReactNode } from 'react';
|
|
2
|
+
import { Node as WireNode, NodeType, Option, PageContainer as KnownPageContainer } from '../types/generated';
|
|
3
|
+
export type { KnownPageContainer, NodeType, WireNode };
|
|
4
|
+
/** Loose props bag for nodes whose `type` is not a generated built-in. */
|
|
3
5
|
export type NodeProps = Record<string, unknown>;
|
|
6
|
+
/** A `{ label, value }` pair used by the choice, select and segmented controls. */
|
|
7
|
+
export type { Option };
|
|
8
|
+
/**
|
|
9
|
+
* A node whose `type` is not one of the generated built-ins. This is the escape
|
|
10
|
+
* hatch that keeps the renderer open to components registered by consumers.
|
|
11
|
+
*/
|
|
12
|
+
export type LooseNode<TType extends string = string> = {
|
|
13
|
+
id?: string;
|
|
14
|
+
key?: string;
|
|
15
|
+
props?: NodeProps;
|
|
16
|
+
schema?: Schema;
|
|
17
|
+
type: TType;
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* Augmentable map of wire `type` string → props. Consumer apps extend it via
|
|
21
|
+
* `declare module "@lattice-php/lattice"` so their custom components gain strong
|
|
22
|
+
* prop types; the entries are generated by `php artisan lattice:typescript`.
|
|
23
|
+
* Built-in components resolve through the generated `WireNode` union below, so
|
|
24
|
+
* this interface starts empty. Types listed in neither fall back to a loose bag.
|
|
25
|
+
*/
|
|
4
26
|
export interface ComponentProps {
|
|
5
|
-
[component: string]: NodeProps;
|
|
6
27
|
}
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
28
|
+
type BuiltInPropsOf<TType extends string> = [Extract<WireNode, {
|
|
29
|
+
type: TType;
|
|
30
|
+
}>] extends [never] ? never : Extract<WireNode, {
|
|
31
|
+
type: TType;
|
|
32
|
+
}> extends {
|
|
33
|
+
props: infer TProps;
|
|
34
|
+
} ? TProps : never;
|
|
35
|
+
/**
|
|
36
|
+
* Resolves a wire `type` to its props: consumer augmentations
|
|
37
|
+
* (`ComponentProps`) first, then generated built-ins, then a loose bag.
|
|
38
|
+
*/
|
|
39
|
+
export type PropsOf<TType extends string> = TType extends keyof ComponentProps ? ComponentProps[TType] : [BuiltInPropsOf<TType>] extends [never] ? NodeProps : BuiltInPropsOf<TType>;
|
|
40
|
+
/**
|
|
41
|
+
* Resolves a wire `type` string to its node shape: built-ins narrow to their
|
|
42
|
+
* generated props, unknown types fall back to a loose props bag so custom
|
|
43
|
+
* components still type-check. Built-in `props` is always present — the wire
|
|
44
|
+
* serializes the full prop object, so reads need no optional chaining.
|
|
45
|
+
*/
|
|
46
|
+
export type NodeOfType<TType extends string = string> = string extends TType ? LooseNode : {
|
|
11
47
|
id?: string;
|
|
12
48
|
key?: string;
|
|
13
|
-
props
|
|
49
|
+
props: PropsOf<TType>;
|
|
50
|
+
schema?: Schema;
|
|
14
51
|
type: TType;
|
|
15
52
|
};
|
|
53
|
+
export type Node<TType extends string = string> = NodeOfType<TType>;
|
|
54
|
+
/** An ordered list of component nodes — the content of a page, form, or container. */
|
|
55
|
+
export type Schema = Node[];
|
|
56
|
+
/** A server-composed layout shell: its key plus a schema containing one Outlet. */
|
|
57
|
+
export type LayoutPayload = {
|
|
58
|
+
key: string;
|
|
59
|
+
schema: Schema;
|
|
60
|
+
};
|
|
16
61
|
export type PagePayload = {
|
|
17
62
|
breadcrumbs: PageBreadcrumb[];
|
|
18
|
-
components: Node[];
|
|
19
63
|
container: PageContainer;
|
|
20
|
-
layout:
|
|
21
|
-
|
|
64
|
+
layout: LayoutPayload | null;
|
|
65
|
+
schema: Schema;
|
|
22
66
|
title: string | null;
|
|
23
67
|
};
|
|
24
68
|
export type PageBreadcrumb = {
|
|
25
69
|
href: string;
|
|
26
70
|
title: string;
|
|
27
71
|
};
|
|
28
|
-
export type MenuItem = {
|
|
29
|
-
active: boolean;
|
|
30
|
-
href: string;
|
|
31
|
-
icon: string | null;
|
|
32
|
-
key: string;
|
|
33
|
-
label: string;
|
|
34
|
-
method: Method;
|
|
35
|
-
};
|
|
36
|
-
export type MenuGroup = {
|
|
37
|
-
items: MenuItem[];
|
|
38
|
-
label: string | null;
|
|
39
|
-
};
|
|
40
|
-
export type MenuPayload = {
|
|
41
|
-
groups: MenuGroup[];
|
|
42
|
-
};
|
|
43
|
-
export type KnownPageContainer = "centered" | "default";
|
|
44
72
|
export type PageContainer = KnownPageContainer | (string & {});
|
|
45
73
|
export type RendererComponentProps<TType extends string = string> = {
|
|
46
74
|
children: ReactNode;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { cn } from "../../../lib/utils.js";
|
|
2
|
+
import { Icon } from "../../../icons/sprite.js";
|
|
2
3
|
import "react";
|
|
3
4
|
import { jsx } from "react/jsx-runtime";
|
|
4
|
-
import { CheckIcon } from "lucide-react";
|
|
5
5
|
import * as CheckboxPrimitive from "@radix-ui/react-checkbox";
|
|
6
6
|
//#region resources/js/form/components/base/checkbox.tsx
|
|
7
7
|
function Checkbox({ className, ...props }) {
|
|
@@ -12,7 +12,10 @@ function Checkbox({ className, ...props }) {
|
|
|
12
12
|
children: /* @__PURE__ */ jsx(CheckboxPrimitive.Indicator, {
|
|
13
13
|
"data-slot": "checkbox-indicator",
|
|
14
14
|
className: "flex items-center justify-center text-current transition-none",
|
|
15
|
-
children: /* @__PURE__ */ jsx(
|
|
15
|
+
children: /* @__PURE__ */ jsx(Icon, {
|
|
16
|
+
name: "check",
|
|
17
|
+
className: "size-lt-icon-sm"
|
|
18
|
+
})
|
|
16
19
|
})
|
|
17
20
|
});
|
|
18
21
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"checkbox.js","names":[],"sources":["../../../../resources/js/form/components/base/checkbox.tsx"],"sourcesContent":["import
|
|
1
|
+
{"version":3,"file":"checkbox.js","names":[],"sources":["../../../../resources/js/form/components/base/checkbox.tsx"],"sourcesContent":["import { Icon } from \"@lattice/lattice/icons\";\nimport * as CheckboxPrimitive from \"@radix-ui/react-checkbox\";\nimport * as React from \"react\";\n\nimport { cn } from \"@lattice/lattice/lib/utils\";\n\nfunction Checkbox({ className, ...props }: React.ComponentProps<typeof CheckboxPrimitive.Root>) {\n return (\n <CheckboxPrimitive.Root\n data-slot=\"checkbox\"\n className={cn(\n \"peer border-lt-input data-[state=checked]:bg-lt-primary data-[state=checked]:text-lt-primary-fg data-[state=checked]:border-lt-primary focus-visible:border-lt-ring focus-visible:ring-lt-ring/50 aria-invalid:ring-lt-danger/20 dark:aria-invalid:ring-lt-danger/40 aria-invalid:border-lt-danger size-4 shrink-0 rounded-lt-xs border shadow-xs transition-shadow outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50\",\n className,\n )}\n {...props}\n >\n <CheckboxPrimitive.Indicator\n data-slot=\"checkbox-indicator\"\n className=\"flex items-center justify-center text-current transition-none\"\n >\n <Icon name=\"check\" className=\"size-lt-icon-sm\" />\n </CheckboxPrimitive.Indicator>\n </CheckboxPrimitive.Root>\n );\n}\n\nexport { Checkbox };\n"],"mappings":";;;;;;AAMA,SAAS,SAAS,EAAE,WAAW,GAAG,SAA8D;CAC9F,OACE,oBAAC,kBAAkB,MAAnB;EACE,aAAU;EACV,WAAW,GACT,6bACA,SACF;EACA,GAAI;YAEJ,oBAAC,kBAAkB,WAAnB;GACE,aAAU;GACV,WAAU;aAEV,oBAAC,MAAD;IAAM,MAAK;IAAQ,WAAU;GAAmB,CAAA;EACrB,CAAA;CACP,CAAA;AAE5B"}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { FormLabelAction } from '../types';
|
|
2
|
-
export declare function FormFieldFrame({ children, error, label, labelAction, name, required, }: {
|
|
2
|
+
export declare function FormFieldFrame({ children, error, helperText, label, labelAction, name, required, }: {
|
|
3
3
|
children: React.ReactNode;
|
|
4
4
|
error?: string;
|
|
5
|
+
helperText?: string;
|
|
5
6
|
label: string;
|
|
6
7
|
labelAction?: FormLabelAction;
|
|
7
8
|
name: string;
|
|
@@ -3,7 +3,7 @@ import { Label } from "./label.js";
|
|
|
3
3
|
import InputError from "./input-error.js";
|
|
4
4
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
5
5
|
//#region resources/js/form/components/base/field.tsx
|
|
6
|
-
function FormFieldFrame({ children, error, label, labelAction, name, required }) {
|
|
6
|
+
function FormFieldFrame({ children, error, helperText, label, labelAction, name, required }) {
|
|
7
7
|
return /* @__PURE__ */ jsxs("div", {
|
|
8
8
|
className: "grid gap-2",
|
|
9
9
|
children: [
|
|
@@ -28,6 +28,10 @@ function FormFieldFrame({ children, error, label, labelAction, name, required })
|
|
|
28
28
|
]
|
|
29
29
|
}),
|
|
30
30
|
children,
|
|
31
|
+
helperText && /* @__PURE__ */ jsx("p", {
|
|
32
|
+
className: "text-sm text-lt-muted-fg",
|
|
33
|
+
children: helperText
|
|
34
|
+
}),
|
|
31
35
|
/* @__PURE__ */ jsx(InputError, { message: error })
|
|
32
36
|
]
|
|
33
37
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"field.js","names":[],"sources":["../../../../resources/js/form/components/base/field.tsx"],"sourcesContent":["import InputError from \"@lattice/lattice/form/components/base/input-error\";\nimport { TextLink } from \"@lattice/lattice/core/components/link\";\nimport { Label } from \"@lattice/lattice/form/components/base/label\";\nimport type { FormLabelAction } from \"../types\";\n\nexport function FormFieldFrame({\n children,\n error,\n label,\n labelAction,\n name,\n required,\n}: {\n children: React.ReactNode;\n error?: string;\n label: string;\n labelAction?: FormLabelAction;\n name: string;\n required?: boolean;\n}) {\n return (\n <div className=\"grid gap-2\">\n <div className=\"flex min-h-5 items-center\">\n <Label htmlFor={name}>{label}</Label>\n {required && (\n <span aria-hidden=\"true\" className=\"ml-0.5 text-lt-danger\">\n *\n </span>\n )}\n {labelAction && (\n <TextLink\n href={labelAction.href}\n tabIndex={labelAction.tabIndex}\n className=\"ml-auto text-sm\"\n >\n {labelAction.label}\n </TextLink>\n )}\n </div>\n\n {children}\n\n <InputError message={error} />\n </div>\n );\n}\n"],"mappings":";;;;;AAKA,SAAgB,eAAe,EAC7B,UACA,OACA,OACA,aACA,MACA,
|
|
1
|
+
{"version":3,"file":"field.js","names":[],"sources":["../../../../resources/js/form/components/base/field.tsx"],"sourcesContent":["import InputError from \"@lattice/lattice/form/components/base/input-error\";\nimport { TextLink } from \"@lattice/lattice/core/components/link\";\nimport { Label } from \"@lattice/lattice/form/components/base/label\";\nimport type { FormLabelAction } from \"../types\";\n\nexport function FormFieldFrame({\n children,\n error,\n helperText,\n label,\n labelAction,\n name,\n required,\n}: {\n children: React.ReactNode;\n error?: string;\n helperText?: string;\n label: string;\n labelAction?: FormLabelAction;\n name: string;\n required?: boolean;\n}) {\n return (\n <div className=\"grid gap-2\">\n <div className=\"flex min-h-5 items-center\">\n <Label htmlFor={name}>{label}</Label>\n {required && (\n <span aria-hidden=\"true\" className=\"ml-0.5 text-lt-danger\">\n *\n </span>\n )}\n {labelAction && (\n <TextLink\n href={labelAction.href}\n tabIndex={labelAction.tabIndex}\n className=\"ml-auto text-sm\"\n >\n {labelAction.label}\n </TextLink>\n )}\n </div>\n\n {children}\n\n {helperText && <p className=\"text-sm text-lt-muted-fg\">{helperText}</p>}\n\n <InputError message={error} />\n </div>\n );\n}\n"],"mappings":";;;;;AAKA,SAAgB,eAAe,EAC7B,UACA,OACA,YACA,OACA,aACA,MACA,YASC;CACD,OACE,qBAAC,OAAD;EAAK,WAAU;YAAf;GACE,qBAAC,OAAD;IAAK,WAAU;cAAf;KACE,oBAAC,OAAD;MAAO,SAAS;gBAAO;KAAa,CAAA;KACnC,YACC,oBAAC,QAAD;MAAM,eAAY;MAAO,WAAU;gBAAwB;KAErD,CAAA;KAEP,eACC,oBAAC,UAAD;MACE,MAAM,YAAY;MAClB,UAAU,YAAY;MACtB,WAAU;gBAET,YAAY;KACL,CAAA;IAET;;GAEJ;GAEA,cAAc,oBAAC,KAAD;IAAG,WAAU;cAA4B;GAAc,CAAA;GAEtE,oBAAC,YAAD,EAAY,SAAS,MAAQ,CAAA;EAC1B;;AAET"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { cn } from "../../../lib/utils.js";
|
|
2
|
+
import { Icon } from "../../../icons/sprite.js";
|
|
2
3
|
import { Input } from "./input.js";
|
|
3
4
|
import { useState } from "react";
|
|
4
5
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
5
|
-
import { Eye, EyeOff } from "lucide-react";
|
|
6
6
|
//#region resources/js/form/components/base/password-input.tsx
|
|
7
7
|
function PasswordInput({ className, ref, ...props }) {
|
|
8
8
|
const [showPassword, setShowPassword] = useState(false);
|
|
@@ -15,11 +15,18 @@ function PasswordInput({ className, ref, ...props }) {
|
|
|
15
15
|
...props
|
|
16
16
|
}), /* @__PURE__ */ jsx("button", {
|
|
17
17
|
type: "button",
|
|
18
|
+
"data-test": typeof props.name === "string" ? `${props.name}-visibility` : "password-visibility",
|
|
18
19
|
onClick: () => setShowPassword((prev) => !prev),
|
|
19
20
|
className: "absolute inset-y-0 right-0 flex items-center rounded-r-lt-sm px-3 text-lt-muted-fg hover:text-lt-fg focus-visible:ring-[3px] focus-visible:ring-lt-ring focus-visible:outline-none",
|
|
20
21
|
"aria-label": showPassword ? "Hide password" : "Show password",
|
|
21
22
|
tabIndex: -1,
|
|
22
|
-
children: showPassword ? /* @__PURE__ */ jsx(
|
|
23
|
+
children: showPassword ? /* @__PURE__ */ jsx(Icon, {
|
|
24
|
+
name: "eye-off",
|
|
25
|
+
className: "size-lt-icon-md"
|
|
26
|
+
}) : /* @__PURE__ */ jsx(Icon, {
|
|
27
|
+
name: "eye",
|
|
28
|
+
className: "size-lt-icon-md"
|
|
29
|
+
})
|
|
23
30
|
})]
|
|
24
31
|
});
|
|
25
32
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"password-input.js","names":[],"sources":["../../../../resources/js/form/components/base/password-input.tsx"],"sourcesContent":["import {
|
|
1
|
+
{"version":3,"file":"password-input.js","names":[],"sources":["../../../../resources/js/form/components/base/password-input.tsx"],"sourcesContent":["import { Icon } from \"@lattice/lattice/icons\";\nimport type { ComponentProps, Ref } from \"react\";\nimport { useState } from \"react\";\nimport { Input } from \"@lattice/lattice/form/components/base/input\";\nimport { cn } from \"@lattice/lattice/lib/utils\";\n\ntype PasswordInputProps = Omit<ComponentProps<\"input\">, \"type\"> & {\n passwordrules?: string;\n ref?: Ref<HTMLInputElement>;\n};\n\nexport default function PasswordInput({ className, ref, ...props }: PasswordInputProps) {\n const [showPassword, setShowPassword] = useState(false);\n\n return (\n <div className=\"relative\">\n <Input\n type={showPassword ? \"text\" : \"password\"}\n className={cn(\"pr-10\", className)}\n ref={ref}\n {...props}\n />\n <button\n type=\"button\"\n data-test={\n typeof props.name === \"string\" ? `${props.name}-visibility` : \"password-visibility\"\n }\n onClick={() => setShowPassword((prev) => !prev)}\n className=\"absolute inset-y-0 right-0 flex items-center rounded-r-lt-sm px-3 text-lt-muted-fg hover:text-lt-fg focus-visible:ring-[3px] focus-visible:ring-lt-ring focus-visible:outline-none\"\n aria-label={showPassword ? \"Hide password\" : \"Show password\"}\n tabIndex={-1}\n >\n {showPassword ? (\n <Icon name=\"eye-off\" className=\"size-lt-icon-md\" />\n ) : (\n <Icon name=\"eye\" className=\"size-lt-icon-md\" />\n )}\n </button>\n </div>\n );\n}\n"],"mappings":";;;;;;AAWA,SAAwB,cAAc,EAAE,WAAW,KAAK,GAAG,SAA6B;CACtF,MAAM,CAAC,cAAc,mBAAmB,SAAS,KAAK;CAEtD,OACE,qBAAC,OAAD;EAAK,WAAU;YAAf,CACE,oBAAC,OAAD;GACE,MAAM,eAAe,SAAS;GAC9B,WAAW,GAAG,SAAS,SAAS;GAC3B;GACL,GAAI;EACL,CAAA,GACD,oBAAC,UAAD;GACE,MAAK;GACL,aACE,OAAO,MAAM,SAAS,WAAW,GAAG,MAAM,KAAK,eAAe;GAEhE,eAAe,iBAAiB,SAAS,CAAC,IAAI;GAC9C,WAAU;GACV,cAAY,eAAe,kBAAkB;GAC7C,UAAU;aAET,eACC,oBAAC,MAAD;IAAM,MAAK;IAAU,WAAU;GAAmB,CAAA,IAElD,oBAAC,MAAD;IAAM,MAAK;IAAM,WAAU;GAAmB,CAAA;EAE1C,CAAA,CACL;;AAET"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
export declare function FormSubmitButton({ label, variant, }: {
|
|
1
|
+
import { ButtonVariant } from '../../../types/generated';
|
|
2
|
+
export declare function FormSubmitButton({ label, summaryLabel, variant, }: {
|
|
3
3
|
label: string;
|
|
4
|
-
|
|
4
|
+
summaryLabel: string;
|
|
5
|
+
variant?: ButtonVariant;
|
|
5
6
|
}): import("react").JSX.Element;
|
|
6
|
-
export {};
|