@frontmcp/ui 0.5.1 → 0.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +140 -362
- package/bridge/adapters/base-adapter.d.ts +104 -0
- package/bridge/adapters/base-adapter.d.ts.map +1 -0
- package/bridge/adapters/claude.adapter.d.ts +67 -0
- package/bridge/adapters/claude.adapter.d.ts.map +1 -0
- package/bridge/adapters/ext-apps.adapter.d.ts +143 -0
- package/bridge/adapters/ext-apps.adapter.d.ts.map +1 -0
- package/bridge/adapters/gemini.adapter.d.ts +64 -0
- package/bridge/adapters/gemini.adapter.d.ts.map +1 -0
- package/bridge/adapters/generic.adapter.d.ts +56 -0
- package/bridge/adapters/generic.adapter.d.ts.map +1 -0
- package/bridge/adapters/index.d.ts +26 -0
- package/bridge/adapters/index.d.ts.map +1 -0
- package/bridge/adapters/openai.adapter.d.ts +65 -0
- package/bridge/adapters/openai.adapter.d.ts.map +1 -0
- package/bridge/core/adapter-registry.d.ts +122 -0
- package/bridge/core/adapter-registry.d.ts.map +1 -0
- package/bridge/core/bridge-factory.d.ts +199 -0
- package/bridge/core/bridge-factory.d.ts.map +1 -0
- package/bridge/core/index.d.ts +10 -0
- package/bridge/core/index.d.ts.map +1 -0
- package/bridge/index.d.ts +62 -0
- package/bridge/index.d.ts.map +1 -0
- package/bridge/index.js +2540 -0
- package/bridge/runtime/iife-generator.d.ts +62 -0
- package/bridge/runtime/iife-generator.d.ts.map +1 -0
- package/bridge/runtime/index.d.ts +10 -0
- package/bridge/runtime/index.d.ts.map +1 -0
- package/bridge/types.d.ts +386 -0
- package/bridge/types.d.ts.map +1 -0
- package/bundler/bundler.d.ts +208 -0
- package/bundler/bundler.d.ts.map +1 -0
- package/bundler/cache.d.ts +173 -0
- package/bundler/cache.d.ts.map +1 -0
- package/bundler/file-cache/component-builder.d.ts +167 -0
- package/bundler/file-cache/component-builder.d.ts.map +1 -0
- package/bundler/file-cache/hash-calculator.d.ts +155 -0
- package/bundler/file-cache/hash-calculator.d.ts.map +1 -0
- package/bundler/file-cache/index.d.ts +12 -0
- package/bundler/file-cache/index.d.ts.map +1 -0
- package/bundler/file-cache/storage/filesystem.d.ts +149 -0
- package/bundler/file-cache/storage/filesystem.d.ts.map +1 -0
- package/bundler/file-cache/storage/index.d.ts +11 -0
- package/bundler/file-cache/storage/index.d.ts.map +1 -0
- package/bundler/file-cache/storage/interface.d.ts +152 -0
- package/bundler/file-cache/storage/interface.d.ts.map +1 -0
- package/bundler/file-cache/storage/redis.d.ts +139 -0
- package/bundler/file-cache/storage/redis.d.ts.map +1 -0
- package/bundler/index.d.ts +43 -0
- package/bundler/index.d.ts.map +1 -0
- package/bundler/index.js +3707 -0
- package/bundler/sandbox/enclave-adapter.d.ts +121 -0
- package/bundler/sandbox/enclave-adapter.d.ts.map +1 -0
- package/bundler/sandbox/executor.d.ts +14 -0
- package/bundler/sandbox/executor.d.ts.map +1 -0
- package/bundler/sandbox/policy.d.ts +62 -0
- package/bundler/sandbox/policy.d.ts.map +1 -0
- package/bundler/types.d.ts +702 -0
- package/bundler/types.d.ts.map +1 -0
- package/components/alert.d.ts +66 -0
- package/components/alert.d.ts.map +1 -0
- package/components/alert.schema.d.ts +98 -0
- package/components/alert.schema.d.ts.map +1 -0
- package/components/avatar.d.ts +77 -0
- package/components/avatar.d.ts.map +1 -0
- package/components/avatar.schema.d.ts +170 -0
- package/components/avatar.schema.d.ts.map +1 -0
- package/components/badge.d.ts +64 -0
- package/components/badge.d.ts.map +1 -0
- package/components/badge.schema.d.ts +91 -0
- package/components/badge.schema.d.ts.map +1 -0
- package/components/button.d.ts +100 -0
- package/components/button.d.ts.map +1 -0
- package/components/button.schema.d.ts +120 -0
- package/components/button.schema.d.ts.map +1 -0
- package/components/card.d.ts +53 -0
- package/components/card.d.ts.map +1 -0
- package/components/card.schema.d.ts +93 -0
- package/components/card.schema.d.ts.map +1 -0
- package/components/form.d.ts +212 -0
- package/components/form.d.ts.map +1 -0
- package/components/form.schema.d.ts +365 -0
- package/components/form.schema.d.ts.map +1 -0
- package/components/index.d.ts +29 -0
- package/components/index.d.ts.map +1 -0
- package/components/index.js +2525 -0
- package/components/list.d.ts +121 -0
- package/components/list.d.ts.map +1 -0
- package/components/list.schema.d.ts +129 -0
- package/components/list.schema.d.ts.map +1 -0
- package/components/modal.d.ts +100 -0
- package/components/modal.d.ts.map +1 -0
- package/components/modal.schema.d.ts +151 -0
- package/components/modal.schema.d.ts.map +1 -0
- package/components/table.d.ts +91 -0
- package/components/table.d.ts.map +1 -0
- package/components/table.schema.d.ts +123 -0
- package/components/table.schema.d.ts.map +1 -0
- package/esm/bridge/adapters/base-adapter.d.ts +104 -0
- package/esm/bridge/adapters/base-adapter.d.ts.map +1 -0
- package/esm/bridge/adapters/claude.adapter.d.ts +67 -0
- package/esm/bridge/adapters/claude.adapter.d.ts.map +1 -0
- package/esm/bridge/adapters/ext-apps.adapter.d.ts +143 -0
- package/esm/bridge/adapters/ext-apps.adapter.d.ts.map +1 -0
- package/esm/bridge/adapters/gemini.adapter.d.ts +64 -0
- package/esm/bridge/adapters/gemini.adapter.d.ts.map +1 -0
- package/esm/bridge/adapters/generic.adapter.d.ts +56 -0
- package/esm/bridge/adapters/generic.adapter.d.ts.map +1 -0
- package/esm/bridge/adapters/index.d.ts +26 -0
- package/esm/bridge/adapters/index.d.ts.map +1 -0
- package/esm/bridge/adapters/openai.adapter.d.ts +65 -0
- package/esm/bridge/adapters/openai.adapter.d.ts.map +1 -0
- package/esm/bridge/core/adapter-registry.d.ts +122 -0
- package/esm/bridge/core/adapter-registry.d.ts.map +1 -0
- package/esm/bridge/core/bridge-factory.d.ts +199 -0
- package/esm/bridge/core/bridge-factory.d.ts.map +1 -0
- package/esm/bridge/core/index.d.ts +10 -0
- package/esm/bridge/core/index.d.ts.map +1 -0
- package/esm/bridge/index.d.ts +62 -0
- package/esm/bridge/index.d.ts.map +1 -0
- package/esm/bridge/index.js +2487 -0
- package/esm/bridge/runtime/iife-generator.d.ts +62 -0
- package/esm/bridge/runtime/iife-generator.d.ts.map +1 -0
- package/esm/bridge/runtime/index.d.ts +10 -0
- package/esm/bridge/runtime/index.d.ts.map +1 -0
- package/esm/bridge/types.d.ts +386 -0
- package/esm/bridge/types.d.ts.map +1 -0
- package/esm/bundler/bundler.d.ts +208 -0
- package/esm/bundler/bundler.d.ts.map +1 -0
- package/esm/bundler/cache.d.ts +173 -0
- package/esm/bundler/cache.d.ts.map +1 -0
- package/esm/bundler/file-cache/component-builder.d.ts +167 -0
- package/esm/bundler/file-cache/component-builder.d.ts.map +1 -0
- package/esm/bundler/file-cache/hash-calculator.d.ts +155 -0
- package/esm/bundler/file-cache/hash-calculator.d.ts.map +1 -0
- package/esm/bundler/file-cache/index.d.ts +12 -0
- package/esm/bundler/file-cache/index.d.ts.map +1 -0
- package/esm/bundler/file-cache/storage/filesystem.d.ts +149 -0
- package/esm/bundler/file-cache/storage/filesystem.d.ts.map +1 -0
- package/esm/bundler/file-cache/storage/index.d.ts +11 -0
- package/esm/bundler/file-cache/storage/index.d.ts.map +1 -0
- package/esm/bundler/file-cache/storage/interface.d.ts +152 -0
- package/esm/bundler/file-cache/storage/interface.d.ts.map +1 -0
- package/esm/bundler/file-cache/storage/redis.d.ts +139 -0
- package/esm/bundler/file-cache/storage/redis.d.ts.map +1 -0
- package/esm/bundler/index.d.ts +43 -0
- package/esm/bundler/index.d.ts.map +1 -0
- package/esm/bundler/index.js +3640 -0
- package/esm/bundler/sandbox/enclave-adapter.d.ts +121 -0
- package/esm/bundler/sandbox/enclave-adapter.d.ts.map +1 -0
- package/esm/bundler/sandbox/executor.d.ts +14 -0
- package/esm/bundler/sandbox/executor.d.ts.map +1 -0
- package/esm/bundler/sandbox/policy.d.ts +62 -0
- package/esm/bundler/sandbox/policy.d.ts.map +1 -0
- package/esm/bundler/types.d.ts +702 -0
- package/esm/bundler/types.d.ts.map +1 -0
- package/esm/components/alert.d.ts +66 -0
- package/esm/components/alert.d.ts.map +1 -0
- package/esm/components/alert.schema.d.ts +98 -0
- package/esm/components/alert.schema.d.ts.map +1 -0
- package/esm/components/avatar.d.ts +77 -0
- package/esm/components/avatar.d.ts.map +1 -0
- package/esm/components/avatar.schema.d.ts +170 -0
- package/esm/components/avatar.schema.d.ts.map +1 -0
- package/esm/components/badge.d.ts +64 -0
- package/esm/components/badge.d.ts.map +1 -0
- package/esm/components/badge.schema.d.ts +91 -0
- package/esm/components/badge.schema.d.ts.map +1 -0
- package/esm/components/button.d.ts +100 -0
- package/esm/components/button.d.ts.map +1 -0
- package/esm/components/button.schema.d.ts +120 -0
- package/esm/components/button.schema.d.ts.map +1 -0
- package/esm/components/card.d.ts +53 -0
- package/esm/components/card.d.ts.map +1 -0
- package/esm/components/card.schema.d.ts +93 -0
- package/esm/components/card.schema.d.ts.map +1 -0
- package/esm/components/form.d.ts +212 -0
- package/esm/components/form.d.ts.map +1 -0
- package/esm/components/form.schema.d.ts +365 -0
- package/esm/components/form.schema.d.ts.map +1 -0
- package/esm/components/index.d.ts +29 -0
- package/esm/components/index.d.ts.map +1 -0
- package/esm/components/index.js +2396 -0
- package/esm/components/list.d.ts +121 -0
- package/esm/components/list.d.ts.map +1 -0
- package/esm/components/list.schema.d.ts +129 -0
- package/esm/components/list.schema.d.ts.map +1 -0
- package/esm/components/modal.d.ts +100 -0
- package/esm/components/modal.d.ts.map +1 -0
- package/esm/components/modal.schema.d.ts +151 -0
- package/esm/components/modal.schema.d.ts.map +1 -0
- package/esm/components/table.d.ts +91 -0
- package/esm/components/table.d.ts.map +1 -0
- package/esm/components/table.schema.d.ts +123 -0
- package/esm/components/table.schema.d.ts.map +1 -0
- package/esm/index.d.ts +40 -0
- package/esm/index.d.ts.map +1 -0
- package/esm/index.js +8326 -0
- package/esm/layouts/base.d.ts +86 -0
- package/esm/layouts/base.d.ts.map +1 -0
- package/esm/layouts/index.d.ts +8 -0
- package/esm/layouts/index.d.ts.map +1 -0
- package/esm/layouts/index.js +409 -0
- package/esm/layouts/presets.d.ts +134 -0
- package/esm/layouts/presets.d.ts.map +1 -0
- package/esm/package.json +72 -0
- package/esm/pages/consent.d.ts +117 -0
- package/esm/pages/consent.d.ts.map +1 -0
- package/esm/pages/error.d.ts +101 -0
- package/esm/pages/error.d.ts.map +1 -0
- package/esm/pages/index.d.ts +9 -0
- package/esm/pages/index.d.ts.map +1 -0
- package/esm/pages/index.js +1036 -0
- package/esm/react/Alert.d.ts +101 -0
- package/esm/react/Alert.d.ts.map +1 -0
- package/esm/react/Badge.d.ts +100 -0
- package/esm/react/Badge.d.ts.map +1 -0
- package/esm/react/Button.d.ts +108 -0
- package/esm/react/Button.d.ts.map +1 -0
- package/esm/react/Card.d.ts +103 -0
- package/esm/react/Card.d.ts.map +1 -0
- package/esm/react/hooks/context.d.ts +179 -0
- package/esm/react/hooks/context.d.ts.map +1 -0
- package/esm/react/hooks/index.d.ts +42 -0
- package/esm/react/hooks/index.d.ts.map +1 -0
- package/esm/react/hooks/tools.d.ts +284 -0
- package/esm/react/hooks/tools.d.ts.map +1 -0
- package/esm/react/index.d.ts +80 -0
- package/esm/react/index.d.ts.map +1 -0
- package/esm/react/index.js +3124 -0
- package/esm/react/types.d.ts +105 -0
- package/esm/react/types.d.ts.map +1 -0
- package/esm/react/utils.d.ts +43 -0
- package/esm/react/utils.d.ts.map +1 -0
- package/esm/render/index.d.ts +8 -0
- package/esm/render/index.d.ts.map +1 -0
- package/esm/render/index.js +45 -0
- package/esm/render/prerender.d.ts +57 -0
- package/esm/render/prerender.d.ts.map +1 -0
- package/esm/renderers/index.d.ts +21 -0
- package/esm/renderers/index.d.ts.map +1 -0
- package/esm/renderers/index.js +381 -0
- package/esm/renderers/react.adapter.d.ts +70 -0
- package/esm/renderers/react.adapter.d.ts.map +1 -0
- package/esm/renderers/react.renderer.d.ts +96 -0
- package/esm/renderers/react.renderer.d.ts.map +1 -0
- package/esm/universal/UniversalApp.d.ts +108 -0
- package/esm/universal/UniversalApp.d.ts.map +1 -0
- package/esm/universal/cached-runtime.d.ts +115 -0
- package/esm/universal/cached-runtime.d.ts.map +1 -0
- package/esm/universal/context.d.ts +122 -0
- package/esm/universal/context.d.ts.map +1 -0
- package/esm/universal/index.d.ts +57 -0
- package/esm/universal/index.d.ts.map +1 -0
- package/esm/universal/index.js +1755 -0
- package/esm/universal/renderers/html.renderer.d.ts +37 -0
- package/esm/universal/renderers/html.renderer.d.ts.map +1 -0
- package/esm/universal/renderers/index.d.ts +112 -0
- package/esm/universal/renderers/index.d.ts.map +1 -0
- package/esm/universal/renderers/markdown.renderer.d.ts +33 -0
- package/esm/universal/renderers/markdown.renderer.d.ts.map +1 -0
- package/esm/universal/renderers/mdx.renderer.d.ts +38 -0
- package/esm/universal/renderers/mdx.renderer.d.ts.map +1 -0
- package/esm/universal/renderers/react.renderer.d.ts +46 -0
- package/esm/universal/renderers/react.renderer.d.ts.map +1 -0
- package/esm/universal/runtime-builder.d.ts +33 -0
- package/esm/universal/runtime-builder.d.ts.map +1 -0
- package/esm/universal/store.d.ts +135 -0
- package/esm/universal/store.d.ts.map +1 -0
- package/esm/universal/types.d.ts +199 -0
- package/esm/universal/types.d.ts.map +1 -0
- package/esm/web-components/core/attribute-parser.d.ts +82 -0
- package/esm/web-components/core/attribute-parser.d.ts.map +1 -0
- package/esm/web-components/core/base-element.d.ts +197 -0
- package/esm/web-components/core/base-element.d.ts.map +1 -0
- package/esm/web-components/core/index.d.ts +9 -0
- package/esm/web-components/core/index.d.ts.map +1 -0
- package/esm/web-components/elements/fmcp-alert.d.ts +46 -0
- package/esm/web-components/elements/fmcp-alert.d.ts.map +1 -0
- package/esm/web-components/elements/fmcp-badge.d.ts +47 -0
- package/esm/web-components/elements/fmcp-badge.d.ts.map +1 -0
- package/esm/web-components/elements/fmcp-button.d.ts +117 -0
- package/esm/web-components/elements/fmcp-button.d.ts.map +1 -0
- package/esm/web-components/elements/fmcp-card.d.ts +53 -0
- package/esm/web-components/elements/fmcp-card.d.ts.map +1 -0
- package/esm/web-components/elements/fmcp-input.d.ts +96 -0
- package/esm/web-components/elements/fmcp-input.d.ts.map +1 -0
- package/esm/web-components/elements/fmcp-select.d.ts +100 -0
- package/esm/web-components/elements/fmcp-select.d.ts.map +1 -0
- package/esm/web-components/elements/index.d.ts +13 -0
- package/esm/web-components/elements/index.d.ts.map +1 -0
- package/esm/web-components/index.d.ts +50 -0
- package/esm/web-components/index.d.ts.map +1 -0
- package/esm/web-components/index.js +1993 -0
- package/esm/web-components/register.d.ts +57 -0
- package/esm/web-components/register.d.ts.map +1 -0
- package/esm/web-components/types.d.ts +122 -0
- package/esm/web-components/types.d.ts.map +1 -0
- package/esm/widgets/index.d.ts +8 -0
- package/esm/widgets/index.d.ts.map +1 -0
- package/esm/widgets/index.js +883 -0
- package/esm/widgets/progress.d.ts +133 -0
- package/esm/widgets/progress.d.ts.map +1 -0
- package/esm/widgets/resource.d.ts +163 -0
- package/esm/widgets/resource.d.ts.map +1 -0
- package/index.d.ts +40 -0
- package/index.d.ts.map +1 -0
- package/index.js +8526 -0
- package/layouts/base.d.ts +86 -0
- package/layouts/base.d.ts.map +1 -0
- package/layouts/index.d.ts +8 -0
- package/layouts/index.d.ts.map +1 -0
- package/layouts/index.js +437 -0
- package/layouts/presets.d.ts +134 -0
- package/layouts/presets.d.ts.map +1 -0
- package/package.json +33 -110
- package/pages/consent.d.ts +117 -0
- package/pages/consent.d.ts.map +1 -0
- package/pages/error.d.ts +101 -0
- package/pages/error.d.ts.map +1 -0
- package/pages/index.d.ts +9 -0
- package/pages/index.d.ts.map +1 -0
- package/pages/index.js +1065 -0
- package/react/Alert.d.ts +101 -0
- package/react/Alert.d.ts.map +1 -0
- package/react/Badge.d.ts +100 -0
- package/react/Badge.d.ts.map +1 -0
- package/react/Button.d.ts +108 -0
- package/react/Button.d.ts.map +1 -0
- package/react/Card.d.ts +103 -0
- package/react/Card.d.ts.map +1 -0
- package/react/hooks/context.d.ts +179 -0
- package/react/hooks/context.d.ts.map +1 -0
- package/react/hooks/index.d.ts +42 -0
- package/react/hooks/index.d.ts.map +1 -0
- package/react/hooks/tools.d.ts +284 -0
- package/react/hooks/tools.d.ts.map +1 -0
- package/react/index.d.ts +80 -0
- package/react/index.d.ts.map +1 -0
- package/react/index.js +3160 -0
- package/react/types.d.ts +105 -0
- package/react/types.d.ts.map +1 -0
- package/react/utils.d.ts +43 -0
- package/react/utils.d.ts.map +1 -0
- package/render/index.d.ts +8 -0
- package/render/index.d.ts.map +1 -0
- package/render/index.js +77 -0
- package/render/prerender.d.ts +57 -0
- package/render/prerender.d.ts.map +1 -0
- package/renderers/index.d.ts +21 -0
- package/renderers/index.d.ts.map +1 -0
- package/renderers/index.js +416 -0
- package/renderers/react.adapter.d.ts +70 -0
- package/renderers/react.adapter.d.ts.map +1 -0
- package/renderers/react.renderer.d.ts +96 -0
- package/renderers/react.renderer.d.ts.map +1 -0
- package/universal/UniversalApp.d.ts +108 -0
- package/universal/UniversalApp.d.ts.map +1 -0
- package/universal/cached-runtime.d.ts +115 -0
- package/universal/cached-runtime.d.ts.map +1 -0
- package/universal/context.d.ts +122 -0
- package/universal/context.d.ts.map +1 -0
- package/universal/index.d.ts +57 -0
- package/universal/index.d.ts.map +1 -0
- package/universal/index.js +1841 -0
- package/universal/renderers/html.renderer.d.ts +37 -0
- package/universal/renderers/html.renderer.d.ts.map +1 -0
- package/universal/renderers/index.d.ts +112 -0
- package/universal/renderers/index.d.ts.map +1 -0
- package/universal/renderers/markdown.renderer.d.ts +33 -0
- package/universal/renderers/markdown.renderer.d.ts.map +1 -0
- package/universal/renderers/mdx.renderer.d.ts +38 -0
- package/universal/renderers/mdx.renderer.d.ts.map +1 -0
- package/universal/renderers/react.renderer.d.ts +46 -0
- package/universal/renderers/react.renderer.d.ts.map +1 -0
- package/universal/runtime-builder.d.ts +33 -0
- package/universal/runtime-builder.d.ts.map +1 -0
- package/universal/store.d.ts +135 -0
- package/universal/store.d.ts.map +1 -0
- package/universal/types.d.ts +199 -0
- package/universal/types.d.ts.map +1 -0
- package/web-components/core/attribute-parser.d.ts +82 -0
- package/web-components/core/attribute-parser.d.ts.map +1 -0
- package/web-components/core/base-element.d.ts +197 -0
- package/web-components/core/base-element.d.ts.map +1 -0
- package/web-components/core/index.d.ts +9 -0
- package/web-components/core/index.d.ts.map +1 -0
- package/web-components/elements/fmcp-alert.d.ts +46 -0
- package/web-components/elements/fmcp-alert.d.ts.map +1 -0
- package/web-components/elements/fmcp-badge.d.ts +47 -0
- package/web-components/elements/fmcp-badge.d.ts.map +1 -0
- package/web-components/elements/fmcp-button.d.ts +117 -0
- package/web-components/elements/fmcp-button.d.ts.map +1 -0
- package/web-components/elements/fmcp-card.d.ts +53 -0
- package/web-components/elements/fmcp-card.d.ts.map +1 -0
- package/web-components/elements/fmcp-input.d.ts +96 -0
- package/web-components/elements/fmcp-input.d.ts.map +1 -0
- package/web-components/elements/fmcp-select.d.ts +100 -0
- package/web-components/elements/fmcp-select.d.ts.map +1 -0
- package/web-components/elements/index.d.ts +13 -0
- package/web-components/elements/index.d.ts.map +1 -0
- package/web-components/index.d.ts +50 -0
- package/web-components/index.d.ts.map +1 -0
- package/web-components/index.js +2028 -0
- package/web-components/register.d.ts +57 -0
- package/web-components/register.d.ts.map +1 -0
- package/web-components/types.d.ts +122 -0
- package/web-components/types.d.ts.map +1 -0
- package/widgets/index.d.ts +8 -0
- package/widgets/index.d.ts.map +1 -0
- package/widgets/index.js +910 -0
- package/widgets/progress.d.ts +133 -0
- package/widgets/progress.d.ts.map +1 -0
- package/widgets/resource.d.ts +163 -0
- package/widgets/resource.d.ts.map +1 -0
- package/src/adapters/index.d.ts +0 -10
- package/src/adapters/index.js +0 -18
- package/src/adapters/index.js.map +0 -1
- package/src/adapters/platform-meta.d.ts +0 -165
- package/src/adapters/platform-meta.js +0 -310
- package/src/adapters/platform-meta.js.map +0 -1
- package/src/base-template/bridge.d.ts +0 -89
- package/src/base-template/bridge.js +0 -452
- package/src/base-template/bridge.js.map +0 -1
- package/src/base-template/default-base-template.d.ts +0 -91
- package/src/base-template/default-base-template.js +0 -435
- package/src/base-template/default-base-template.js.map +0 -1
- package/src/base-template/index.d.ts +0 -14
- package/src/base-template/index.js +0 -30
- package/src/base-template/index.js.map +0 -1
- package/src/base-template/polyfills.d.ts +0 -30
- package/src/base-template/polyfills.js +0 -190
- package/src/base-template/polyfills.js.map +0 -1
- package/src/base-template/theme-styles.d.ts +0 -73
- package/src/base-template/theme-styles.js +0 -95
- package/src/base-template/theme-styles.js.map +0 -1
- package/src/bridge/adapters/base-adapter.d.ts +0 -103
- package/src/bridge/adapters/base-adapter.js +0 -314
- package/src/bridge/adapters/base-adapter.js.map +0 -1
- package/src/bridge/adapters/claude.adapter.d.ts +0 -66
- package/src/bridge/adapters/claude.adapter.js +0 -145
- package/src/bridge/adapters/claude.adapter.js.map +0 -1
- package/src/bridge/adapters/ext-apps.adapter.d.ts +0 -142
- package/src/bridge/adapters/ext-apps.adapter.js +0 -416
- package/src/bridge/adapters/ext-apps.adapter.js.map +0 -1
- package/src/bridge/adapters/gemini.adapter.d.ts +0 -63
- package/src/bridge/adapters/gemini.adapter.js +0 -160
- package/src/bridge/adapters/gemini.adapter.js.map +0 -1
- package/src/bridge/adapters/generic.adapter.d.ts +0 -55
- package/src/bridge/adapters/generic.adapter.js +0 -108
- package/src/bridge/adapters/generic.adapter.js.map +0 -1
- package/src/bridge/adapters/index.d.ts +0 -25
- package/src/bridge/adapters/index.js +0 -65
- package/src/bridge/adapters/index.js.map +0 -1
- package/src/bridge/adapters/openai.adapter.d.ts +0 -64
- package/src/bridge/adapters/openai.adapter.js +0 -194
- package/src/bridge/adapters/openai.adapter.js.map +0 -1
- package/src/bridge/core/adapter-registry.d.ts +0 -121
- package/src/bridge/core/adapter-registry.js +0 -271
- package/src/bridge/core/adapter-registry.js.map +0 -1
- package/src/bridge/core/bridge-factory.d.ts +0 -198
- package/src/bridge/core/bridge-factory.js +0 -428
- package/src/bridge/core/bridge-factory.js.map +0 -1
- package/src/bridge/core/index.d.ts +0 -9
- package/src/bridge/core/index.js +0 -22
- package/src/bridge/core/index.js.map +0 -1
- package/src/bridge/index.d.ts +0 -61
- package/src/bridge/index.js +0 -94
- package/src/bridge/index.js.map +0 -1
- package/src/bridge/runtime/iife-generator.d.ts +0 -61
- package/src/bridge/runtime/iife-generator.js +0 -940
- package/src/bridge/runtime/iife-generator.js.map +0 -1
- package/src/bridge/runtime/index.d.ts +0 -8
- package/src/bridge/runtime/index.js +0 -16
- package/src/bridge/runtime/index.js.map +0 -1
- package/src/bridge/types.d.ts +0 -385
- package/src/bridge/types.js +0 -11
- package/src/bridge/types.js.map +0 -1
- package/src/build/cdn-resources.d.ts +0 -140
- package/src/build/cdn-resources.js +0 -314
- package/src/build/cdn-resources.js.map +0 -1
- package/src/build/index.d.ts +0 -294
- package/src/build/index.js +0 -325
- package/src/build/index.js.map +0 -1
- package/src/build/widget-manifest.d.ts +0 -212
- package/src/build/widget-manifest.js +0 -652
- package/src/build/widget-manifest.js.map +0 -1
- package/src/bundler/bundler.d.ts +0 -110
- package/src/bundler/bundler.js +0 -432
- package/src/bundler/bundler.js.map +0 -1
- package/src/bundler/cache.d.ts +0 -172
- package/src/bundler/cache.js +0 -250
- package/src/bundler/cache.js.map +0 -1
- package/src/bundler/index.d.ts +0 -41
- package/src/bundler/index.js +0 -73
- package/src/bundler/index.js.map +0 -1
- package/src/bundler/sandbox/enclave-adapter.d.ts +0 -120
- package/src/bundler/sandbox/enclave-adapter.js +0 -339
- package/src/bundler/sandbox/enclave-adapter.js.map +0 -1
- package/src/bundler/sandbox/executor.d.ts +0 -13
- package/src/bundler/sandbox/executor.js +0 -22
- package/src/bundler/sandbox/executor.js.map +0 -1
- package/src/bundler/sandbox/policy.d.ts +0 -61
- package/src/bundler/sandbox/policy.js +0 -238
- package/src/bundler/sandbox/policy.js.map +0 -1
- package/src/bundler/types.d.ts +0 -347
- package/src/bundler/types.js +0 -132
- package/src/bundler/types.js.map +0 -1
- package/src/components/alert.d.ts +0 -71
- package/src/components/alert.js +0 -189
- package/src/components/alert.js.map +0 -1
- package/src/components/alert.schema.d.ts +0 -114
- package/src/components/alert.schema.js +0 -105
- package/src/components/alert.schema.js.map +0 -1
- package/src/components/avatar.d.ts +0 -76
- package/src/components/avatar.js +0 -176
- package/src/components/avatar.js.map +0 -1
- package/src/components/avatar.schema.d.ts +0 -169
- package/src/components/avatar.schema.js +0 -103
- package/src/components/avatar.schema.js.map +0 -1
- package/src/components/badge.d.ts +0 -70
- package/src/components/badge.js +0 -149
- package/src/components/badge.js.map +0 -1
- package/src/components/badge.schema.d.ts +0 -109
- package/src/components/badge.schema.js +0 -96
- package/src/components/badge.schema.js.map +0 -1
- package/src/components/button.d.ts +0 -111
- package/src/components/button.js +0 -336
- package/src/components/button.js.map +0 -1
- package/src/components/button.schema.d.ts +0 -148
- package/src/components/button.schema.js +0 -121
- package/src/components/button.schema.js.map +0 -1
- package/src/components/card.d.ts +0 -60
- package/src/components/card.js +0 -117
- package/src/components/card.js.map +0 -1
- package/src/components/card.schema.d.ts +0 -113
- package/src/components/card.schema.js +0 -98
- package/src/components/card.schema.js.map +0 -1
- package/src/components/form.d.ts +0 -239
- package/src/components/form.js +0 -420
- package/src/components/form.js.map +0 -1
- package/src/components/form.schema.d.ts +0 -441
- package/src/components/form.schema.js +0 -406
- package/src/components/form.schema.js.map +0 -1
- package/src/components/index.d.ts +0 -29
- package/src/components/index.js +0 -98
- package/src/components/index.js.map +0 -1
- package/src/components/list.d.ts +0 -127
- package/src/components/list.js +0 -279
- package/src/components/list.js.map +0 -1
- package/src/components/list.schema.d.ts +0 -134
- package/src/components/list.schema.js +0 -168
- package/src/components/list.schema.js.map +0 -1
- package/src/components/modal.d.ts +0 -111
- package/src/components/modal.js +0 -260
- package/src/components/modal.js.map +0 -1
- package/src/components/modal.schema.d.ts +0 -186
- package/src/components/modal.schema.js +0 -167
- package/src/components/modal.schema.js.map +0 -1
- package/src/components/table.d.ts +0 -105
- package/src/components/table.js +0 -283
- package/src/components/table.js.map +0 -1
- package/src/components/table.schema.d.ts +0 -159
- package/src/components/table.schema.js +0 -173
- package/src/components/table.schema.js.map +0 -1
- package/src/handlebars/helpers.d.ts +0 -348
- package/src/handlebars/helpers.js +0 -605
- package/src/handlebars/helpers.js.map +0 -1
- package/src/handlebars/index.d.ts +0 -193
- package/src/handlebars/index.js +0 -350
- package/src/handlebars/index.js.map +0 -1
- package/src/index.d.ts +0 -50
- package/src/index.js +0 -192
- package/src/index.js.map +0 -1
- package/src/layouts/base.d.ts +0 -88
- package/src/layouts/base.js +0 -227
- package/src/layouts/base.js.map +0 -1
- package/src/layouts/index.d.ts +0 -7
- package/src/layouts/index.js +0 -25
- package/src/layouts/index.js.map +0 -1
- package/src/layouts/presets.d.ts +0 -133
- package/src/layouts/presets.js +0 -277
- package/src/layouts/presets.js.map +0 -1
- package/src/pages/consent.d.ts +0 -116
- package/src/pages/consent.js +0 -218
- package/src/pages/consent.js.map +0 -1
- package/src/pages/error.d.ts +0 -100
- package/src/pages/error.js +0 -263
- package/src/pages/error.js.map +0 -1
- package/src/pages/index.d.ts +0 -8
- package/src/pages/index.js +0 -27
- package/src/pages/index.js.map +0 -1
- package/src/react/Alert.d.ts +0 -101
- package/src/react/Alert.js +0 -51
- package/src/react/Alert.js.map +0 -1
- package/src/react/Badge.d.ts +0 -100
- package/src/react/Badge.js +0 -55
- package/src/react/Badge.js.map +0 -1
- package/src/react/Button.d.ts +0 -108
- package/src/react/Button.js +0 -52
- package/src/react/Button.js.map +0 -1
- package/src/react/Card.d.ts +0 -103
- package/src/react/Card.js +0 -55
- package/src/react/Card.js.map +0 -1
- package/src/react/hooks/context.d.ts +0 -178
- package/src/react/hooks/context.js +0 -287
- package/src/react/hooks/context.js.map +0 -1
- package/src/react/hooks/index.d.ts +0 -41
- package/src/react/hooks/index.js +0 -61
- package/src/react/hooks/index.js.map +0 -1
- package/src/react/hooks/tools.d.ts +0 -283
- package/src/react/hooks/tools.js +0 -465
- package/src/react/hooks/tools.js.map +0 -1
- package/src/react/index.d.ts +0 -80
- package/src/react/index.js +0 -113
- package/src/react/index.js.map +0 -1
- package/src/react/types.d.ts +0 -105
- package/src/react/types.js +0 -12
- package/src/react/types.js.map +0 -1
- package/src/react/utils.d.ts +0 -42
- package/src/react/utils.js +0 -99
- package/src/react/utils.js.map +0 -1
- package/src/registry/index.d.ts +0 -45
- package/src/registry/index.js +0 -67
- package/src/registry/index.js.map +0 -1
- package/src/registry/render-template.d.ts +0 -86
- package/src/registry/render-template.js +0 -239
- package/src/registry/render-template.js.map +0 -1
- package/src/registry/tool-ui.registry.d.ts +0 -260
- package/src/registry/tool-ui.registry.js +0 -438
- package/src/registry/tool-ui.registry.js.map +0 -1
- package/src/registry/uri-utils.d.ts +0 -55
- package/src/registry/uri-utils.js +0 -97
- package/src/registry/uri-utils.js.map +0 -1
- package/src/render/index.d.ts +0 -7
- package/src/render/index.js +0 -14
- package/src/render/index.js.map +0 -1
- package/src/render/prerender.d.ts +0 -56
- package/src/render/prerender.js +0 -98
- package/src/render/prerender.js.map +0 -1
- package/src/renderers/cache.d.ts +0 -144
- package/src/renderers/cache.js +0 -240
- package/src/renderers/cache.js.map +0 -1
- package/src/renderers/html.renderer.d.ts +0 -122
- package/src/renderers/html.renderer.js +0 -204
- package/src/renderers/html.renderer.js.map +0 -1
- package/src/renderers/index.d.ts +0 -35
- package/src/renderers/index.js +0 -70
- package/src/renderers/index.js.map +0 -1
- package/src/renderers/mdx.renderer.d.ts +0 -119
- package/src/renderers/mdx.renderer.js +0 -305
- package/src/renderers/mdx.renderer.js.map +0 -1
- package/src/renderers/react.renderer.d.ts +0 -95
- package/src/renderers/react.renderer.js +0 -260
- package/src/renderers/react.renderer.js.map +0 -1
- package/src/renderers/registry.d.ts +0 -133
- package/src/renderers/registry.js +0 -232
- package/src/renderers/registry.js.map +0 -1
- package/src/renderers/types.d.ts +0 -341
- package/src/renderers/types.js +0 -9
- package/src/renderers/types.js.map +0 -1
- package/src/renderers/utils/detect.d.ts +0 -106
- package/src/renderers/utils/detect.js +0 -267
- package/src/renderers/utils/detect.js.map +0 -1
- package/src/renderers/utils/hash.d.ts +0 -39
- package/src/renderers/utils/hash.js +0 -75
- package/src/renderers/utils/hash.js.map +0 -1
- package/src/renderers/utils/index.d.ts +0 -8
- package/src/renderers/utils/index.js +0 -28
- package/src/renderers/utils/index.js.map +0 -1
- package/src/renderers/utils/transpiler.d.ts +0 -88
- package/src/renderers/utils/transpiler.js +0 -215
- package/src/renderers/utils/transpiler.js.map +0 -1
- package/src/runtime/adapters/html.adapter.d.ts +0 -58
- package/src/runtime/adapters/html.adapter.js +0 -131
- package/src/runtime/adapters/html.adapter.js.map +0 -1
- package/src/runtime/adapters/index.d.ts +0 -25
- package/src/runtime/adapters/index.js +0 -54
- package/src/runtime/adapters/index.js.map +0 -1
- package/src/runtime/adapters/mdx.adapter.d.ts +0 -72
- package/src/runtime/adapters/mdx.adapter.js +0 -241
- package/src/runtime/adapters/mdx.adapter.js.map +0 -1
- package/src/runtime/adapters/react.adapter.d.ts +0 -69
- package/src/runtime/adapters/react.adapter.js +0 -245
- package/src/runtime/adapters/react.adapter.js.map +0 -1
- package/src/runtime/adapters/types.d.ts +0 -94
- package/src/runtime/adapters/types.js +0 -11
- package/src/runtime/adapters/types.js.map +0 -1
- package/src/runtime/csp.d.ts +0 -37
- package/src/runtime/csp.js +0 -140
- package/src/runtime/csp.js.map +0 -1
- package/src/runtime/index.d.ts +0 -16
- package/src/runtime/index.js +0 -72
- package/src/runtime/index.js.map +0 -1
- package/src/runtime/mcp-bridge.d.ts +0 -100
- package/src/runtime/mcp-bridge.js +0 -581
- package/src/runtime/mcp-bridge.js.map +0 -1
- package/src/runtime/renderer-runtime.d.ts +0 -132
- package/src/runtime/renderer-runtime.js +0 -389
- package/src/runtime/renderer-runtime.js.map +0 -1
- package/src/runtime/sanitizer.d.ts +0 -171
- package/src/runtime/sanitizer.js +0 -318
- package/src/runtime/sanitizer.js.map +0 -1
- package/src/runtime/types.d.ts +0 -414
- package/src/runtime/types.js +0 -12
- package/src/runtime/types.js.map +0 -1
- package/src/runtime/wrapper.d.ts +0 -375
- package/src/runtime/wrapper.js +0 -1793
- package/src/runtime/wrapper.js.map +0 -1
- package/src/styles/index.d.ts +0 -7
- package/src/styles/index.js +0 -11
- package/src/styles/index.js.map +0 -1
- package/src/styles/variants.d.ts +0 -50
- package/src/styles/variants.js +0 -175
- package/src/styles/variants.js.map +0 -1
- package/src/theme/cdn.d.ts +0 -194
- package/src/theme/cdn.js +0 -375
- package/src/theme/cdn.js.map +0 -1
- package/src/theme/index.d.ts +0 -17
- package/src/theme/index.js +0 -57
- package/src/theme/index.js.map +0 -1
- package/src/theme/platforms.d.ts +0 -106
- package/src/theme/platforms.js +0 -161
- package/src/theme/platforms.js.map +0 -1
- package/src/theme/presets/github-openai.d.ts +0 -49
- package/src/theme/presets/github-openai.js +0 -189
- package/src/theme/presets/github-openai.js.map +0 -1
- package/src/theme/presets/index.d.ts +0 -10
- package/src/theme/presets/index.js +0 -17
- package/src/theme/presets/index.js.map +0 -1
- package/src/theme/theme.d.ts +0 -395
- package/src/theme/theme.js +0 -332
- package/src/theme/theme.js.map +0 -1
- package/src/tool-template/builder.d.ts +0 -212
- package/src/tool-template/builder.js +0 -397
- package/src/tool-template/builder.js.map +0 -1
- package/src/tool-template/index.d.ts +0 -15
- package/src/tool-template/index.js +0 -38
- package/src/tool-template/index.js.map +0 -1
- package/src/types/index.d.ts +0 -13
- package/src/types/index.js +0 -26
- package/src/types/index.js.map +0 -1
- package/src/types/ui-config.d.ts +0 -357
- package/src/types/ui-config.js +0 -12
- package/src/types/ui-config.js.map +0 -1
- package/src/types/ui-runtime.d.ts +0 -965
- package/src/types/ui-runtime.js +0 -117
- package/src/types/ui-runtime.js.map +0 -1
- package/src/validation/error-box.d.ts +0 -55
- package/src/validation/error-box.js +0 -75
- package/src/validation/error-box.js.map +0 -1
- package/src/validation/index.d.ts +0 -12
- package/src/validation/index.js +0 -21
- package/src/validation/index.js.map +0 -1
- package/src/validation/wrapper.d.ts +0 -96
- package/src/validation/wrapper.js +0 -117
- package/src/validation/wrapper.js.map +0 -1
- package/src/web-components/core/attribute-parser.d.ts +0 -85
- package/src/web-components/core/attribute-parser.js +0 -189
- package/src/web-components/core/attribute-parser.js.map +0 -1
- package/src/web-components/core/base-element.d.ts +0 -197
- package/src/web-components/core/base-element.js +0 -289
- package/src/web-components/core/base-element.js.map +0 -1
- package/src/web-components/core/index.d.ts +0 -8
- package/src/web-components/core/index.js +0 -18
- package/src/web-components/core/index.js.map +0 -1
- package/src/web-components/elements/fmcp-alert.d.ts +0 -45
- package/src/web-components/elements/fmcp-alert.js +0 -93
- package/src/web-components/elements/fmcp-alert.js.map +0 -1
- package/src/web-components/elements/fmcp-badge.d.ts +0 -46
- package/src/web-components/elements/fmcp-badge.js +0 -99
- package/src/web-components/elements/fmcp-badge.js.map +0 -1
- package/src/web-components/elements/fmcp-button.d.ts +0 -124
- package/src/web-components/elements/fmcp-button.js +0 -233
- package/src/web-components/elements/fmcp-button.js.map +0 -1
- package/src/web-components/elements/fmcp-card.d.ts +0 -52
- package/src/web-components/elements/fmcp-card.js +0 -115
- package/src/web-components/elements/fmcp-card.js.map +0 -1
- package/src/web-components/elements/fmcp-input.d.ts +0 -95
- package/src/web-components/elements/fmcp-input.js +0 -248
- package/src/web-components/elements/fmcp-input.js.map +0 -1
- package/src/web-components/elements/fmcp-select.d.ts +0 -99
- package/src/web-components/elements/fmcp-select.js +0 -243
- package/src/web-components/elements/fmcp-select.js.map +0 -1
- package/src/web-components/elements/index.d.ts +0 -12
- package/src/web-components/elements/index.js +0 -34
- package/src/web-components/elements/index.js.map +0 -1
- package/src/web-components/index.d.ts +0 -49
- package/src/web-components/index.js +0 -75
- package/src/web-components/index.js.map +0 -1
- package/src/web-components/register.d.ts +0 -56
- package/src/web-components/register.js +0 -80
- package/src/web-components/register.js.map +0 -1
- package/src/web-components/types.d.ts +0 -121
- package/src/web-components/types.js +0 -25
- package/src/web-components/types.js.map +0 -1
- package/src/widgets/index.d.ts +0 -7
- package/src/widgets/index.js +0 -24
- package/src/widgets/index.js.map +0 -1
- package/src/widgets/progress.d.ts +0 -132
- package/src/widgets/progress.js +0 -303
- package/src/widgets/progress.js.map +0 -1
- package/src/widgets/resource.d.ts +0 -162
- package/src/widgets/resource.js +0 -340
- package/src/widgets/resource.js.map +0 -1
package/src/components/button.js
DELETED
|
@@ -1,336 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* @file button.ts
|
|
4
|
-
* @description Button Component for FrontMCP UI.
|
|
5
|
-
*
|
|
6
|
-
* Versatile button component with multiple variants, sizes, and states.
|
|
7
|
-
* Includes HTMX support for dynamic interactions without JavaScript.
|
|
8
|
-
*
|
|
9
|
-
* @example Basic button
|
|
10
|
-
* ```typescript
|
|
11
|
-
* import { button } from '@frontmcp/ui';
|
|
12
|
-
*
|
|
13
|
-
* // Primary button (default)
|
|
14
|
-
* const html = button('Click Me');
|
|
15
|
-
* // <button type="button" class="...bg-primary...">Click Me</button>
|
|
16
|
-
* ```
|
|
17
|
-
*
|
|
18
|
-
* @example Button variants
|
|
19
|
-
* ```typescript
|
|
20
|
-
* import { button, primaryButton, dangerButton, outlineButton } from '@frontmcp/ui';
|
|
21
|
-
*
|
|
22
|
-
* // Using variant option
|
|
23
|
-
* const secondary = button('Save', { variant: 'secondary' });
|
|
24
|
-
* const danger = button('Delete', { variant: 'danger' });
|
|
25
|
-
*
|
|
26
|
-
* // Using shorthand functions
|
|
27
|
-
* const primary = primaryButton('Submit');
|
|
28
|
-
* const outline = outlineButton('Cancel');
|
|
29
|
-
* ```
|
|
30
|
-
*
|
|
31
|
-
* @example Button with loading state
|
|
32
|
-
* ```typescript
|
|
33
|
-
* const loadingBtn = button('Saving...', {
|
|
34
|
-
* loading: true,
|
|
35
|
-
* disabled: true,
|
|
36
|
-
* });
|
|
37
|
-
* ```
|
|
38
|
-
*
|
|
39
|
-
* @example Button with HTMX
|
|
40
|
-
* ```typescript
|
|
41
|
-
* const htmxBtn = button('Load More', {
|
|
42
|
-
* htmx: {
|
|
43
|
-
* get: '/api/items?page=2',
|
|
44
|
-
* target: '#items-list',
|
|
45
|
-
* swap: 'beforeend',
|
|
46
|
-
* },
|
|
47
|
-
* });
|
|
48
|
-
* ```
|
|
49
|
-
*
|
|
50
|
-
* @example Button group
|
|
51
|
-
* ```typescript
|
|
52
|
-
* import { button, buttonGroup } from '@frontmcp/ui';
|
|
53
|
-
*
|
|
54
|
-
* const group = buttonGroup([
|
|
55
|
-
* button('Edit', { variant: 'outline' }),
|
|
56
|
-
* button('Delete', { variant: 'danger' }),
|
|
57
|
-
* ], { attached: true });
|
|
58
|
-
* ```
|
|
59
|
-
*
|
|
60
|
-
* @module @frontmcp/ui/components/button
|
|
61
|
-
*/
|
|
62
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
63
|
-
exports.linkButton = exports.dangerButton = exports.ghostButton = exports.outlineButton = exports.secondaryButton = exports.primaryButton = void 0;
|
|
64
|
-
exports.button = button;
|
|
65
|
-
exports.buttonGroup = buttonGroup;
|
|
66
|
-
const base_1 = require("../layouts/base");
|
|
67
|
-
const validation_1 = require("../validation");
|
|
68
|
-
const button_schema_1 = require("./button.schema");
|
|
69
|
-
// ============================================
|
|
70
|
-
// Button Builder
|
|
71
|
-
// ============================================
|
|
72
|
-
/**
|
|
73
|
-
* Get variant CSS classes
|
|
74
|
-
*/
|
|
75
|
-
function getVariantClasses(variant) {
|
|
76
|
-
const variants = {
|
|
77
|
-
primary: 'bg-primary hover:bg-primary/90 text-white shadow-sm',
|
|
78
|
-
secondary: 'bg-secondary hover:bg-secondary/90 text-white shadow-sm',
|
|
79
|
-
outline: 'border-2 border-primary text-primary hover:bg-primary/10',
|
|
80
|
-
ghost: 'text-text-primary hover:bg-gray-100',
|
|
81
|
-
danger: 'bg-danger hover:bg-danger/90 text-white shadow-sm',
|
|
82
|
-
success: 'bg-success hover:bg-success/90 text-white shadow-sm',
|
|
83
|
-
link: 'text-primary hover:text-primary/80 hover:underline',
|
|
84
|
-
};
|
|
85
|
-
return variants[variant];
|
|
86
|
-
}
|
|
87
|
-
/**
|
|
88
|
-
* Get size CSS classes
|
|
89
|
-
*/
|
|
90
|
-
function getSizeClasses(size, iconOnly) {
|
|
91
|
-
if (iconOnly) {
|
|
92
|
-
const iconSizes = {
|
|
93
|
-
xs: 'p-1.5',
|
|
94
|
-
sm: 'p-2',
|
|
95
|
-
md: 'p-2.5',
|
|
96
|
-
lg: 'p-3',
|
|
97
|
-
xl: 'p-4',
|
|
98
|
-
};
|
|
99
|
-
return iconSizes[size];
|
|
100
|
-
}
|
|
101
|
-
const sizes = {
|
|
102
|
-
xs: 'px-2.5 py-1.5 text-xs',
|
|
103
|
-
sm: 'px-3 py-2 text-sm',
|
|
104
|
-
md: 'px-4 py-2.5 text-sm',
|
|
105
|
-
lg: 'px-5 py-3 text-base',
|
|
106
|
-
xl: 'px-6 py-3.5 text-lg',
|
|
107
|
-
};
|
|
108
|
-
return sizes[size];
|
|
109
|
-
}
|
|
110
|
-
/**
|
|
111
|
-
* Sanitize a data-* attribute key to prevent malformed attributes / injection
|
|
112
|
-
* Returns null if the key is invalid after sanitization
|
|
113
|
-
*/
|
|
114
|
-
function sanitizeDataKey(key) {
|
|
115
|
-
// Only allow lowercase letters, numbers, underscores, and hyphens
|
|
116
|
-
const sanitized = key
|
|
117
|
-
.toLowerCase()
|
|
118
|
-
.replace(/[^a-z0-9_-]/g, '-')
|
|
119
|
-
.replace(/-+/g, '-')
|
|
120
|
-
.replace(/^-|-$/g, '');
|
|
121
|
-
if (!sanitized) {
|
|
122
|
-
console.warn(`[frontmcp/ui] Dropping invalid data-* key: "${key}"`);
|
|
123
|
-
return null;
|
|
124
|
-
}
|
|
125
|
-
return sanitized;
|
|
126
|
-
}
|
|
127
|
-
/**
|
|
128
|
-
* Build HTMX attributes string
|
|
129
|
-
*/
|
|
130
|
-
function buildHtmxAttrs(htmx) {
|
|
131
|
-
if (!htmx)
|
|
132
|
-
return '';
|
|
133
|
-
const attrs = [];
|
|
134
|
-
if (htmx.get)
|
|
135
|
-
attrs.push(`hx-get="${(0, base_1.escapeHtml)(htmx.get)}"`);
|
|
136
|
-
if (htmx.post)
|
|
137
|
-
attrs.push(`hx-post="${(0, base_1.escapeHtml)(htmx.post)}"`);
|
|
138
|
-
if (htmx.put)
|
|
139
|
-
attrs.push(`hx-put="${(0, base_1.escapeHtml)(htmx.put)}"`);
|
|
140
|
-
if (htmx.delete)
|
|
141
|
-
attrs.push(`hx-delete="${(0, base_1.escapeHtml)(htmx.delete)}"`);
|
|
142
|
-
if (htmx.target)
|
|
143
|
-
attrs.push(`hx-target="${(0, base_1.escapeHtml)(htmx.target)}"`);
|
|
144
|
-
if (htmx.swap)
|
|
145
|
-
attrs.push(`hx-swap="${(0, base_1.escapeHtml)(htmx.swap)}"`);
|
|
146
|
-
if (htmx.trigger)
|
|
147
|
-
attrs.push(`hx-trigger="${(0, base_1.escapeHtml)(htmx.trigger)}"`);
|
|
148
|
-
if (htmx.confirm)
|
|
149
|
-
attrs.push(`hx-confirm="${(0, base_1.escapeHtml)(htmx.confirm)}"`);
|
|
150
|
-
if (htmx.indicator)
|
|
151
|
-
attrs.push(`hx-indicator="${(0, base_1.escapeHtml)(htmx.indicator)}"`);
|
|
152
|
-
return attrs.join(' ');
|
|
153
|
-
}
|
|
154
|
-
/**
|
|
155
|
-
* Loading spinner SVG
|
|
156
|
-
*/
|
|
157
|
-
const loadingSpinner = `<svg class="animate-spin -ml-1 mr-2 h-4 w-4" fill="none" viewBox="0 0 24 24">
|
|
158
|
-
<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
|
|
159
|
-
<path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
|
|
160
|
-
</svg>`;
|
|
161
|
-
/**
|
|
162
|
-
* Validate href protocol to prevent javascript: and other dangerous protocols
|
|
163
|
-
*/
|
|
164
|
-
function isValidHrefProtocol(href) {
|
|
165
|
-
const trimmed = href.trim().toLowerCase();
|
|
166
|
-
// Allow only safe protocols (allowlist approach is more secure than blocklist)
|
|
167
|
-
return (trimmed.startsWith('http://') ||
|
|
168
|
-
trimmed.startsWith('https://') ||
|
|
169
|
-
trimmed.startsWith('/') ||
|
|
170
|
-
trimmed.startsWith('#') ||
|
|
171
|
-
trimmed.startsWith('mailto:') ||
|
|
172
|
-
trimmed.startsWith('tel:'));
|
|
173
|
-
}
|
|
174
|
-
/**
|
|
175
|
-
* Build a button component
|
|
176
|
-
*
|
|
177
|
-
* @param text - Button label text (used as aria-label for icon-only buttons)
|
|
178
|
-
* @param options - Button configuration options
|
|
179
|
-
* @returns HTML string for the button, or validation error box on invalid input
|
|
180
|
-
*
|
|
181
|
-
* @remarks
|
|
182
|
-
* **Security considerations:**
|
|
183
|
-
* - The `iconBefore` and `iconAfter` options accept raw HTML strings for SVG icons.
|
|
184
|
-
* These are NOT escaped and should only contain trusted content (e.g., icon library output).
|
|
185
|
-
* Never pass user-provided content to these options.
|
|
186
|
-
* - The `href` option uses an allowlist for safe protocols. Only the following are allowed:
|
|
187
|
-
* - `http://`, `https://` - absolute URLs
|
|
188
|
-
* - `/` - absolute paths (e.g., "/login", "/api/users")
|
|
189
|
-
* - `#` - anchor links (e.g., "#section")
|
|
190
|
-
* - `mailto:` - email links
|
|
191
|
-
* - `tel:` - phone links
|
|
192
|
-
* Note: Bare relative URLs like "login" or "./foo" are NOT allowed and will fall back to
|
|
193
|
-
* button behavior. Use absolute paths ("/login") instead.
|
|
194
|
-
* - The `data` option keys are sanitized to prevent malformed attributes.
|
|
195
|
-
*
|
|
196
|
-
* **Accessibility:**
|
|
197
|
-
* - When `iconOnly: true`, the `text` parameter is automatically used as `aria-label`
|
|
198
|
-
* unless an explicit `ariaLabel` option is provided.
|
|
199
|
-
* - Empty button text with `iconOnly: false` will log a warning for accessibility.
|
|
200
|
-
* - Icon-only buttons without text or ariaLabel will log a warning.
|
|
201
|
-
*/
|
|
202
|
-
function button(text, options = {}) {
|
|
203
|
-
// Validate options using Zod schema
|
|
204
|
-
const validation = (0, validation_1.validateOptions)(options, {
|
|
205
|
-
schema: button_schema_1.ButtonOptionsSchema,
|
|
206
|
-
componentName: 'button',
|
|
207
|
-
});
|
|
208
|
-
if (!validation.success) {
|
|
209
|
-
return validation.error;
|
|
210
|
-
}
|
|
211
|
-
const validatedOptions = validation.data;
|
|
212
|
-
const { variant = 'primary', size = 'md', type = 'button', disabled = false, loading = false, fullWidth = false, iconBefore, iconAfter, iconOnly = false, className = '', id, name, value, href, target, htmx, data, ariaLabel, } = validatedOptions;
|
|
213
|
-
// Warn about empty button text (accessibility concern)
|
|
214
|
-
if (!iconOnly && !text.trim()) {
|
|
215
|
-
console.warn('[frontmcp/ui] Button has empty text. Consider providing text or using iconOnly with ariaLabel.');
|
|
216
|
-
}
|
|
217
|
-
// Warn about icon-only buttons without accessible label
|
|
218
|
-
if (iconOnly && !ariaLabel && !text.trim()) {
|
|
219
|
-
console.warn('[frontmcp/ui] iconOnly button requires non-empty text or ariaLabel for accessibility; control will have no label.');
|
|
220
|
-
}
|
|
221
|
-
// Validate href protocol
|
|
222
|
-
if (href && !isValidHrefProtocol(href)) {
|
|
223
|
-
console.warn(`[frontmcp/ui] Button href contains potentially dangerous protocol: "${href.slice(0, 20)}..."`);
|
|
224
|
-
// Don't render the href - fall back to button behavior
|
|
225
|
-
}
|
|
226
|
-
const variantClasses = getVariantClasses(variant);
|
|
227
|
-
const sizeClasses = getSizeClasses(size, iconOnly);
|
|
228
|
-
// Escape className to prevent XSS via attribute injection (e.g., `btn" onclick="...`)
|
|
229
|
-
const safeClassName = className ? (0, base_1.escapeHtml)(className) : '';
|
|
230
|
-
const baseClasses = [
|
|
231
|
-
'inline-flex items-center justify-center',
|
|
232
|
-
'font-medium',
|
|
233
|
-
'rounded-lg',
|
|
234
|
-
'transition-colors duration-200',
|
|
235
|
-
'focus:outline-none focus:ring-2 focus:ring-primary/50 focus:ring-offset-2',
|
|
236
|
-
disabled || loading ? 'opacity-50 cursor-not-allowed' : 'cursor-pointer',
|
|
237
|
-
fullWidth ? 'w-full' : '',
|
|
238
|
-
variantClasses,
|
|
239
|
-
sizeClasses,
|
|
240
|
-
safeClassName,
|
|
241
|
-
]
|
|
242
|
-
.filter(Boolean)
|
|
243
|
-
.join(' ');
|
|
244
|
-
const htmxAttrs = buildHtmxAttrs(htmx);
|
|
245
|
-
const dataAttrs = data
|
|
246
|
-
? Object.entries(data)
|
|
247
|
-
.map(([key, val]) => {
|
|
248
|
-
const safeKey = sanitizeDataKey(key);
|
|
249
|
-
return safeKey ? `data-${safeKey}="${(0, base_1.escapeHtml)(val)}"` : '';
|
|
250
|
-
})
|
|
251
|
-
.filter(Boolean)
|
|
252
|
-
.join(' ')
|
|
253
|
-
: '';
|
|
254
|
-
const idAttr = id ? `id="${(0, base_1.escapeHtml)(id)}"` : '';
|
|
255
|
-
const nameAttr = name ? `name="${(0, base_1.escapeHtml)(name)}"` : '';
|
|
256
|
-
const valueAttr = value ? `value="${(0, base_1.escapeHtml)(value)}"` : '';
|
|
257
|
-
const disabledAttr = disabled || loading ? 'disabled' : '';
|
|
258
|
-
const targetAttr = target ? `target="${(0, base_1.escapeHtml)(target)}"` : '';
|
|
259
|
-
// Add rel="noopener noreferrer" for target="_blank" to prevent window.opener access
|
|
260
|
-
const relAttr = target === '_blank' ? 'rel="noopener noreferrer"' : '';
|
|
261
|
-
// For icon-only buttons, use text as aria-label if no explicit ariaLabel provided (WCAG)
|
|
262
|
-
const trimmedText = text.trim();
|
|
263
|
-
const effectiveAriaLabel = ariaLabel ?? (iconOnly && trimmedText ? trimmedText : undefined);
|
|
264
|
-
const ariaLabelAttr = effectiveAriaLabel ? `aria-label="${(0, base_1.escapeHtml)(effectiveAriaLabel)}"` : '';
|
|
265
|
-
// Build content (both icons hide during loading for consistent visual behavior)
|
|
266
|
-
const iconBeforeHtml = iconBefore && !loading ? `<span class="${iconOnly ? '' : 'mr-2'}">${iconBefore}</span>` : '';
|
|
267
|
-
const iconAfterHtml = iconAfter && !loading ? `<span class="${iconOnly ? '' : 'ml-2'}">${iconAfter}</span>` : '';
|
|
268
|
-
const loadingHtml = loading ? loadingSpinner : '';
|
|
269
|
-
const textHtml = iconOnly ? '' : (0, base_1.escapeHtml)(text);
|
|
270
|
-
const contentHtml = `${loadingHtml}${iconBeforeHtml}${textHtml}${iconAfterHtml}`;
|
|
271
|
-
// Use anchor tag if href provided and protocol is safe
|
|
272
|
-
if (href && !disabled && !loading && isValidHrefProtocol(href)) {
|
|
273
|
-
return `<a href="${(0, base_1.escapeHtml)(href)}" class="${baseClasses}" ${idAttr} ${htmxAttrs} ${dataAttrs} ${ariaLabelAttr} ${targetAttr} ${relAttr}>
|
|
274
|
-
${contentHtml}
|
|
275
|
-
</a>`;
|
|
276
|
-
}
|
|
277
|
-
return `<button type="${type}" class="${baseClasses}" ${idAttr} ${nameAttr} ${valueAttr} ${disabledAttr} ${htmxAttrs} ${dataAttrs} ${ariaLabelAttr}>
|
|
278
|
-
${contentHtml}
|
|
279
|
-
</button>`;
|
|
280
|
-
}
|
|
281
|
-
/**
|
|
282
|
-
* Build a button group
|
|
283
|
-
*
|
|
284
|
-
* @param buttons - Array of button HTML strings
|
|
285
|
-
* @param options - Button group configuration options
|
|
286
|
-
* @returns HTML string for the button group, or validation error box on invalid input
|
|
287
|
-
*/
|
|
288
|
-
function buttonGroup(buttons, options = {}) {
|
|
289
|
-
if (buttons.length === 0) {
|
|
290
|
-
console.warn('[frontmcp/ui] buttonGroup called with empty buttons array');
|
|
291
|
-
return '';
|
|
292
|
-
}
|
|
293
|
-
// Validate options using Zod schema
|
|
294
|
-
const validation = (0, validation_1.validateOptions)(options, {
|
|
295
|
-
schema: button_schema_1.ButtonGroupOptionsSchema,
|
|
296
|
-
componentName: 'buttonGroup',
|
|
297
|
-
});
|
|
298
|
-
if (!validation.success) {
|
|
299
|
-
return validation.error;
|
|
300
|
-
}
|
|
301
|
-
const validatedOptions = validation.data;
|
|
302
|
-
const { attached = false, direction = 'horizontal', gap = 'md', className = '' } = validatedOptions;
|
|
303
|
-
// Escape className to prevent XSS via attribute injection
|
|
304
|
-
const safeClassName = className ? (0, base_1.escapeHtml)(className) : '';
|
|
305
|
-
if (attached) {
|
|
306
|
-
const classes = direction === 'horizontal'
|
|
307
|
-
? 'inline-flex rounded-lg shadow-sm [&>*:first-child]:rounded-r-none [&>*:last-child]:rounded-l-none [&>*:not(:first-child):not(:last-child)]:rounded-none [&>*:not(:first-child)]:-ml-px'
|
|
308
|
-
: 'inline-flex flex-col rounded-lg shadow-sm [&>*:first-child]:rounded-b-none [&>*:last-child]:rounded-t-none [&>*:not(:first-child):not(:last-child)]:rounded-none [&>*:not(:first-child)]:-mt-px';
|
|
309
|
-
return `<div class="${classes} ${safeClassName}">${buttons.join('')}</div>`;
|
|
310
|
-
}
|
|
311
|
-
const gapClasses = { sm: 'gap-2', md: 'gap-3', lg: 'gap-4' };
|
|
312
|
-
const directionClasses = direction === 'horizontal' ? 'flex flex-row' : 'flex flex-col';
|
|
313
|
-
return `<div class="${directionClasses} ${gapClasses[gap]} ${safeClassName}">${buttons.join('')}</div>`;
|
|
314
|
-
}
|
|
315
|
-
// ============================================
|
|
316
|
-
// Convenience Functions
|
|
317
|
-
// ============================================
|
|
318
|
-
/** Primary button shorthand */
|
|
319
|
-
const primaryButton = (text, opts) => button(text, { ...opts, variant: 'primary' });
|
|
320
|
-
exports.primaryButton = primaryButton;
|
|
321
|
-
/** Secondary button shorthand */
|
|
322
|
-
const secondaryButton = (text, opts) => button(text, { ...opts, variant: 'secondary' });
|
|
323
|
-
exports.secondaryButton = secondaryButton;
|
|
324
|
-
/** Outline button shorthand */
|
|
325
|
-
const outlineButton = (text, opts) => button(text, { ...opts, variant: 'outline' });
|
|
326
|
-
exports.outlineButton = outlineButton;
|
|
327
|
-
/** Ghost button shorthand */
|
|
328
|
-
const ghostButton = (text, opts) => button(text, { ...opts, variant: 'ghost' });
|
|
329
|
-
exports.ghostButton = ghostButton;
|
|
330
|
-
/** Danger button shorthand */
|
|
331
|
-
const dangerButton = (text, opts) => button(text, { ...opts, variant: 'danger' });
|
|
332
|
-
exports.dangerButton = dangerButton;
|
|
333
|
-
/** Link button shorthand */
|
|
334
|
-
const linkButton = (text, opts) => button(text, { ...opts, variant: 'link' });
|
|
335
|
-
exports.linkButton = linkButton;
|
|
336
|
-
//# sourceMappingURL=button.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"button.js","sourceRoot":"","sources":["../../../src/components/button.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @file button.ts\n * @description Button Component for FrontMCP UI.\n *\n * Versatile button component with multiple variants, sizes, and states.\n * Includes HTMX support for dynamic interactions without JavaScript.\n *\n * @example Basic button\n * ```typescript\n * import { button } from '@frontmcp/ui';\n *\n * // Primary button (default)\n * const html = button('Click Me');\n * // <button type=\"button\" class=\"...bg-primary...\">Click Me</button>\n * ```\n *\n * @example Button variants\n * ```typescript\n * import { button, primaryButton, dangerButton, outlineButton } from '@frontmcp/ui';\n *\n * // Using variant option\n * const secondary = button('Save', { variant: 'secondary' });\n * const danger = button('Delete', { variant: 'danger' });\n *\n * // Using shorthand functions\n * const primary = primaryButton('Submit');\n * const outline = outlineButton('Cancel');\n * ```\n *\n * @example Button with loading state\n * ```typescript\n * const loadingBtn = button('Saving...', {\n * loading: true,\n * disabled: true,\n * });\n * ```\n *\n * @example Button with HTMX\n * ```typescript\n * const htmxBtn = button('Load More', {\n * htmx: {\n * get: '/api/items?page=2',\n * target: '#items-list',\n * swap: 'beforeend',\n * },\n * });\n * ```\n *\n * @example Button group\n * ```typescript\n * import { button, buttonGroup } from '@frontmcp/ui';\n *\n * const group = buttonGroup([\n * button('Edit', { variant: 'outline' }),\n * button('Delete', { variant: 'danger' }),\n * ], { attached: true });\n * ```\n *\n * @module @frontmcp/ui/components/button\n */\n\nimport { escapeHtml } from '../layouts/base';\nimport { validateOptions } from '../validation';\nimport {\n ButtonOptionsSchema,\n ButtonGroupOptionsSchema,\n type ButtonOptions,\n type ButtonVariant,\n type ButtonSize,\n type ButtonGroupOptions,\n} from './button.schema';\n\n// Re-export types from schema\nexport type { ButtonOptions, ButtonVariant, ButtonSize, ButtonGroupOptions };\n\n// ============================================\n// Button Builder\n// ============================================\n\n/**\n * Get variant CSS classes\n */\nfunction getVariantClasses(variant: ButtonVariant): string {\n const variants: Record<ButtonVariant, string> = {\n primary: 'bg-primary hover:bg-primary/90 text-white shadow-sm',\n secondary: 'bg-secondary hover:bg-secondary/90 text-white shadow-sm',\n outline: 'border-2 border-primary text-primary hover:bg-primary/10',\n ghost: 'text-text-primary hover:bg-gray-100',\n danger: 'bg-danger hover:bg-danger/90 text-white shadow-sm',\n success: 'bg-success hover:bg-success/90 text-white shadow-sm',\n link: 'text-primary hover:text-primary/80 hover:underline',\n };\n return variants[variant];\n}\n\n/**\n * Get size CSS classes\n */\nfunction getSizeClasses(size: ButtonSize, iconOnly: boolean): string {\n if (iconOnly) {\n const iconSizes: Record<ButtonSize, string> = {\n xs: 'p-1.5',\n sm: 'p-2',\n md: 'p-2.5',\n lg: 'p-3',\n xl: 'p-4',\n };\n return iconSizes[size];\n }\n\n const sizes: Record<ButtonSize, string> = {\n xs: 'px-2.5 py-1.5 text-xs',\n sm: 'px-3 py-2 text-sm',\n md: 'px-4 py-2.5 text-sm',\n lg: 'px-5 py-3 text-base',\n xl: 'px-6 py-3.5 text-lg',\n };\n return sizes[size];\n}\n\n/**\n * Sanitize a data-* attribute key to prevent malformed attributes / injection\n * Returns null if the key is invalid after sanitization\n */\nfunction sanitizeDataKey(key: string): string | null {\n // Only allow lowercase letters, numbers, underscores, and hyphens\n const sanitized = key\n .toLowerCase()\n .replace(/[^a-z0-9_-]/g, '-')\n .replace(/-+/g, '-')\n .replace(/^-|-$/g, '');\n if (!sanitized) {\n console.warn(`[frontmcp/ui] Dropping invalid data-* key: \"${key}\"`);\n return null;\n }\n return sanitized;\n}\n\n/**\n * Build HTMX attributes string\n */\nfunction buildHtmxAttrs(htmx?: ButtonOptions['htmx']): string {\n if (!htmx) return '';\n const attrs: string[] = [];\n if (htmx.get) attrs.push(`hx-get=\"${escapeHtml(htmx.get)}\"`);\n if (htmx.post) attrs.push(`hx-post=\"${escapeHtml(htmx.post)}\"`);\n if (htmx.put) attrs.push(`hx-put=\"${escapeHtml(htmx.put)}\"`);\n if (htmx.delete) attrs.push(`hx-delete=\"${escapeHtml(htmx.delete)}\"`);\n if (htmx.target) attrs.push(`hx-target=\"${escapeHtml(htmx.target)}\"`);\n if (htmx.swap) attrs.push(`hx-swap=\"${escapeHtml(htmx.swap)}\"`);\n if (htmx.trigger) attrs.push(`hx-trigger=\"${escapeHtml(htmx.trigger)}\"`);\n if (htmx.confirm) attrs.push(`hx-confirm=\"${escapeHtml(htmx.confirm)}\"`);\n if (htmx.indicator) attrs.push(`hx-indicator=\"${escapeHtml(htmx.indicator)}\"`);\n return attrs.join(' ');\n}\n\n/**\n * Loading spinner SVG\n */\nconst loadingSpinner = `<svg class=\"animate-spin -ml-1 mr-2 h-4 w-4\" fill=\"none\" viewBox=\"0 0 24 24\">\n <circle class=\"opacity-25\" cx=\"12\" cy=\"12\" r=\"10\" stroke=\"currentColor\" stroke-width=\"4\"></circle>\n <path class=\"opacity-75\" fill=\"currentColor\" d=\"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z\"></path>\n</svg>`;\n\n/**\n * Validate href protocol to prevent javascript: and other dangerous protocols\n */\nfunction isValidHrefProtocol(href: string): boolean {\n const trimmed = href.trim().toLowerCase();\n // Allow only safe protocols (allowlist approach is more secure than blocklist)\n return (\n trimmed.startsWith('http://') ||\n trimmed.startsWith('https://') ||\n trimmed.startsWith('/') ||\n trimmed.startsWith('#') ||\n trimmed.startsWith('mailto:') ||\n trimmed.startsWith('tel:')\n );\n}\n\n/**\n * Build a button component\n *\n * @param text - Button label text (used as aria-label for icon-only buttons)\n * @param options - Button configuration options\n * @returns HTML string for the button, or validation error box on invalid input\n *\n * @remarks\n * **Security considerations:**\n * - The `iconBefore` and `iconAfter` options accept raw HTML strings for SVG icons.\n * These are NOT escaped and should only contain trusted content (e.g., icon library output).\n * Never pass user-provided content to these options.\n * - The `href` option uses an allowlist for safe protocols. Only the following are allowed:\n * - `http://`, `https://` - absolute URLs\n * - `/` - absolute paths (e.g., \"/login\", \"/api/users\")\n * - `#` - anchor links (e.g., \"#section\")\n * - `mailto:` - email links\n * - `tel:` - phone links\n * Note: Bare relative URLs like \"login\" or \"./foo\" are NOT allowed and will fall back to\n * button behavior. Use absolute paths (\"/login\") instead.\n * - The `data` option keys are sanitized to prevent malformed attributes.\n *\n * **Accessibility:**\n * - When `iconOnly: true`, the `text` parameter is automatically used as `aria-label`\n * unless an explicit `ariaLabel` option is provided.\n * - Empty button text with `iconOnly: false` will log a warning for accessibility.\n * - Icon-only buttons without text or ariaLabel will log a warning.\n */\nexport function button(text: string, options: ButtonOptions = {}): string {\n // Validate options using Zod schema\n const validation = validateOptions<ButtonOptions>(options, {\n schema: ButtonOptionsSchema,\n componentName: 'button',\n });\n\n if (!validation.success) {\n return validation.error;\n }\n\n const validatedOptions = validation.data;\n const {\n variant = 'primary',\n size = 'md',\n type = 'button',\n disabled = false,\n loading = false,\n fullWidth = false,\n iconBefore,\n iconAfter,\n iconOnly = false,\n className = '',\n id,\n name,\n value,\n href,\n target,\n htmx,\n data,\n ariaLabel,\n } = validatedOptions;\n\n // Warn about empty button text (accessibility concern)\n if (!iconOnly && !text.trim()) {\n console.warn('[frontmcp/ui] Button has empty text. Consider providing text or using iconOnly with ariaLabel.');\n }\n\n // Warn about icon-only buttons without accessible label\n if (iconOnly && !ariaLabel && !text.trim()) {\n console.warn(\n '[frontmcp/ui] iconOnly button requires non-empty text or ariaLabel for accessibility; control will have no label.',\n );\n }\n\n // Validate href protocol\n if (href && !isValidHrefProtocol(href)) {\n console.warn(`[frontmcp/ui] Button href contains potentially dangerous protocol: \"${href.slice(0, 20)}...\"`);\n // Don't render the href - fall back to button behavior\n }\n\n const variantClasses = getVariantClasses(variant);\n const sizeClasses = getSizeClasses(size, iconOnly);\n\n // Escape className to prevent XSS via attribute injection (e.g., `btn\" onclick=\"...`)\n const safeClassName = className ? escapeHtml(className) : '';\n\n const baseClasses = [\n 'inline-flex items-center justify-center',\n 'font-medium',\n 'rounded-lg',\n 'transition-colors duration-200',\n 'focus:outline-none focus:ring-2 focus:ring-primary/50 focus:ring-offset-2',\n disabled || loading ? 'opacity-50 cursor-not-allowed' : 'cursor-pointer',\n fullWidth ? 'w-full' : '',\n variantClasses,\n sizeClasses,\n safeClassName,\n ]\n .filter(Boolean)\n .join(' ');\n\n const htmxAttrs = buildHtmxAttrs(htmx);\n const dataAttrs = data\n ? Object.entries(data)\n .map(([key, val]) => {\n const safeKey = sanitizeDataKey(key);\n return safeKey ? `data-${safeKey}=\"${escapeHtml(val)}\"` : '';\n })\n .filter(Boolean)\n .join(' ')\n : '';\n\n const idAttr = id ? `id=\"${escapeHtml(id)}\"` : '';\n const nameAttr = name ? `name=\"${escapeHtml(name)}\"` : '';\n const valueAttr = value ? `value=\"${escapeHtml(value)}\"` : '';\n const disabledAttr = disabled || loading ? 'disabled' : '';\n const targetAttr = target ? `target=\"${escapeHtml(target)}\"` : '';\n // Add rel=\"noopener noreferrer\" for target=\"_blank\" to prevent window.opener access\n const relAttr = target === '_blank' ? 'rel=\"noopener noreferrer\"' : '';\n\n // For icon-only buttons, use text as aria-label if no explicit ariaLabel provided (WCAG)\n const trimmedText = text.trim();\n const effectiveAriaLabel = ariaLabel ?? (iconOnly && trimmedText ? trimmedText : undefined);\n const ariaLabelAttr = effectiveAriaLabel ? `aria-label=\"${escapeHtml(effectiveAriaLabel)}\"` : '';\n\n // Build content (both icons hide during loading for consistent visual behavior)\n const iconBeforeHtml = iconBefore && !loading ? `<span class=\"${iconOnly ? '' : 'mr-2'}\">${iconBefore}</span>` : '';\n const iconAfterHtml = iconAfter && !loading ? `<span class=\"${iconOnly ? '' : 'ml-2'}\">${iconAfter}</span>` : '';\n const loadingHtml = loading ? loadingSpinner : '';\n const textHtml = iconOnly ? '' : escapeHtml(text);\n\n const contentHtml = `${loadingHtml}${iconBeforeHtml}${textHtml}${iconAfterHtml}`;\n\n // Use anchor tag if href provided and protocol is safe\n if (href && !disabled && !loading && isValidHrefProtocol(href)) {\n return `<a href=\"${escapeHtml(\n href,\n )}\" class=\"${baseClasses}\" ${idAttr} ${htmxAttrs} ${dataAttrs} ${ariaLabelAttr} ${targetAttr} ${relAttr}>\n ${contentHtml}\n </a>`;\n }\n\n return `<button type=\"${type}\" class=\"${baseClasses}\" ${idAttr} ${nameAttr} ${valueAttr} ${disabledAttr} ${htmxAttrs} ${dataAttrs} ${ariaLabelAttr}>\n ${contentHtml}\n </button>`;\n}\n\n/**\n * Build a button group\n *\n * @param buttons - Array of button HTML strings\n * @param options - Button group configuration options\n * @returns HTML string for the button group, or validation error box on invalid input\n */\nexport function buttonGroup(buttons: string[], options: ButtonGroupOptions = {}): string {\n if (buttons.length === 0) {\n console.warn('[frontmcp/ui] buttonGroup called with empty buttons array');\n return '';\n }\n\n // Validate options using Zod schema\n const validation = validateOptions<ButtonGroupOptions>(options, {\n schema: ButtonGroupOptionsSchema,\n componentName: 'buttonGroup',\n });\n\n if (!validation.success) {\n return validation.error;\n }\n\n const validatedOptions = validation.data;\n const { attached = false, direction = 'horizontal', gap = 'md', className = '' } = validatedOptions;\n\n // Escape className to prevent XSS via attribute injection\n const safeClassName = className ? escapeHtml(className) : '';\n\n if (attached) {\n const classes =\n direction === 'horizontal'\n ? 'inline-flex rounded-lg shadow-sm [&>*:first-child]:rounded-r-none [&>*:last-child]:rounded-l-none [&>*:not(:first-child):not(:last-child)]:rounded-none [&>*:not(:first-child)]:-ml-px'\n : 'inline-flex flex-col rounded-lg shadow-sm [&>*:first-child]:rounded-b-none [&>*:last-child]:rounded-t-none [&>*:not(:first-child):not(:last-child)]:rounded-none [&>*:not(:first-child)]:-mt-px';\n return `<div class=\"${classes} ${safeClassName}\">${buttons.join('')}</div>`;\n }\n\n const gapClasses = { sm: 'gap-2', md: 'gap-3', lg: 'gap-4' };\n const directionClasses = direction === 'horizontal' ? 'flex flex-row' : 'flex flex-col';\n\n return `<div class=\"${directionClasses} ${gapClasses[gap]} ${safeClassName}\">${buttons.join('')}</div>`;\n}\n\n// ============================================\n// Convenience Functions\n// ============================================\n\n/** Primary button shorthand */\nexport const primaryButton = (text: string, opts?: Omit<ButtonOptions, 'variant'>) =>\n button(text, { ...opts, variant: 'primary' });\n\n/** Secondary button shorthand */\nexport const secondaryButton = (text: string, opts?: Omit<ButtonOptions, 'variant'>) =>\n button(text, { ...opts, variant: 'secondary' });\n\n/** Outline button shorthand */\nexport const outlineButton = (text: string, opts?: Omit<ButtonOptions, 'variant'>) =>\n button(text, { ...opts, variant: 'outline' });\n\n/** Ghost button shorthand */\nexport const ghostButton = (text: string, opts?: Omit<ButtonOptions, 'variant'>) =>\n button(text, { ...opts, variant: 'ghost' });\n\n/** Danger button shorthand */\nexport const dangerButton = (text: string, opts?: Omit<ButtonOptions, 'variant'>) =>\n button(text, { ...opts, variant: 'danger' });\n\n/** Link button shorthand */\nexport const linkButton = (text: string, opts?: Omit<ButtonOptions, 'variant'>) =>\n button(text, { ...opts, variant: 'link' });\n"]}
|
|
@@ -1,148 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @file button.schema.ts
|
|
3
|
-
* @description Zod schemas for Button component options validation.
|
|
4
|
-
*
|
|
5
|
-
* Provides strict validation schemas for button options including variants,
|
|
6
|
-
* sizes, HTMX attributes, and data attributes. All schemas use .strict()
|
|
7
|
-
* to reject unknown properties.
|
|
8
|
-
*
|
|
9
|
-
* @example
|
|
10
|
-
* ```typescript
|
|
11
|
-
* import { ButtonOptionsSchema } from '@frontmcp/ui';
|
|
12
|
-
*
|
|
13
|
-
* // Validate button options
|
|
14
|
-
* const result = ButtonOptionsSchema.safeParse({ variant: 'primary' });
|
|
15
|
-
* if (result.success) {
|
|
16
|
-
* // Use result.data
|
|
17
|
-
* }
|
|
18
|
-
* ```
|
|
19
|
-
*
|
|
20
|
-
* @module @frontmcp/ui/components/button.schema
|
|
21
|
-
*/
|
|
22
|
-
import { z } from 'zod';
|
|
23
|
-
/**
|
|
24
|
-
* Button variant enum schema
|
|
25
|
-
*/
|
|
26
|
-
export declare const ButtonVariantSchema: z.ZodEnum<{
|
|
27
|
-
primary: "primary";
|
|
28
|
-
secondary: "secondary";
|
|
29
|
-
link: "link";
|
|
30
|
-
success: "success";
|
|
31
|
-
danger: "danger";
|
|
32
|
-
outline: "outline";
|
|
33
|
-
ghost: "ghost";
|
|
34
|
-
}>;
|
|
35
|
-
/**
|
|
36
|
-
* Button variant type
|
|
37
|
-
*/
|
|
38
|
-
export type ButtonVariant = z.infer<typeof ButtonVariantSchema>;
|
|
39
|
-
/**
|
|
40
|
-
* Button size enum schema
|
|
41
|
-
*/
|
|
42
|
-
export declare const ButtonSizeSchema: z.ZodEnum<{
|
|
43
|
-
xs: "xs";
|
|
44
|
-
sm: "sm";
|
|
45
|
-
lg: "lg";
|
|
46
|
-
xl: "xl";
|
|
47
|
-
md: "md";
|
|
48
|
-
}>;
|
|
49
|
-
/**
|
|
50
|
-
* Button size type
|
|
51
|
-
*/
|
|
52
|
-
export type ButtonSize = z.infer<typeof ButtonSizeSchema>;
|
|
53
|
-
/**
|
|
54
|
-
* HTMX attributes schema for button
|
|
55
|
-
*/
|
|
56
|
-
export declare const ButtonHtmxSchema: z.ZodOptional<z.ZodObject<{
|
|
57
|
-
get: z.ZodOptional<z.ZodString>;
|
|
58
|
-
post: z.ZodOptional<z.ZodString>;
|
|
59
|
-
put: z.ZodOptional<z.ZodString>;
|
|
60
|
-
delete: z.ZodOptional<z.ZodString>;
|
|
61
|
-
target: z.ZodOptional<z.ZodString>;
|
|
62
|
-
swap: z.ZodOptional<z.ZodString>;
|
|
63
|
-
trigger: z.ZodOptional<z.ZodString>;
|
|
64
|
-
confirm: z.ZodOptional<z.ZodString>;
|
|
65
|
-
indicator: z.ZodOptional<z.ZodString>;
|
|
66
|
-
}, z.core.$strict>>;
|
|
67
|
-
/**
|
|
68
|
-
* HTMX attributes type
|
|
69
|
-
*/
|
|
70
|
-
export type ButtonHtmx = z.infer<typeof ButtonHtmxSchema>;
|
|
71
|
-
/**
|
|
72
|
-
* Complete button options schema
|
|
73
|
-
*/
|
|
74
|
-
export declare const ButtonOptionsSchema: z.ZodObject<{
|
|
75
|
-
variant: z.ZodOptional<z.ZodEnum<{
|
|
76
|
-
primary: "primary";
|
|
77
|
-
secondary: "secondary";
|
|
78
|
-
link: "link";
|
|
79
|
-
success: "success";
|
|
80
|
-
danger: "danger";
|
|
81
|
-
outline: "outline";
|
|
82
|
-
ghost: "ghost";
|
|
83
|
-
}>>;
|
|
84
|
-
size: z.ZodOptional<z.ZodEnum<{
|
|
85
|
-
xs: "xs";
|
|
86
|
-
sm: "sm";
|
|
87
|
-
lg: "lg";
|
|
88
|
-
xl: "xl";
|
|
89
|
-
md: "md";
|
|
90
|
-
}>>;
|
|
91
|
-
type: z.ZodOptional<z.ZodEnum<{
|
|
92
|
-
button: "button";
|
|
93
|
-
submit: "submit";
|
|
94
|
-
reset: "reset";
|
|
95
|
-
}>>;
|
|
96
|
-
disabled: z.ZodOptional<z.ZodBoolean>;
|
|
97
|
-
loading: z.ZodOptional<z.ZodBoolean>;
|
|
98
|
-
fullWidth: z.ZodOptional<z.ZodBoolean>;
|
|
99
|
-
iconBefore: z.ZodOptional<z.ZodString>;
|
|
100
|
-
iconAfter: z.ZodOptional<z.ZodString>;
|
|
101
|
-
iconOnly: z.ZodOptional<z.ZodBoolean>;
|
|
102
|
-
className: z.ZodOptional<z.ZodString>;
|
|
103
|
-
id: z.ZodOptional<z.ZodString>;
|
|
104
|
-
name: z.ZodOptional<z.ZodString>;
|
|
105
|
-
value: z.ZodOptional<z.ZodString>;
|
|
106
|
-
href: z.ZodOptional<z.ZodString>;
|
|
107
|
-
target: z.ZodOptional<z.ZodEnum<{
|
|
108
|
-
_blank: "_blank";
|
|
109
|
-
_self: "_self";
|
|
110
|
-
}>>;
|
|
111
|
-
htmx: z.ZodOptional<z.ZodObject<{
|
|
112
|
-
get: z.ZodOptional<z.ZodString>;
|
|
113
|
-
post: z.ZodOptional<z.ZodString>;
|
|
114
|
-
put: z.ZodOptional<z.ZodString>;
|
|
115
|
-
delete: z.ZodOptional<z.ZodString>;
|
|
116
|
-
target: z.ZodOptional<z.ZodString>;
|
|
117
|
-
swap: z.ZodOptional<z.ZodString>;
|
|
118
|
-
trigger: z.ZodOptional<z.ZodString>;
|
|
119
|
-
confirm: z.ZodOptional<z.ZodString>;
|
|
120
|
-
indicator: z.ZodOptional<z.ZodString>;
|
|
121
|
-
}, z.core.$strict>>;
|
|
122
|
-
data: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
123
|
-
ariaLabel: z.ZodOptional<z.ZodString>;
|
|
124
|
-
}, z.core.$strict>;
|
|
125
|
-
/**
|
|
126
|
-
* Button options type (derived from schema)
|
|
127
|
-
*/
|
|
128
|
-
export type ButtonOptions = z.infer<typeof ButtonOptionsSchema>;
|
|
129
|
-
/**
|
|
130
|
-
* Button group options schema
|
|
131
|
-
*/
|
|
132
|
-
export declare const ButtonGroupOptionsSchema: z.ZodObject<{
|
|
133
|
-
attached: z.ZodOptional<z.ZodBoolean>;
|
|
134
|
-
direction: z.ZodOptional<z.ZodEnum<{
|
|
135
|
-
horizontal: "horizontal";
|
|
136
|
-
vertical: "vertical";
|
|
137
|
-
}>>;
|
|
138
|
-
gap: z.ZodOptional<z.ZodEnum<{
|
|
139
|
-
sm: "sm";
|
|
140
|
-
lg: "lg";
|
|
141
|
-
md: "md";
|
|
142
|
-
}>>;
|
|
143
|
-
className: z.ZodOptional<z.ZodString>;
|
|
144
|
-
}, z.core.$strict>;
|
|
145
|
-
/**
|
|
146
|
-
* Button group options type
|
|
147
|
-
*/
|
|
148
|
-
export type ButtonGroupOptions = z.infer<typeof ButtonGroupOptionsSchema>;
|
|
@@ -1,121 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* @file button.schema.ts
|
|
4
|
-
* @description Zod schemas for Button component options validation.
|
|
5
|
-
*
|
|
6
|
-
* Provides strict validation schemas for button options including variants,
|
|
7
|
-
* sizes, HTMX attributes, and data attributes. All schemas use .strict()
|
|
8
|
-
* to reject unknown properties.
|
|
9
|
-
*
|
|
10
|
-
* @example
|
|
11
|
-
* ```typescript
|
|
12
|
-
* import { ButtonOptionsSchema } from '@frontmcp/ui';
|
|
13
|
-
*
|
|
14
|
-
* // Validate button options
|
|
15
|
-
* const result = ButtonOptionsSchema.safeParse({ variant: 'primary' });
|
|
16
|
-
* if (result.success) {
|
|
17
|
-
* // Use result.data
|
|
18
|
-
* }
|
|
19
|
-
* ```
|
|
20
|
-
*
|
|
21
|
-
* @module @frontmcp/ui/components/button.schema
|
|
22
|
-
*/
|
|
23
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
24
|
-
exports.ButtonGroupOptionsSchema = exports.ButtonOptionsSchema = exports.ButtonHtmxSchema = exports.ButtonSizeSchema = exports.ButtonVariantSchema = void 0;
|
|
25
|
-
const zod_1 = require("zod");
|
|
26
|
-
// ============================================
|
|
27
|
-
// Variant and Size Schemas
|
|
28
|
-
// ============================================
|
|
29
|
-
/**
|
|
30
|
-
* Button variant enum schema
|
|
31
|
-
*/
|
|
32
|
-
exports.ButtonVariantSchema = zod_1.z.enum(['primary', 'secondary', 'outline', 'ghost', 'danger', 'success', 'link']);
|
|
33
|
-
/**
|
|
34
|
-
* Button size enum schema
|
|
35
|
-
*/
|
|
36
|
-
exports.ButtonSizeSchema = zod_1.z.enum(['xs', 'sm', 'md', 'lg', 'xl']);
|
|
37
|
-
// ============================================
|
|
38
|
-
// HTMX Schema
|
|
39
|
-
// ============================================
|
|
40
|
-
/**
|
|
41
|
-
* HTMX attributes schema for button
|
|
42
|
-
*/
|
|
43
|
-
exports.ButtonHtmxSchema = zod_1.z
|
|
44
|
-
.object({
|
|
45
|
-
get: zod_1.z.string().optional(),
|
|
46
|
-
post: zod_1.z.string().optional(),
|
|
47
|
-
put: zod_1.z.string().optional(),
|
|
48
|
-
delete: zod_1.z.string().optional(),
|
|
49
|
-
target: zod_1.z.string().optional(),
|
|
50
|
-
swap: zod_1.z.string().optional(),
|
|
51
|
-
trigger: zod_1.z.string().optional(),
|
|
52
|
-
confirm: zod_1.z.string().optional(),
|
|
53
|
-
indicator: zod_1.z.string().optional(),
|
|
54
|
-
})
|
|
55
|
-
.strict()
|
|
56
|
-
.optional();
|
|
57
|
-
// ============================================
|
|
58
|
-
// Button Options Schema
|
|
59
|
-
// ============================================
|
|
60
|
-
/**
|
|
61
|
-
* Complete button options schema
|
|
62
|
-
*/
|
|
63
|
-
exports.ButtonOptionsSchema = zod_1.z
|
|
64
|
-
.object({
|
|
65
|
-
/** Button variant */
|
|
66
|
-
variant: exports.ButtonVariantSchema.optional(),
|
|
67
|
-
/** Button size */
|
|
68
|
-
size: exports.ButtonSizeSchema.optional(),
|
|
69
|
-
/** Button type attribute */
|
|
70
|
-
type: zod_1.z.enum(['button', 'submit', 'reset']).optional(),
|
|
71
|
-
/** Disabled state */
|
|
72
|
-
disabled: zod_1.z.boolean().optional(),
|
|
73
|
-
/** Loading state */
|
|
74
|
-
loading: zod_1.z.boolean().optional(),
|
|
75
|
-
/** Full width */
|
|
76
|
-
fullWidth: zod_1.z.boolean().optional(),
|
|
77
|
-
/** Icon before text (HTML string) */
|
|
78
|
-
iconBefore: zod_1.z.string().optional(),
|
|
79
|
-
/** Icon after text (HTML string) */
|
|
80
|
-
iconAfter: zod_1.z.string().optional(),
|
|
81
|
-
/** Icon only (no text) */
|
|
82
|
-
iconOnly: zod_1.z.boolean().optional(),
|
|
83
|
-
/** Additional CSS classes */
|
|
84
|
-
className: zod_1.z.string().optional(),
|
|
85
|
-
/** Button ID */
|
|
86
|
-
id: zod_1.z.string().optional(),
|
|
87
|
-
/** Name attribute */
|
|
88
|
-
name: zod_1.z.string().optional(),
|
|
89
|
-
/** Value attribute */
|
|
90
|
-
value: zod_1.z.string().optional(),
|
|
91
|
-
/** Click handler (URL for links) */
|
|
92
|
-
href: zod_1.z.string().optional(),
|
|
93
|
-
/** Open in new tab */
|
|
94
|
-
target: zod_1.z.enum(['_blank', '_self']).optional(),
|
|
95
|
-
/** HTMX attributes */
|
|
96
|
-
htmx: exports.ButtonHtmxSchema,
|
|
97
|
-
/** Data attributes */
|
|
98
|
-
data: zod_1.z.record(zod_1.z.string(), zod_1.z.string()).optional(),
|
|
99
|
-
/** ARIA label */
|
|
100
|
-
ariaLabel: zod_1.z.string().optional(),
|
|
101
|
-
})
|
|
102
|
-
.strict();
|
|
103
|
-
// ============================================
|
|
104
|
-
// Button Group Schema
|
|
105
|
-
// ============================================
|
|
106
|
-
/**
|
|
107
|
-
* Button group options schema
|
|
108
|
-
*/
|
|
109
|
-
exports.ButtonGroupOptionsSchema = zod_1.z
|
|
110
|
-
.object({
|
|
111
|
-
/** Attach buttons visually */
|
|
112
|
-
attached: zod_1.z.boolean().optional(),
|
|
113
|
-
/** Direction */
|
|
114
|
-
direction: zod_1.z.enum(['horizontal', 'vertical']).optional(),
|
|
115
|
-
/** Gap between buttons */
|
|
116
|
-
gap: zod_1.z.enum(['sm', 'md', 'lg']).optional(),
|
|
117
|
-
/** Additional CSS classes */
|
|
118
|
-
className: zod_1.z.string().optional(),
|
|
119
|
-
})
|
|
120
|
-
.strict();
|
|
121
|
-
//# sourceMappingURL=button.schema.js.map
|