@inglorious/ui 9.9.0 → 9.10.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 (35) hide show
  1. package/package.json +28 -3
  2. package/src/controls/chip-picker/chip-picker.stories.js +22 -0
  3. package/src/controls/chip-picker/index.js +3 -0
  4. package/src/controls/chip-picker/style.css +26 -0
  5. package/src/controls/chip-picker/template.js +53 -0
  6. package/src/controls/combobox/handlers.js +81 -19
  7. package/src/controls/controls.css +3 -2
  8. package/src/data-display/data-display.css +1 -0
  9. package/src/data-display/lightbox/index.js +3 -0
  10. package/src/data-display/lightbox/lightbox.stories.js +25 -0
  11. package/src/data-display/lightbox/style.css +97 -0
  12. package/src/data-display/lightbox/template.js +153 -0
  13. package/src/feedback/confirm-dialog/confirm-dialog.stories.js +33 -0
  14. package/src/feedback/confirm-dialog/index.js +3 -0
  15. package/src/feedback/confirm-dialog/style.css +16 -0
  16. package/src/feedback/confirm-dialog/template.js +70 -0
  17. package/src/feedback/crop-dialog/index.js +3 -0
  18. package/src/feedback/crop-dialog/style.css +43 -0
  19. package/src/feedback/crop-dialog/template.js +82 -0
  20. package/src/feedback/dialog/style.css +2 -1
  21. package/src/feedback/dialog/template.js +5 -2
  22. package/src/feedback/feedback.css +3 -0
  23. package/src/feedback/load-status/index.js +3 -0
  24. package/src/feedback/load-status/load-status.stories.js +16 -0
  25. package/src/feedback/load-status/style.css +10 -0
  26. package/src/feedback/load-status/template.js +43 -0
  27. package/src/index.js +5 -0
  28. package/src/shared/icons.js +12 -0
  29. package/types/controls/chip-picker.d.ts +23 -0
  30. package/types/controls/combobox.d.ts +20 -2
  31. package/types/data-display/lightbox.d.ts +35 -0
  32. package/types/feedback/confirm-dialog.d.ts +34 -0
  33. package/types/feedback/crop-dialog.d.ts +35 -0
  34. package/types/feedback/load-status.d.ts +22 -0
  35. package/types/index.d.ts +17 -0
@@ -0,0 +1,16 @@
1
+ .iw-confirm-dialog-actions {
2
+ display: flex;
3
+ flex-direction: column;
4
+ gap: var(--iw-space-2);
5
+ width: 100%;
6
+
7
+ > * {
8
+ flex: 1;
9
+ }
10
+ }
11
+
12
+ @media (min-width: 48rem) {
13
+ .iw-confirm-dialog-actions {
14
+ flex-direction: row;
15
+ }
16
+ }
@@ -0,0 +1,70 @@
1
+ /**
2
+ * @typedef {import('../../../types/feedback/confirm-dialog').ConfirmDialogProps} ConfirmDialogProps
3
+ * @typedef {import('@inglorious/web').TemplateResult} TemplateResult
4
+ */
5
+
6
+ import { html } from "@inglorious/web"
7
+
8
+ import { Button } from "../../controls/button/index.js"
9
+ import { Dialog } from "../dialog/index.js"
10
+
11
+ /**
12
+ * Renders a sheet asking to confirm an action, with the confirm button first.
13
+ * While `isBusy` it cannot be dismissed, and the confirm button shows
14
+ * `busyLabel`.
15
+ * @param {ConfirmDialogProps} props
16
+ * @returns {TemplateResult}
17
+ */
18
+ export function render(props) {
19
+ const {
20
+ id,
21
+ isOpen = false,
22
+ message,
23
+ children,
24
+ confirmLabel,
25
+ busyLabel = confirmLabel,
26
+ cancelLabel = "Cancel",
27
+ closeLabel,
28
+ tone = "danger",
29
+ isBusy = false,
30
+ isDisabled = false,
31
+ className = "",
32
+ onConfirm,
33
+ onCancel,
34
+ } = props
35
+
36
+ const isDanger = tone === "danger"
37
+
38
+ return Dialog.render({
39
+ id,
40
+ isOpen,
41
+ variant: "sheet",
42
+ size: "sm",
43
+ description: message,
44
+ children,
45
+ className: ["iw-confirm-dialog", className].filter(Boolean).join(" "),
46
+ closeLabel,
47
+ actions: html`<div class="iw-confirm-dialog-actions">
48
+ ${Button.render({
49
+ children: isBusy ? busyLabel : confirmLabel,
50
+ color: isDanger ? "error" : "primary",
51
+ variant: isDanger ? "outline" : "default",
52
+ shape: "pill",
53
+ size: "md",
54
+ isDisabled: isBusy || isDisabled,
55
+ onClick: () => {
56
+ if (!isBusy && !isDisabled) onConfirm?.()
57
+ },
58
+ })}
59
+ ${Button.render({
60
+ children: cancelLabel,
61
+ variant: "outline",
62
+ shape: "pill",
63
+ size: "md",
64
+ isDisabled: isBusy,
65
+ onClick: onCancel,
66
+ })}
67
+ </div>`,
68
+ onClose: isBusy ? undefined : onCancel,
69
+ })
70
+ }
@@ -0,0 +1,3 @@
1
+ import * as renderers from "./template.js"
2
+
3
+ export const CropDialog = { ...renderers }
@@ -0,0 +1,43 @@
1
+ .iw-dialog.iw-crop-dialog {
2
+ width: min(48rem, calc(100vw - 2 * var(--iw-space-4)));
3
+ min-width: 0;
4
+ max-width: none;
5
+ max-height: calc(
6
+ 100dvh - 2 * var(--iw-space-4) - var(--safe-area-top, 0px) -
7
+ var(--safe-area-bottom, 0px)
8
+ );
9
+ overflow-x: hidden;
10
+ overflow-y: auto;
11
+ overscroll-behavior: contain;
12
+ }
13
+
14
+ .iw-crop-dialog-viewport {
15
+ width: 100%;
16
+ --iw-image-cropper-max-height: 55dvh;
17
+ }
18
+
19
+ @media (max-height: 32rem) {
20
+ .iw-crop-dialog-viewport {
21
+ --iw-image-cropper-max-height: 35dvh;
22
+ }
23
+ }
24
+
25
+ .iw-crop-dialog-error {
26
+ margin: var(--iw-space-3) 0 0;
27
+ }
28
+
29
+ .iw-crop-dialog-actions {
30
+ display: flex;
31
+ justify-content: flex-end;
32
+ align-items: center;
33
+ gap: var(--iw-space-2);
34
+ width: 100%;
35
+
36
+ .iw-button {
37
+ flex: 0 1 auto;
38
+ min-width: 0;
39
+ padding-inline: var(--iw-space-3);
40
+ font-size: var(--iw-font-size-sm);
41
+ white-space: nowrap;
42
+ }
43
+ }
@@ -0,0 +1,82 @@
1
+ /**
2
+ * @typedef {import('../../../types/feedback/crop-dialog').CropDialogProps} CropDialogProps
3
+ * @typedef {import('@inglorious/web').TemplateResult} TemplateResult
4
+ * @typedef {import('@inglorious/web').Api} Api
5
+ */
6
+
7
+ import { html } from "@inglorious/web"
8
+ import { when } from "@inglorious/web/directives/when"
9
+
10
+ import { Button } from "../../controls/button/index.js"
11
+ import { Alert } from "../alert/index.js"
12
+ import { Dialog } from "../dialog/index.js"
13
+
14
+ /**
15
+ * Renders an ImageCropper entity in a dialog, with cancel and apply buttons.
16
+ * Apply stays disabled until the image has loaded, and passes the cropper's
17
+ * `rect`.
18
+ * @param {CropDialogProps} props
19
+ * @param {Api} api
20
+ * @returns {TemplateResult}
21
+ */
22
+ export function render(props, api) {
23
+ const {
24
+ id,
25
+ isOpen = false,
26
+ cropperId,
27
+ title,
28
+ description,
29
+ applyLabel = "Apply",
30
+ savingLabel = "Saving…",
31
+ cancelLabel = "Cancel",
32
+ closeLabel,
33
+ loadErrorText = "The image could not be loaded.",
34
+ error,
35
+ isSaving = false,
36
+ className = "",
37
+ onCancel,
38
+ onApply,
39
+ } = props
40
+
41
+ const cropper = api.getEntity(cropperId)
42
+ const isLoaded = Boolean(cropper?.naturalWidth)
43
+ const shownError = error || (cropper?.hasError ? loadErrorText : null)
44
+
45
+ return Dialog.render({
46
+ id,
47
+ isOpen,
48
+ title,
49
+ description,
50
+ closeLabel,
51
+ className: ["iw-crop-dialog", className].filter(Boolean).join(" "),
52
+ onClose: onCancel,
53
+ children: html`
54
+ <div class="iw-crop-dialog-viewport">${api.render(cropperId)}</div>
55
+ ${when(shownError, () =>
56
+ Alert.render({
57
+ severity: "error",
58
+ className: "iw-crop-dialog-error",
59
+ children: shownError,
60
+ }),
61
+ )}
62
+ `,
63
+ actions: html`<div class="iw-crop-dialog-actions">
64
+ ${Button.render({
65
+ children: cancelLabel,
66
+ variant: "ghost",
67
+ shape: "pill",
68
+ size: "sm",
69
+ isDisabled: isSaving,
70
+ onClick: onCancel,
71
+ })}
72
+ ${Button.render({
73
+ children: isSaving ? savingLabel : applyLabel,
74
+ color: "primary",
75
+ shape: "pill",
76
+ size: "sm",
77
+ isDisabled: isSaving || !isLoaded,
78
+ onClick: () => onApply?.(cropper.rect),
79
+ })}
80
+ </div>`,
81
+ })
82
+ }
@@ -43,8 +43,9 @@
43
43
  font-size: 1.1rem;
44
44
  }
45
45
 
46
- .iw-dialog-close {
46
+ .iw-dialog-header .iw-dialog-close {
47
47
  flex-shrink: 0;
48
+ margin-inline-start: auto;
48
49
  }
49
50
 
50
51
  .iw-dialog-description {
@@ -53,6 +53,9 @@ export function render(props) {
53
53
 
54
54
  const titleId = id && title ? `${id}-title` : ""
55
55
  const descriptionId = id && description ? `${id}-description` : ""
56
+ // Without a title, the description is what the dialog asks: its name.
57
+ const labelId = titleId || descriptionId
58
+ const describedById = titleId ? descriptionId : ""
56
59
  const onBackdrop = onBackdropClick ?? onClose
57
60
 
58
61
  return html`<dialog
@@ -63,8 +66,8 @@ export function render(props) {
63
66
  "iw-dialog-sheet": variant === "sheet",
64
67
  ...extraClasses,
65
68
  })}
66
- aria-labelledby=${titleId || nothing}
67
- aria-describedby=${descriptionId || nothing}
69
+ aria-labelledby=${labelId || nothing}
70
+ aria-describedby=${describedById || nothing}
68
71
  @pointerdown=${(event) => {
69
72
  backdropPresses.set(
70
73
  event.currentTarget,
@@ -1,6 +1,9 @@
1
1
  @import "./alert/style.css";
2
2
  @import "./backdrop/style.css";
3
+ @import "./confirm-dialog/style.css";
4
+ @import "./crop-dialog/style.css";
3
5
  @import "./dialog/style.css";
6
+ @import "./load-status/style.css";
4
7
  @import "./progress/style.css";
5
8
  @import "./skeleton/style.css";
6
9
  @import "./snackbar/style.css";
@@ -0,0 +1,3 @@
1
+ import * as renderers from "./template.js"
2
+
3
+ export const LoadStatus = { ...renderers }
@@ -0,0 +1,16 @@
1
+ import { createRender } from "../../stories/notify-story.js"
2
+ import { LoadStatus } from "."
3
+
4
+ export default {
5
+ title: "Feedback/LoadStatus",
6
+ tags: ["autodocs"],
7
+ render: createRender(LoadStatus),
8
+ }
9
+
10
+ export const Loading = { args: { isLoading: true } }
11
+
12
+ export const Empty = { args: { isEmpty: true, emptyText: "No events yet." } }
13
+
14
+ export const Error = {
15
+ args: { isError: true, error: "The events could not be loaded." },
16
+ }
@@ -0,0 +1,10 @@
1
+ .iw-load-status {
2
+ display: flex;
3
+ flex-direction: column;
4
+ align-items: center;
5
+ grid-column: 1 / -1;
6
+ padding: var(--iw-space-10) 0;
7
+ text-align: center;
8
+ font-size: var(--iw-font-size-sm);
9
+ color: var(--iw-color-text-muted, var(--iw-color-text));
10
+ }
@@ -0,0 +1,43 @@
1
+ /**
2
+ * @typedef {import('../../../types/feedback/load-status').LoadStatusProps} LoadStatusProps
3
+ * @typedef {import('@inglorious/web').TemplateResult} TemplateResult
4
+ */
5
+
6
+ import { html, nothing } from "@inglorious/web"
7
+
8
+ import { Progress } from "../progress/index.js"
9
+
10
+ /**
11
+ * Renders where a load stands instead of what it loads: an error, a loader or
12
+ * an empty message, in that order of precedence. Otherwise it renders
13
+ * `content`, a function so that it runs only once there is something to show.
14
+ * @param {LoadStatusProps} props
15
+ * @returns {import('../../../types/shared/renderable').Renderable}
16
+ */
17
+ export function render(props) {
18
+ const {
19
+ isError = false,
20
+ error,
21
+ isLoading = false,
22
+ loader,
23
+ loadingLabel = "Loading…",
24
+ isEmpty = false,
25
+ emptyText,
26
+ content,
27
+ className = "",
28
+ } = props
29
+
30
+ const classes = ["iw-load-status", className].filter(Boolean).join(" ")
31
+
32
+ if (isError) return html`<div class=${classes} role="alert">${error}</div>`
33
+ if (isLoading) {
34
+ return html`<div class=${classes} role="status">
35
+ ${
36
+ loader ??
37
+ Progress.render({ variant: "circular", ariaLabel: loadingLabel })
38
+ }
39
+ </div>`
40
+ }
41
+ if (isEmpty) return html`<div class=${classes}>${emptyText}</div>`
42
+ return content ? content() : nothing
43
+ }
package/src/index.js CHANGED
@@ -1,6 +1,7 @@
1
1
  export { Button } from "./controls/button/index.js"
2
2
  export { ButtonGroup } from "./controls/button-group/index.js"
3
3
  export { Checkbox } from "./controls/checkbox/index.js"
4
+ export { ChipPicker } from "./controls/chip-picker/index.js"
4
5
  export { Fab } from "./controls/fab/index.js"
5
6
  export { FileUpload } from "./controls/file-upload/index.js"
6
7
  export { IconButton } from "./controls/icon-button/index.js"
@@ -25,6 +26,7 @@ export { Chip } from "./data-display/chip/index.js"
25
26
  export { DataGrid } from "./data-display/data-grid/index.js"
26
27
  export { Divider } from "./data-display/divider/index.js"
27
28
  export { Icon } from "./data-display/icon/index.js"
29
+ export { Lightbox } from "./data-display/lightbox/index.js"
28
30
  export { List } from "./data-display/list/index.js"
29
31
  export { Table } from "./data-display/table/index.js"
30
32
  export { Tooltip } from "./data-display/tooltip/index.js"
@@ -32,7 +34,10 @@ export { Typography } from "./data-display/typography/index.js"
32
34
  export { VirtualList } from "./data-display/virtual-list/index.js"
33
35
  export { Alert } from "./feedback/alert/index.js"
34
36
  export { Backdrop } from "./feedback/backdrop/index.js"
37
+ export { ConfirmDialog } from "./feedback/confirm-dialog/index.js"
38
+ export { CropDialog } from "./feedback/crop-dialog/index.js"
35
39
  export { Dialog } from "./feedback/dialog/index.js"
40
+ export { LoadStatus } from "./feedback/load-status/index.js"
36
41
  export { Progress } from "./feedback/progress/index.js"
37
42
  export { Skeleton } from "./feedback/skeleton/index.js"
38
43
  export { Snackbar } from "./feedback/snackbar/index.js"
@@ -9,3 +9,15 @@ export const leftPanelClose = {
9
9
  height: 24,
10
10
  body: '<path fill="currentColor" d="M16.5 16V8l-4 4zM5 21q-.825 0-1.412-.587T3 19V5q0-.825.588-1.412T5 3h14q.825 0 1.413.588T21 5v14q0 .825-.587 1.413T19 21zm3-2V5H5v14zm2 0h9V5h-9zm-2 0H5z"/>',
11
11
  }
12
+
13
+ export const chevronLeft = {
14
+ width: 24,
15
+ height: 24,
16
+ body: '<path fill="currentColor" d="m14 18l-6-6l6-6l1.4 1.4l-4.6 4.6l4.6 4.6z"/>',
17
+ }
18
+
19
+ export const chevronRight = {
20
+ width: 24,
21
+ height: 24,
22
+ body: '<path fill="currentColor" d="M12.6 12L8 7.4L9.4 6l6 6l-6 6L8 16.6z"/>',
23
+ }
@@ -0,0 +1,23 @@
1
+ import type { TemplateResult } from "@inglorious/web"
2
+
3
+ import type { ComboboxOption } from "./combobox"
4
+
5
+ export interface ChipPickerProps {
6
+ /** The fieldset's legend. */
7
+ label?: TemplateResult | string
8
+ hint?: TemplateResult | string
9
+ /** Strings, numbers or `{ value, label, isDisabled }`, as in Combobox. */
10
+ options?: ComboboxOption[]
11
+ /** The values picked. */
12
+ value?: (string | number)[]
13
+ isDisabled?: boolean
14
+ className?: string
15
+ /** Called with the value of the chip pressed, picked or not. */
16
+ onToggle?: (value: string | number) => void
17
+ }
18
+
19
+ export type ChipPickerType = {
20
+ render(props: ChipPickerProps): TemplateResult
21
+ }
22
+
23
+ export declare const ChipPicker: ChipPickerType
@@ -45,6 +45,16 @@ export interface ComboboxProps {
45
45
  noOptionsMessage?: string
46
46
  loadingMessage?: string
47
47
 
48
+ /** A validation message, shown under the control. */
49
+ error?: string | null
50
+ /**
51
+ * An event to notify when the user picks or clears a value, such as
52
+ * `"#form:fieldChange"`. The payload is `changePayload` with the new `value`.
53
+ */
54
+ changeEvent?: string
55
+ /** Merged into `changeEvent`'s payload, such as `{ path: "country" }`. */
56
+ changePayload?: Record<string, unknown>
57
+
48
58
  isFullWidth?: boolean
49
59
  size?: "sm" | "md" | "lg"
50
60
  onToggle?: () => void
@@ -68,13 +78,21 @@ export type ComboboxType = {
68
78
  open(entity: ComboboxProps): void
69
79
  close(entity: ComboboxProps): void
70
80
  toggle(entity: ComboboxProps): void
71
- optionSelect(entity: ComboboxProps, option: ComboboxOption): void
72
- clear(entity: ComboboxProps): void
81
+ optionSelect(entity: ComboboxProps, option: ComboboxOption, api?: Api): void
82
+ clear(entity: ComboboxProps, payload?: unknown, api?: Api): void
73
83
  searchChange(entity: ComboboxProps, searchTerm: string): void
74
84
  focusNext(entity: ComboboxProps): void
75
85
  focusPrev(entity: ComboboxProps): void
76
86
  focusFirst(entity: ComboboxProps): void
77
87
  focusLast(entity: ComboboxProps): void
88
+ focusSet(entity: ComboboxProps, index: number): void
89
+ /** Sets the value from outside, without notifying `changeEvent`. An empty string is no value. */
90
+ valueSet(
91
+ entity: ComboboxProps,
92
+ value: string | number | (string | number)[] | null,
93
+ ): void
94
+ optionsSet(entity: ComboboxProps, options: ComboboxOption[]): void
95
+ errorSet(entity: ComboboxProps, error: string | null): void
78
96
  }
79
97
 
80
98
  export declare const Combobox: ComboboxType
@@ -0,0 +1,35 @@
1
+ import type { TemplateResult, nothing } from "@inglorious/web"
2
+
3
+ export interface LightboxImage {
4
+ src: string
5
+ /** Defaults to empty, for images the page describes already. */
6
+ alt?: string
7
+ }
8
+
9
+ export interface LightboxProps {
10
+ id?: string
11
+ /** URLs, or `{ src, alt }`. Renders nothing when empty. */
12
+ images?: (string | LightboxImage)[]
13
+ /** The image shown. Any integer: it wraps around. */
14
+ index?: number
15
+ isOpen?: boolean
16
+ /** The dialog's accessible name. Defaults to `"Photos"`. */
17
+ label?: string
18
+ /** Defaults to `"Close"`. */
19
+ closeLabel?: string
20
+ /** Defaults to `"Previous photo"`. */
21
+ previousLabel?: string
22
+ /** Defaults to `"Next photo"`. */
23
+ nextLabel?: string
24
+ className?: string
25
+ /** `1` for the next image, `-1` for the previous. Without it there is no navigation. */
26
+ onStep?: (step: 1 | -1) => void
27
+ /** Called by the close button, Esc and a press outside the image. */
28
+ onClose?: () => void
29
+ }
30
+
31
+ export type LightboxType = {
32
+ render(props: LightboxProps): TemplateResult | typeof nothing
33
+ }
34
+
35
+ export declare const Lightbox: LightboxType
@@ -0,0 +1,34 @@
1
+ import type { TemplateResult } from "@inglorious/web"
2
+
3
+ import type { Renderable } from "../shared/renderable"
4
+
5
+ export interface ConfirmDialogProps {
6
+ id?: string
7
+ isOpen?: boolean
8
+ /** The question, such as "Delete this event?". */
9
+ message?: TemplateResult | string | number
10
+ /** Anything more to show under the message, such as an error. */
11
+ children?: Renderable
12
+ confirmLabel: string
13
+ /** The confirm button's text while `isBusy`. Defaults to `confirmLabel`. */
14
+ busyLabel?: string
15
+ /** Defaults to `"Cancel"`. */
16
+ cancelLabel?: string
17
+ /** The close button's accessible name. Defaults to `"Close"`. */
18
+ closeLabel?: string
19
+ /** `"danger"` (default) for an action that cannot be undone, `"primary"` otherwise. */
20
+ tone?: "danger" | "primary"
21
+ /** The action is running: nothing can be pressed and the sheet stays open. */
22
+ isBusy?: boolean
23
+ isDisabled?: boolean
24
+ className?: string
25
+ onConfirm?: () => void
26
+ /** Called by the cancel button, Esc and the backdrop. */
27
+ onCancel?: () => void
28
+ }
29
+
30
+ export type ConfirmDialogType = {
31
+ render(props: ConfirmDialogProps): TemplateResult
32
+ }
33
+
34
+ export declare const ConfirmDialog: ConfirmDialogType
@@ -0,0 +1,35 @@
1
+ import type { Api, TemplateResult } from "@inglorious/web"
2
+
3
+ import type { CropRect } from "../controls/image-cropper"
4
+
5
+ export interface CropDialogProps {
6
+ id?: string
7
+ isOpen?: boolean
8
+ /** The id of the ImageCropper entity to show. */
9
+ cropperId: string
10
+ title?: TemplateResult | string
11
+ description?: TemplateResult | string
12
+ /** Defaults to `"Apply"`. */
13
+ applyLabel?: string
14
+ /** The apply button's text while `isSaving`. Defaults to `"Saving…"`. */
15
+ savingLabel?: string
16
+ /** Defaults to `"Cancel"`. */
17
+ cancelLabel?: string
18
+ /** The close button's accessible name. Defaults to `"Close"`. */
19
+ closeLabel?: string
20
+ /** Shown when the cropper cannot load its image. */
21
+ loadErrorText?: string
22
+ /** An error of the caller's, such as a failed upload. Wins over `loadErrorText`. */
23
+ error?: TemplateResult | string | null
24
+ isSaving?: boolean
25
+ className?: string
26
+ onCancel?: () => void
27
+ /** Receives the cropper's `rect`. */
28
+ onApply?: (rect: CropRect) => void
29
+ }
30
+
31
+ export type CropDialogType = {
32
+ render(props: CropDialogProps, api: Api): TemplateResult
33
+ }
34
+
35
+ export declare const CropDialog: CropDialogType
@@ -0,0 +1,22 @@
1
+ import type { Renderable } from "../shared/renderable"
2
+
3
+ export interface LoadStatusProps {
4
+ isError?: boolean
5
+ error?: Renderable
6
+ isLoading?: boolean
7
+ /** Replaces the circular progress, such as with the app's own animation. */
8
+ loader?: Renderable
9
+ /** The progress indicator's accessible name. Defaults to `"Loading…"`. */
10
+ loadingLabel?: string
11
+ isEmpty?: boolean
12
+ emptyText?: Renderable
13
+ /** What to render when there is no status to show. Runs only then, so it can read data still loading. */
14
+ content?: () => Renderable
15
+ className?: string
16
+ }
17
+
18
+ export type LoadStatusType = {
19
+ render(props: LoadStatusProps): Renderable
20
+ }
21
+
22
+ export declare const LoadStatus: LoadStatusType
package/types/index.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  export { Button } from "./controls/button"
2
2
  export { ButtonGroup } from "./controls/button-group"
3
3
  export { Checkbox } from "./controls/checkbox"
4
+ export { ChipPicker } from "./controls/chip-picker"
4
5
  export { Fab } from "./controls/fab"
5
6
  export { FileUpload } from "./controls/file-upload"
6
7
  export { IconButton } from "./controls/icon-button"
@@ -18,6 +19,7 @@ export { BeforeAfter } from "./data-display/before-after"
18
19
  export { Carousel } from "./data-display/carousel"
19
20
  export { Chat } from "./data-display/chat"
20
21
  export { Chip } from "./data-display/chip"
22
+ export { Lightbox } from "./data-display/lightbox"
21
23
  export { DataGrid } from "./data-display/data-grid"
22
24
  export { Divider } from "./data-display/divider"
23
25
  export { Icon } from "./data-display/icon"
@@ -28,7 +30,10 @@ export { Typography } from "./data-display/typography"
28
30
  export { VirtualList } from "./data-display/virtual-list"
29
31
  export { Alert } from "./feedback/alert"
30
32
  export { Backdrop } from "./feedback/backdrop"
33
+ export { ConfirmDialog } from "./feedback/confirm-dialog"
34
+ export { CropDialog } from "./feedback/crop-dialog"
31
35
  export { Dialog } from "./feedback/dialog"
36
+ export { LoadStatus } from "./feedback/load-status"
32
37
  export { Progress } from "./feedback/progress"
33
38
  export { Skeleton } from "./feedback/skeleton"
34
39
  export { Snackbar } from "./feedback/snackbar"
@@ -53,6 +58,7 @@ export { Paper } from "./surfaces/paper"
53
58
  export type { ButtonProps, ButtonType } from "./controls/button"
54
59
  export type { ButtonGroupProps, ButtonGroupType } from "./controls/button-group"
55
60
  export type { CheckboxProps, CheckboxType } from "./controls/checkbox"
61
+ export type { ChipPickerProps, ChipPickerType } from "./controls/chip-picker"
56
62
  export type {
57
63
  ComboboxProps,
58
64
  ComboboxType,
@@ -119,6 +125,11 @@ export type { PaperProps, PaperType } from "./surfaces/paper"
119
125
  export type { AvatarProps, AvatarType } from "./data-display/avatar"
120
126
  export type { BadgeProps, BadgeType } from "./data-display/badge"
121
127
  export type { ChipProps, ChipType } from "./data-display/chip"
128
+ export type {
129
+ LightboxImage,
130
+ LightboxProps,
131
+ LightboxType,
132
+ } from "./data-display/lightbox"
122
133
  export type {
123
134
  DataGridProps,
124
135
  DataGridType,
@@ -148,7 +159,13 @@ export type {
148
159
  } from "./data-display/typography"
149
160
  export type { AlertProps, AlertType } from "./feedback/alert"
150
161
  export type { BackdropProps, BackdropType } from "./feedback/backdrop"
162
+ export type {
163
+ ConfirmDialogProps,
164
+ ConfirmDialogType,
165
+ } from "./feedback/confirm-dialog"
166
+ export type { CropDialogProps, CropDialogType } from "./feedback/crop-dialog"
151
167
  export type { DialogProps, DialogType } from "./feedback/dialog"
168
+ export type { LoadStatusProps, LoadStatusType } from "./feedback/load-status"
152
169
  export type { ProgressProps, ProgressType } from "./feedback/progress"
153
170
  export type { SkeletonProps, SkeletonType } from "./feedback/skeleton"
154
171
  export type { SnackbarProps, SnackbarType } from "./feedback/snackbar"