@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.
- package/package.json +28 -3
- package/src/controls/chip-picker/chip-picker.stories.js +22 -0
- package/src/controls/chip-picker/index.js +3 -0
- package/src/controls/chip-picker/style.css +26 -0
- package/src/controls/chip-picker/template.js +53 -0
- package/src/controls/combobox/handlers.js +81 -19
- package/src/controls/controls.css +3 -2
- package/src/data-display/data-display.css +1 -0
- package/src/data-display/lightbox/index.js +3 -0
- package/src/data-display/lightbox/lightbox.stories.js +25 -0
- package/src/data-display/lightbox/style.css +97 -0
- package/src/data-display/lightbox/template.js +153 -0
- package/src/feedback/confirm-dialog/confirm-dialog.stories.js +33 -0
- package/src/feedback/confirm-dialog/index.js +3 -0
- package/src/feedback/confirm-dialog/style.css +16 -0
- package/src/feedback/confirm-dialog/template.js +70 -0
- package/src/feedback/crop-dialog/index.js +3 -0
- package/src/feedback/crop-dialog/style.css +43 -0
- package/src/feedback/crop-dialog/template.js +82 -0
- package/src/feedback/dialog/style.css +2 -1
- package/src/feedback/dialog/template.js +5 -2
- package/src/feedback/feedback.css +3 -0
- package/src/feedback/load-status/index.js +3 -0
- package/src/feedback/load-status/load-status.stories.js +16 -0
- package/src/feedback/load-status/style.css +10 -0
- package/src/feedback/load-status/template.js +43 -0
- package/src/index.js +5 -0
- package/src/shared/icons.js +12 -0
- package/types/controls/chip-picker.d.ts +23 -0
- package/types/controls/combobox.d.ts +20 -2
- package/types/data-display/lightbox.d.ts +35 -0
- package/types/feedback/confirm-dialog.d.ts +34 -0
- package/types/feedback/crop-dialog.d.ts +35 -0
- package/types/feedback/load-status.d.ts +22 -0
- package/types/index.d.ts +17 -0
|
@@ -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,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
|
+
}
|
|
@@ -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=${
|
|
67
|
-
aria-describedby=${
|
|
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,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"
|
package/src/shared/icons.js
CHANGED
|
@@ -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"
|