@keepui/ui 0.1.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.
Files changed (56) hide show
  1. package/README.md +267 -0
  2. package/capacitor/index.d.ts +6 -0
  3. package/capacitor/keepui-ui-capacitor.d.ts.map +1 -0
  4. package/capacitor/lib/providers/provide-keep-ui-capacitor.d.ts +22 -0
  5. package/capacitor/lib/providers/provide-keep-ui-capacitor.d.ts.map +1 -0
  6. package/capacitor/lib/services/capacitor-file.service.d.ts +23 -0
  7. package/capacitor/lib/services/capacitor-file.service.d.ts.map +1 -0
  8. package/capacitor/public-api.d.ts +3 -0
  9. package/capacitor/public-api.d.ts.map +1 -0
  10. package/fesm2022/keepui-ui-capacitor.mjs +79 -0
  11. package/fesm2022/keepui-ui-capacitor.mjs.map +1 -0
  12. package/fesm2022/keepui-ui.mjs +656 -0
  13. package/fesm2022/keepui-ui.mjs.map +1 -0
  14. package/index.d.ts +6 -0
  15. package/keepui-ui.d.ts.map +1 -0
  16. package/lib/components/button/button.component.d.ts +72 -0
  17. package/lib/components/button/button.component.d.ts.map +1 -0
  18. package/lib/components/button/button.types.d.ts +17 -0
  19. package/lib/components/button/button.types.d.ts.map +1 -0
  20. package/lib/components/card/card.component.d.ts +23 -0
  21. package/lib/components/card/card.component.d.ts.map +1 -0
  22. package/lib/components/image-preview/image-preview.component.d.ts +40 -0
  23. package/lib/components/image-preview/image-preview.component.d.ts.map +1 -0
  24. package/lib/i18n/keep-ui-translations.d.ts +21 -0
  25. package/lib/i18n/keep-ui-translations.d.ts.map +1 -0
  26. package/lib/i18n/translation-keys.d.ts +26 -0
  27. package/lib/i18n/translation-keys.d.ts.map +1 -0
  28. package/lib/models/file-result.model.d.ts +11 -0
  29. package/lib/models/file-result.model.d.ts.map +1 -0
  30. package/lib/ports/file.port.d.ts +17 -0
  31. package/lib/ports/file.port.d.ts.map +1 -0
  32. package/lib/providers/keep-ui-i18n.provider.d.ts +43 -0
  33. package/lib/providers/keep-ui-i18n.provider.d.ts.map +1 -0
  34. package/lib/providers/provide-keep-ui.d.ts +16 -0
  35. package/lib/providers/provide-keep-ui.d.ts.map +1 -0
  36. package/lib/services/keep-ui-language.service.d.ts +36 -0
  37. package/lib/services/keep-ui-language.service.d.ts.map +1 -0
  38. package/lib/services/keep-ui-transloco-loader.service.d.ts +18 -0
  39. package/lib/services/keep-ui-transloco-loader.service.d.ts.map +1 -0
  40. package/lib/services/web-file.service.d.ts +17 -0
  41. package/lib/services/web-file.service.d.ts.map +1 -0
  42. package/lib/testing/mock-file.service.d.ts +21 -0
  43. package/lib/testing/mock-file.service.d.ts.map +1 -0
  44. package/lib/tokens/file.token.d.ts +11 -0
  45. package/lib/tokens/file.token.d.ts.map +1 -0
  46. package/package.json +40 -0
  47. package/public-api.d.ts +15 -0
  48. package/public-api.d.ts.map +1 -0
  49. package/schematics/collection.json +10 -0
  50. package/schematics/ng-add/index.d.ts +12 -0
  51. package/schematics/ng-add/index.js +34 -0
  52. package/schematics/ng-add/index.js.map +1 -0
  53. package/schematics/ng-add/index.ts +42 -0
  54. package/schematics/ng-add/schema.json +16 -0
  55. package/styles/_index.css +73 -0
  56. package/styles/themes.css +130 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"keepui-ui.mjs","sources":["../../../projects/keep-ui/src/lib/tokens/file.token.ts","../../../projects/keep-ui/src/lib/services/web-file.service.ts","../../../projects/keep-ui/src/lib/components/button/button.component.ts","../../../projects/keep-ui/src/lib/components/card/card.component.ts","../../../projects/keep-ui/src/lib/i18n/translation-keys.ts","../../../projects/keep-ui/src/lib/components/image-preview/image-preview.component.ts","../../../projects/keep-ui/src/lib/providers/provide-keep-ui.ts","../../../projects/keep-ui/src/lib/i18n/keep-ui-translations.ts","../../../projects/keep-ui/src/lib/services/keep-ui-transloco-loader.service.ts","../../../projects/keep-ui/src/lib/services/keep-ui-language.service.ts","../../../projects/keep-ui/src/lib/providers/keep-ui-i18n.provider.ts","../../../projects/keep-ui/src/lib/testing/mock-file.service.ts","../../../projects/keep-ui/src/public-api.ts","../../../projects/keep-ui/src/keepui-ui.ts"],"sourcesContent":["import { InjectionToken } from '@angular/core';\r\nimport { FilePort } from '../ports/file.port';\r\n\r\n/**\r\n * Injection token for the platform file/image adapter.\r\n *\r\n * Register a concrete implementation with:\r\n * - `provideKeepUi()` for web projects\r\n * - `provideKeepUiCapacitor()` for Angular + Capacitor projects\r\n */\r\nexport const FILE_PORT = new InjectionToken<FilePort>('FILE_PORT');\r\n","import { Injectable } from '@angular/core';\r\nimport { FilePort } from '../ports/file.port';\r\nimport { FileResult } from '../models/file-result.model';\r\n\r\n/**\r\n * Web implementation of `FilePort`.\r\n *\r\n * Uses a hidden `<input type=\"file\">` and the `FileReader` API to let the user\r\n * pick an image from the file system in a browser environment.\r\n *\r\n * This implementation has no dependency on Capacitor or any native plugin.\r\n */\r\n@Injectable()\r\nexport class WebFileService implements FilePort {\r\n pickImage(): Promise<FileResult> {\r\n return new Promise<FileResult>((resolve, reject) => {\r\n const input = document.createElement('input');\r\n input.type = 'file';\r\n input.accept = 'image/*';\r\n\r\n input.onchange = () => {\r\n const file = input.files?.[0];\r\n if (!file) {\r\n reject(new Error('No file selected'));\r\n return;\r\n }\r\n\r\n const reader = new FileReader();\r\n reader.onload = () => {\r\n resolve({\r\n dataUrl: reader.result as string,\r\n mimeType: file.type,\r\n });\r\n };\r\n reader.onerror = () => reject(reader.error ?? new Error('FileReader error'));\r\n reader.readAsDataURL(file);\r\n };\r\n\r\n input.click();\r\n });\r\n }\r\n}\r\n","import { Component, ChangeDetectionStrategy, computed, input, output } from '@angular/core';\r\nimport { ButtonVariant, ButtonSize, ButtonShape, ButtonType } from './button.types';\r\n\r\n/**\r\n * Accessible, themed action button with support for variants, shapes, sizes,\r\n * loading state, full-width layout, and named icon slots.\r\n *\r\n * Works identically on **web** and **Angular + Capacitor** (no native API usage).\r\n *\r\n * ```html\r\n * <!-- Basic usage -->\r\n * <keepui-button (clicked)=\"save()\">Save</keepui-button>\r\n *\r\n * <!-- Primary, pill-shaped, fixed width -->\r\n * <keepui-button variant=\"primary\" shape=\"pill\">Confirm</keepui-button>\r\n *\r\n * <!-- With leading icon (any inline element) -->\r\n * <keepui-button variant=\"outline\" size=\"auto\">\r\n * <svg slot=\"leading\" width=\"16\" height=\"16\" aria-hidden=\"true\">…</svg>\r\n * Upload\r\n * </keepui-button>\r\n *\r\n * <!-- Loading state -->\r\n * <keepui-button [loading]=\"isSaving()\">Saving…</keepui-button>\r\n *\r\n * <!-- Full-width, danger -->\r\n * <keepui-button variant=\"danger\" [fullWidth]=\"true\">Delete account</keepui-button>\r\n *\r\n * <!-- Icon-only (requires ariaLabel for accessibility) -->\r\n * <keepui-button variant=\"ghost\" size=\"auto\" ariaLabel=\"Close dialog\">\r\n * <svg slot=\"leading\" …>…</svg>\r\n * </keepui-button>\r\n * ```\r\n */\r\n@Component({\r\n selector: 'keepui-button',\r\n standalone: true,\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n host: {\r\n '[style.display]': 'fullWidth() ? \"block\" : \"inline-block\"',\r\n '[style.width]': 'fullWidth() ? \"100%\" : null',\r\n },\r\n template: `\r\n <button\r\n [attr.type]=\"type()\"\r\n [disabled]=\"isDisabled()\"\r\n [attr.aria-disabled]=\"isDisabled() ? true : null\"\r\n [attr.aria-busy]=\"loading() ? true : null\"\r\n [attr.aria-label]=\"ariaLabel() || null\"\r\n (click)=\"handleClick()\"\r\n [class]=\"buttonClass()\"\r\n >\r\n @if (loading()) {\r\n <span class=\"keepui-btn-spinner\" aria-hidden=\"true\"></span>\r\n } @else {\r\n <ng-content select=\"[slot='leading']\" />\r\n }\r\n\r\n <ng-content />\r\n\r\n @if (!loading()) {\r\n <ng-content select=\"[slot='trailing']\" />\r\n }\r\n </button>\r\n `,\r\n styles: [`\r\n .keepui-btn-spinner {\r\n display: inline-block;\r\n width: 1em;\r\n height: 1em;\r\n border: 2px solid currentColor;\r\n border-top-color: transparent;\r\n border-radius: 50%;\r\n animation: keepui-spin 0.65s linear infinite;\r\n flex-shrink: 0;\r\n }\r\n\r\n @keyframes keepui-spin {\r\n to { transform: rotate(360deg); }\r\n }\r\n `],\r\n})\r\nexport class ButtonComponent {\r\n /** Visual style of the button. @default 'primary' */\r\n readonly variant = input<ButtonVariant>('primary');\r\n\r\n /**\r\n * Size mode.\r\n * - `md` → fixed 160 px wide, 40 px tall.\r\n * - `auto` → padding-driven width, 40 px tall.\r\n * @default 'md'\r\n */\r\n readonly size = input<ButtonSize>('md');\r\n\r\n /** Border-radius style. @default 'pill' */\r\n readonly shape = input<ButtonShape>('pill');\r\n\r\n /** HTML `type` attribute of the inner `<button>`. @default 'button' */\r\n readonly type = input<ButtonType>('button');\r\n\r\n /** Disables the button when `true`. @default false */\r\n readonly disabled = input(false);\r\n\r\n /**\r\n * Replaces the content with an animated spinner and sets `aria-busy`.\r\n * Also disables the button until the operation completes.\r\n * @default false\r\n */\r\n readonly loading = input(false);\r\n\r\n /** Expands the button to fill its container width. @default false */\r\n readonly fullWidth = input(false);\r\n\r\n /**\r\n * Accessible label for icon-only buttons.\r\n * When provided, sets the `aria-label` attribute on the inner `<button>`.\r\n * @default ''\r\n */\r\n readonly ariaLabel = input('');\r\n\r\n /** Emitted when the button is clicked and is not disabled or loading. */\r\n readonly clicked = output<void>();\r\n\r\n protected readonly isDisabled = computed(() => this.disabled() || this.loading());\r\n\r\n protected readonly buttonClass = computed(() => {\r\n const base = [\r\n 'inline-flex items-center justify-center gap-2',\r\n 'min-h-[2.75rem] text-sm font-medium cursor-pointer select-none',\r\n 'transition-colors duration-200',\r\n 'focus-visible:outline-none focus-visible:ring-2',\r\n 'focus-visible:ring-keepui-primary focus-visible:ring-offset-2',\r\n 'disabled:opacity-50 disabled:cursor-not-allowed',\r\n ].join(' ');\r\n\r\n const sizeClass = this.fullWidth()\r\n ? 'w-full h-10 px-4'\r\n : this.size() === 'md'\r\n ? 'w-40 h-10'\r\n : 'px-6 h-10';\r\n\r\n const shapeMap: Record<ButtonShape, string> = {\r\n pill: 'rounded-full',\r\n rounded: 'rounded-2xl',\r\n };\r\n\r\n const variantMap: Record<ButtonVariant, string> = {\r\n primary: [\r\n 'bg-keepui-primary text-keepui-primary-fg border border-keepui-primary',\r\n 'enabled:hover:bg-keepui-primary-hover enabled:hover:border-keepui-primary-hover',\r\n 'enabled:active:bg-keepui-primary-active enabled:active:border-keepui-primary-active',\r\n ].join(' '),\r\n secondary: [\r\n 'bg-keepui-surface text-keepui-text border border-keepui-border',\r\n 'enabled:hover:bg-keepui-surface-hover enabled:hover:border-keepui-border-strong',\r\n 'disabled:text-keepui-text-disabled',\r\n ].join(' '),\r\n outline: [\r\n 'bg-transparent border border-keepui-border text-keepui-text',\r\n 'enabled:hover:border-keepui-primary enabled:hover:text-keepui-primary',\r\n ].join(' '),\r\n ghost: [\r\n 'bg-transparent border border-keepui-primary text-keepui-primary',\r\n 'enabled:hover:bg-keepui-primary/10',\r\n ].join(' '),\r\n danger: [\r\n 'bg-keepui-error text-keepui-error-fg border border-keepui-error',\r\n 'enabled:hover:opacity-90',\r\n 'enabled:active:opacity-80',\r\n ].join(' '),\r\n };\r\n\r\n return [base, sizeClass, shapeMap[this.shape()], variantMap[this.variant()]].join(' ');\r\n });\r\n\r\n protected handleClick(): void {\r\n if (!this.isDisabled()) {\r\n this.clicked.emit();\r\n }\r\n }\r\n}\r\n","import { Component, computed, input } from '@angular/core';\r\n\r\n/**\r\n * A versatile card container component.\r\n *\r\n * ```html\r\n * <keepui-card>\r\n * <h2>Title</h2>\r\n * <p>Some content</p>\r\n * </keepui-card>\r\n *\r\n * <keepui-card [elevation]=\"2\">\r\n * Elevated card\r\n * </keepui-card>\r\n * ```\r\n */\r\n@Component({\r\n selector: 'keepui-card',\r\n standalone: true,\r\n host: { class: 'block' },\r\n template: `\r\n <div [class]=\"cardClass()\">\r\n <ng-content />\r\n </div>\r\n `,\r\n})\r\nexport class CardComponent {\r\n /** Shadow elevation level (0–3). */\r\n readonly elevation = input<0 | 1 | 2 | 3>(1);\r\n\r\n protected readonly cardClass = computed(() => {\r\n const base = [\r\n 'rounded-lg p-4',\r\n 'bg-keepui-surface border border-keepui-border text-keepui-text',\r\n 'transition-all duration-200',\r\n ].join(' ');\r\n\r\n const shadowMap: Record<0 | 1 | 2 | 3, string> = {\r\n 0: '',\r\n 1: 'shadow-keepui-sm',\r\n 2: 'shadow-keepui-md',\r\n 3: 'shadow-keepui-lg',\r\n };\r\n\r\n const shadow = shadowMap[this.elevation()];\r\n return shadow ? `${base} ${shadow}` : base;\r\n });\r\n}\r\n","/**\r\n * Typed constants for every translation key used in @keepui/ui.\r\n *\r\n * Use these instead of raw strings so that renaming a key is caught by\r\n * the TypeScript compiler across all consumers.\r\n *\r\n * @example\r\n * ```ts\r\n * import { KEEPUI_TRANSLATION_KEYS as T } from '@keepui/ui';\r\n *\r\n * const label = translocoService.translate(T.IMAGE_PREVIEW.SELECT_IMAGE);\r\n * ```\r\n */\r\nexport const KEEPUI_TRANSLATION_KEYS = {\r\n IMAGE_PREVIEW: {\r\n SELECT_IMAGE: 'imagePreview.selectImage',\r\n LOADING: 'imagePreview.loading',\r\n PREVIEW_ALT: 'imagePreview.previewAlt',\r\n ERROR_UNEXPECTED: 'imagePreview.errorUnexpected',\r\n },\r\n} as const;\r\n\r\n/** Union of all supported KeepUI locales. */\r\nexport type KeepUiLanguage = 'en' | 'es' | 'de';\r\n\r\n/** Ordered list of languages available in KeepUI. */\r\nexport const KEEPUI_AVAILABLE_LANGUAGES: readonly KeepUiLanguage[] = [\r\n 'en',\r\n 'es',\r\n 'de',\r\n] as const;\r\n\r\n","import { Component, ChangeDetectionStrategy, inject, signal } from '@angular/core';\r\nimport { TranslocoPipe, TRANSLOCO_SCOPE } from '@jsverse/transloco';\r\nimport { FILE_PORT } from '../../tokens/file.token';\r\nimport { KEEPUI_TRANSLATION_KEYS as T } from '../../i18n/translation-keys';\r\nimport { ButtonComponent } from '../button/button.component';\r\n\r\n/**\r\n * Standalone component that allows the user to pick and preview an image.\r\n *\r\n * This component is fully platform-agnostic. It delegates file picking to\r\n * whatever `FilePort` implementation is provided via `FILE_PORT`.\r\n *\r\n * UI strings are fully internationalised via Transloco (scope `'keepui'`).\r\n * Call `provideKeepUiI18n()` in your `app.config.ts` and use\r\n * `KeepUiLanguageService.setLanguage(lang)` to change locale at runtime.\r\n *\r\n * Usage:\r\n * ```html\r\n * <keepui-image-preview />\r\n * ```\r\n *\r\n * Prerequisites — register providers in `app.config.ts`:\r\n * - Web: `provideKeepUi()` + `provideKeepUiI18n()`\r\n * - Capacitor: `provideKeepUiCapacitor()` + `provideKeepUiI18n()`\r\n */\r\n@Component({\r\n selector: 'keepui-image-preview',\r\n standalone: true,\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n imports: [TranslocoPipe, ButtonComponent],\r\n providers: [{ provide: TRANSLOCO_SCOPE, useValue: 'keepui' }],\r\n host: { class: 'block' },\r\n template: `\r\n <div class=\"flex flex-col gap-4\">\r\n\r\n <keepui-button\r\n type=\"button\"\r\n variant=\"secondary\"\r\n size=\"auto\"\r\n shape=\"rounded\"\r\n [loading]=\"loading()\"\r\n (clicked)=\"pickImage()\"\r\n >\r\n {{ (loading() ? keys.LOADING : keys.SELECT_IMAGE) | transloco }}\r\n </keepui-button>\r\n\r\n <span role=\"status\" class=\"sr-only\">\r\n @if (imageUrl()) {\r\n {{ keys.PREVIEW_ALT | transloco }}\r\n }\r\n </span>\r\n\r\n @if (imageUrl()) {\r\n <div class=\"max-w-full\">\r\n <img\r\n class=\"max-w-full h-auto rounded border border-keepui-border\"\r\n [src]=\"imageUrl()\"\r\n [attr.alt]=\"keys.PREVIEW_ALT | transloco\"\r\n />\r\n </div>\r\n }\r\n\r\n @if (error()) {\r\n <p class=\"text-keepui-error text-sm m-0\" role=\"alert\">{{ error() }}</p>\r\n }\r\n\r\n </div>\r\n `,\r\n})\r\nexport class ImagePreviewComponent {\r\n private readonly filePort = inject(FILE_PORT);\r\n\r\n /** Translation key references (typed via KEEPUI_TRANSLATION_KEYS). */\r\n protected readonly keys = T.IMAGE_PREVIEW;\r\n\r\n /** URL of the selected image, ready to bind to `[src]`. */\r\n readonly imageUrl = signal<string | null>(null);\r\n /** Error message if the last pick operation failed. */\r\n readonly error = signal<string | null>(null);\r\n /** True while the pick operation is in progress. */\r\n readonly loading = signal(false);\r\n\r\n async pickImage(): Promise<void> {\r\n this.error.set(null);\r\n this.loading.set(true);\r\n\r\n try {\r\n const result = await this.filePort.pickImage();\r\n this.imageUrl.set(result.dataUrl);\r\n } catch (err) {\r\n this.error.set(\r\n err instanceof Error ? err.message : T.IMAGE_PREVIEW.ERROR_UNEXPECTED,\r\n );\r\n } finally {\r\n this.loading.set(false);\r\n }\r\n }\r\n}\r\n","import { EnvironmentProviders, makeEnvironmentProviders } from '@angular/core';\r\nimport { FILE_PORT } from '../tokens/file.token';\r\nimport { WebFileService } from '../services/web-file.service';\r\n\r\n/**\r\n * Registers KeepUI core providers for a **web** Angular application.\r\n *\r\n * Registers `WebFileService` as the implementation of `FILE_PORT`, enabling\r\n * all KeepUI components to use the browser's native file picker.\r\n *\r\n * Add to `app.config.ts`:\r\n * ```ts\r\n * export const appConfig: ApplicationConfig = {\r\n * providers: [provideKeepUi()],\r\n * };\r\n * ```\r\n */\r\nexport function provideKeepUi(): EnvironmentProviders {\r\n return makeEnvironmentProviders([\r\n { provide: FILE_PORT, useClass: WebFileService },\r\n ]);\r\n}\r\n","/**\r\n * Inline translation objects for KeepUI.\r\n *\r\n * These mirror `en.json`, `es.json` and `de.json` and are bundled directly\r\n * into the library so that no HTTP request is needed at runtime.\r\n *\r\n * > **Do not edit this file manually.**\r\n * > Keep it in sync with the JSON files inside `/i18n/`.\r\n */\r\n\r\nimport { KeepUiLanguage } from './translation-keys';\r\n\r\nexport interface KeepUiTranslationSchema {\r\n imagePreview: {\r\n selectImage: string;\r\n loading: string;\r\n previewAlt: string;\r\n errorUnexpected: string;\r\n };\r\n}\r\n\r\nconst EN: KeepUiTranslationSchema = {\r\n imagePreview: {\r\n selectImage: 'Select image',\r\n loading: 'Loading…',\r\n previewAlt: 'Selected image preview',\r\n errorUnexpected: 'An unexpected error occurred',\r\n },\r\n};\r\n\r\nconst ES: KeepUiTranslationSchema = {\r\n imagePreview: {\r\n selectImage: 'Seleccionar imagen',\r\n loading: 'Cargando…',\r\n previewAlt: 'Vista previa de imagen seleccionada',\r\n errorUnexpected: 'Ha ocurrido un error inesperado',\r\n },\r\n};\r\n\r\nconst DE: KeepUiTranslationSchema = {\r\n imagePreview: {\r\n selectImage: 'Bild auswählen',\r\n loading: 'Laden…',\r\n previewAlt: 'Vorschau des ausgewählten Bildes',\r\n errorUnexpected: 'Ein unerwarteter Fehler ist aufgetreten',\r\n },\r\n};\r\n\r\n/** Map from locale code to its translation object. */\r\nexport const KEEPUI_TRANSLATIONS: Record<KeepUiLanguage, KeepUiTranslationSchema> = {\r\n en: EN,\r\n es: ES,\r\n de: DE,\r\n};\r\n\r\n","import { Injectable } from '@angular/core';\r\nimport { Translation, TranslocoLoader } from '@jsverse/transloco';\r\nimport { Observable, of } from 'rxjs';\r\nimport { KeepUiLanguage } from '../i18n/translation-keys';\r\nimport { KEEPUI_TRANSLATIONS } from '../i18n/keep-ui-translations';\r\n\r\n/**\r\n * Transloco loader for KeepUI.\r\n *\r\n * Serves translations **inline** (bundled in the library JS) so that no HTTP\r\n * request is required. It handles both plain lang paths (`'en'`, `'es'`, …)\r\n * and scope-prefixed paths (`'keepui/en'`, `'keepui/es'`, …).\r\n *\r\n * @internal\r\n */\r\n@Injectable()\r\nexport class KeepUiTranslocoLoader implements TranslocoLoader {\r\n getTranslation(langPath: string): Observable<Translation> {\r\n // Transloco calls this with 'keepui/en', 'keepui/es', etc.\r\n // when a component has TRANSLOCO_SCOPE = 'keepui'.\r\n const lang = langPath.includes('/') ? langPath.split('/')[1] : langPath;\r\n\r\n const isValid = (l: string): l is KeepUiLanguage =>\r\n l === 'en' || l === 'es' || l === 'de';\r\n\r\n const translations = isValid(lang)\r\n ? KEEPUI_TRANSLATIONS[lang]\r\n : KEEPUI_TRANSLATIONS['en'];\r\n\r\n return of(translations as unknown as Translation);\r\n }\r\n}\r\n\r\n","import { Injectable, inject, signal } from '@angular/core';\r\nimport { TranslocoService } from '@jsverse/transloco';\r\nimport { KeepUiLanguage, KEEPUI_AVAILABLE_LANGUAGES } from '../i18n/translation-keys';\r\n\r\n/**\r\n * Service that exposes a public API for changing the active language of all\r\n * KeepUI components at runtime.\r\n *\r\n * ### Usage\r\n * ```ts\r\n * // Inject anywhere in the host application\r\n * const lang = inject(KeepUiLanguageService);\r\n *\r\n * // Switch to Spanish\r\n * lang.setLanguage('es');\r\n *\r\n * // Read the active language\r\n * console.log(lang.activeLanguage()); // 'es'\r\n * ```\r\n *\r\n * Register via `provideKeepUiI18n()` in `app.config.ts`.\r\n */\r\n@Injectable()\r\nexport class KeepUiLanguageService {\r\n private readonly transloco = inject(TranslocoService);\r\n\r\n /** Signal that reflects the currently active KeepUI locale. */\r\n readonly activeLanguage = signal<KeepUiLanguage>(\r\n this.transloco.getActiveLang() as KeepUiLanguage,\r\n );\r\n\r\n /** Ordered list of all supported locales. */\r\n readonly availableLanguages: readonly KeepUiLanguage[] = KEEPUI_AVAILABLE_LANGUAGES;\r\n\r\n /**\r\n * Changes the active language for all KeepUI components.\r\n *\r\n * @param lang - One of `'en'`, `'es'` or `'de'`.\r\n */\r\n setLanguage(lang: KeepUiLanguage): void {\r\n this.transloco.setActiveLang(lang);\r\n this.activeLanguage.set(lang);\r\n }\r\n}\r\n\r\n","import { EnvironmentProviders, makeEnvironmentProviders } from '@angular/core';\r\nimport { provideTransloco } from '@jsverse/transloco';\r\nimport { KeepUiLanguage, KEEPUI_AVAILABLE_LANGUAGES } from '../i18n/translation-keys';\r\nimport { KeepUiTranslocoLoader } from '../services/keep-ui-transloco-loader.service';\r\nimport { KeepUiLanguageService } from '../services/keep-ui-language.service';\r\n\r\n/**\r\n * Options for `provideKeepUiI18n()`.\r\n */\r\nexport interface KeepUiI18nOptions {\r\n /**\r\n * The default language to use when the app starts.\r\n * @default 'en'\r\n */\r\n defaultLang?: KeepUiLanguage;\r\n}\r\n\r\n/**\r\n * Registers all providers required for KeepUI internationalisation.\r\n *\r\n * - Configures a self-contained Transloco instance scoped to `'keepui'`.\r\n * - Bundles all translations **inline** — no HTTP assets required.\r\n * - Provides {@link KeepUiLanguageService} so the host app can switch locale.\r\n *\r\n * ### Usage in `app.config.ts`\r\n * ```ts\r\n * export const appConfig: ApplicationConfig = {\r\n * providers: [\r\n * provideKeepUi(),\r\n * provideKeepUiI18n(), // default language: 'en'\r\n * provideKeepUiI18n({ defaultLang: 'es' }), // or start in Spanish\r\n * ],\r\n * };\r\n * ```\r\n *\r\n * ### Changing language at runtime\r\n * ```ts\r\n * const lang = inject(KeepUiLanguageService);\r\n * lang.setLanguage('de');\r\n * ```\r\n *\r\n * > **Note:** If your application already calls `provideTransloco()`, do NOT\r\n * > call `provideKeepUiI18n()` — instead configure your Transloco loader to\r\n * > handle the `'keepui/{lang}'` scope paths, and provide `KeepUiLanguageService`\r\n * > manually.\r\n */\r\nexport function provideKeepUiI18n(\r\n options: KeepUiI18nOptions = {},\r\n): EnvironmentProviders {\r\n const defaultLang: KeepUiLanguage = options.defaultLang ?? 'en';\r\n\r\n return makeEnvironmentProviders([\r\n provideTransloco({\r\n config: {\r\n defaultLang,\r\n availableLangs: [...KEEPUI_AVAILABLE_LANGUAGES],\r\n reRenderOnLangChange: true,\r\n failedRetries: 0,\r\n missingHandler: { useFallbackTranslation: true },\r\n fallbackLang: 'en',\r\n },\r\n loader: KeepUiTranslocoLoader,\r\n }),\r\n\r\n KeepUiLanguageService,\r\n ]);\r\n}\r\n\r\n","import { Injectable } from '@angular/core';\r\nimport { FilePort } from '../ports/file.port';\r\nimport { FileResult } from '../models/file-result.model';\r\n\r\n/**\r\n * A controllable mock implementation of `FilePort` for use in unit tests.\r\n *\r\n * By default, `pickImage()` resolves successfully. Set `nextError` to make the\r\n * next call reject with that error.\r\n *\r\n * ```ts\r\n * providers: [{ provide: FILE_PORT, useClass: MockFileService }]\r\n * ```\r\n */\r\n@Injectable()\r\nexport class MockFileService implements FilePort {\r\n /** Set this to make the next `pickImage()` call reject with this error. */\r\n nextError: Error | null = null;\r\n\r\n pickImage(): Promise<FileResult> {\r\n if (this.nextError) {\r\n const err = this.nextError;\r\n this.nextError = null;\r\n return Promise.reject(err);\r\n }\r\n return Promise.resolve({\r\n dataUrl: 'data:image/jpeg;base64,mockImageData==',\r\n mimeType: 'image/jpeg',\r\n });\r\n }\r\n}\r\n","// Public API Surface of @keepui/ui\r\n\r\n// Models\r\nexport * from './lib/models/file-result.model';\r\n\r\n// Ports (interfaces)\r\nexport * from './lib/ports/file.port';\r\n\r\n// Injection tokens\r\nexport * from './lib/tokens/file.token';\r\n\r\n// Services\r\nexport * from './lib/services/web-file.service';\r\n\r\n// Components\r\nexport * from './lib/components/button/button.types';\r\nexport * from './lib/components/button/button.component';\r\nexport * from './lib/components/card/card.component';\r\nexport * from './lib/components/image-preview/image-preview.component';\r\n\r\n// Providers\r\nexport * from './lib/providers/provide-keep-ui';\r\nexport * from './lib/providers/keep-ui-i18n.provider';\r\n\r\n// i18n – translation keys & language utilities\r\nexport * from './lib/i18n/translation-keys';\r\nexport * from './lib/i18n/keep-ui-translations';\r\nexport * from './lib/services/keep-ui-language.service';\r\n\r\n// Testing utilities\r\nexport * from './lib/testing/mock-file.service';\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["T"],"mappings":"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"}
package/index.d.ts ADDED
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Generated bundle index. Do not edit.
3
+ */
4
+ /// <amd-module name="@keepui/ui" />
5
+ export * from './public-api';
6
+ //# sourceMappingURL=keepui-ui.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"keepui-ui.d.ts","sourceRoot":"","sources":["../../projects/keep-ui/src/keepui-ui.ts"],"names":[],"mappings":"AAAA;;GAEG;;AAEH,cAAc,cAAc,CAAC"}
@@ -0,0 +1,72 @@
1
+ import { ButtonVariant, ButtonSize, ButtonShape, ButtonType } from './button.types';
2
+ import * as i0 from "@angular/core";
3
+ /**
4
+ * Accessible, themed action button with support for variants, shapes, sizes,
5
+ * loading state, full-width layout, and named icon slots.
6
+ *
7
+ * Works identically on **web** and **Angular + Capacitor** (no native API usage).
8
+ *
9
+ * ```html
10
+ * <!-- Basic usage -->
11
+ * <keepui-button (clicked)="save()">Save</keepui-button>
12
+ *
13
+ * <!-- Primary, pill-shaped, fixed width -->
14
+ * <keepui-button variant="primary" shape="pill">Confirm</keepui-button>
15
+ *
16
+ * <!-- With leading icon (any inline element) -->
17
+ * <keepui-button variant="outline" size="auto">
18
+ * <svg slot="leading" width="16" height="16" aria-hidden="true">…</svg>
19
+ * Upload
20
+ * </keepui-button>
21
+ *
22
+ * <!-- Loading state -->
23
+ * <keepui-button [loading]="isSaving()">Saving…</keepui-button>
24
+ *
25
+ * <!-- Full-width, danger -->
26
+ * <keepui-button variant="danger" [fullWidth]="true">Delete account</keepui-button>
27
+ *
28
+ * <!-- Icon-only (requires ariaLabel for accessibility) -->
29
+ * <keepui-button variant="ghost" size="auto" ariaLabel="Close dialog">
30
+ * <svg slot="leading" …>…</svg>
31
+ * </keepui-button>
32
+ * ```
33
+ */
34
+ export declare class ButtonComponent {
35
+ /** Visual style of the button. @default 'primary' */
36
+ readonly variant: import("@angular/core").InputSignal<ButtonVariant>;
37
+ /**
38
+ * Size mode.
39
+ * - `md` → fixed 160 px wide, 40 px tall.
40
+ * - `auto` → padding-driven width, 40 px tall.
41
+ * @default 'md'
42
+ */
43
+ readonly size: import("@angular/core").InputSignal<ButtonSize>;
44
+ /** Border-radius style. @default 'pill' */
45
+ readonly shape: import("@angular/core").InputSignal<ButtonShape>;
46
+ /** HTML `type` attribute of the inner `<button>`. @default 'button' */
47
+ readonly type: import("@angular/core").InputSignal<ButtonType>;
48
+ /** Disables the button when `true`. @default false */
49
+ readonly disabled: import("@angular/core").InputSignal<boolean>;
50
+ /**
51
+ * Replaces the content with an animated spinner and sets `aria-busy`.
52
+ * Also disables the button until the operation completes.
53
+ * @default false
54
+ */
55
+ readonly loading: import("@angular/core").InputSignal<boolean>;
56
+ /** Expands the button to fill its container width. @default false */
57
+ readonly fullWidth: import("@angular/core").InputSignal<boolean>;
58
+ /**
59
+ * Accessible label for icon-only buttons.
60
+ * When provided, sets the `aria-label` attribute on the inner `<button>`.
61
+ * @default ''
62
+ */
63
+ readonly ariaLabel: import("@angular/core").InputSignal<string>;
64
+ /** Emitted when the button is clicked and is not disabled or loading. */
65
+ readonly clicked: import("@angular/core").OutputEmitterRef<void>;
66
+ protected readonly isDisabled: import("@angular/core").Signal<boolean>;
67
+ protected readonly buttonClass: import("@angular/core").Signal<string>;
68
+ protected handleClick(): void;
69
+ static ɵfac: i0.ɵɵFactoryDeclaration<ButtonComponent, never>;
70
+ static ɵcmp: i0.ɵɵComponentDeclaration<ButtonComponent, "keepui-button", never, { "variant": { "alias": "variant"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "shape": { "alias": "shape"; "required": false; "isSignal": true; }; "type": { "alias": "type"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "loading": { "alias": "loading"; "required": false; "isSignal": true; }; "fullWidth": { "alias": "fullWidth"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; }, { "clicked": "clicked"; }, never, ["[slot='leading']", "*", "[slot='trailing']"], true, never>;
71
+ }
72
+ //# sourceMappingURL=button.component.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"button.component.d.ts","sourceRoot":"","sources":["../../../../../projects/keep-ui/src/lib/components/button/button.component.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;;AAEpF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,qBAgDa,eAAe;IAC1B,qDAAqD;IACrD,QAAQ,CAAC,OAAO,qDAAmC;IAEnD;;;;;OAKG;IACH,QAAQ,CAAC,IAAI,kDAA2B;IAExC,2CAA2C;IAC3C,QAAQ,CAAC,KAAK,mDAA8B;IAE5C,uEAAuE;IACvE,QAAQ,CAAC,IAAI,kDAA+B;IAE5C,sDAAsD;IACtD,QAAQ,CAAC,QAAQ,+CAAgB;IAEjC;;;;OAIG;IACH,QAAQ,CAAC,OAAO,+CAAgB;IAEhC,qEAAqE;IACrE,QAAQ,CAAC,SAAS,+CAAgB;IAElC;;;;OAIG;IACH,QAAQ,CAAC,SAAS,8CAAa;IAE/B,yEAAyE;IACzE,QAAQ,CAAC,OAAO,iDAAkB;IAElC,SAAS,CAAC,QAAQ,CAAC,UAAU,0CAAqD;IAElF,SAAS,CAAC,QAAQ,CAAC,WAAW,yCAgD3B;IAEH,SAAS,CAAC,WAAW,IAAI,IAAI;yCA7FlB,eAAe;2CAAf,eAAe;CAkG3B"}
@@ -0,0 +1,17 @@
1
+ /** Visual style variant of the button. */
2
+ export type ButtonVariant = 'primary' | 'secondary' | 'outline' | 'ghost' | 'danger';
3
+ /**
4
+ * Size mode of the button.
5
+ * - `md`: fixed width (160 px) and height (40 px).
6
+ * - `auto`: height fixed (40 px), width grows with padding to fit content.
7
+ */
8
+ export type ButtonSize = 'md' | 'auto';
9
+ /**
10
+ * Border-radius style of the button.
11
+ * - `pill`: fully rounded (`rounded-full`).
12
+ * - `rounded`: moderately rounded (`rounded-2xl`).
13
+ */
14
+ export type ButtonShape = 'pill' | 'rounded';
15
+ /** HTML `type` attribute for the underlying `<button>` element. */
16
+ export type ButtonType = 'button' | 'submit' | 'reset';
17
+ //# sourceMappingURL=button.types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"button.types.d.ts","sourceRoot":"","sources":["../../../../../projects/keep-ui/src/lib/components/button/button.types.ts"],"names":[],"mappings":"AAAA,0CAA0C;AAC1C,MAAM,MAAM,aAAa,GAAG,SAAS,GAAG,WAAW,GAAG,SAAS,GAAG,OAAO,GAAG,QAAQ,CAAC;AAErF;;;;GAIG;AACH,MAAM,MAAM,UAAU,GAAG,IAAI,GAAG,MAAM,CAAC;AAEvC;;;;GAIG;AACH,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,SAAS,CAAC;AAE7C,mEAAmE;AACnE,MAAM,MAAM,UAAU,GAAG,QAAQ,GAAG,QAAQ,GAAG,OAAO,CAAC"}
@@ -0,0 +1,23 @@
1
+ import * as i0 from "@angular/core";
2
+ /**
3
+ * A versatile card container component.
4
+ *
5
+ * ```html
6
+ * <keepui-card>
7
+ * <h2>Title</h2>
8
+ * <p>Some content</p>
9
+ * </keepui-card>
10
+ *
11
+ * <keepui-card [elevation]="2">
12
+ * Elevated card
13
+ * </keepui-card>
14
+ * ```
15
+ */
16
+ export declare class CardComponent {
17
+ /** Shadow elevation level (0–3). */
18
+ readonly elevation: import("@angular/core").InputSignal<0 | 1 | 2 | 3>;
19
+ protected readonly cardClass: import("@angular/core").Signal<string>;
20
+ static ɵfac: i0.ɵɵFactoryDeclaration<CardComponent, never>;
21
+ static ɵcmp: i0.ɵɵComponentDeclaration<CardComponent, "keepui-card", never, { "elevation": { "alias": "elevation"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
22
+ }
23
+ //# sourceMappingURL=card.component.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"card.component.d.ts","sourceRoot":"","sources":["../../../../../projects/keep-ui/src/lib/components/card/card.component.ts"],"names":[],"mappings":";AAEA;;;;;;;;;;;;;GAaG;AACH,qBAUa,aAAa;IACxB,oCAAoC;IACpC,QAAQ,CAAC,SAAS,qDAA2B;IAE7C,SAAS,CAAC,QAAQ,CAAC,SAAS,yCAgBzB;yCApBQ,aAAa;2CAAb,aAAa;CAqBzB"}
@@ -0,0 +1,40 @@
1
+ import * as i0 from "@angular/core";
2
+ /**
3
+ * Standalone component that allows the user to pick and preview an image.
4
+ *
5
+ * This component is fully platform-agnostic. It delegates file picking to
6
+ * whatever `FilePort` implementation is provided via `FILE_PORT`.
7
+ *
8
+ * UI strings are fully internationalised via Transloco (scope `'keepui'`).
9
+ * Call `provideKeepUiI18n()` in your `app.config.ts` and use
10
+ * `KeepUiLanguageService.setLanguage(lang)` to change locale at runtime.
11
+ *
12
+ * Usage:
13
+ * ```html
14
+ * <keepui-image-preview />
15
+ * ```
16
+ *
17
+ * Prerequisites — register providers in `app.config.ts`:
18
+ * - Web: `provideKeepUi()` + `provideKeepUiI18n()`
19
+ * - Capacitor: `provideKeepUiCapacitor()` + `provideKeepUiI18n()`
20
+ */
21
+ export declare class ImagePreviewComponent {
22
+ private readonly filePort;
23
+ /** Translation key references (typed via KEEPUI_TRANSLATION_KEYS). */
24
+ protected readonly keys: {
25
+ readonly SELECT_IMAGE: "imagePreview.selectImage";
26
+ readonly LOADING: "imagePreview.loading";
27
+ readonly PREVIEW_ALT: "imagePreview.previewAlt";
28
+ readonly ERROR_UNEXPECTED: "imagePreview.errorUnexpected";
29
+ };
30
+ /** URL of the selected image, ready to bind to `[src]`. */
31
+ readonly imageUrl: import("@angular/core").WritableSignal<string | null>;
32
+ /** Error message if the last pick operation failed. */
33
+ readonly error: import("@angular/core").WritableSignal<string | null>;
34
+ /** True while the pick operation is in progress. */
35
+ readonly loading: import("@angular/core").WritableSignal<boolean>;
36
+ pickImage(): Promise<void>;
37
+ static ɵfac: i0.ɵɵFactoryDeclaration<ImagePreviewComponent, never>;
38
+ static ɵcmp: i0.ɵɵComponentDeclaration<ImagePreviewComponent, "keepui-image-preview", never, {}, {}, never, never, true, never>;
39
+ }
40
+ //# sourceMappingURL=image-preview.component.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"image-preview.component.d.ts","sourceRoot":"","sources":["../../../../../projects/keep-ui/src/lib/components/image-preview/image-preview.component.ts"],"names":[],"mappings":";AAMA;;;;;;;;;;;;;;;;;;GAkBG;AACH,qBA4Ca,qBAAqB;IAChC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAqB;IAE9C,sEAAsE;IACtE,SAAS,CAAC,QAAQ,CAAC,IAAI;;;;;MAAmB;IAE1C,2DAA2D;IAC3D,QAAQ,CAAC,QAAQ,wDAA+B;IAChD,uDAAuD;IACvD,QAAQ,CAAC,KAAK,wDAA+B;IAC7C,oDAAoD;IACpD,QAAQ,CAAC,OAAO,kDAAiB;IAE3B,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC;yCAbrB,qBAAqB;2CAArB,qBAAqB;CA4BjC"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Inline translation objects for KeepUI.
3
+ *
4
+ * These mirror `en.json`, `es.json` and `de.json` and are bundled directly
5
+ * into the library so that no HTTP request is needed at runtime.
6
+ *
7
+ * > **Do not edit this file manually.**
8
+ * > Keep it in sync with the JSON files inside `/i18n/`.
9
+ */
10
+ import { KeepUiLanguage } from './translation-keys';
11
+ export interface KeepUiTranslationSchema {
12
+ imagePreview: {
13
+ selectImage: string;
14
+ loading: string;
15
+ previewAlt: string;
16
+ errorUnexpected: string;
17
+ };
18
+ }
19
+ /** Map from locale code to its translation object. */
20
+ export declare const KEEPUI_TRANSLATIONS: Record<KeepUiLanguage, KeepUiTranslationSchema>;
21
+ //# sourceMappingURL=keep-ui-translations.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"keep-ui-translations.d.ts","sourceRoot":"","sources":["../../../../projects/keep-ui/src/lib/i18n/keep-ui-translations.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAEpD,MAAM,WAAW,uBAAuB;IACtC,YAAY,EAAE;QACZ,WAAW,EAAE,MAAM,CAAC;QACpB,OAAO,EAAE,MAAM,CAAC;QAChB,UAAU,EAAE,MAAM,CAAC;QACnB,eAAe,EAAE,MAAM,CAAC;KACzB,CAAC;CACH;AA6BD,sDAAsD;AACtD,eAAO,MAAM,mBAAmB,EAAE,MAAM,CAAC,cAAc,EAAE,uBAAuB,CAI/E,CAAC"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Typed constants for every translation key used in @keepui/ui.
3
+ *
4
+ * Use these instead of raw strings so that renaming a key is caught by
5
+ * the TypeScript compiler across all consumers.
6
+ *
7
+ * @example
8
+ * ```ts
9
+ * import { KEEPUI_TRANSLATION_KEYS as T } from '@keepui/ui';
10
+ *
11
+ * const label = translocoService.translate(T.IMAGE_PREVIEW.SELECT_IMAGE);
12
+ * ```
13
+ */
14
+ export declare const KEEPUI_TRANSLATION_KEYS: {
15
+ readonly IMAGE_PREVIEW: {
16
+ readonly SELECT_IMAGE: "imagePreview.selectImage";
17
+ readonly LOADING: "imagePreview.loading";
18
+ readonly PREVIEW_ALT: "imagePreview.previewAlt";
19
+ readonly ERROR_UNEXPECTED: "imagePreview.errorUnexpected";
20
+ };
21
+ };
22
+ /** Union of all supported KeepUI locales. */
23
+ export type KeepUiLanguage = 'en' | 'es' | 'de';
24
+ /** Ordered list of languages available in KeepUI. */
25
+ export declare const KEEPUI_AVAILABLE_LANGUAGES: readonly KeepUiLanguage[];
26
+ //# sourceMappingURL=translation-keys.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"translation-keys.d.ts","sourceRoot":"","sources":["../../../../projects/keep-ui/src/lib/i18n/translation-keys.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,uBAAuB;;;;;;;CAO1B,CAAC;AAEX,6CAA6C;AAC7C,MAAM,MAAM,cAAc,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AAEhD,qDAAqD;AACrD,eAAO,MAAM,0BAA0B,EAAE,SAAS,cAAc,EAItD,CAAC"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Represents the result of a file/image selection operation.
3
+ * This model is platform-agnostic and used across all adapters.
4
+ */
5
+ export interface FileResult {
6
+ /** A data URL (e.g. `data:image/jpeg;base64,...`) or an HTTP/file URL ready to display. */
7
+ dataUrl: string;
8
+ /** MIME type of the selected file, e.g. `image/jpeg`. */
9
+ mimeType: string;
10
+ }
11
+ //# sourceMappingURL=file-result.model.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file-result.model.d.ts","sourceRoot":"","sources":["../../../../projects/keep-ui/src/lib/models/file-result.model.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,WAAW,UAAU;IACzB,2FAA2F;IAC3F,OAAO,EAAE,MAAM,CAAC;IAChB,yDAAyD;IACzD,QAAQ,EAAE,MAAM,CAAC;CAClB"}
@@ -0,0 +1,17 @@
1
+ import { FileResult } from '../models/file-result.model';
2
+ /**
3
+ * Platform-agnostic port (interface) for file/image selection.
4
+ *
5
+ * Provide a concrete implementation via the `FILE_PORT` injection token.
6
+ * - Web: `WebFileService`
7
+ * - Capacitor: `CapacitorFileService` (from `@keepui/ui/capacitor`)
8
+ */
9
+ export interface FilePort {
10
+ /**
11
+ * Opens a platform-native image picker and returns the selected image.
12
+ * Resolves with a `FileResult` containing a displayable URL and MIME type.
13
+ * Rejects if the user cancels or an error occurs.
14
+ */
15
+ pickImage(): Promise<FileResult>;
16
+ }
17
+ //# sourceMappingURL=file.port.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file.port.d.ts","sourceRoot":"","sources":["../../../../projects/keep-ui/src/lib/ports/file.port.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AAEzD;;;;;;GAMG;AACH,MAAM,WAAW,QAAQ;IACvB;;;;OAIG;IACH,SAAS,IAAI,OAAO,CAAC,UAAU,CAAC,CAAC;CAClC"}
@@ -0,0 +1,43 @@
1
+ import { EnvironmentProviders } from '@angular/core';
2
+ import { KeepUiLanguage } from '../i18n/translation-keys';
3
+ /**
4
+ * Options for `provideKeepUiI18n()`.
5
+ */
6
+ export interface KeepUiI18nOptions {
7
+ /**
8
+ * The default language to use when the app starts.
9
+ * @default 'en'
10
+ */
11
+ defaultLang?: KeepUiLanguage;
12
+ }
13
+ /**
14
+ * Registers all providers required for KeepUI internationalisation.
15
+ *
16
+ * - Configures a self-contained Transloco instance scoped to `'keepui'`.
17
+ * - Bundles all translations **inline** — no HTTP assets required.
18
+ * - Provides {@link KeepUiLanguageService} so the host app can switch locale.
19
+ *
20
+ * ### Usage in `app.config.ts`
21
+ * ```ts
22
+ * export const appConfig: ApplicationConfig = {
23
+ * providers: [
24
+ * provideKeepUi(),
25
+ * provideKeepUiI18n(), // default language: 'en'
26
+ * provideKeepUiI18n({ defaultLang: 'es' }), // or start in Spanish
27
+ * ],
28
+ * };
29
+ * ```
30
+ *
31
+ * ### Changing language at runtime
32
+ * ```ts
33
+ * const lang = inject(KeepUiLanguageService);
34
+ * lang.setLanguage('de');
35
+ * ```
36
+ *
37
+ * > **Note:** If your application already calls `provideTransloco()`, do NOT
38
+ * > call `provideKeepUiI18n()` — instead configure your Transloco loader to
39
+ * > handle the `'keepui/{lang}'` scope paths, and provide `KeepUiLanguageService`
40
+ * > manually.
41
+ */
42
+ export declare function provideKeepUiI18n(options?: KeepUiI18nOptions): EnvironmentProviders;
43
+ //# sourceMappingURL=keep-ui-i18n.provider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"keep-ui-i18n.provider.d.ts","sourceRoot":"","sources":["../../../../projects/keep-ui/src/lib/providers/keep-ui-i18n.provider.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAA4B,MAAM,eAAe,CAAC;AAE/E,OAAO,EAAE,cAAc,EAA8B,MAAM,0BAA0B,CAAC;AAItF;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC;;;OAGG;IACH,WAAW,CAAC,EAAE,cAAc,CAAC;CAC9B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAgB,iBAAiB,CAC/B,OAAO,GAAE,iBAAsB,GAC9B,oBAAoB,CAkBtB"}
@@ -0,0 +1,16 @@
1
+ import { EnvironmentProviders } from '@angular/core';
2
+ /**
3
+ * Registers KeepUI core providers for a **web** Angular application.
4
+ *
5
+ * Registers `WebFileService` as the implementation of `FILE_PORT`, enabling
6
+ * all KeepUI components to use the browser's native file picker.
7
+ *
8
+ * Add to `app.config.ts`:
9
+ * ```ts
10
+ * export const appConfig: ApplicationConfig = {
11
+ * providers: [provideKeepUi()],
12
+ * };
13
+ * ```
14
+ */
15
+ export declare function provideKeepUi(): EnvironmentProviders;
16
+ //# sourceMappingURL=provide-keep-ui.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provide-keep-ui.d.ts","sourceRoot":"","sources":["../../../../projects/keep-ui/src/lib/providers/provide-keep-ui.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAA4B,MAAM,eAAe,CAAC;AAI/E;;;;;;;;;;;;GAYG;AACH,wBAAgB,aAAa,IAAI,oBAAoB,CAIpD"}
@@ -0,0 +1,36 @@
1
+ import { KeepUiLanguage } from '../i18n/translation-keys';
2
+ import * as i0 from "@angular/core";
3
+ /**
4
+ * Service that exposes a public API for changing the active language of all
5
+ * KeepUI components at runtime.
6
+ *
7
+ * ### Usage
8
+ * ```ts
9
+ * // Inject anywhere in the host application
10
+ * const lang = inject(KeepUiLanguageService);
11
+ *
12
+ * // Switch to Spanish
13
+ * lang.setLanguage('es');
14
+ *
15
+ * // Read the active language
16
+ * console.log(lang.activeLanguage()); // 'es'
17
+ * ```
18
+ *
19
+ * Register via `provideKeepUiI18n()` in `app.config.ts`.
20
+ */
21
+ export declare class KeepUiLanguageService {
22
+ private readonly transloco;
23
+ /** Signal that reflects the currently active KeepUI locale. */
24
+ readonly activeLanguage: import("@angular/core").WritableSignal<KeepUiLanguage>;
25
+ /** Ordered list of all supported locales. */
26
+ readonly availableLanguages: readonly KeepUiLanguage[];
27
+ /**
28
+ * Changes the active language for all KeepUI components.
29
+ *
30
+ * @param lang - One of `'en'`, `'es'` or `'de'`.
31
+ */
32
+ setLanguage(lang: KeepUiLanguage): void;
33
+ static ɵfac: i0.ɵɵFactoryDeclaration<KeepUiLanguageService, never>;
34
+ static ɵprov: i0.ɵɵInjectableDeclaration<KeepUiLanguageService>;
35
+ }
36
+ //# sourceMappingURL=keep-ui-language.service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"keep-ui-language.service.d.ts","sourceRoot":"","sources":["../../../../projects/keep-ui/src/lib/services/keep-ui-language.service.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,cAAc,EAA8B,MAAM,0BAA0B,CAAC;;AAEtF;;;;;;;;;;;;;;;;;GAiBG;AACH,qBACa,qBAAqB;IAChC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA4B;IAEtD,+DAA+D;IAC/D,QAAQ,CAAC,cAAc,yDAErB;IAEF,6CAA6C;IAC7C,QAAQ,CAAC,kBAAkB,EAAE,SAAS,cAAc,EAAE,CAA8B;IAEpF;;;;OAIG;IACH,WAAW,CAAC,IAAI,EAAE,cAAc,GAAG,IAAI;yCAhB5B,qBAAqB;6CAArB,qBAAqB;CAoBjC"}
@@ -0,0 +1,18 @@
1
+ import { Translation, TranslocoLoader } from '@jsverse/transloco';
2
+ import { Observable } from 'rxjs';
3
+ import * as i0 from "@angular/core";
4
+ /**
5
+ * Transloco loader for KeepUI.
6
+ *
7
+ * Serves translations **inline** (bundled in the library JS) so that no HTTP
8
+ * request is required. It handles both plain lang paths (`'en'`, `'es'`, …)
9
+ * and scope-prefixed paths (`'keepui/en'`, `'keepui/es'`, …).
10
+ *
11
+ * @internal
12
+ */
13
+ export declare class KeepUiTranslocoLoader implements TranslocoLoader {
14
+ getTranslation(langPath: string): Observable<Translation>;
15
+ static ɵfac: i0.ɵɵFactoryDeclaration<KeepUiTranslocoLoader, never>;
16
+ static ɵprov: i0.ɵɵInjectableDeclaration<KeepUiTranslocoLoader>;
17
+ }
18
+ //# sourceMappingURL=keep-ui-transloco-loader.service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"keep-ui-transloco-loader.service.d.ts","sourceRoot":"","sources":["../../../../projects/keep-ui/src/lib/services/keep-ui-transloco-loader.service.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAClE,OAAO,EAAE,UAAU,EAAM,MAAM,MAAM,CAAC;;AAItC;;;;;;;;GAQG;AACH,qBACa,qBAAsB,YAAW,eAAe;IAC3D,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,UAAU,CAAC,WAAW,CAAC;yCAD9C,qBAAqB;6CAArB,qBAAqB;CAejC"}
@@ -0,0 +1,17 @@
1
+ import { FilePort } from '../ports/file.port';
2
+ import { FileResult } from '../models/file-result.model';
3
+ import * as i0 from "@angular/core";
4
+ /**
5
+ * Web implementation of `FilePort`.
6
+ *
7
+ * Uses a hidden `<input type="file">` and the `FileReader` API to let the user
8
+ * pick an image from the file system in a browser environment.
9
+ *
10
+ * This implementation has no dependency on Capacitor or any native plugin.
11
+ */
12
+ export declare class WebFileService implements FilePort {
13
+ pickImage(): Promise<FileResult>;
14
+ static ɵfac: i0.ɵɵFactoryDeclaration<WebFileService, never>;
15
+ static ɵprov: i0.ɵɵInjectableDeclaration<WebFileService>;
16
+ }
17
+ //# sourceMappingURL=web-file.service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"web-file.service.d.ts","sourceRoot":"","sources":["../../../../projects/keep-ui/src/lib/services/web-file.service.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;;AAEzD;;;;;;;GAOG;AACH,qBACa,cAAe,YAAW,QAAQ;IAC7C,SAAS,IAAI,OAAO,CAAC,UAAU,CAAC;yCADrB,cAAc;6CAAd,cAAc;CA4B1B"}
@@ -0,0 +1,21 @@
1
+ import { FilePort } from '../ports/file.port';
2
+ import { FileResult } from '../models/file-result.model';
3
+ import * as i0 from "@angular/core";
4
+ /**
5
+ * A controllable mock implementation of `FilePort` for use in unit tests.
6
+ *
7
+ * By default, `pickImage()` resolves successfully. Set `nextError` to make the
8
+ * next call reject with that error.
9
+ *
10
+ * ```ts
11
+ * providers: [{ provide: FILE_PORT, useClass: MockFileService }]
12
+ * ```
13
+ */
14
+ export declare class MockFileService implements FilePort {
15
+ /** Set this to make the next `pickImage()` call reject with this error. */
16
+ nextError: Error | null;
17
+ pickImage(): Promise<FileResult>;
18
+ static ɵfac: i0.ɵɵFactoryDeclaration<MockFileService, never>;
19
+ static ɵprov: i0.ɵɵInjectableDeclaration<MockFileService>;
20
+ }
21
+ //# sourceMappingURL=mock-file.service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mock-file.service.d.ts","sourceRoot":"","sources":["../../../../projects/keep-ui/src/lib/testing/mock-file.service.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;;AAEzD;;;;;;;;;GASG;AACH,qBACa,eAAgB,YAAW,QAAQ;IAC9C,2EAA2E;IAC3E,SAAS,EAAE,KAAK,GAAG,IAAI,CAAQ;IAE/B,SAAS,IAAI,OAAO,CAAC,UAAU,CAAC;yCAJrB,eAAe;6CAAf,eAAe;CAe3B"}
@@ -0,0 +1,11 @@
1
+ import { InjectionToken } from '@angular/core';
2
+ import { FilePort } from '../ports/file.port';
3
+ /**
4
+ * Injection token for the platform file/image adapter.
5
+ *
6
+ * Register a concrete implementation with:
7
+ * - `provideKeepUi()` for web projects
8
+ * - `provideKeepUiCapacitor()` for Angular + Capacitor projects
9
+ */
10
+ export declare const FILE_PORT: InjectionToken<FilePort>;
11
+ //# sourceMappingURL=file.token.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file.token.d.ts","sourceRoot":"","sources":["../../../../projects/keep-ui/src/lib/tokens/file.token.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAE9C;;;;;;GAMG;AACH,eAAO,MAAM,SAAS,0BAA4C,CAAC"}
package/package.json ADDED
@@ -0,0 +1,40 @@
1
+ {
2
+ "name": "@keepui/ui",
3
+ "version": "0.1.0",
4
+ "description": "KeepUI — Angular cross-platform UI component library with optional Capacitor support",
5
+ "keywords": [
6
+ "angular",
7
+ "capacitor",
8
+ "ui-library",
9
+ "components",
10
+ "cross-platform"
11
+ ],
12
+ "license": "MIT",
13
+ "sideEffects": false,
14
+ "peerDependencies": {
15
+ "@angular/common": ">=19.0.0",
16
+ "@angular/core": ">=19.0.0"
17
+ },
18
+ "dependencies": {
19
+ "tslib": "^2.8.0"
20
+ },
21
+ "schematics": "./schematics/collection.json",
22
+ "ng-add": {
23
+ "save": "dependencies"
24
+ },
25
+ "module": "fesm2022/keepui-ui.mjs",
26
+ "typings": "index.d.ts",
27
+ "exports": {
28
+ "./package.json": {
29
+ "default": "./package.json"
30
+ },
31
+ ".": {
32
+ "types": "./index.d.ts",
33
+ "default": "./fesm2022/keepui-ui.mjs"
34
+ },
35
+ "./capacitor": {
36
+ "types": "./capacitor/index.d.ts",
37
+ "default": "./fesm2022/keepui-ui-capacitor.mjs"
38
+ }
39
+ }
40
+ }