@motifx-community/ui 0.1.0-beta.1 → 0.1.0-beta.2
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/CHANGELOG.md +64 -0
- package/README.md +16 -10
- package/dist/components/calendar/Calendar.d.ts +12 -0
- package/dist/components/calendar/calendar-props.d.ts +5 -0
- package/dist/components/daterangebox/DateRangeBox.d.ts +121 -0
- package/dist/components/daterangebox/date-range-box-props.d.ts +35 -0
- package/dist/components/daterangebox/date-range-preset.d.ts +6 -0
- package/dist/components/daterangebox/date-range.d.ts +2 -0
- package/dist/components/daterangebox/index.d.ts +4 -0
- package/dist/components/fileuploader/FileUploader.d.ts +133 -0
- package/dist/components/fileuploader/file-uploader-props.d.ts +46 -0
- package/dist/components/fileuploader/files-added-event-args.d.ts +9 -0
- package/dist/components/fileuploader/index.d.ts +7 -0
- package/dist/components/fileuploader/upload-event-args.d.ts +10 -0
- package/dist/components/fileuploader/upload-item.d.ts +12 -0
- package/dist/components/fileuploader/upload-mode.d.ts +2 -0
- package/dist/components/fileuploader/upload-status.d.ts +2 -0
- package/dist/components/loadpanel/LoadPanel.d.ts +70 -0
- package/dist/components/loadpanel/index.d.ts +3 -0
- package/dist/components/loadpanel/load-panel-props.d.ts +29 -0
- package/dist/components/loadpanel/load-panel-target.d.ts +3 -0
- package/dist/components/popover/Popover.d.ts +98 -0
- package/dist/components/popover/index.d.ts +5 -0
- package/dist/components/popover/popover-close-reason.d.ts +2 -0
- package/dist/components/popover/popover-closing-event-args.d.ts +8 -0
- package/dist/components/popover/popover-props.d.ts +39 -0
- package/dist/components/popover/popover-show-on.d.ts +2 -0
- package/dist/components/scrollview/ScrollView.d.ts +109 -0
- package/dist/components/scrollview/index.d.ts +7 -0
- package/dist/components/scrollview/pull-down-event-args.d.ts +9 -0
- package/dist/components/scrollview/reach-bottom-event-args.d.ts +9 -0
- package/dist/components/scrollview/scroll-event-args.d.ts +7 -0
- package/dist/components/scrollview/scroll-view-bars.d.ts +2 -0
- package/dist/components/scrollview/scroll-view-direction.d.ts +2 -0
- package/dist/components/scrollview/scroll-view-props.d.ts +31 -0
- package/dist/components/sortable/Sortable.d.ts +106 -0
- package/dist/components/sortable/index.d.ts +5 -0
- package/dist/components/sortable/sortable-drag-event-args.d.ts +15 -0
- package/dist/components/sortable/sortable-drop-event-args.d.ts +11 -0
- package/dist/components/sortable/sortable-orientation.d.ts +2 -0
- package/dist/components/sortable/sortable-props.d.ts +34 -0
- package/dist/components/stepper/Stepper.d.ts +121 -0
- package/dist/components/stepper/Wizard.d.ts +112 -0
- package/dist/components/stepper/WizardStep.d.ts +44 -0
- package/dist/components/stepper/index.d.ts +13 -0
- package/dist/components/stepper/step-changed-event-args.d.ts +11 -0
- package/dist/components/stepper/step-changing-event-args.d.ts +18 -0
- package/dist/components/stepper/stepper-item.d.ts +20 -0
- package/dist/components/stepper/stepper-label-position.d.ts +2 -0
- package/dist/components/stepper/stepper-orientation.d.ts +1 -0
- package/dist/components/stepper/stepper-props.d.ts +32 -0
- package/dist/components/stepper/stepper-status.d.ts +2 -0
- package/dist/components/stepper/wizard-finishing-event-args.d.ts +7 -0
- package/dist/components/stepper/wizard-props.d.ts +48 -0
- package/dist/components/stepper/wizard-step-props.d.ts +32 -0
- package/dist/core/flow-home.d.ts +6 -0
- package/dist/core/fold-text.d.ts +6 -0
- package/dist/core/ui-locale.d.ts +0 -2
- package/dist/core/ui-strings.d.ts +41 -0
- package/dist/generated/tokens.d.ts +1146 -11
- package/dist/index.d.ts +8 -1
- package/dist/index.js +22564 -20283
- package/dist/index.js.map +1 -1
- package/dist/locales/en.json +38 -1
- package/dist/locales/tr.json +38 -1
- package/dist/styles.css +1825 -5
- package/dist/tokens/index.d.ts +1146 -11
- package/dist/tokens/index.js +1146 -11
- package/dist/tokens/index.js.map +1 -1
- package/dist/tr-B218zMtu.js +1191 -0
- package/dist/tr-B218zMtu.js.map +1 -0
- package/docs/accordion.md +1 -1
- package/docs/actionsheet.md +1 -1
- package/docs/avatar.md +1 -1
- package/docs/badge.md +1 -1
- package/docs/bottomsheet.md +3 -3
- package/docs/breadcrumb.md +2 -2
- package/docs/button.md +3 -3
- package/docs/buttongroup.md +1 -1
- package/docs/calendar.md +1 -1
- package/docs/card.md +1 -1
- package/docs/checkbox.md +3 -3
- package/docs/chip.md +1 -1
- package/docs/colorbox.md +1 -1
- package/docs/combobox.md +1 -1
- package/docs/control.md +1 -1
- package/docs/datagrid-api.md +3 -3
- package/docs/datagrid-bands.md +1 -1
- package/docs/datagrid-drag-select.md +1 -1
- package/docs/datagrid-drag.md +1 -1
- package/docs/datagrid-editing.md +1 -1
- package/docs/datagrid-filtering.md +1 -1
- package/docs/datagrid-forms.md +1 -1
- package/docs/datagrid-grouping.md +1 -1
- package/docs/datagrid-layout.md +1 -1
- package/docs/datagrid-lookups.md +1 -1
- package/docs/datagrid-master-detail.md +1 -1
- package/docs/datagrid-scrolling.md +1 -1
- package/docs/datagrid-selection.md +1 -1
- package/docs/datagrid.md +1 -1
- package/docs/datebox.md +3 -3
- package/docs/daterangebox.md +192 -0
- package/docs/drawer.md +1 -1
- package/docs/dropdown.md +3 -3
- package/docs/fileuploader.md +201 -0
- package/docs/filterbuilder.md +3 -3
- package/docs/formlayout.md +1 -1
- package/docs/home.md +1 -1
- package/docs/keyboard.md +1 -1
- package/docs/language.md +229 -0
- package/docs/layout.md +3 -3
- package/docs/listbox.md +3 -3
- package/docs/loadpanel.md +184 -0
- package/docs/lookup.md +1 -1
- package/docs/menus.md +1 -1
- package/docs/numberbox.md +3 -3
- package/docs/pagination.md +1 -1
- package/docs/popover.md +221 -0
- package/docs/progress.md +3 -3
- package/docs/radiogroup.md +1 -1
- package/docs/rating.md +1 -1
- package/docs/scheduler-agenda.md +1 -1
- package/docs/scheduler-big-data.md +1 -1
- package/docs/scheduler-editing.md +1 -1
- package/docs/scheduler-form.md +1 -1
- package/docs/scheduler-icalendar.md +1 -1
- package/docs/scheduler-mobile.md +1 -1
- package/docs/scheduler-recurrence.md +1 -1
- package/docs/scheduler-resources.md +1 -1
- package/docs/scheduler-timeline.md +1 -1
- package/docs/scheduler.md +1 -1
- package/docs/scrollview.md +185 -0
- package/docs/showcase.md +1 -1
- package/docs/skeleton.md +1 -1
- package/docs/slider.md +3 -3
- package/docs/sortable.md +213 -0
- package/docs/stepper.md +238 -0
- package/docs/switch.md +1 -1
- package/docs/tabdocs-dock.md +1 -1
- package/docs/tabdocs-drag.md +1 -1
- package/docs/tabdocs-menus.md +1 -1
- package/docs/tabdocs-mobile.md +1 -1
- package/docs/tabdocs-tabs.md +1 -1
- package/docs/tabdocs-windows.md +1 -1
- package/docs/tabdocs-workspace.md +1 -1
- package/docs/tabdocs.md +1 -1
- package/docs/tabs.md +3 -3
- package/docs/tagbox.md +3 -3
- package/docs/textarea.md +3 -3
- package/docs/textbox.md +3 -3
- package/docs/toast.md +3 -3
- package/docs/tokens.md +349 -122
- package/docs/toolbar.md +3 -3
- package/docs/tooltip.md +1 -1
- package/docs/treeview.md +3 -3
- package/docs/window.md +3 -3
- package/docs/wizard.md +240 -0
- package/llms-full.txt +2415 -240
- package/llms.txt +10 -1
- package/package.json +9 -3
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,70 @@ The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and
|
|
|
6
6
|
|
|
7
7
|
## [Unreleased]
|
|
8
8
|
|
|
9
|
+
## [0.1.0-beta.2] - 2026-11-05
|
|
10
|
+
|
|
11
|
+
### New components
|
|
12
|
+
|
|
13
|
+
- `Stepper`: the steps of a longer task and where the user stands, an indicator and a text per step, a line between
|
|
14
|
+
them; completed, current, pending and error statuses, optional and disabled steps, an icon in place of the number;
|
|
15
|
+
linear order (a press reaches a completed step or the next one) or free; `onStepChanging` may refuse or wait on a
|
|
16
|
+
promise; `next()`, `previous()`, `goTo()`; horizontal with the texts under or after the indicators, or vertical;
|
|
17
|
+
one Tab stop with the arrow keys; `x-model`. Units in the five languages: the step, its indicator, the mark, the
|
|
18
|
+
texts and the line (which turns a quarter standing).
|
|
19
|
+
- `Wizard` and `WizardStep`: a stepper above or beside a page per step and the Back and Next buttons. Next validates
|
|
20
|
+
the kit's fields on the page, then the step's own `validate`; a page that fails keeps the wizard, marks its step
|
|
21
|
+
and focuses the first invalid field. On the last step Next finishes (`onFinishing` may wait, `onFinished`). Steps
|
|
22
|
+
from JSX or from `steps` with content factories, `add`, `insert`, `remove`; `lazy` and `keepAlive` as in `Tabs`.
|
|
23
|
+
- Kit texts `steps`, `stepOf`, `stepOptional`, `stepDone`, `stepError`, `wizardNext`, `wizardPrevious`,
|
|
24
|
+
`wizardFinish` in English and Turkish.
|
|
25
|
+
- `Popover`: content next to the element it belongs to, with a title, a close button and an arrow where the
|
|
26
|
+
design language draws one (Tactile, Fluent, Lilac); opened by a press on the target, by the pointer resting on it
|
|
27
|
+
(`showOn: 'hover'`, keyboard focus too) or from code; every placement of the kit's popups, a width of its own;
|
|
28
|
+
focus goes in and comes back; Escape, a press outside, focus leaving and the close button close it, and
|
|
29
|
+
`onClosing` may keep it open; `value` and `x-model`.
|
|
30
|
+
- `LoadPanel`: a loading layer over a container or the whole page: a shade, a pane with the kit's spinner and a
|
|
31
|
+
message, a Cancel button (`onCancel`, Escape too); what is under it is inert and `aria-busy`, focus waits on the
|
|
32
|
+
panel and comes back; `delay` keeps quick work from flashing it; `value` and `x-model`, `show()` and `hide()`.
|
|
33
|
+
- `homeOf` in the core: where a surface made from code goes for its anchor (the tooltip's rule, now shared).
|
|
34
|
+
- `DateRangeBox`: a start and an end in one field, typed through two masks or picked on two months side by side
|
|
35
|
+
(the first pick the start, the second the end, the pointer showing the range meanwhile), ready-made ranges
|
|
36
|
+
(`presets`), `min`, `max`, `disabledDates`, the least and the most days a range may span (`minDays`, `maxDays`),
|
|
37
|
+
`datetime` too; the value a `[start, end]` pair, `x-model`. The `Calendar` draws a range over its days
|
|
38
|
+
(`rangeStart`, `rangeEnd`: the cell states `range-start`, `range-end`, `range-single`, `range-in` in every
|
|
39
|
+
language) and tells the day under the pointer (`onDayPointed`).
|
|
40
|
+
- `FileUploader`: files chosen with a button or dropped on the box, listed with their size and what happens to
|
|
41
|
+
them; `accept`, `maxFileSize`, `minFileSize` and `maxFiles` turn files away with the reason; uploaded as they come,
|
|
42
|
+
on an Upload button or from code, by the uploader itself (`uploadUrl`, in one piece or in chunks with
|
|
43
|
+
`Content-Range`, with progress) or by your own `upload`; cancel, retry and remove on each row; a field (label,
|
|
44
|
+
`required`, rules); kit glyphs `upload` and `file`.
|
|
45
|
+
- Kit texts for both, in English and Turkish.
|
|
46
|
+
- `Sortable`: items the user puts in order by dragging them, with the pointer or a finger (a long press), or
|
|
47
|
+
with the keys (Ctrl + an arrow, Home, End; each move read out); a copy follows the pointer, a line shows where
|
|
48
|
+
it would land, the list scrolls near its edges; sortables of one `group` take each other's items; the items
|
|
49
|
+
are the JSX children, or `items` drawn with `itemTemplate` (the rows keyed by item, kept as the order
|
|
50
|
+
changes); a `handle` takes the drag and the keys; `onDragStarting`, `onDragChanging` and `onDragEnding` may
|
|
51
|
+
refuse; `onReorder`, `onRemove` and `onAdd` tell the indexes and the data stays yours; `move()` from code.
|
|
52
|
+
Units in the five languages: the list, an item, the line, the copy.
|
|
53
|
+
- `ScrollView`: content that scrolls in a box of its own; the bars shown on scroll, on hover, always or never;
|
|
54
|
+
pull to refresh with a finger or the pointer (`onPullDown`, a promise or `release()`); more loaded near the
|
|
55
|
+
end (`onReachBottom`, `reachBottomOffset`, `release(true)` when there is no more; content that does not fill
|
|
56
|
+
the box asks at once, and again as it grows); `scrollTo`, `scrollBy`, `scrollToElement`, `onScrolled`.
|
|
57
|
+
- Kit texts `sortableMoved`, `scrollPullDown`, `scrollRelease` and `scrollRefreshing` in English and Turkish.
|
|
58
|
+
|
|
59
|
+
### Language
|
|
60
|
+
|
|
61
|
+
- A Language page in the docs: switching, the packs, a pack of your own, `connectI18n`, your own texts that follow,
|
|
62
|
+
a control's own `locale`, and what a pack is checked for.
|
|
63
|
+
- `npm run locales` checks every pack against the built-in texts: every key, the same ICU arguments, `UiStrings` in
|
|
64
|
+
step with `en.json`; `npm run locales -- path/to/de.json` checks a pack of your own.
|
|
65
|
+
- The Turkish pack is a chunk of the package, loaded when `uiLocale.use('tr')` first asks for it; it is no longer
|
|
66
|
+
in the main bundle.
|
|
67
|
+
|
|
68
|
+
### Removed
|
|
69
|
+
|
|
70
|
+
- `trStrings`. Switch with `await uiLocale.use('tr')`, or add the JSON from `@motifx-community/ui/locales/tr.json`
|
|
71
|
+
with `uiLocale.add('tr', pack)`.
|
|
72
|
+
|
|
9
73
|
## [0.1.0-beta.1] - 2026-11-04
|
|
10
74
|
|
|
11
75
|
### DropDown and Lookup: a value on no loaded page is asked for by key
|
package/README.md
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
# @motifx-community/ui
|
|
2
2
|
|
|
3
|
+
[](https://www.npmjs.com/package/@motifx-community/ui)
|
|
4
|
+
[](https://github.com/motifjs-community/motifjs-ui/actions/workflows/ci.yml)
|
|
5
|
+
[](LICENSE)
|
|
6
|
+
|
|
3
7
|
UI components for **MotifJS** (`@motifx/core`) that work the way desktop UI does: a component is an
|
|
4
8
|
object you create when you need it, show anywhere, and close like a window — or write in JSX and
|
|
5
9
|
bind to state. Everything is drawn from the [MotifJS design system](https://github.com/motifjs-community/motifjs-design-system)
|
|
@@ -9,6 +13,8 @@ overrides. This package adds the components and their component tokens, nothing
|
|
|
9
13
|
> **Preview** (`beta`): complete enough to build with; the API may still change before 1.0. Updates come as new
|
|
10
14
|
> beta versions.
|
|
11
15
|
|
|
16
|
+
The docs: [ui.motifjs.com](https://ui.motifjs.com). The same pages come with the package as Markdown, in `docs/`.
|
|
17
|
+
|
|
12
18
|
## Install
|
|
13
19
|
|
|
14
20
|
```sh
|
|
@@ -37,14 +43,14 @@ each (`npm run dev`).
|
|
|
37
43
|
| --- | --- |
|
|
38
44
|
| Buttons and commands | `Button` (menu, split, drop-down, toggle, busy), `ButtonGroup` (segmented choice), `Toolbar` (overflow menu), `MenuBar`, `ContextMenu` |
|
|
39
45
|
| Display | `Badge`, `Avatar`, `AvatarGroup`, `Chip`, `ChipGroup`, `Card`, `Skeleton` |
|
|
40
|
-
| Navigation | `Tabs`, `Accordion`, `Breadcrumb`, `Pagination`, `TabDocumentManager` |
|
|
46
|
+
| Navigation | `Tabs`, `Accordion`, `Breadcrumb`, `Pagination`, `Stepper`, `Wizard`, `TabDocumentManager` |
|
|
41
47
|
| More editors | `Rating`, `ColorBox`, `ColorPicker` |
|
|
42
48
|
| Scheduling | `Scheduler` (day, week, month, timeline, agenda; recurrence, resources, iCalendar) |
|
|
43
|
-
| Editors | `TextBox` (mask, validation), `TextArea` (auto-grow), `NumberBox` (locale formats, spin), `DateBox` (date, time, both), `Calendar`, `Slider` (range) |
|
|
49
|
+
| Editors | `TextBox` (mask, validation), `TextArea` (auto-grow), `NumberBox` (locale formats, spin), `DateBox` (date, time, both), `DateRangeBox` (two months, presets, a span), `Calendar`, `Slider` (range), `FileUploader` (drop, limits, chunks, progress) |
|
|
44
50
|
| Choice | `CheckBox` (three states), `Switch`, `RadioGroup`, `DropDown`, `ComboBox`, `Autocomplete`, `Lookup` (columns), `TagBox`, `ListBox` |
|
|
45
51
|
| Data | `DataGrid` (virtual or paged, editing with three save modes, row actions, selection, filters, search panel, grouping with a group panel, toolbar, lookup columns, copy and paste, CSV and Excel export, kept layout), `TreeView` (lazy, check boxes, filter); lists and grids read `@motifx-community/data` sources |
|
|
46
|
-
| Layout and windows | `Stack`, `Grid`, `DockPanel`, `Panel`, `GroupBox`, `SplitContainer`, `FormLayout`, `Tabs`, `Accordion`, `MxForm` (window and modal form), `messageBox`, `confirm` |
|
|
47
|
-
| Feedback | `ProgressBar`, `Spinner` (cover a panel), `Tooltip`, `Toast` |
|
|
52
|
+
| Layout and windows | `Stack`, `Grid`, `DockPanel`, `Panel`, `GroupBox`, `SplitContainer`, `ScrollView` (pull to refresh, load more), `Sortable` (drag or keys, lists of a group), `FormLayout`, `Tabs`, `Accordion`, `MxForm` (window and modal form), `messageBox`, `confirm` |
|
|
53
|
+
| Feedback | `ProgressBar`, `Spinner` (cover a panel), `LoadPanel`, `Tooltip`, `Popover`, `Toast` |
|
|
48
54
|
| Shared parts | `Field` (base of every editor), `InputMask`, `ValidationGroup`, `validateFields`, `checkRules`, `OptionList`, `DataItems`, `Popup`, `MenuList`, date helpers (`datePatternOf`) |
|
|
49
55
|
| Base | `Control`, `FocusContainer`, `addShortcut`, `parseAccessKey`, `uiLocale` (English, Turkish) |
|
|
50
56
|
|
|
@@ -127,12 +133,12 @@ own components. A full page per component, `Control`, keyboard and focus, and a
|
|
|
127
133
|
|
|
128
134
|
## Contributing
|
|
129
135
|
|
|
130
|
-
The design system
|
|
131
|
-
`motifjs-design-system` next to this repository and build
|
|
132
|
-
`npm
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
+
The design system, the translations and the data layer are dependencies by path until they are published: clone
|
|
137
|
+
`motifjs-design-system`, `motifjs-i18n` and `motifjs-data` next to this repository and build each once, then
|
|
138
|
+
`npm ci` here links them. `npm run check` must stay green (typecheck, `motif-lint`, stylelint with the design
|
|
139
|
+
system's shared config, tests, build, docs build). The setup, the checks and the rules a change follows are in
|
|
140
|
+
[CONTRIBUTING.md](CONTRIBUTING.md). Questions and ideas go to the
|
|
141
|
+
[MotifJS discussions](https://github.com/motifjsdev/motifjs/discussions).
|
|
136
142
|
|
|
137
143
|
## License
|
|
138
144
|
|
|
@@ -37,6 +37,12 @@ export declare class Calendar extends Control<HTMLDivElement, CalendarProps> {
|
|
|
37
37
|
set currentView(value: Bind<CalendarView>);
|
|
38
38
|
/** The date with the Tab stop; its month (or year) is the one on screen. */
|
|
39
39
|
get focusedDate(): Date;
|
|
40
|
+
get rangeStart(): Date | null;
|
|
41
|
+
set rangeStart(value: Bind<Date | null>);
|
|
42
|
+
get rangeEnd(): Date | null;
|
|
43
|
+
set rangeEnd(value: Bind<Date | null>);
|
|
44
|
+
/** The pointer came over a day in the month view, or left the days (`null`). */
|
|
45
|
+
get onDayPointed(): MotifEvent<Date | null>;
|
|
40
46
|
get onValueChanged(): MotifEvent<ValueChangedEventArgs<Date | null>>;
|
|
41
47
|
/** Shows the month of `date` and puts the Tab stop on it. */
|
|
42
48
|
goTo(date: Date): void;
|
|
@@ -54,6 +60,12 @@ export declare class Calendar extends Control<HTMLDivElement, CalendarProps> {
|
|
|
54
60
|
/** The first and last day of what is on screen. */
|
|
55
61
|
private shownRange;
|
|
56
62
|
private renderMonth;
|
|
63
|
+
/** The range's ends in order, as days. */
|
|
64
|
+
private rangeOf;
|
|
65
|
+
/** Where a day stands in the range drawn: its start, its end, one day of both, or between. */
|
|
66
|
+
private rangeMark;
|
|
67
|
+
private pointedOver;
|
|
68
|
+
private point;
|
|
57
69
|
/** The year view (twelve months) and the decade view (twelve years, one on each side). */
|
|
58
70
|
private renderBlock;
|
|
59
71
|
/** A month or a year can be chosen when one of its days can. */
|
|
@@ -22,5 +22,10 @@ export interface CalendarProps extends ControlProps {
|
|
|
22
22
|
currentView?: Bind<CalendarView>;
|
|
23
23
|
/** The view a choice is made in: `'year'` picks a month, `'decade'` a year. Default `'month'`. */
|
|
24
24
|
minView?: Bind<CalendarView>;
|
|
25
|
+
/** A range drawn over the days (its ends and the days between), for a date range box; the value is still one day. */
|
|
26
|
+
rangeStart?: Bind<Date | null>;
|
|
27
|
+
rangeEnd?: Bind<Date | null>;
|
|
25
28
|
onValueChanged?: (e: ValueChangedEventArgs<Date | null>) => void;
|
|
29
|
+
/** The pointer came over a day (`null`: it left the days). */
|
|
30
|
+
onDayPointed?: (day: Date | null) => void;
|
|
26
31
|
}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import { Emitter, type Bind, type Event as MotifEvent, type IBaseProp } from "@motifx/core";
|
|
2
|
+
import type { DateKind } from "../../parts/dates/date-kind";
|
|
3
|
+
import type { DatePattern } from "../../parts/dates/date-pattern";
|
|
4
|
+
import { Field } from "../../parts/field/Field";
|
|
5
|
+
import { OptionList } from "../../parts/list/OptionList";
|
|
6
|
+
import { InputMask } from "../../parts/mask/InputMask";
|
|
7
|
+
import { Popup } from "../../parts/popup/Popup";
|
|
8
|
+
import type { PopupCloseReason } from "../../parts/popup/popup-close-reason";
|
|
9
|
+
import type { ValidationRule } from "../../parts/validation/validation-rule";
|
|
10
|
+
import { Calendar } from "../calendar/Calendar";
|
|
11
|
+
import type { DateRange } from "./date-range";
|
|
12
|
+
import type { DateRangeBoxProps } from "./date-range-box-props";
|
|
13
|
+
import type { DateRangePreset } from "./date-range-preset";
|
|
14
|
+
interface Parts {
|
|
15
|
+
startInput: HTMLInputElement;
|
|
16
|
+
endInput: HTMLInputElement;
|
|
17
|
+
separator: HTMLSpanElement;
|
|
18
|
+
startMask: InputMask;
|
|
19
|
+
endMask: InputMask;
|
|
20
|
+
pattern: DatePattern;
|
|
21
|
+
unfinished: [boolean, boolean];
|
|
22
|
+
toggle: HTMLButtonElement | null;
|
|
23
|
+
popup: Popup | null;
|
|
24
|
+
calendars: Calendar[];
|
|
25
|
+
presetList: OptionList<DateRangePreset> | null;
|
|
26
|
+
stage: 0 | 1;
|
|
27
|
+
opened: Emitter<void>;
|
|
28
|
+
closed: Emitter<PopupCloseReason>;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* A start and an end date in one field: typed in the locale's order through two masks, or picked on the popup from
|
|
32
|
+
* two months side by side (the first pick the start, the second the end), from ready-made ranges (`presets`), with
|
|
33
|
+
* `min`, `max`, `disabledDates`, and the least and the most days a range may span (`minDays`, `maxDays`). The
|
|
34
|
+
* value is a `[start, end]` pair; `x-model` binds it.
|
|
35
|
+
*
|
|
36
|
+
* @example
|
|
37
|
+
* <DateRangeBox label="Stay" x-model={() => this.booking.nights} minDays={1} maxDays={30} presets />
|
|
38
|
+
* <DateRangeBox label="Report" type="datetime" calendars={1} />
|
|
39
|
+
*/
|
|
40
|
+
export declare class DateRangeBox extends Field<DateRange, DateRangeBoxProps> {
|
|
41
|
+
constructor(props?: IBaseProp<DateRangeBoxProps>);
|
|
42
|
+
get type(): Exclude<DateKind, 'time'>;
|
|
43
|
+
set type(value: Bind<Exclude<DateKind, 'time'>>);
|
|
44
|
+
get min(): Date | null;
|
|
45
|
+
set min(value: Bind<Date | null>);
|
|
46
|
+
get max(): Date | null;
|
|
47
|
+
set max(value: Bind<Date | null>);
|
|
48
|
+
get disabledDates(): ((date: Date) => boolean) | null;
|
|
49
|
+
set disabledDates(value: Bind<((date: Date) => boolean) | null>);
|
|
50
|
+
get minDays(): number | null;
|
|
51
|
+
set minDays(value: Bind<number | null>);
|
|
52
|
+
get maxDays(): number | null;
|
|
53
|
+
set maxDays(value: Bind<number | null>);
|
|
54
|
+
get locale(): string;
|
|
55
|
+
set locale(value: Bind<string>);
|
|
56
|
+
get displayFormat(): Intl.DateTimeFormatOptions | null;
|
|
57
|
+
set displayFormat(value: Bind<Intl.DateTimeFormatOptions | null>);
|
|
58
|
+
get startPlaceholder(): string;
|
|
59
|
+
set startPlaceholder(value: Bind<string>);
|
|
60
|
+
get endPlaceholder(): string;
|
|
61
|
+
set endPlaceholder(value: Bind<string>);
|
|
62
|
+
get clearButton(): boolean;
|
|
63
|
+
set clearButton(value: Bind<boolean>);
|
|
64
|
+
get showSeconds(): boolean;
|
|
65
|
+
set showSeconds(value: Bind<boolean>);
|
|
66
|
+
get firstDayOfWeek(): number | null;
|
|
67
|
+
set firstDayOfWeek(value: Bind<number | null>);
|
|
68
|
+
get showWeekNumbers(): boolean;
|
|
69
|
+
set showWeekNumbers(value: Bind<boolean>);
|
|
70
|
+
get showPickerButton(): boolean;
|
|
71
|
+
set showPickerButton(value: Bind<boolean>);
|
|
72
|
+
get calendars(): 1 | 2;
|
|
73
|
+
set calendars(value: Bind<1 | 2>);
|
|
74
|
+
get presets(): readonly DateRangePreset[] | boolean;
|
|
75
|
+
set presets(value: Bind<readonly DateRangePreset[] | boolean>);
|
|
76
|
+
get closeOnComplete(): boolean;
|
|
77
|
+
set closeOnComplete(value: Bind<boolean>);
|
|
78
|
+
/** The start, and the end, as properties of their own. */
|
|
79
|
+
get startDate(): Date | null;
|
|
80
|
+
set startDate(value: Date | null);
|
|
81
|
+
get endDate(): Date | null;
|
|
82
|
+
set endDate(value: Date | null);
|
|
83
|
+
/** The start's input; the end's is `endInputElement`. */
|
|
84
|
+
get inputElement(): HTMLInputElement;
|
|
85
|
+
get endInputElement(): HTMLInputElement;
|
|
86
|
+
/** A side's text is not a whole, real date yet. */
|
|
87
|
+
get unfinished(): boolean;
|
|
88
|
+
/** Whether the popup is open. Reactive. */
|
|
89
|
+
get opened(): boolean;
|
|
90
|
+
set opened(value: boolean);
|
|
91
|
+
get onOpened(): MotifEvent<void>;
|
|
92
|
+
get onClosed(): MotifEvent<PopupCloseReason>;
|
|
93
|
+
/** Opens the calendars; `false` when disabled or read-only. */
|
|
94
|
+
open(): boolean;
|
|
95
|
+
close(): void;
|
|
96
|
+
clear(): void;
|
|
97
|
+
protected createControl(): HTMLElement;
|
|
98
|
+
protected emptyValue(): DateRange;
|
|
99
|
+
protected normalizeValue(value: DateRange): DateRange;
|
|
100
|
+
protected sameValue(a: DateRange, b: DateRange): boolean;
|
|
101
|
+
protected isEmptyValue(value: DateRange): boolean;
|
|
102
|
+
protected renderValue(value: DateRange): void;
|
|
103
|
+
protected builtInRules(): ValidationRule<DateRange>[];
|
|
104
|
+
written(date: Date | null | undefined): string;
|
|
105
|
+
get rangeParts(): Parts;
|
|
106
|
+
renderPattern(): void;
|
|
107
|
+
renderNames(): void;
|
|
108
|
+
listen(): void;
|
|
109
|
+
typed(side: 0 | 1, e: Event): void;
|
|
110
|
+
showDisplayText(): void;
|
|
111
|
+
renderToggle(): void;
|
|
112
|
+
renderClear(): void;
|
|
113
|
+
createPopup(): Popup;
|
|
114
|
+
fillPopup(): void;
|
|
115
|
+
presetsNow(): DateRangePreset[];
|
|
116
|
+
followMonths(calendar: Calendar, index: number): void;
|
|
117
|
+
picked(day: Date, event?: Event): void;
|
|
118
|
+
pointed(day: Date | null): void;
|
|
119
|
+
syncPicker(): void;
|
|
120
|
+
}
|
|
121
|
+
export {};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { Bind } from '@motifx/core';
|
|
2
|
+
import type { DateKind } from '../../parts/dates/date-kind';
|
|
3
|
+
import type { FieldProps } from '../../parts/field/field-props';
|
|
4
|
+
import type { DateRange } from './date-range';
|
|
5
|
+
import type { DateRangePreset } from './date-range-preset';
|
|
6
|
+
/** Props of `DateRangeBox`: the field props (the value a `[start, end]` pair) plus its own. Each one is also a settable property. */
|
|
7
|
+
export interface DateRangeBoxProps extends FieldProps<DateRange> {
|
|
8
|
+
/** `'date'` (the default) or `'datetime'`: the time is typed after the date, the calendars keep it. */
|
|
9
|
+
type?: Bind<Exclude<DateKind, 'time'>>;
|
|
10
|
+
min?: Bind<Date | null>;
|
|
11
|
+
max?: Bind<Date | null>;
|
|
12
|
+
disabledDates?: Bind<((date: Date) => boolean) | null>;
|
|
13
|
+
/** The least and the most days a range may span (the end counted from the start). */
|
|
14
|
+
minDays?: Bind<number | null>;
|
|
15
|
+
maxDays?: Bind<number | null>;
|
|
16
|
+
/** Default: the kit's language. It decides the order of the parts and the names of months and days. */
|
|
17
|
+
locale?: Bind<string>;
|
|
18
|
+
/** How the dates are shown while the field is not being edited, e.g. `{ dateStyle: 'medium' }`. */
|
|
19
|
+
displayFormat?: Bind<Intl.DateTimeFormatOptions | null>;
|
|
20
|
+
/** Shown in an empty box: the start's, and the end's. */
|
|
21
|
+
startPlaceholder?: Bind<string>;
|
|
22
|
+
endPlaceholder?: Bind<string>;
|
|
23
|
+
clearButton?: Bind<boolean>;
|
|
24
|
+
showSeconds?: Bind<boolean>;
|
|
25
|
+
firstDayOfWeek?: Bind<number | null>;
|
|
26
|
+
showWeekNumbers?: Bind<boolean>;
|
|
27
|
+
/** The button that opens the calendars. Default `true`. */
|
|
28
|
+
showPickerButton?: Bind<boolean>;
|
|
29
|
+
/** How many months the popup shows side by side. Default `2`. */
|
|
30
|
+
calendars?: Bind<1 | 2>;
|
|
31
|
+
/** Ready-made ranges beside the calendars: `true` for the kit's (today, yesterday, the last 7 and 30 days, this and last month), your own, or none. Default `false`. */
|
|
32
|
+
presets?: Bind<readonly DateRangePreset[] | boolean>;
|
|
33
|
+
/** Closes the popup once both ends are chosen. Default `true`. */
|
|
34
|
+
closeOnComplete?: Bind<boolean>;
|
|
35
|
+
}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import { Component, Emitter, type Bind, type Event as MotifEvent, type IBaseProp } from "@motifx/core";
|
|
2
|
+
import { Field } from "../../parts/field/Field";
|
|
3
|
+
import type { ValidationRule } from "../../parts/validation/validation-rule";
|
|
4
|
+
import { Button } from "../button/Button";
|
|
5
|
+
import { ProgressBar } from "../progress/ProgressBar";
|
|
6
|
+
import type { FileUploaderProps } from "./file-uploader-props";
|
|
7
|
+
import type { FilesAddedEventArgs } from "./files-added-event-args";
|
|
8
|
+
import type { UploadEventArgs } from "./upload-event-args";
|
|
9
|
+
import type { UploadItem } from "./upload-item";
|
|
10
|
+
import type { UploadMode } from "./upload-mode";
|
|
11
|
+
import type { UploadStatus } from "./upload-status";
|
|
12
|
+
interface Parts {
|
|
13
|
+
select: HTMLButtonElement;
|
|
14
|
+
selectText: HTMLSpanElement;
|
|
15
|
+
input: HTMLInputElement;
|
|
16
|
+
drop: HTMLSpanElement;
|
|
17
|
+
uploadButton: HTMLButtonElement;
|
|
18
|
+
list: Component<HTMLUListElement> | null;
|
|
19
|
+
rows: Map<UploadItem, Row>;
|
|
20
|
+
items: UploadItem[];
|
|
21
|
+
jobs: Map<UploadItem, AbortController>;
|
|
22
|
+
dragDepth: number;
|
|
23
|
+
}
|
|
24
|
+
interface Row {
|
|
25
|
+
li: Component<HTMLLIElement>;
|
|
26
|
+
name: Component<HTMLSpanElement>;
|
|
27
|
+
size: Component<HTMLSpanElement>;
|
|
28
|
+
state: Component<HTMLSpanElement>;
|
|
29
|
+
bar: ProgressBar;
|
|
30
|
+
abort: Button;
|
|
31
|
+
retry: Button;
|
|
32
|
+
remove: Button;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Files chosen with a button or dropped on the box, listed with their size and what happens to them: uploaded as
|
|
36
|
+
* they come (`uploadUrl`, in one piece or in chunks, or your own `upload`), on an Upload button, or from code;
|
|
37
|
+
* progress, cancel, retry and remove on each. `accept`, `maxFileSize`, `minFileSize` and `maxFiles` turn files
|
|
38
|
+
* away, each listed with the reason. The value is the files taken; `x-model` binds it.
|
|
39
|
+
*
|
|
40
|
+
* @example
|
|
41
|
+
* <FileUploader label="Attachments" accept=".pdf,image/*" maxFileSize={5_000_000} uploadUrl="/api/files" x-model={() => this.form.files} />
|
|
42
|
+
* <FileUploader label="Photo" multiple={false} upload={(file, report, signal) => this.api.send(file, report, signal)} />
|
|
43
|
+
*/
|
|
44
|
+
export declare class FileUploader extends Field<readonly File[], FileUploaderProps> {
|
|
45
|
+
filesAdded: Emitter<FilesAddedEventArgs>;
|
|
46
|
+
fileRemoved: Emitter<UploadEventArgs>;
|
|
47
|
+
uploadStarted: Emitter<UploadEventArgs>;
|
|
48
|
+
progressed: Emitter<UploadEventArgs>;
|
|
49
|
+
uploaded: Emitter<UploadEventArgs>;
|
|
50
|
+
uploadFailed: Emitter<UploadEventArgs>;
|
|
51
|
+
uploadAborted: Emitter<UploadEventArgs>;
|
|
52
|
+
uploadWith: ((file: File, report: (fraction: number) => void, signal: AbortSignal) => Promise<unknown>) | null;
|
|
53
|
+
constructor(props?: IBaseProp<FileUploaderProps>);
|
|
54
|
+
get multiple(): boolean;
|
|
55
|
+
set multiple(value: Bind<boolean>);
|
|
56
|
+
get accept(): string;
|
|
57
|
+
set accept(value: Bind<string>);
|
|
58
|
+
get maxFileSize(): number | null;
|
|
59
|
+
set maxFileSize(value: Bind<number | null>);
|
|
60
|
+
get minFileSize(): number | null;
|
|
61
|
+
set minFileSize(value: Bind<number | null>);
|
|
62
|
+
get maxFiles(): number | null;
|
|
63
|
+
set maxFiles(value: Bind<number | null>);
|
|
64
|
+
get allowDrop(): boolean;
|
|
65
|
+
set allowDrop(value: Bind<boolean>);
|
|
66
|
+
get uploadMode(): UploadMode;
|
|
67
|
+
set uploadMode(value: Bind<UploadMode>);
|
|
68
|
+
get uploadUrl(): string | null;
|
|
69
|
+
set uploadUrl(value: Bind<string | null>);
|
|
70
|
+
get uploadMethod(): string;
|
|
71
|
+
set uploadMethod(value: Bind<string>);
|
|
72
|
+
get uploadHeaders(): Record<string, string> | null;
|
|
73
|
+
set uploadHeaders(value: Bind<Record<string, string> | null>);
|
|
74
|
+
get uploadField(): string;
|
|
75
|
+
set uploadField(value: Bind<string>);
|
|
76
|
+
get chunkSize(): number | null;
|
|
77
|
+
set chunkSize(value: Bind<number | null>);
|
|
78
|
+
get selectText(): string;
|
|
79
|
+
set selectText(value: Bind<string>);
|
|
80
|
+
get dropText(): string;
|
|
81
|
+
set dropText(value: Bind<string>);
|
|
82
|
+
get uploadText(): string;
|
|
83
|
+
set uploadText(value: Bind<string>);
|
|
84
|
+
get showFileList(): boolean;
|
|
85
|
+
set showFileList(value: Bind<boolean>);
|
|
86
|
+
/** Every file in the list, the refused ones too, with what happened to each. */
|
|
87
|
+
get items(): readonly UploadItem[];
|
|
88
|
+
/** An upload is running. */
|
|
89
|
+
get isUploading(): boolean;
|
|
90
|
+
get onFilesAdded(): MotifEvent<FilesAddedEventArgs>;
|
|
91
|
+
get onFileRemoved(): MotifEvent<UploadEventArgs>;
|
|
92
|
+
get onUploadStarted(): MotifEvent<UploadEventArgs>;
|
|
93
|
+
get onProgress(): MotifEvent<UploadEventArgs>;
|
|
94
|
+
get onUploaded(): MotifEvent<UploadEventArgs>;
|
|
95
|
+
get onUploadError(): MotifEvent<UploadEventArgs>;
|
|
96
|
+
get onUploadAborted(): MotifEvent<UploadEventArgs>;
|
|
97
|
+
/** Opens the browser's file dialog, as the button does. */
|
|
98
|
+
openDialog(): void;
|
|
99
|
+
/** Takes files as if chosen: the limits apply, `onFilesAdded` is asked, uploads start as the mode says. */
|
|
100
|
+
addFiles(files: Iterable<File>, event?: Event): void;
|
|
101
|
+
/** Uploads the files waiting (or one of them); `manual` mode calls this. */
|
|
102
|
+
upload(item?: UploadItem): Promise<void>;
|
|
103
|
+
/** Stops the upload of a file (or of every one); the file stays, listed as cancelled. */
|
|
104
|
+
abort(item?: UploadItem): void;
|
|
105
|
+
/** Takes a file out of the list and the value; a running upload is stopped. */
|
|
106
|
+
remove(item: UploadItem, event?: Event): void;
|
|
107
|
+
/** Takes every file out. */
|
|
108
|
+
clear(): void;
|
|
109
|
+
protected createControl(): HTMLElement;
|
|
110
|
+
protected emptyValue(): readonly File[];
|
|
111
|
+
protected normalizeValue(value: readonly File[]): readonly File[];
|
|
112
|
+
protected sameValue(a: readonly File[], b: readonly File[]): boolean;
|
|
113
|
+
protected isEmptyValue(value: readonly File[]): boolean;
|
|
114
|
+
protected renderValue(value: readonly File[]): void;
|
|
115
|
+
protected builtInRules(): ValidationRule<readonly File[]>[];
|
|
116
|
+
get uploadParts(): Parts;
|
|
117
|
+
listen(): void;
|
|
118
|
+
drawTexts(): void;
|
|
119
|
+
drawList(): void;
|
|
120
|
+
makeRow(item: UploadItem): Row;
|
|
121
|
+
drawRow(item: UploadItem, row: Row): void;
|
|
122
|
+
setStatus(item: UploadItem, status: UploadStatus, progress?: number, message?: string): void;
|
|
123
|
+
stop(item: UploadItem): void;
|
|
124
|
+
uploadItem(item: UploadItem): Promise<void>;
|
|
125
|
+
send(file: File, url: string, report: (fraction: number) => void, signal: AbortSignal): Promise<unknown>;
|
|
126
|
+
request(url: string, blob: Blob, file: File, piece: {
|
|
127
|
+
index: number;
|
|
128
|
+
count: number;
|
|
129
|
+
start: number;
|
|
130
|
+
end: number;
|
|
131
|
+
} | null, loaded: (bytes: number) => void, signal: AbortSignal): Promise<unknown>;
|
|
132
|
+
}
|
|
133
|
+
export {};
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { Bind } from '@motifx/core';
|
|
2
|
+
import type { FieldProps } from '../../parts/field/field-props';
|
|
3
|
+
import type { FilesAddedEventArgs } from './files-added-event-args';
|
|
4
|
+
import type { UploadEventArgs } from './upload-event-args';
|
|
5
|
+
import type { UploadMode } from './upload-mode';
|
|
6
|
+
/** Props of `FileUploader`: the field props (the value the files taken) plus its own. Each one is also a settable property. */
|
|
7
|
+
export interface FileUploaderProps extends FieldProps<readonly File[]> {
|
|
8
|
+
/** Several files at once. Default `true`. */
|
|
9
|
+
multiple?: Bind<boolean>;
|
|
10
|
+
/** What may be chosen, as for an `<input type="file">`: `.png,.jpg`, `image/*`, `application/pdf`. */
|
|
11
|
+
accept?: Bind<string>;
|
|
12
|
+
/** Bytes. A file outside is listed as refused, with the reason. */
|
|
13
|
+
maxFileSize?: Bind<number | null>;
|
|
14
|
+
minFileSize?: Bind<number | null>;
|
|
15
|
+
/** How many files may be taken in all. */
|
|
16
|
+
maxFiles?: Bind<number | null>;
|
|
17
|
+
/** Files may be dropped on the box. Default `true`. */
|
|
18
|
+
allowDrop?: Bind<boolean>;
|
|
19
|
+
/** When files are uploaded: `instant` (as chosen), `button` (an Upload button), `manual` (`upload()` from code). Default `instant` with `uploadUrl` or `upload`, else `manual`. */
|
|
20
|
+
uploadMode?: Bind<UploadMode>;
|
|
21
|
+
/** Where files are sent, by the uploader itself (XMLHttpRequest, with progress). */
|
|
22
|
+
uploadUrl?: Bind<string | null>;
|
|
23
|
+
/** Default `'POST'`. */
|
|
24
|
+
uploadMethod?: Bind<string>;
|
|
25
|
+
uploadHeaders?: Bind<Record<string, string> | null>;
|
|
26
|
+
/** The form field the file is sent in. Default `'file'`. */
|
|
27
|
+
uploadField?: Bind<string>;
|
|
28
|
+
/** Bytes per request; the file goes in pieces, each with its `Content-Range`. Default: the whole file at once. */
|
|
29
|
+
chunkSize?: Bind<number | null>;
|
|
30
|
+
/** Your own upload instead of `uploadUrl`: report progress (0 to 1) and stop on the signal; what it resolves to is the response. */
|
|
31
|
+
upload?: (file: File, report: (fraction: number) => void, signal: AbortSignal) => Promise<unknown>;
|
|
32
|
+
/** The texts: the select button, the drop hint, the Upload button; the kit's when not given. */
|
|
33
|
+
selectText?: Bind<string>;
|
|
34
|
+
dropText?: Bind<string>;
|
|
35
|
+
uploadText?: Bind<string>;
|
|
36
|
+
/** The list of files under the box. Default `true`. */
|
|
37
|
+
showFileList?: Bind<boolean>;
|
|
38
|
+
/** Files were chosen or dropped; cancelable. */
|
|
39
|
+
onFilesAdded?: (e: FilesAddedEventArgs) => void;
|
|
40
|
+
onFileRemoved?: (e: UploadEventArgs) => void;
|
|
41
|
+
onUploadStarted?: (e: UploadEventArgs) => void;
|
|
42
|
+
onProgress?: (e: UploadEventArgs) => void;
|
|
43
|
+
onUploaded?: (e: UploadEventArgs) => void;
|
|
44
|
+
onUploadError?: (e: UploadEventArgs) => void;
|
|
45
|
+
onUploadAborted?: (e: UploadEventArgs) => void;
|
|
46
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { EventArgs } from '@motifx/core';
|
|
2
|
+
import type { FileUploader } from './FileUploader';
|
|
3
|
+
import type { UploadItem } from './upload-item';
|
|
4
|
+
/** Files were chosen or dropped. `cancel = true` takes none of them; `refused` lists those the limits turned away. */
|
|
5
|
+
export interface FilesAddedEventArgs extends EventArgs {
|
|
6
|
+
files: File[];
|
|
7
|
+
refused: UploadItem[];
|
|
8
|
+
source: FileUploader;
|
|
9
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { FileUploader } from './FileUploader';
|
|
2
|
+
export type { FileUploaderProps } from './file-uploader-props';
|
|
3
|
+
export type { UploadItem } from './upload-item';
|
|
4
|
+
export type { UploadStatus } from './upload-status';
|
|
5
|
+
export type { UploadMode } from './upload-mode';
|
|
6
|
+
export type { UploadEventArgs } from './upload-event-args';
|
|
7
|
+
export type { FilesAddedEventArgs } from './files-added-event-args';
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { FileUploader } from './FileUploader';
|
|
2
|
+
import type { UploadItem } from './upload-item';
|
|
3
|
+
/** Something happened to one file of the uploader. */
|
|
4
|
+
export interface UploadEventArgs {
|
|
5
|
+
item: UploadItem;
|
|
6
|
+
file: File;
|
|
7
|
+
/** What went wrong, when it did. */
|
|
8
|
+
error?: unknown;
|
|
9
|
+
source: FileUploader;
|
|
10
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { UploadStatus } from './upload-status';
|
|
2
|
+
/** A file in the uploader's list, with what happened to it. */
|
|
3
|
+
export interface UploadItem {
|
|
4
|
+
file: File;
|
|
5
|
+
status: UploadStatus;
|
|
6
|
+
/** 0 to 1 while uploading. */
|
|
7
|
+
progress: number;
|
|
8
|
+
/** What the upload answered (the response, or what your `upload` returned). */
|
|
9
|
+
response: unknown;
|
|
10
|
+
/** Why it failed or was refused, in the kit's language or the server's words. */
|
|
11
|
+
message: string;
|
|
12
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { Component, Emitter, type Bind, type Event as MotifEvent, type IBaseProp } from "@motifx/core";
|
|
2
|
+
import { Control } from "../../core/control";
|
|
3
|
+
import { Button } from "../button/Button";
|
|
4
|
+
import { Spinner } from "../progress/Spinner";
|
|
5
|
+
import type { LoadPanelProps } from "./load-panel-props";
|
|
6
|
+
import type { LoadPanelTarget } from "./load-panel-target";
|
|
7
|
+
/**
|
|
8
|
+
* A "loading" layer over a container or the whole page: a shade, a pane with a turning indicator and a message,
|
|
9
|
+
* a Cancel button when the work can be stopped. What is under it cannot be pressed or focused meanwhile; focus
|
|
10
|
+
* that was inside waits on the pane and comes back afterwards. It shows after `delay`, so quick work does not
|
|
11
|
+
* flash it. `value` (or `x-model`) shows and hides it; so do `show()` and `hide()`.
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* <LoadPanel target={() => this.ordersPanel} message="Loading orders" x-model={() => this.state.loading} />
|
|
15
|
+
*
|
|
16
|
+
* const panel = new LoadPanel({ cancelable: true, onCancel: () => this.job.stop() });
|
|
17
|
+
* panel.show();
|
|
18
|
+
*/
|
|
19
|
+
export declare class LoadPanel extends Control<HTMLDivElement, LoadPanelProps> {
|
|
20
|
+
pane: Component<HTMLDivElement>;
|
|
21
|
+
spinner: Spinner;
|
|
22
|
+
messagePart: Component<HTMLDivElement>;
|
|
23
|
+
cancelButton: Button;
|
|
24
|
+
shownNow: boolean;
|
|
25
|
+
timer: ReturnType<typeof setTimeout> | null;
|
|
26
|
+
host: HTMLElement | null;
|
|
27
|
+
undo: (() => void) | null;
|
|
28
|
+
returnTo: HTMLElement | null;
|
|
29
|
+
telling: boolean;
|
|
30
|
+
shownEmitter: Emitter<void>;
|
|
31
|
+
hiddenEmitter: Emitter<void>;
|
|
32
|
+
cancelled: Emitter<void>;
|
|
33
|
+
constructor(props?: IBaseProp<LoadPanelProps>);
|
|
34
|
+
get target(): LoadPanelTarget;
|
|
35
|
+
set target(value: Bind<LoadPanelTarget>);
|
|
36
|
+
get message(): string;
|
|
37
|
+
set message(value: Bind<string>);
|
|
38
|
+
/** Shown or not. Reactive; setting it shows or hides. */
|
|
39
|
+
get value(): boolean;
|
|
40
|
+
set value(value: Bind<boolean>);
|
|
41
|
+
get delay(): number;
|
|
42
|
+
set delay(value: Bind<number>);
|
|
43
|
+
get shade(): boolean;
|
|
44
|
+
set shade(value: Bind<boolean>);
|
|
45
|
+
get showPane(): boolean;
|
|
46
|
+
set showPane(value: Bind<boolean>);
|
|
47
|
+
get showIndicator(): boolean;
|
|
48
|
+
set showIndicator(value: Bind<boolean>);
|
|
49
|
+
get cancelable(): boolean;
|
|
50
|
+
set cancelable(value: Bind<boolean>);
|
|
51
|
+
get cancelText(): string;
|
|
52
|
+
set cancelText(value: Bind<string>);
|
|
53
|
+
get closeOnOutside(): boolean;
|
|
54
|
+
set closeOnOutside(value: Bind<boolean>);
|
|
55
|
+
/** Whether it is on the screen now (after its delay). */
|
|
56
|
+
get isShown(): boolean;
|
|
57
|
+
get onShown(): MotifEvent<void>;
|
|
58
|
+
get onHidden(): MotifEvent<void>;
|
|
59
|
+
/** The Cancel button was pressed (or Escape); the panel hides after. */
|
|
60
|
+
get onCancel(): MotifEvent<void>;
|
|
61
|
+
/** Shows it over its target after `delay`; `false` when it is shown or waiting already. */
|
|
62
|
+
show(): boolean;
|
|
63
|
+
/** Hides it; what it covered can be used again, and focus goes back where it was. */
|
|
64
|
+
hide(): void;
|
|
65
|
+
/** What the Cancel button does: tells `onCancel`, then hides. */
|
|
66
|
+
cancel(): void;
|
|
67
|
+
mount(): void;
|
|
68
|
+
tell(value: boolean): void;
|
|
69
|
+
drawTexts(): void;
|
|
70
|
+
}
|