forty-cdk 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/accordion/README.md +122 -0
- package/aspect-ratio/README.md +76 -0
- package/avatar/README.md +100 -0
- package/breadcrumbs/README.md +49 -0
- package/breakpoints/README.md +81 -0
- package/button/README.md +49 -0
- package/calendar/README.md +458 -0
- package/carousel/README.md +358 -0
- package/checkbox/README.md +146 -0
- package/combobox/README.md +535 -0
- package/context-menu/README.md +139 -0
- package/date-field/README.md +184 -0
- package/date-picker/README.md +338 -0
- package/dialog/README.md +388 -0
- package/disclosure/README.md +114 -0
- package/drag-drop/README.md +359 -0
- package/drawer/README.md +560 -0
- package/dropdown-menu/README.md +176 -0
- package/fesm2022/forty-cdk-accordion.mjs +348 -0
- package/fesm2022/forty-cdk-accordion.mjs.map +1 -0
- package/fesm2022/forty-cdk-aspect-ratio.mjs +74 -0
- package/fesm2022/forty-cdk-aspect-ratio.mjs.map +1 -0
- package/fesm2022/forty-cdk-avatar.mjs +308 -0
- package/fesm2022/forty-cdk-avatar.mjs.map +1 -0
- package/fesm2022/forty-cdk-breadcrumbs.mjs +125 -0
- package/fesm2022/forty-cdk-breadcrumbs.mjs.map +1 -0
- package/fesm2022/forty-cdk-breakpoints.mjs +117 -0
- package/fesm2022/forty-cdk-breakpoints.mjs.map +1 -0
- package/fesm2022/forty-cdk-button.mjs +134 -0
- package/fesm2022/forty-cdk-button.mjs.map +1 -0
- package/fesm2022/forty-cdk-calendar.mjs +2034 -0
- package/fesm2022/forty-cdk-calendar.mjs.map +1 -0
- package/fesm2022/forty-cdk-carousel.mjs +968 -0
- package/fesm2022/forty-cdk-carousel.mjs.map +1 -0
- package/fesm2022/forty-cdk-checkbox.mjs +226 -0
- package/fesm2022/forty-cdk-checkbox.mjs.map +1 -0
- package/fesm2022/forty-cdk-combobox.mjs +2596 -0
- package/fesm2022/forty-cdk-combobox.mjs.map +1 -0
- package/fesm2022/forty-cdk-context-menu.mjs +413 -0
- package/fesm2022/forty-cdk-context-menu.mjs.map +1 -0
- package/fesm2022/forty-cdk-core.mjs +9022 -0
- package/fesm2022/forty-cdk-core.mjs.map +1 -0
- package/fesm2022/forty-cdk-date-field.mjs +744 -0
- package/fesm2022/forty-cdk-date-field.mjs.map +1 -0
- package/fesm2022/forty-cdk-date-picker.mjs +1011 -0
- package/fesm2022/forty-cdk-date-picker.mjs.map +1 -0
- package/fesm2022/forty-cdk-dialog.mjs +707 -0
- package/fesm2022/forty-cdk-dialog.mjs.map +1 -0
- package/fesm2022/forty-cdk-disclosure.mjs +190 -0
- package/fesm2022/forty-cdk-disclosure.mjs.map +1 -0
- package/fesm2022/forty-cdk-drag-drop.mjs +1180 -0
- package/fesm2022/forty-cdk-drag-drop.mjs.map +1 -0
- package/fesm2022/forty-cdk-drawer.mjs +1641 -0
- package/fesm2022/forty-cdk-drawer.mjs.map +1 -0
- package/fesm2022/forty-cdk-dropdown-menu.mjs +350 -0
- package/fesm2022/forty-cdk-dropdown-menu.mjs.map +1 -0
- package/fesm2022/forty-cdk-field.mjs +425 -0
- package/fesm2022/forty-cdk-field.mjs.map +1 -0
- package/fesm2022/forty-cdk-fieldset.mjs +164 -0
- package/fesm2022/forty-cdk-fieldset.mjs.map +1 -0
- package/fesm2022/forty-cdk-file-upload.mjs +221 -0
- package/fesm2022/forty-cdk-file-upload.mjs.map +1 -0
- package/fesm2022/forty-cdk-hover-card.mjs +496 -0
- package/fesm2022/forty-cdk-hover-card.mjs.map +1 -0
- package/fesm2022/forty-cdk-input.mjs +274 -0
- package/fesm2022/forty-cdk-input.mjs.map +1 -0
- package/fesm2022/forty-cdk-internationalized-date.mjs +1 -1
- package/fesm2022/forty-cdk-internationalized-date.mjs.map +1 -1
- package/fesm2022/forty-cdk-listbox.mjs +1279 -0
- package/fesm2022/forty-cdk-listbox.mjs.map +1 -0
- package/fesm2022/forty-cdk-menu.mjs +1439 -0
- package/fesm2022/forty-cdk-menu.mjs.map +1 -0
- package/fesm2022/forty-cdk-menubar.mjs +787 -0
- package/fesm2022/forty-cdk-menubar.mjs.map +1 -0
- package/fesm2022/forty-cdk-meter.mjs +211 -0
- package/fesm2022/forty-cdk-meter.mjs.map +1 -0
- package/fesm2022/forty-cdk-navigation-menu.mjs +1145 -0
- package/fesm2022/forty-cdk-navigation-menu.mjs.map +1 -0
- package/fesm2022/forty-cdk-number-input.mjs +559 -0
- package/fesm2022/forty-cdk-number-input.mjs.map +1 -0
- package/fesm2022/forty-cdk-otp-input.mjs +527 -0
- package/fesm2022/forty-cdk-otp-input.mjs.map +1 -0
- package/fesm2022/forty-cdk-pagination.mjs +323 -0
- package/fesm2022/forty-cdk-pagination.mjs.map +1 -0
- package/fesm2022/forty-cdk-pane-resizer.mjs +297 -0
- package/fesm2022/forty-cdk-pane-resizer.mjs.map +1 -0
- package/fesm2022/forty-cdk-popover.mjs +698 -0
- package/fesm2022/forty-cdk-popover.mjs.map +1 -0
- package/fesm2022/forty-cdk-progress.mjs +226 -0
- package/fesm2022/forty-cdk-progress.mjs.map +1 -0
- package/fesm2022/forty-cdk-radio-group.mjs +378 -0
- package/fesm2022/forty-cdk-radio-group.mjs.map +1 -0
- package/fesm2022/forty-cdk-scroll-area.mjs +640 -0
- package/fesm2022/forty-cdk-scroll-area.mjs.map +1 -0
- package/fesm2022/forty-cdk-search.mjs +205 -0
- package/fesm2022/forty-cdk-search.mjs.map +1 -0
- package/fesm2022/forty-cdk-select.mjs +1661 -0
- package/fesm2022/forty-cdk-select.mjs.map +1 -0
- package/fesm2022/forty-cdk-separator.mjs +82 -0
- package/fesm2022/forty-cdk-separator.mjs.map +1 -0
- package/fesm2022/forty-cdk-signal-forms.mjs +97 -0
- package/fesm2022/forty-cdk-signal-forms.mjs.map +1 -0
- package/fesm2022/forty-cdk-slider.mjs +803 -0
- package/fesm2022/forty-cdk-slider.mjs.map +1 -0
- package/fesm2022/forty-cdk-stepper.mjs +886 -0
- package/fesm2022/forty-cdk-stepper.mjs.map +1 -0
- package/fesm2022/forty-cdk-switch.mjs +137 -0
- package/fesm2022/forty-cdk-switch.mjs.map +1 -0
- package/fesm2022/forty-cdk-table.mjs +1518 -0
- package/fesm2022/forty-cdk-table.mjs.map +1 -0
- package/fesm2022/forty-cdk-tabs.mjs +400 -0
- package/fesm2022/forty-cdk-tabs.mjs.map +1 -0
- package/fesm2022/forty-cdk-time-field.mjs +593 -0
- package/fesm2022/forty-cdk-time-field.mjs.map +1 -0
- package/fesm2022/forty-cdk-time-picker.mjs +1013 -0
- package/fesm2022/forty-cdk-time-picker.mjs.map +1 -0
- package/fesm2022/forty-cdk-toast.mjs +1153 -0
- package/fesm2022/forty-cdk-toast.mjs.map +1 -0
- package/fesm2022/forty-cdk-toggle.mjs +516 -0
- package/fesm2022/forty-cdk-toggle.mjs.map +1 -0
- package/fesm2022/forty-cdk-toolbar.mjs +374 -0
- package/fesm2022/forty-cdk-toolbar.mjs.map +1 -0
- package/fesm2022/forty-cdk-tooltip.mjs +672 -0
- package/fesm2022/forty-cdk-tooltip.mjs.map +1 -0
- package/fesm2022/forty-cdk-tree.mjs +2007 -0
- package/fesm2022/forty-cdk-tree.mjs.map +1 -0
- package/fesm2022/forty-cdk-virtualization.mjs +1 -1
- package/fesm2022/forty-cdk-virtualization.mjs.map +1 -1
- package/fesm2022/forty-cdk.mjs +0 -43310
- package/fesm2022/forty-cdk.mjs.map +1 -1
- package/field/README.md +97 -0
- package/fieldset/README.md +86 -0
- package/file-upload/README.md +73 -0
- package/hover-card/README.md +171 -0
- package/input/README.md +156 -0
- package/listbox/README.md +424 -0
- package/menu/README.md +181 -0
- package/menubar/README.md +140 -0
- package/meter/README.md +128 -0
- package/navigation-menu/README.md +253 -0
- package/number-input/README.md +171 -0
- package/otp-input/README.md +198 -0
- package/package.json +213 -1
- package/pagination/README.md +61 -0
- package/pane-resizer/README.md +136 -0
- package/popover/README.md +262 -0
- package/progress/README.md +115 -0
- package/radio-group/README.md +129 -0
- package/scroll-area/README.md +184 -0
- package/search/README.md +42 -0
- package/select/README.md +488 -0
- package/separator/README.md +84 -0
- package/signal-forms/README.md +72 -0
- package/slider/README.md +152 -0
- package/stepper/README.md +292 -0
- package/switch/README.md +116 -0
- package/table/README.md +769 -0
- package/tabs/README.md +130 -0
- package/time-field/README.md +157 -0
- package/time-picker/README.md +172 -0
- package/toast/README.md +398 -0
- package/toggle/README.md +224 -0
- package/toolbar/README.md +109 -0
- package/tooltip/README.md +274 -0
- package/tree/README.md +708 -0
- package/types/forty-cdk-accordion.d.ts +242 -0
- package/types/forty-cdk-aspect-ratio.d.ts +59 -0
- package/types/forty-cdk-avatar.d.ts +133 -0
- package/types/forty-cdk-breadcrumbs.d.ts +92 -0
- package/types/forty-cdk-breakpoints.d.ts +141 -0
- package/types/forty-cdk-button.d.ts +80 -0
- package/types/forty-cdk-calendar.d.ts +914 -0
- package/types/forty-cdk-carousel.d.ts +530 -0
- package/types/forty-cdk-checkbox.d.ts +141 -0
- package/types/forty-cdk-combobox.d.ts +1259 -0
- package/types/forty-cdk-context-menu.d.ts +313 -0
- package/types/forty-cdk-core.d.ts +5774 -0
- package/types/forty-cdk-date-field.d.ts +307 -0
- package/types/forty-cdk-date-picker.d.ts +622 -0
- package/types/forty-cdk-dialog.d.ts +546 -0
- package/types/forty-cdk-disclosure.d.ts +127 -0
- package/types/forty-cdk-drag-drop.d.ts +456 -0
- package/types/forty-cdk-drawer.d.ts +871 -0
- package/types/forty-cdk-dropdown-menu.d.ts +242 -0
- package/types/forty-cdk-field.d.ts +236 -0
- package/types/forty-cdk-fieldset.d.ts +119 -0
- package/types/forty-cdk-file-upload.d.ts +124 -0
- package/types/forty-cdk-hover-card.d.ts +320 -0
- package/types/forty-cdk-input.d.ts +169 -0
- package/types/forty-cdk-internationalized-date.d.ts +1 -1
- package/types/forty-cdk-listbox.d.ts +513 -0
- package/types/forty-cdk-menu.d.ts +629 -0
- package/types/forty-cdk-menubar.d.ts +451 -0
- package/types/forty-cdk-meter.d.ts +122 -0
- package/types/forty-cdk-navigation-menu.d.ts +514 -0
- package/types/forty-cdk-number-input.d.ts +319 -0
- package/types/forty-cdk-otp-input.d.ts +248 -0
- package/types/forty-cdk-pagination.d.ts +214 -0
- package/types/forty-cdk-pane-resizer.d.ts +145 -0
- package/types/forty-cdk-popover.d.ts +509 -0
- package/types/forty-cdk-progress.d.ts +143 -0
- package/types/forty-cdk-radio-group.d.ts +222 -0
- package/types/forty-cdk-scroll-area.d.ts +258 -0
- package/types/forty-cdk-search.d.ts +142 -0
- package/types/forty-cdk-select.d.ts +899 -0
- package/types/forty-cdk-separator.d.ts +59 -0
- package/types/forty-cdk-signal-forms.d.ts +58 -0
- package/types/forty-cdk-slider.d.ts +379 -0
- package/types/forty-cdk-stepper.d.ts +650 -0
- package/types/forty-cdk-switch.d.ts +87 -0
- package/types/forty-cdk-table.d.ts +723 -0
- package/types/forty-cdk-tabs.d.ts +235 -0
- package/types/forty-cdk-time-field.d.ts +307 -0
- package/types/forty-cdk-time-picker.d.ts +578 -0
- package/types/forty-cdk-toast.d.ts +598 -0
- package/types/forty-cdk-toggle.d.ts +310 -0
- package/types/forty-cdk-toolbar.d.ts +217 -0
- package/types/forty-cdk-tooltip.d.ts +436 -0
- package/types/forty-cdk-tree.d.ts +688 -0
- package/types/forty-cdk.d.ts +1 -19743
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"forty-cdk-fieldset.mjs","sources":["../../../projects/forty-cdk/fieldset/src/fieldset.ts","../../../projects/forty-cdk/fieldset/src/fieldset-legend.ts","../../../projects/forty-cdk/fieldset/src/fieldset-defaults.ts","../../../projects/forty-cdk/fieldset/src/forty-cdk-fieldset.ts"],"sourcesContent":["import {\n booleanAttribute,\n computed,\n Directive,\n ElementRef,\n inject,\n input,\n signal,\n} from '@angular/core';\n\nimport {\n reflectDisabled,\n IdGenerator,\n FOR_FIELDSET_CONTEXT,\n type ForFieldsetContext,\n} from 'forty-cdk/core';\n\n/**\n * Headless grouping container that gives a set of related fields a shared\n * accessible name — the styleless counterpart to a native `<fieldset>` +\n * `<legend>`, and the grouping companion to `ForField`.\n *\n * On a native `<fieldset>` it relies on the implicit grouping and emits no\n * role; on any other element it emits `role=\"group\"` + `aria-labelledby`\n * pointing at the `[forFieldsetLegend]` (same host-tag detection idiom as\n * `ForLabel`'s `<label>` check).\n *\n * The `disabled` input reflects `data-disabled` and is provided via context so\n * descendant `ForField` controls OR it into their own disabled state — native\n * `<fieldset disabled>` does not reach custom-role controls like `forSwitch`.\n *\n * @example\n * ```html\n * <fieldset forFieldset [disabled]=\"locked()\">\n * <legend forFieldsetLegend>Shipping address</legend>\n * <div forField>\n * <label forLabel>Street</label>\n * <input forFieldControl />\n * </div>\n * </fieldset>\n * ```\n */\n@Directive({\n selector: '[forFieldset]',\n exportAs: 'forFieldset',\n host: {\n '[attr.role]': 'roleAttr()',\n '[attr.aria-labelledby]': 'labelledBy()',\n '[attr.aria-disabled]': '!isNativeFieldset() && disabled() ? \"true\" : null',\n '[attr.data-disabled]': 'disabled() ? \"\" : null',\n },\n providers: [{ provide: FOR_FIELDSET_CONTEXT, useExisting: ForFieldset }],\n})\nexport class ForFieldset implements ForFieldsetContext {\n readonly #idGen = inject(IdGenerator);\n readonly #host = inject<ElementRef<HTMLElement>>(ElementRef);\n readonly #parent = inject(FOR_FIELDSET_CONTEXT, { optional: true, skipSelf: true });\n readonly #legends = signal(0);\n\n /**\n * Whether the group is disabled, as bound by the consumer via `[disabled]`.\n * The host reflection and descendant controls read the composed\n * {@link disabled} signal below, which also folds in an enclosing disabled\n * `[forFieldset]`.\n */\n readonly disabledInput = input(false, { transform: booleanAttribute, alias: 'disabled' });\n\n /**\n * Effective disabled: the group's own `[disabled]` OR'd with an enclosing\n * disabled `[forFieldset]`. Reflects `data-disabled`, emits the native\n * `disabled` attribute on a `<fieldset>` (or `aria-disabled` elsewhere), and\n * propagates to descendant controls via context — so a disabled fieldset\n * reaches custom-role controls (`forSwitch`, `forCheckbox`, …) a native\n * `<fieldset disabled>` can't, and nesting composes like native fieldsets\n * (a disabled outer group cannot be re-enabled by an inner one).\n */\n readonly disabled = computed(() => this.disabledInput() || (this.#parent?.disabled() ?? false));\n\n /** Id of the legend element; the group's `aria-labelledby` resolves here. */\n readonly legendId = signal(this.#idGen.next('for-fieldset-legend'));\n\n /** Whether the host element is a native `<fieldset>` (no role/labelledby needed). */\n protected readonly isNativeFieldset = computed(\n () => this.#host.nativeElement.tagName === 'FIELDSET',\n );\n\n /**\n * Native `disabled` is reflected only on a real `<fieldset>` (where it\n * natively disables descendant controls); a non-`<fieldset>` host advertises\n * its disabled state via `aria-disabled` instead.\n */\n protected readonly nativeDisabled = computed(() => this.isNativeFieldset() && this.disabled());\n\n constructor() {\n reflectDisabled(this.nativeDisabled);\n }\n\n /** `role=\"group\"` on a non-`<fieldset>` element, else null. */\n protected readonly roleAttr = computed(() => (this.isNativeFieldset() ? null : 'group'));\n\n /**\n * Resolved `aria-labelledby`: the legend id on a non-`<fieldset>` element when\n * a legend is registered, else null (a native `<fieldset>`/`<legend>` groups\n * implicitly and needs none).\n */\n protected readonly labelledBy = computed(() =>\n !this.isNativeFieldset() && this.#legends() > 0 ? this.legendId() : null,\n );\n\n /** Mark a legend present; returns an unregister callback. */\n registerLegend(): () => void {\n this.#legends.update((n) => n + 1);\n return () => this.#legends.update((n) => n - 1);\n }\n}\n","import { computed, DestroyRef, Directive, inject } from '@angular/core';\n\nimport { FOR_FIELDSET_CONTEXT } from 'forty-cdk/core';\n\n/**\n * Accessible group label for a `[forFieldset]`. Inside a fieldset it adopts the\n * fieldset's `legendId` and registers itself so the group's `aria-labelledby`\n * resolves; on a native `<fieldset>`/`<legend>` the id is harmless extra wiring\n * (the browser groups implicitly).\n *\n * Usable standalone outside a fieldset — there it is an inert marker.\n *\n * @example\n * ```html\n * <div forFieldset>\n * <span forFieldsetLegend>Notification preferences</span>\n * <!-- … fields … -->\n * </div>\n * ```\n */\n@Directive({\n selector: '[forFieldsetLegend]',\n exportAs: 'forFieldsetLegend',\n host: {\n '[attr.id]': 'legendId()',\n },\n})\nexport class ForFieldsetLegend {\n protected readonly ctx = inject(FOR_FIELDSET_CONTEXT, { optional: true });\n\n /** The legend's id when inside a fieldset, else null. */\n protected readonly legendId = computed(() => this.ctx?.legendId() ?? null);\n\n constructor() {\n const ctx = this.ctx;\n if (ctx) {\n const unregister = ctx.registerLegend();\n inject(DestroyRef).onDestroy(unregister);\n }\n }\n}\n","import { type Provider } from '@angular/core';\n\nimport { createDefaults } from 'forty-cdk/core';\n\n/**\n * Defaults inherited by descendant fieldsets in the surrounding injector scope.\n * Configure with `provideForFieldsetDefaults`. The shape is a stub today —\n * present so future per-scope tuning can land without churning the public\n * surface.\n */\n// eslint-disable-next-line @typescript-eslint/no-empty-object-type\nexport interface ForFieldsetDefaults {}\n\nconst FALLBACK: ForFieldsetDefaults = {};\n\nconst { token, provideDefaults } = createDefaults<ForFieldsetDefaults>(\n 'FOR_FIELDSET_DEFAULTS',\n FALLBACK,\n);\n\n/** Token holding the resolved fieldset defaults for the current scope. */\nexport const FOR_FIELDSET_DEFAULTS = token;\n\n/**\n * Configures forty-cdk fieldset defaults for this injector scope. Partial\n * overrides inherit unspecified keys from the parent scope (or library\n * defaults at the root).\n */\nexport function provideForFieldsetDefaults(\n defaults: Partial<ForFieldsetDefaults> = {},\n): Provider[] {\n return provideDefaults(defaults);\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { InjectionToken, inject, input, booleanAttribute, output, signal, Directive, ElementRef } from '@angular/core';
|
|
3
|
+
import { reflectDisabled, createDefaults } from 'forty-cdk/core';
|
|
4
|
+
|
|
5
|
+
const FOR_FILE_UPLOAD_CONTEXT = new InjectionToken('FOR_FILE_UPLOAD_CONTEXT');
|
|
6
|
+
/**
|
|
7
|
+
* Injects the file-upload context or throws a prefixed, actionable error
|
|
8
|
+
* naming the piece that was used outside `[forFileUpload]`.
|
|
9
|
+
*/
|
|
10
|
+
function injectFileUploadContext(piece) {
|
|
11
|
+
const ctx = inject(FOR_FILE_UPLOAD_CONTEXT, { optional: true });
|
|
12
|
+
if (!ctx) {
|
|
13
|
+
throw new Error(`[forty-cdk/file-upload] ${piece} must be used inside a [forFileUpload] element.`);
|
|
14
|
+
}
|
|
15
|
+
return ctx;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Root drop zone for the FileUpload primitive. Composes with
|
|
20
|
+
* `[forFileUploadInput]` (the accessible native file input) and
|
|
21
|
+
* `[forFileUploadTrigger]` (the button that opens the dialog).
|
|
22
|
+
*
|
|
23
|
+
* `filesChange` is a plain `output<FileList>()` — this primitive is not a
|
|
24
|
+
* Signal Forms control; the native `<input type="file">` is the form participant.
|
|
25
|
+
*
|
|
26
|
+
* Reflects `data-dragging` while files are dragged over the zone and
|
|
27
|
+
* `data-disabled` when the input is disabled.
|
|
28
|
+
*/
|
|
29
|
+
class ForFileUpload {
|
|
30
|
+
/** MIME types or file extensions accepted by the file chooser (e.g. `"image/*,.pdf"`). */
|
|
31
|
+
accept = input(null, /* @ts-ignore */
|
|
32
|
+
...(ngDevMode ? [{ debugName: "accept" }] : /* istanbul ignore next */ []));
|
|
33
|
+
/** Whether multiple files can be selected at once. */
|
|
34
|
+
multiple = input(false, { ...(ngDevMode ? { debugName: "multiple" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
35
|
+
/**
|
|
36
|
+
* When `true`, the native picker selects a whole folder; the emitted
|
|
37
|
+
* `FileList` then contains every file inside it (each carrying a
|
|
38
|
+
* `webkitRelativePath` so the consumer can reconstruct the tree).
|
|
39
|
+
*/
|
|
40
|
+
directory = input(false, { ...(ngDevMode ? { debugName: "directory" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
41
|
+
/** Whether the file upload zone and all its pieces are disabled. */
|
|
42
|
+
disabled = input(false, { ...(ngDevMode ? { debugName: "disabled" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
43
|
+
/** Emitted when files are chosen via the dialog or dropped onto the zone. */
|
|
44
|
+
filesChange = output();
|
|
45
|
+
#dragging = signal(false, /* @ts-ignore */
|
|
46
|
+
...(ngDevMode ? [{ debugName: "#dragging" }] : /* istanbul ignore next */ []));
|
|
47
|
+
dragging = this.#dragging.asReadonly();
|
|
48
|
+
#dragDepth = 0;
|
|
49
|
+
#input = null;
|
|
50
|
+
/** Registers the native input so the root can open the dialog and sync dropped files. */
|
|
51
|
+
registerInput(el) {
|
|
52
|
+
this.#input = el;
|
|
53
|
+
}
|
|
54
|
+
/** Opens the native file chooser dialog if not disabled. */
|
|
55
|
+
openFileDialog() {
|
|
56
|
+
if (this.disabled())
|
|
57
|
+
return;
|
|
58
|
+
this.#input?.click();
|
|
59
|
+
}
|
|
60
|
+
/** Emits `filesChange` with the provided `FileList` if it contains at least one file. */
|
|
61
|
+
emitFiles(files) {
|
|
62
|
+
if (files.length > 0)
|
|
63
|
+
this.filesChange.emit(files);
|
|
64
|
+
}
|
|
65
|
+
onDragEnter(event) {
|
|
66
|
+
if (this.disabled())
|
|
67
|
+
return;
|
|
68
|
+
event.preventDefault();
|
|
69
|
+
this.#dragDepth++;
|
|
70
|
+
this.#dragging.set(true);
|
|
71
|
+
}
|
|
72
|
+
onDragOver(event) {
|
|
73
|
+
if (this.disabled())
|
|
74
|
+
return;
|
|
75
|
+
event.preventDefault();
|
|
76
|
+
if (event.dataTransfer)
|
|
77
|
+
event.dataTransfer.dropEffect = 'copy';
|
|
78
|
+
}
|
|
79
|
+
onDragLeave() {
|
|
80
|
+
if (this.disabled())
|
|
81
|
+
return;
|
|
82
|
+
this.#dragDepth = Math.max(0, this.#dragDepth - 1);
|
|
83
|
+
if (this.#dragDepth === 0)
|
|
84
|
+
this.#dragging.set(false);
|
|
85
|
+
}
|
|
86
|
+
onDrop(event) {
|
|
87
|
+
if (this.disabled())
|
|
88
|
+
return;
|
|
89
|
+
event.preventDefault();
|
|
90
|
+
this.#dragDepth = 0;
|
|
91
|
+
this.#dragging.set(false);
|
|
92
|
+
const dropped = event.dataTransfer?.files;
|
|
93
|
+
if (!dropped || dropped.length === 0)
|
|
94
|
+
return;
|
|
95
|
+
const files = this.#resolveFiles(dropped);
|
|
96
|
+
if (this.#input)
|
|
97
|
+
this.#input.files = files;
|
|
98
|
+
this.emitFiles(files);
|
|
99
|
+
}
|
|
100
|
+
#resolveFiles(files) {
|
|
101
|
+
if (this.multiple() || files.length <= 1)
|
|
102
|
+
return files;
|
|
103
|
+
const dataTransfer = new DataTransfer();
|
|
104
|
+
dataTransfer.items.add(files[0]);
|
|
105
|
+
return dataTransfer.files;
|
|
106
|
+
}
|
|
107
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: ForFileUpload, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
108
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.0.2", type: ForFileUpload, isStandalone: true, selector: "[forFileUpload]", inputs: { accept: { classPropertyName: "accept", publicName: "accept", isSignal: true, isRequired: false, transformFunction: null }, multiple: { classPropertyName: "multiple", publicName: "multiple", isSignal: true, isRequired: false, transformFunction: null }, directory: { classPropertyName: "directory", publicName: "directory", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { filesChange: "filesChange" }, host: { listeners: { "dragenter": "onDragEnter($event)", "dragover": "onDragOver($event)", "dragleave": "onDragLeave()", "drop": "onDrop($event)" }, properties: { "attr.data-dragging": "dragging() ? '' : null", "attr.data-disabled": "disabled() ? '' : null" } }, providers: [{ provide: FOR_FILE_UPLOAD_CONTEXT, useExisting: ForFileUpload }], exportAs: ["forFileUpload"], ngImport: i0 });
|
|
109
|
+
}
|
|
110
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: ForFileUpload, decorators: [{
|
|
111
|
+
type: Directive,
|
|
112
|
+
args: [{
|
|
113
|
+
selector: '[forFileUpload]',
|
|
114
|
+
exportAs: 'forFileUpload',
|
|
115
|
+
host: {
|
|
116
|
+
'[attr.data-dragging]': "dragging() ? '' : null",
|
|
117
|
+
'[attr.data-disabled]': "disabled() ? '' : null",
|
|
118
|
+
'(dragenter)': 'onDragEnter($event)',
|
|
119
|
+
'(dragover)': 'onDragOver($event)',
|
|
120
|
+
'(dragleave)': 'onDragLeave()',
|
|
121
|
+
'(drop)': 'onDrop($event)',
|
|
122
|
+
},
|
|
123
|
+
providers: [{ provide: FOR_FILE_UPLOAD_CONTEXT, useExisting: ForFileUpload }],
|
|
124
|
+
}]
|
|
125
|
+
}], propDecorators: { accept: [{ type: i0.Input, args: [{ isSignal: true, alias: "accept", required: false }] }], multiple: [{ type: i0.Input, args: [{ isSignal: true, alias: "multiple", required: false }] }], directory: [{ type: i0.Input, args: [{ isSignal: true, alias: "directory", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], filesChange: [{ type: i0.Output, args: ["filesChange"] }] } });
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* The native `<input type="file">` piece of the FileUpload primitive.
|
|
129
|
+
* Apply on a real `<input>` element inside `[forFileUpload]`.
|
|
130
|
+
*
|
|
131
|
+
* The directive forces `type="file"` and mirrors `accept`, `multiple`,
|
|
132
|
+
* `directory` (as `webkitdirectory`), and `disabled` from the root context.
|
|
133
|
+
* When the user selects files via the native dialog the `change` event emits
|
|
134
|
+
* `filesChange` on the root.
|
|
135
|
+
*
|
|
136
|
+
* Consumers are expected to visually hide this input with their own CSS
|
|
137
|
+
* (e.g. an `sr-only` / `visually-hidden` utility) while keeping it focusable
|
|
138
|
+
* so keyboard users and assistive technology can activate it directly. The
|
|
139
|
+
* directive never sets `hidden`, `display:none`, or `visibility:hidden` — it
|
|
140
|
+
* remains strictly headless.
|
|
141
|
+
*/
|
|
142
|
+
class ForFileUploadInput {
|
|
143
|
+
#el = inject(ElementRef).nativeElement;
|
|
144
|
+
ctx = injectFileUploadContext('[forFileUploadInput]');
|
|
145
|
+
constructor() {
|
|
146
|
+
this.ctx.registerInput(this.#el);
|
|
147
|
+
}
|
|
148
|
+
onChange() {
|
|
149
|
+
const files = this.#el.files;
|
|
150
|
+
if (files && files.length > 0)
|
|
151
|
+
this.ctx.emitFiles(files);
|
|
152
|
+
}
|
|
153
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: ForFileUploadInput, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
154
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.0.2", type: ForFileUploadInput, isStandalone: true, selector: "input[forFileUploadInput]", host: { attributes: { "type": "file" }, listeners: { "change": "onChange()" }, properties: { "attr.accept": "ctx.accept()", "attr.multiple": "ctx.multiple() ? '' : null", "attr.webkitdirectory": "ctx.directory() ? '' : null", "disabled": "ctx.disabled()" } }, exportAs: ["forFileUploadInput"], ngImport: i0 });
|
|
155
|
+
}
|
|
156
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: ForFileUploadInput, decorators: [{
|
|
157
|
+
type: Directive,
|
|
158
|
+
args: [{
|
|
159
|
+
selector: 'input[forFileUploadInput]',
|
|
160
|
+
exportAs: 'forFileUploadInput',
|
|
161
|
+
host: {
|
|
162
|
+
type: 'file',
|
|
163
|
+
'[attr.accept]': 'ctx.accept()',
|
|
164
|
+
'[attr.multiple]': "ctx.multiple() ? '' : null",
|
|
165
|
+
'[attr.webkitdirectory]': "ctx.directory() ? '' : null",
|
|
166
|
+
'[disabled]': 'ctx.disabled()',
|
|
167
|
+
'(change)': 'onChange()',
|
|
168
|
+
},
|
|
169
|
+
}]
|
|
170
|
+
}], ctorParameters: () => [] });
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* Trigger button that opens the native file chooser dialog.
|
|
174
|
+
* Apply on a native `<button>` inside `[forFileUpload]`.
|
|
175
|
+
*
|
|
176
|
+
* `type="button"` is forced to prevent accidental form submission.
|
|
177
|
+
* The native `disabled` attribute is reflected imperatively so the button
|
|
178
|
+
* is visually and functionally disabled when the root zone is disabled.
|
|
179
|
+
*/
|
|
180
|
+
class ForFileUploadTrigger {
|
|
181
|
+
ctx = injectFileUploadContext('[forFileUploadTrigger]');
|
|
182
|
+
constructor() {
|
|
183
|
+
reflectDisabled(this.ctx.disabled);
|
|
184
|
+
}
|
|
185
|
+
onClick() {
|
|
186
|
+
this.ctx.openFileDialog();
|
|
187
|
+
}
|
|
188
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: ForFileUploadTrigger, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
189
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.0.2", type: ForFileUploadTrigger, isStandalone: true, selector: "[forFileUploadTrigger]", host: { attributes: { "type": "button" }, listeners: { "click": "onClick()" } }, exportAs: ["forFileUploadTrigger"], ngImport: i0 });
|
|
190
|
+
}
|
|
191
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: ForFileUploadTrigger, decorators: [{
|
|
192
|
+
type: Directive,
|
|
193
|
+
args: [{
|
|
194
|
+
selector: '[forFileUploadTrigger]',
|
|
195
|
+
exportAs: 'forFileUploadTrigger',
|
|
196
|
+
host: {
|
|
197
|
+
type: 'button',
|
|
198
|
+
'(click)': 'onClick()',
|
|
199
|
+
},
|
|
200
|
+
}]
|
|
201
|
+
}], ctorParameters: () => [] });
|
|
202
|
+
|
|
203
|
+
const FALLBACK = {};
|
|
204
|
+
const { token, provideDefaults } = createDefaults('FOR_FILE_UPLOAD_DEFAULTS', FALLBACK);
|
|
205
|
+
/** Token holding the resolved file-upload defaults for the current scope. */
|
|
206
|
+
const FOR_FILE_UPLOAD_DEFAULTS = token;
|
|
207
|
+
/**
|
|
208
|
+
* Configures forty-cdk file-upload defaults for this injector scope. Partial
|
|
209
|
+
* overrides inherit unspecified keys from the parent scope (or library
|
|
210
|
+
* defaults at the root).
|
|
211
|
+
*/
|
|
212
|
+
function provideForFileUploadDefaults(defaults = {}) {
|
|
213
|
+
return provideDefaults(defaults);
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
/**
|
|
217
|
+
* Generated bundle index. Do not edit.
|
|
218
|
+
*/
|
|
219
|
+
|
|
220
|
+
export { FOR_FILE_UPLOAD_CONTEXT, FOR_FILE_UPLOAD_DEFAULTS, ForFileUpload, ForFileUploadInput, ForFileUploadTrigger, provideForFileUploadDefaults };
|
|
221
|
+
//# sourceMappingURL=forty-cdk-file-upload.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"forty-cdk-file-upload.mjs","sources":["../../../projects/forty-cdk/file-upload/src/file-upload-context.ts","../../../projects/forty-cdk/file-upload/src/file-upload.ts","../../../projects/forty-cdk/file-upload/src/file-upload-input.ts","../../../projects/forty-cdk/file-upload/src/file-upload-trigger.ts","../../../projects/forty-cdk/file-upload/src/file-upload-defaults.ts","../../../projects/forty-cdk/file-upload/src/forty-cdk-file-upload.ts"],"sourcesContent":["import { inject, InjectionToken, type Signal } from '@angular/core';\n\n/**\n * Shared state contract between the pieces of a FileUpload primitive.\n * Provided by `ForFileUpload`, consumed by `ForFileUploadInput` and\n * `ForFileUploadTrigger`.\n */\nexport interface ForFileUploadContext {\n readonly accept: Signal<string | null>;\n readonly multiple: Signal<boolean>;\n readonly directory: Signal<boolean>;\n readonly disabled: Signal<boolean>;\n /** Registers the native `<input type=\"file\">` so the root can open the dialog and sync dropped files. */\n registerInput(el: HTMLInputElement): void;\n /** Opens the native file chooser dialog by programmatically clicking the registered input. */\n openFileDialog(): void;\n /** Emits `filesChange` with the given `FileList` if it is non-empty. */\n emitFiles(files: FileList): void;\n}\n\nexport const FOR_FILE_UPLOAD_CONTEXT = new InjectionToken<ForFileUploadContext>(\n 'FOR_FILE_UPLOAD_CONTEXT',\n);\n\n/**\n * Injects the file-upload context or throws a prefixed, actionable error\n * naming the piece that was used outside `[forFileUpload]`.\n */\nexport function injectFileUploadContext(piece: string): ForFileUploadContext {\n const ctx = inject(FOR_FILE_UPLOAD_CONTEXT, { optional: true });\n if (!ctx) {\n throw new Error(\n `[forty-cdk/file-upload] ${piece} must be used inside a [forFileUpload] element.`,\n );\n }\n return ctx;\n}\n","import { booleanAttribute, Directive, input, output, signal } from '@angular/core';\n\nimport { FOR_FILE_UPLOAD_CONTEXT, type ForFileUploadContext } from './file-upload-context';\n\n/**\n * Root drop zone for the FileUpload primitive. Composes with\n * `[forFileUploadInput]` (the accessible native file input) and\n * `[forFileUploadTrigger]` (the button that opens the dialog).\n *\n * `filesChange` is a plain `output<FileList>()` — this primitive is not a\n * Signal Forms control; the native `<input type=\"file\">` is the form participant.\n *\n * Reflects `data-dragging` while files are dragged over the zone and\n * `data-disabled` when the input is disabled.\n */\n@Directive({\n selector: '[forFileUpload]',\n exportAs: 'forFileUpload',\n host: {\n '[attr.data-dragging]': \"dragging() ? '' : null\",\n '[attr.data-disabled]': \"disabled() ? '' : null\",\n '(dragenter)': 'onDragEnter($event)',\n '(dragover)': 'onDragOver($event)',\n '(dragleave)': 'onDragLeave()',\n '(drop)': 'onDrop($event)',\n },\n providers: [{ provide: FOR_FILE_UPLOAD_CONTEXT, useExisting: ForFileUpload }],\n})\nexport class ForFileUpload implements ForFileUploadContext {\n /** MIME types or file extensions accepted by the file chooser (e.g. `\"image/*,.pdf\"`). */\n readonly accept = input<string | null>(null);\n /** Whether multiple files can be selected at once. */\n readonly multiple = input(false, { transform: booleanAttribute });\n /**\n * When `true`, the native picker selects a whole folder; the emitted\n * `FileList` then contains every file inside it (each carrying a\n * `webkitRelativePath` so the consumer can reconstruct the tree).\n */\n readonly directory = input(false, { transform: booleanAttribute });\n /** Whether the file upload zone and all its pieces are disabled. */\n readonly disabled = input(false, { transform: booleanAttribute });\n /** Emitted when files are chosen via the dialog or dropped onto the zone. */\n readonly filesChange = output<FileList>();\n\n readonly #dragging = signal(false);\n protected readonly dragging = this.#dragging.asReadonly();\n #dragDepth = 0;\n #input: HTMLInputElement | null = null;\n\n /** Registers the native input so the root can open the dialog and sync dropped files. */\n registerInput(el: HTMLInputElement): void {\n this.#input = el;\n }\n\n /** Opens the native file chooser dialog if not disabled. */\n openFileDialog(): void {\n if (this.disabled()) return;\n this.#input?.click();\n }\n\n /** Emits `filesChange` with the provided `FileList` if it contains at least one file. */\n emitFiles(files: FileList): void {\n if (files.length > 0) this.filesChange.emit(files);\n }\n\n protected onDragEnter(event: DragEvent): void {\n if (this.disabled()) return;\n event.preventDefault();\n this.#dragDepth++;\n this.#dragging.set(true);\n }\n\n protected onDragOver(event: DragEvent): void {\n if (this.disabled()) return;\n event.preventDefault();\n if (event.dataTransfer) event.dataTransfer.dropEffect = 'copy';\n }\n\n protected onDragLeave(): void {\n if (this.disabled()) return;\n this.#dragDepth = Math.max(0, this.#dragDepth - 1);\n if (this.#dragDepth === 0) this.#dragging.set(false);\n }\n\n protected onDrop(event: DragEvent): void {\n if (this.disabled()) return;\n event.preventDefault();\n this.#dragDepth = 0;\n this.#dragging.set(false);\n const dropped = event.dataTransfer?.files;\n if (!dropped || dropped.length === 0) return;\n const files = this.#resolveFiles(dropped);\n if (this.#input) this.#input.files = files;\n this.emitFiles(files);\n }\n\n #resolveFiles(files: FileList): FileList {\n if (this.multiple() || files.length <= 1) return files;\n const dataTransfer = new DataTransfer();\n dataTransfer.items.add(files[0]!);\n return dataTransfer.files;\n }\n}\n","import { Directive, ElementRef, inject } from '@angular/core';\n\nimport { injectFileUploadContext } from './file-upload-context';\n\n/**\n * The native `<input type=\"file\">` piece of the FileUpload primitive.\n * Apply on a real `<input>` element inside `[forFileUpload]`.\n *\n * The directive forces `type=\"file\"` and mirrors `accept`, `multiple`,\n * `directory` (as `webkitdirectory`), and `disabled` from the root context.\n * When the user selects files via the native dialog the `change` event emits\n * `filesChange` on the root.\n *\n * Consumers are expected to visually hide this input with their own CSS\n * (e.g. an `sr-only` / `visually-hidden` utility) while keeping it focusable\n * so keyboard users and assistive technology can activate it directly. The\n * directive never sets `hidden`, `display:none`, or `visibility:hidden` — it\n * remains strictly headless.\n */\n@Directive({\n selector: 'input[forFileUploadInput]',\n exportAs: 'forFileUploadInput',\n host: {\n type: 'file',\n '[attr.accept]': 'ctx.accept()',\n '[attr.multiple]': \"ctx.multiple() ? '' : null\",\n '[attr.webkitdirectory]': \"ctx.directory() ? '' : null\",\n '[disabled]': 'ctx.disabled()',\n '(change)': 'onChange()',\n },\n})\nexport class ForFileUploadInput {\n readonly #el = inject<ElementRef<HTMLInputElement>>(ElementRef).nativeElement;\n protected readonly ctx = injectFileUploadContext('[forFileUploadInput]');\n\n constructor() {\n this.ctx.registerInput(this.#el);\n }\n\n protected onChange(): void {\n const files = this.#el.files;\n if (files && files.length > 0) this.ctx.emitFiles(files);\n }\n}\n","import { Directive } from '@angular/core';\n\nimport { reflectDisabled } from 'forty-cdk/core';\nimport { injectFileUploadContext } from './file-upload-context';\n\n/**\n * Trigger button that opens the native file chooser dialog.\n * Apply on a native `<button>` inside `[forFileUpload]`.\n *\n * `type=\"button\"` is forced to prevent accidental form submission.\n * The native `disabled` attribute is reflected imperatively so the button\n * is visually and functionally disabled when the root zone is disabled.\n */\n@Directive({\n selector: '[forFileUploadTrigger]',\n exportAs: 'forFileUploadTrigger',\n host: {\n type: 'button',\n '(click)': 'onClick()',\n },\n})\nexport class ForFileUploadTrigger {\n protected readonly ctx = injectFileUploadContext('[forFileUploadTrigger]');\n\n constructor() {\n reflectDisabled(this.ctx.disabled);\n }\n\n protected onClick(): void {\n this.ctx.openFileDialog();\n }\n}\n","import { type Provider } from '@angular/core';\n\nimport { createDefaults } from 'forty-cdk/core';\n\n/**\n * Defaults inherited by descendant file-upload zones in the surrounding\n * injector scope. Configure with `provideForFileUploadDefaults`. The shape\n * is a stub today — present so future per-scope tuning can land without\n * churning the public surface.\n */\n// eslint-disable-next-line @typescript-eslint/no-empty-object-type\nexport interface ForFileUploadDefaults {}\n\nconst FALLBACK: ForFileUploadDefaults = {};\n\nconst { token, provideDefaults } = createDefaults<ForFileUploadDefaults>(\n 'FOR_FILE_UPLOAD_DEFAULTS',\n FALLBACK,\n);\n\n/** Token holding the resolved file-upload defaults for the current scope. */\nexport const FOR_FILE_UPLOAD_DEFAULTS = token;\n\n/**\n * Configures forty-cdk file-upload defaults for this injector scope. Partial\n * overrides inherit unspecified keys from the parent scope (or library\n * defaults at the root).\n */\nexport function provideForFileUploadDefaults(\n defaults: Partial<ForFileUploadDefaults> = {},\n): Provider[] {\n return provideDefaults(defaults);\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|