@crewlethq/ui 0.34.1 → 0.35.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/README.md +51 -0
- package/dist/AppShell/index.js +2 -2
- package/dist/ArtifactBar/ArtifactBar.d.ts +7 -1
- package/dist/ArtifactBar/index.d.ts +1 -0
- package/dist/ArtifactBar/index.js +4 -14
- package/dist/{ArtifactBar-C462VD4C.css → ArtifactBar-HV5AT4RG.css} +39 -2
- package/dist/ArtifactCard/ArtifactCard.d.ts +1 -10
- package/dist/ArtifactCard/index.d.ts +5 -2
- package/dist/ArtifactCard/index.js +3 -2
- package/dist/{ArtifactCard-XHRLAL7C.css → ArtifactCard-OGTMO2KI.css} +15 -16
- package/dist/ArtifactCover/index.js +2 -14
- package/dist/ArtifactIcon/ArtifactIcon.d.ts +1 -1
- package/dist/ArtifactIcon/index.js +2 -15
- package/dist/ArtifactKindGlyph/ArtifactKindGlyph.d.ts +10 -0
- package/dist/ArtifactKindGlyph/index.d.ts +2 -0
- package/dist/ArtifactKindGlyph/index.js +1 -0
- package/dist/ArtifactKindIllustration/ArtifactKindIllustration.d.ts +15 -2
- package/dist/ArtifactKindIllustration/index.d.ts +1 -0
- package/dist/ArtifactKindIllustration/index.js +1 -1
- package/dist/{ArtifactKindIllustration-4NG6IE3C.css → ArtifactKindIllustration-5FPRJQ3P.css} +32 -26
- package/dist/ArtifactKinds-CVD3FCYO.css +15 -0
- package/dist/AvatarPicker/index.js +3 -3
- package/dist/CanvasBoard/CanvasBoard.d.ts +30 -12
- package/dist/CanvasBoard/index.js +1 -1
- package/dist/ChangeMark/index.js +2 -2
- package/dist/ChoiceList/ChoiceList.d.ts +7 -1
- package/dist/ChoiceList/index.js +1 -1
- package/dist/{ChoiceList-2PQJS4DX.css → ChoiceList-RBL7FNQL.css} +39 -0
- package/dist/CommentThread/index.js +2 -2
- package/dist/DataTable/index.js +2 -2
- package/dist/DataView/index.js +5 -5
- package/dist/DateTimePicker/index.js +2 -2
- package/dist/DocTabsEditor/index.js +2 -2
- package/dist/{Editor-UUZ7XKCU.js → Editor-BVQHBF7L.js} +4 -4
- package/dist/FileDrop/FileDrop.d.ts +64 -0
- package/dist/FileDrop/index.d.ts +3 -0
- package/dist/FileDrop/index.js +4 -0
- package/dist/FileDrop-WE7BNZGV.css +80 -0
- package/dist/FindingList/FindingList.d.ts +35 -0
- package/dist/FindingList/index.d.ts +3 -0
- package/dist/FindingList/index.js +3 -0
- package/dist/FindingList-PMYA2R6Q.css +71 -0
- package/dist/HuePicker/HuePicker.d.ts +9 -0
- package/dist/HuePicker/index.d.ts +1 -1
- package/dist/HuePicker/index.js +1 -1
- package/dist/Markdown/index.js +1 -1
- package/dist/Menu/Menu.d.ts +6 -1
- package/dist/Menu/index.js +1 -1
- package/dist/OrgTable/index.js +1 -1
- package/dist/RichEditor/index.js +3 -3
- package/dist/RichEditorMarkdown/index.js +3 -3
- package/dist/SheetColumnEditor/SheetColumnEditor.d.ts +94 -0
- package/dist/SheetColumnEditor/index.d.ts +3 -0
- package/dist/SheetColumnEditor/index.js +23 -0
- package/dist/SheetColumnEditor-BO2HKFRB.css +73 -0
- package/dist/SheetGrid/SheetGrid.d.ts +19 -1
- package/dist/SheetGrid/index.js +5 -4
- package/dist/{SheetGrid-GDPCCZ4V.css → SheetGrid-YRDXTIIZ.css} +48 -0
- package/dist/SheetModel/index.js +1 -1
- package/dist/SheetModel/labels.d.ts +6 -0
- package/dist/SlideFilmstrip/SlideFilmstrip.d.ts +30 -1
- package/dist/SlideFilmstrip/index.js +5 -1
- package/dist/{SlideFilmstrip-5U6Z55GS.css → SlideFilmstrip-4ITZLMO4.css} +49 -0
- package/dist/SourceEditor/SourceEditor.d.ts +62 -0
- package/dist/SourceEditor/index.d.ts +3 -0
- package/dist/SourceEditor/index.js +3 -0
- package/dist/SourceEditor-G2C3STPX.css +160 -0
- package/dist/ThemeGallery/ThemeGallery.d.ts +10 -3
- package/dist/ThemeGallery/index.js +1 -1
- package/dist/{ThemeGallery-NITASULQ.css → ThemeGallery-HSUKBDWY.css} +9 -0
- package/dist/TimeWindowPicker/index.js +2 -2
- package/dist/{chunk-UXXJDIYE.js → chunk-22CQQDFW.js} +1 -1
- package/dist/{chunk-E4NNGC6X.js → chunk-3VD3G3IL.js} +2 -2
- package/dist/{chunk-EWAFN2IU.js → chunk-5VCG26CV.js} +281 -234
- package/dist/{chunk-XTOVADJU.js → chunk-7UYONN6K.js} +7 -18
- package/dist/{chunk-CFAJP777.js → chunk-AXBRWRGV.js} +1 -1
- package/dist/{chunk-KK5OYNAF.js → chunk-BAKPMH3S.js} +8 -4
- package/dist/{chunk-3EB2AV3H.js → chunk-BUVCV3WI.js} +1 -1
- package/dist/chunk-CE2THTQR.js +19 -0
- package/dist/{chunk-4B6LSFDS.js → chunk-CSQTDGTS.js} +1 -1
- package/dist/{chunk-WPX6A5BV.js → chunk-E35CMI5D.js} +22 -6
- package/dist/{chunk-EBCHVFCS.js → chunk-FJJHD73S.js} +2 -2
- package/dist/{chunk-SGHIAGPR.js → chunk-HAKTRTRP.js} +1 -1
- package/dist/{chunk-PLDUNXAO.js → chunk-ILDNJHRU.js} +1 -1
- package/dist/chunk-MAD6WPER.js +342 -0
- package/dist/{chunk-IUD5VA2Z.js → chunk-NKZCJRKO.js} +10 -5
- package/dist/chunk-NTB5LRRD.js +52 -0
- package/dist/{chunk-VI5FWDZW.js → chunk-OOMXLJ3S.js} +4 -1
- package/dist/{chunk-UOR7TOAU.js → chunk-OSFA5ROT.js} +86 -1
- package/dist/{chunk-T46NR3WP.js → chunk-PGZ2R3ON.js} +1 -1
- package/dist/chunk-PI7HKLIT.js +245 -0
- package/dist/{chunk-YZFLH463.js → chunk-QEFHYUCY.js} +1 -1
- package/dist/{chunk-7Q7WDXHG.js → chunk-QFNWMWWY.js} +3 -3
- package/dist/{chunk-C7DKX453.js → chunk-QH6VYJ3X.js} +1 -1
- package/dist/{chunk-XV32RKQZ.js → chunk-QIXMNOBD.js} +67 -6
- package/dist/{chunk-GPHWCK7M.js → chunk-SUXP4OBT.js} +6 -3
- package/dist/{chunk-TRQCHF2F.js → chunk-SWD4QBL6.js} +1 -1
- package/dist/chunk-THDGBD6Y.js +154 -0
- package/dist/{chunk-C2FRTWKO.js → chunk-W3UVOZKL.js} +3 -2
- package/dist/{chunk-UDQW6UK7.js → chunk-W7QBBKUE.js} +34 -7
- package/dist/{chunk-QBXZLGK2.js → chunk-ZU3DUXD2.js} +3 -2
- package/dist/generated/index.d.ts +5 -0
- package/dist/generated/index.js +73 -68
- package/dist/index.js +73 -68
- package/dist/styles.css +652 -51
- package/dist/utils/csv.d.ts +35 -0
- package/dist/utils/index.d.ts +2 -1
- package/dist/utils/index.js +1 -1
- package/package.json +3 -3
- package/dist/{chunk-YCARLYI6.js → chunk-3WCNHYXE.js} +0 -0
- package/dist/{chunk-IYO2N5ZH.js → chunk-6JVRY5DQ.js} +1 -1
- package/dist/{chunk-BY4N65PM.js → chunk-73A7D5CE.js} +1 -1
- package/dist/{chunk-AORVEG5V.js → chunk-F2KY4RLI.js} +1 -1
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A sheet column's settings, as a compact panel: its name, its type, the
|
|
3
|
+
* choices a select, multi-select or status column offers (each with its
|
|
4
|
+
* colour, or its category for a status), whether a value is required, and
|
|
5
|
+
* moving or deleting the column. What a SheetGrid header's popover holds
|
|
6
|
+
* (`renderColumnEditor`), and what any schema surface that edits one column
|
|
7
|
+
* at a time draws.
|
|
8
|
+
*
|
|
9
|
+
* LIVE, NOT A FORM TO SUBMIT. Every change is handed to the host at once as
|
|
10
|
+
* the next `SheetColumn`, so the grid beside it redraws as the reader types
|
|
11
|
+
* and picks; Done only closes. A name cleared to nothing is held here and
|
|
12
|
+
* not handed on, since a column with no name is one nobody can find, and the
|
|
13
|
+
* name it had comes back if the reader leaves it empty.
|
|
14
|
+
*
|
|
15
|
+
* A CHOICE'S ID IS MADE ONCE, from its label when it is added, and never
|
|
16
|
+
* changes after, so renaming a choice never rewrites a value that chose it.
|
|
17
|
+
* A host whose store has its own id rule passes `optionId`.
|
|
18
|
+
*/
|
|
19
|
+
import { type SheetColumn, type SheetColumnType, type SheetStatusCategory } from '../SheetModel/index.js';
|
|
20
|
+
/** The glyph each column type is drawn with, in a type menu and beside a column's name. */
|
|
21
|
+
export declare function SheetColumnTypeGlyph({ type, size }: {
|
|
22
|
+
type: SheetColumnType;
|
|
23
|
+
size?: 'xs' | 'sm' | 'md' | undefined;
|
|
24
|
+
}): import("react").JSX.Element;
|
|
25
|
+
export interface SheetColumnEditorLabels {
|
|
26
|
+
name: string;
|
|
27
|
+
/** Said when the name field is left empty. */
|
|
28
|
+
nameMissing: string;
|
|
29
|
+
type: string;
|
|
30
|
+
/** Each type's name. */
|
|
31
|
+
types: Record<SheetColumnType, string>;
|
|
32
|
+
/** What each type holds, under its name in the type list. */
|
|
33
|
+
typeDetails: Record<SheetColumnType, string>;
|
|
34
|
+
/** The suggestion beside the type: "Looks like dates". */
|
|
35
|
+
suggestion: (type: string) => string;
|
|
36
|
+
/** The button that takes the suggestion: "Use Date". */
|
|
37
|
+
useType: (type: string) => string;
|
|
38
|
+
choices: string;
|
|
39
|
+
addChoice: string;
|
|
40
|
+
choiceName: (index: number) => string;
|
|
41
|
+
choiceColor: (choice: string) => string;
|
|
42
|
+
noColor: string;
|
|
43
|
+
choiceCategory: (choice: string) => string;
|
|
44
|
+
categories: Record<SheetStatusCategory, string>;
|
|
45
|
+
removeChoice: (choice: string) => string;
|
|
46
|
+
noChoices: string;
|
|
47
|
+
duplicateChoice: (choice: string) => string;
|
|
48
|
+
/** The choices a new status column starts with, one per category it names. */
|
|
49
|
+
statusStarters: readonly {
|
|
50
|
+
label: string;
|
|
51
|
+
category: SheetStatusCategory;
|
|
52
|
+
}[];
|
|
53
|
+
required: string;
|
|
54
|
+
requiredDetail: string;
|
|
55
|
+
stars: string;
|
|
56
|
+
moveBefore: string;
|
|
57
|
+
moveAfter: string;
|
|
58
|
+
deleteColumn: string;
|
|
59
|
+
done: string;
|
|
60
|
+
}
|
|
61
|
+
export declare const SHEET_COLUMN_EDITOR_LABELS: SheetColumnEditorLabels;
|
|
62
|
+
export interface SheetColumnEditorProps {
|
|
63
|
+
column: SheetColumn;
|
|
64
|
+
/** Every change, at once, as the next column. */
|
|
65
|
+
onChange: (next: SheetColumn) => void;
|
|
66
|
+
/** Done: the host closes the panel. Enter in the name field does the same. */
|
|
67
|
+
onDone?: (() => void) | undefined;
|
|
68
|
+
/** Shows Delete column. */
|
|
69
|
+
onDelete?: (() => void) | undefined;
|
|
70
|
+
/** Why Delete column cannot be pressed, said on it: the one column a sheet needs, say. */
|
|
71
|
+
deleteDisabledReason?: string | undefined;
|
|
72
|
+
/** Shows Move left and Move right. */
|
|
73
|
+
onMove?: ((step: -1 | 1) => void) | undefined;
|
|
74
|
+
canMoveBefore?: boolean | undefined;
|
|
75
|
+
canMoveAfter?: boolean | undefined;
|
|
76
|
+
/** The types offered, in their order. Every type by default. */
|
|
77
|
+
types?: readonly SheetColumnType[] | undefined;
|
|
78
|
+
/** Why the type cannot change, said under it: the column every row is named by, say. */
|
|
79
|
+
typeLockedReason?: string | undefined;
|
|
80
|
+
/** A type the host proposes from the column's name or its values, offered as one press. */
|
|
81
|
+
suggestedType?: SheetColumnType | undefined;
|
|
82
|
+
/** Why the host refuses the name (another column has it, say). */
|
|
83
|
+
nameError?: string | undefined;
|
|
84
|
+
/** Makes a new choice's id from its label, unique among `taken`. */
|
|
85
|
+
optionId?: ((label: string, taken: readonly string[]) => string) | undefined;
|
|
86
|
+
/**
|
|
87
|
+
* Starts on the name, selected, so typing replaces it: a panel opened on a
|
|
88
|
+
* header, or on a column just added with a placeholder name.
|
|
89
|
+
*/
|
|
90
|
+
selectName?: boolean | undefined;
|
|
91
|
+
labels?: Partial<SheetColumnEditorLabels> | undefined;
|
|
92
|
+
className?: string | undefined;
|
|
93
|
+
}
|
|
94
|
+
export declare function SheetColumnEditor({ column, onChange, onDone, onDelete, deleteDisabledReason, onMove, canMoveBefore, canMoveAfter, types, typeLockedReason, suggestedType, nameError, optionId, selectName, labels: overrides, className, }: SheetColumnEditorProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export { SHEET_COLUMN_EDITOR_LABELS, SheetColumnEditor, SheetColumnTypeGlyph } from '../chunk-MAD6WPER.js';
|
|
2
|
+
import '../chunk-BQ7AKL2N.js';
|
|
3
|
+
import '../chunk-FFMCMSJB.js';
|
|
4
|
+
import '../chunk-F73MC7EZ.js';
|
|
5
|
+
import '../chunk-OOMXLJ3S.js';
|
|
6
|
+
import '../chunk-Z7JYG5TF.js';
|
|
7
|
+
import '../chunk-SUXP4OBT.js';
|
|
8
|
+
import '../chunk-AYKXMIOR.js';
|
|
9
|
+
import '../chunk-CPEPST4S.js';
|
|
10
|
+
import '../chunk-6QFAK2WV.js';
|
|
11
|
+
import '../chunk-SMBKXWML.js';
|
|
12
|
+
import '../chunk-CCAXYHQS.js';
|
|
13
|
+
import '../chunk-VL6CUNSX.js';
|
|
14
|
+
import '../chunk-RKKO7QHH.js';
|
|
15
|
+
import '../chunk-BHHIIK3M.js';
|
|
16
|
+
import '../chunk-PQADV6P6.js';
|
|
17
|
+
import '../chunk-BUVCV3WI.js';
|
|
18
|
+
import '../chunk-OMV5W53A.js';
|
|
19
|
+
import '../chunk-R25RGPUB.js';
|
|
20
|
+
import '../chunk-OG6CL3EB.js';
|
|
21
|
+
import '../chunk-4FQT6ZAY.js';
|
|
22
|
+
import '../chunk-BZFWDIV6.js';
|
|
23
|
+
import '../chunk-ODEQTPFM.js';
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* A sheet column's settings (SheetColumnEditor.tsx): a column of fields at
|
|
3
|
+
* the compact step, the choices as rows of a swatch, a name and a remove
|
|
4
|
+
* control, and a foot with the column's own actions at the start and Done at
|
|
5
|
+
* the end. It sits in a popover, so it sets no surface of its own.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
.crewlet-sheet-column-editor {
|
|
9
|
+
display: flex;
|
|
10
|
+
flex-direction: column;
|
|
11
|
+
gap: var(--spacing-3);
|
|
12
|
+
width: 100%;
|
|
13
|
+
min-width: 0;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/* The suggestion: a quiet line naming the type, and the press that takes it. */
|
|
17
|
+
.crewlet-sheet-column-editor__suggestion {
|
|
18
|
+
display: flex;
|
|
19
|
+
align-items: center;
|
|
20
|
+
justify-content: space-between;
|
|
21
|
+
gap: var(--spacing-2);
|
|
22
|
+
margin-top: calc(var(--spacing-2) * -1);
|
|
23
|
+
color: var(--color-text-secondary);
|
|
24
|
+
font-size: var(--font-size-xs);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
.crewlet-sheet-column-editor__suggestion-text {
|
|
28
|
+
display: inline-flex;
|
|
29
|
+
align-items: center;
|
|
30
|
+
gap: var(--spacing-1);
|
|
31
|
+
min-width: 0;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
.crewlet-sheet-column-editor__choices {
|
|
35
|
+
display: flex;
|
|
36
|
+
flex-direction: column;
|
|
37
|
+
gap: var(--spacing-1);
|
|
38
|
+
margin: 0 0 var(--spacing-1);
|
|
39
|
+
padding: 0;
|
|
40
|
+
list-style: none;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
.crewlet-sheet-column-editor__choices:empty {
|
|
44
|
+
display: none;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
.crewlet-sheet-column-editor__choice {
|
|
48
|
+
display: flex;
|
|
49
|
+
align-items: center;
|
|
50
|
+
gap: var(--spacing-1);
|
|
51
|
+
min-width: 0;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
.crewlet-sheet-column-editor__choice > .crewlet-input {
|
|
55
|
+
flex: 1 1 auto;
|
|
56
|
+
min-width: 0;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/* The foot: a hairline above it, the column's own actions, then Done. */
|
|
60
|
+
.crewlet-sheet-column-editor__foot {
|
|
61
|
+
display: flex;
|
|
62
|
+
align-items: center;
|
|
63
|
+
justify-content: space-between;
|
|
64
|
+
gap: var(--spacing-2);
|
|
65
|
+
padding-top: var(--spacing-3);
|
|
66
|
+
border-top: 1px solid var(--color-border-default);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
.crewlet-sheet-column-editor__foot-start {
|
|
70
|
+
display: flex;
|
|
71
|
+
align-items: center;
|
|
72
|
+
gap: var(--spacing-1);
|
|
73
|
+
}
|
|
@@ -28,6 +28,7 @@
|
|
|
28
28
|
* row's `aria-rowindex` tell assistive technology how many there are and
|
|
29
29
|
* where it is.
|
|
30
30
|
*/
|
|
31
|
+
import { type ReactNode } from 'react';
|
|
31
32
|
import { type PresenceLabels } from '../PresenceModel/index.js';
|
|
32
33
|
import { type SheetCellPresence, type SheetColumn, type SheetEdit, type SheetLabels, type SheetPerson, type SheetRow, type SheetSort, type SheetSyncState } from '../SheetModel/index.js';
|
|
33
34
|
/** `edit` takes edits; `read` draws the same grid with every cell read only. */
|
|
@@ -95,10 +96,27 @@ export interface SheetGridProps {
|
|
|
95
96
|
* (`sync.refused`), so the reader clears them once they have read why.
|
|
96
97
|
*/
|
|
97
98
|
onDismissRefused?: (() => void) | undefined;
|
|
99
|
+
/**
|
|
100
|
+
* Makes each column header open the host's column settings in a popover
|
|
101
|
+
* anchored to it: a click, Enter or Space on a header opens it, and Escape
|
|
102
|
+
* closes it and returns to the header. The grid owns the popover and its
|
|
103
|
+
* placement; the host draws what is inside and changes its own `columns`.
|
|
104
|
+
* A header that opens settings does not sort on a click: a host that offers
|
|
105
|
+
* both puts its sort in the settings, as a spreadsheet's column menu does.
|
|
106
|
+
*/
|
|
107
|
+
renderColumnEditor?: ((column: SheetColumn, close: () => void) => ReactNode) | undefined;
|
|
108
|
+
/**
|
|
109
|
+
* The field whose settings are open, for a host that opens them itself (a
|
|
110
|
+
* column it has just added, say). Leave it out and the grid keeps its own.
|
|
111
|
+
*/
|
|
112
|
+
settingsColumn?: string | null | undefined;
|
|
113
|
+
onSettingsColumnChange?: ((field: string | null) => void) | undefined;
|
|
114
|
+
/** Shows the Add column control after the last header. The host appends the column. */
|
|
115
|
+
onAddColumn?: (() => void) | undefined;
|
|
98
116
|
/** A BCP 47 tag for numbers and dates; the reader's own locale when absent. */
|
|
99
117
|
locale?: string | undefined;
|
|
100
118
|
className?: string | undefined;
|
|
101
119
|
labels?: Partial<SheetLabels> | undefined;
|
|
102
120
|
presenceLabels?: Partial<PresenceLabels> | undefined;
|
|
103
121
|
}
|
|
104
|
-
export declare function SheetGrid({ label, columns: declared, rows: given, people, mode, onEdit, onAddRow, onShowHistory, onActiveCellChange, onEditingChange, onUndo, onRedo, onOpenLink, presence, sort, onSortChange, sync, onRetry, height, fit, onDeleteRow, onDismissRefused, locale, className, labels: labelOverrides, presenceLabels: presenceOverrides, }: SheetGridProps): import("react").JSX.Element;
|
|
122
|
+
export declare function SheetGrid({ label, columns: declared, rows: given, people, mode, onEdit, onAddRow, onShowHistory, onActiveCellChange, onEditingChange, onUndo, onRedo, onOpenLink, presence, sort, onSortChange, sync, onRetry, height, fit, onDeleteRow, onDismissRefused, renderColumnEditor, settingsColumn, onSettingsColumnChange, onAddColumn, locale, className, labels: labelOverrides, presenceLabels: presenceOverrides, }: SheetGridProps): import("react").JSX.Element;
|
package/dist/SheetGrid/index.js
CHANGED
|
@@ -1,18 +1,19 @@
|
|
|
1
|
-
export { CellDisplay, CellEditor, CheckboxCell, DateCell, LongTextCell, MultiSelectCell, NumberCell, PersonCell, RatingCell, SelectCell, SheetCell, SheetGrid, StatusCell, TextCell, UrlCell } from '../chunk-
|
|
1
|
+
export { CellDisplay, CellEditor, CheckboxCell, DateCell, LongTextCell, MultiSelectCell, NumberCell, PersonCell, RatingCell, SelectCell, SheetCell, SheetGrid, StatusCell, TextCell, UrlCell } from '../chunk-5VCG26CV.js';
|
|
2
2
|
import '../chunk-O2EGEONV.js';
|
|
3
3
|
import '../chunk-CENOOTAV.js';
|
|
4
4
|
import '../chunk-GFV4LJHH.js';
|
|
5
5
|
import '../chunk-WIATRXEJ.js';
|
|
6
6
|
import '../chunk-3BYIWOTV.js';
|
|
7
7
|
import '../chunk-I6POAB4V.js';
|
|
8
|
-
import '../chunk-
|
|
9
|
-
import '../chunk-
|
|
8
|
+
import '../chunk-HAKTRTRP.js';
|
|
9
|
+
import '../chunk-OOMXLJ3S.js';
|
|
10
10
|
import '../chunk-Z7JYG5TF.js';
|
|
11
|
+
import '../chunk-K3IJQNB7.js';
|
|
11
12
|
import '../chunk-AYKXMIOR.js';
|
|
12
13
|
import '../chunk-6ZJ3N7QI.js';
|
|
13
14
|
import '../chunk-5AQBPHZD.js';
|
|
14
15
|
import '../chunk-PZKHBB7D.js';
|
|
15
|
-
import '../chunk-
|
|
16
|
+
import '../chunk-BUVCV3WI.js';
|
|
16
17
|
import '../chunk-OMV5W53A.js';
|
|
17
18
|
import '../chunk-R25RGPUB.js';
|
|
18
19
|
import '../chunk-OG6CL3EB.js';
|
|
@@ -426,6 +426,54 @@
|
|
|
426
426
|
font-size: var(--font-size-xs);
|
|
427
427
|
}
|
|
428
428
|
|
|
429
|
+
/* A HEADER THAT OPENS ITS COLUMN'S SETTINGS reads as pressable: the pointer,
|
|
430
|
+
and the hover tint the open header keeps while its popover is up. */
|
|
431
|
+
.crewlet-sheet-grid__header--settings {
|
|
432
|
+
cursor: pointer;
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
.crewlet-sheet-grid__header--settings:hover,
|
|
436
|
+
.crewlet-sheet-grid__header--open {
|
|
437
|
+
background: var(--color-surface-hover);
|
|
438
|
+
color: var(--color-text-primary);
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
/* A COLUMN'S SETTINGS: the popover holds a short form, so it is padded as a
|
|
442
|
+
panel and given the room a list of choices needs before it scrolls. */
|
|
443
|
+
.crewlet-popover.crewlet-sheet-grid__column-settings {
|
|
444
|
+
width: 300px;
|
|
445
|
+
max-height: min(560px, 80vh);
|
|
446
|
+
padding: var(--spacing-3);
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
/* ADD COLUMN stands beside the header row, outside the grid's roles: the
|
|
450
|
+
scroller lays the grid and the control side by side, the grid's last track
|
|
451
|
+
still takes the slack up to the control, and the control sticks to the top
|
|
452
|
+
with the header while the rows scroll under it. */
|
|
453
|
+
.crewlet-sheet-grid__scroller--add-column {
|
|
454
|
+
--crewlet-sheet-add-column-width: var(--size-target-min);
|
|
455
|
+
display: flex;
|
|
456
|
+
align-items: flex-start;
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
.crewlet-sheet-grid__scroller--add-column > .crewlet-sheet-grid__grid {
|
|
460
|
+
flex: 0 0 auto;
|
|
461
|
+
min-width: calc(100% - var(--crewlet-sheet-add-column-width));
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
.crewlet-sheet-grid__add-column {
|
|
465
|
+
position: sticky;
|
|
466
|
+
top: 0;
|
|
467
|
+
z-index: var(--z-index-sticky);
|
|
468
|
+
display: flex;
|
|
469
|
+
flex: 0 0 var(--crewlet-sheet-add-column-width);
|
|
470
|
+
align-items: center;
|
|
471
|
+
justify-content: center;
|
|
472
|
+
box-sizing: border-box;
|
|
473
|
+
border-bottom: 1px solid var(--color-border-default);
|
|
474
|
+
background: var(--color-surface-subtle);
|
|
475
|
+
}
|
|
476
|
+
|
|
429
477
|
.crewlet-sheet-grid__sync {
|
|
430
478
|
display: inline-flex;
|
|
431
479
|
align-items: center;
|
package/dist/SheetModel/index.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export { LONGTEXT_MAX_DEFAULT, RATING_MAX_CEILING, RATING_MAX_DEFAULT, SHEET_COLUMN_BOUNDS, SHEET_COLUMN_TYPES, SHEET_COLUMN_WIDTHS, SHEET_FIT_SAMPLES, SHEET_LABELS, SHEET_ROW_HEIGHT, SHEET_ROW_NUMBER_WIDTH, SheetPendingEdits, TEXT_MAX_DEFAULT, URL_MAX, cellDescription, cellKey, cellSpeech, changeText, changeTime, checkValue, columnOffsets, columnWidth, compareValues, displayText, drawnColumns, editText, editorSide, findOption, findPerson, fitSamples, fittedWidth, flagText, hasPrevious, inRange, isEmptyValue, isMod, isMultiCell, isSheetColumnType, isTypingKey, liveOptions, moveFrom, nextSort, normalizeValue, optionHue, parseOptionList, parseTSV, parseText, planClear, planPaste, presenceByCell, presenceByColumn, presenceByRow, rangeOf, ratingMax, refusalText, rowName, sameValue, scrollToRow, sheetLabels, sortRows, spokenText, statusTone, textMax, toTSV, visibleRows } from '../chunk-
|
|
1
|
+
export { LONGTEXT_MAX_DEFAULT, RATING_MAX_CEILING, RATING_MAX_DEFAULT, SHEET_COLUMN_BOUNDS, SHEET_COLUMN_TYPES, SHEET_COLUMN_WIDTHS, SHEET_FIT_SAMPLES, SHEET_LABELS, SHEET_ROW_HEIGHT, SHEET_ROW_NUMBER_WIDTH, SheetPendingEdits, TEXT_MAX_DEFAULT, URL_MAX, cellDescription, cellKey, cellSpeech, changeText, changeTime, checkValue, columnOffsets, columnWidth, compareValues, displayText, drawnColumns, editText, editorSide, findOption, findPerson, fitSamples, fittedWidth, flagText, hasPrevious, inRange, isEmptyValue, isMod, isMultiCell, isSheetColumnType, isTypingKey, liveOptions, moveFrom, nextSort, normalizeValue, optionHue, parseOptionList, parseTSV, parseText, planClear, planPaste, presenceByCell, presenceByColumn, presenceByRow, rangeOf, ratingMax, refusalText, rowName, sameValue, scrollToRow, sheetLabels, sortRows, spokenText, statusTone, textMax, toTSV, visibleRows } from '../chunk-OOMXLJ3S.js';
|
|
2
2
|
import '../chunk-Z7JYG5TF.js';
|
|
3
3
|
import '../chunk-AYKXMIOR.js';
|
|
@@ -74,6 +74,12 @@ export interface SheetLabels {
|
|
|
74
74
|
keyboardHelp: string;
|
|
75
75
|
/** A sort, for the header's control. */
|
|
76
76
|
sortBy: (column: string) => string;
|
|
77
|
+
/** A column's settings popover, its name and its header's tip. */
|
|
78
|
+
columnSettings: (column: string) => string;
|
|
79
|
+
/** Appended to the keyboard help when headers open their column's settings. */
|
|
80
|
+
columnSettingsHelp: string;
|
|
81
|
+
/** The control after the last header that adds a column. */
|
|
82
|
+
addColumn: string;
|
|
77
83
|
}
|
|
78
84
|
export declare const SHEET_LABELS: SheetLabels;
|
|
79
85
|
/** Labels with a caller's overrides applied, the one way both renderers merge them. */
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { type ReactNode } from 'react';
|
|
2
|
+
import { type MenuEntry } from '../Menu/index.js';
|
|
2
3
|
/** One slide as the filmstrip lists it. */
|
|
3
4
|
export interface FilmstripSlide {
|
|
4
5
|
id: string;
|
|
@@ -14,6 +15,10 @@ export interface SlideFilmstripLabels {
|
|
|
14
15
|
slide: (position: number, title: string) => string;
|
|
15
16
|
hidden: string;
|
|
16
17
|
untitled: string;
|
|
18
|
+
/** A slide's actions menu: "Actions for slide 4, The plan". */
|
|
19
|
+
actions: (position: number, title: string) => string;
|
|
20
|
+
duplicate: string;
|
|
21
|
+
delete: string;
|
|
17
22
|
}
|
|
18
23
|
/**
|
|
19
24
|
* Which way the strip runs: a column beside the stage, or a row under it
|
|
@@ -33,6 +38,23 @@ export interface SlideFilmstripProps {
|
|
|
33
38
|
*/
|
|
34
39
|
onReorder?: ((ids: string[]) => void) | undefined;
|
|
35
40
|
orientation?: SlideFilmstripOrientation | undefined;
|
|
41
|
+
/**
|
|
42
|
+
* Copy a slide in place, after itself: Command+D (Control+D elsewhere) on
|
|
43
|
+
* its thumbnail, or its actions menu. Left out, nothing duplicates.
|
|
44
|
+
*/
|
|
45
|
+
onDuplicate?: ((id: string) => void) | undefined;
|
|
46
|
+
/**
|
|
47
|
+
* Remove a slide: Delete or Backspace on its thumbnail, or its actions
|
|
48
|
+
* menu. Left out, nothing deletes. The caller moves the selection.
|
|
49
|
+
*/
|
|
50
|
+
onDelete?: ((id: string) => void) | undefined;
|
|
51
|
+
/** Further entries of a slide's actions menu, after Duplicate and Delete. */
|
|
52
|
+
actions?: ((id: string) => readonly MenuEntry[]) | undefined;
|
|
53
|
+
/**
|
|
54
|
+
* What follows the last slide inside the strip, such as a New slide
|
|
55
|
+
* control, so it scrolls with the slides it adds to.
|
|
56
|
+
*/
|
|
57
|
+
footer?: ReactNode;
|
|
36
58
|
className?: string | undefined;
|
|
37
59
|
labels?: Partial<SlideFilmstripLabels> | undefined;
|
|
38
60
|
}
|
|
@@ -57,5 +79,12 @@ export interface SlideFilmstripProps {
|
|
|
57
79
|
*
|
|
58
80
|
* THUMBNAILS ARE THE SLIDES THEMSELVES, drawn by the caller at the slide's own
|
|
59
81
|
* size and scaled by `SlideStage`, so what the strip shows is what presents.
|
|
82
|
+
*
|
|
83
|
+
* A SLIDE'S ACTIONS ARE KEYS ON ITS THUMBNAIL AND A MENU BESIDE IT, as a
|
|
84
|
+
* presentation editor's filmstrip has them: Command+D (Control+D) duplicates,
|
|
85
|
+
* Delete or Backspace deletes, and the menu names both with their keys, so the
|
|
86
|
+
* pointer and the keyboard reach the same acts and the menu teaches the keys.
|
|
87
|
+
* The menu's trigger is out of the tab order, since the thumbnail's keys reach
|
|
88
|
+
* every act it holds and the Menu key (or Shift+F10) opens it from there.
|
|
60
89
|
*/
|
|
61
|
-
export declare function SlideFilmstrip({ slides, selected, onSelect, renderSlide, onReorder, orientation, className, labels, }: SlideFilmstripProps): import("react").JSX.Element;
|
|
90
|
+
export declare function SlideFilmstrip({ slides, selected, onSelect, renderSlide, onReorder, orientation, onDuplicate, onDelete, actions, footer, className, labels, }: SlideFilmstripProps): import("react").JSX.Element;
|
|
@@ -1,8 +1,12 @@
|
|
|
1
|
-
export { SlideFilmstrip } from '../chunk-
|
|
1
|
+
export { SlideFilmstrip } from '../chunk-QIXMNOBD.js';
|
|
2
2
|
import '../chunk-LV4APO72.js';
|
|
3
3
|
import '../chunk-XJ2QEBMM.js';
|
|
4
|
+
import '../chunk-SMBKXWML.js';
|
|
5
|
+
import '../chunk-BUVCV3WI.js';
|
|
4
6
|
import '../chunk-OMV5W53A.js';
|
|
5
7
|
import '../chunk-R25RGPUB.js';
|
|
8
|
+
import '../chunk-OG6CL3EB.js';
|
|
6
9
|
import '../chunk-RSAQOKH3.js';
|
|
10
|
+
import '../chunk-4FQT6ZAY.js';
|
|
7
11
|
import '../chunk-BZFWDIV6.js';
|
|
8
12
|
import '../chunk-ODEQTPFM.js';
|
|
@@ -167,3 +167,52 @@
|
|
|
167
167
|
.crewlet-slide-filmstrip--horizontal .crewlet-slide-filmstrip__item[data-reorder-target='after'] .crewlet-slide-filmstrip__thumb {
|
|
168
168
|
box-shadow: var(--spacing-1) 0 0 var(--color-brand-accent);
|
|
169
169
|
}
|
|
170
|
+
|
|
171
|
+
/* A SLIDE'S CONTROLS, beside its thumbnail: the handle over the actions menu,
|
|
172
|
+
one column, so a thumbnail keeps the strip's full width beside them. The
|
|
173
|
+
menu's trigger shows on the selected slide and under the pointer or focus,
|
|
174
|
+
so a strip of twelve slides is not twelve rows of ellipses. */
|
|
175
|
+
.crewlet-slide-filmstrip__controls {
|
|
176
|
+
display: flex;
|
|
177
|
+
flex-direction: column;
|
|
178
|
+
align-items: center;
|
|
179
|
+
gap: var(--spacing-0);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
.crewlet-slide-filmstrip__controls .crewlet-menu-anchor {
|
|
183
|
+
opacity: 0;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
.crewlet-slide-filmstrip__item[data-selected='true'] .crewlet-menu-anchor,
|
|
187
|
+
.crewlet-slide-filmstrip__item:hover .crewlet-menu-anchor,
|
|
188
|
+
.crewlet-slide-filmstrip__controls .crewlet-menu-anchor:focus-within,
|
|
189
|
+
.crewlet-slide-filmstrip__controls .crewlet-menu-anchor:has([aria-expanded='true']) {
|
|
190
|
+
opacity: 1;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
@media (hover: none) {
|
|
194
|
+
.crewlet-slide-filmstrip__controls .crewlet-menu-anchor {
|
|
195
|
+
opacity: 1;
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/* What follows the slides (a New slide control), aligned with the thumbnails
|
|
200
|
+
rather than with the numbers beside them. */
|
|
201
|
+
.crewlet-slide-filmstrip__footer {
|
|
202
|
+
padding: var(--spacing-1) var(--spacing-1) var(--spacing-2) calc(var(--spacing-5) + var(--spacing-2));
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
.crewlet-slide-filmstrip--horizontal {
|
|
206
|
+
display: flex;
|
|
207
|
+
align-items: flex-start;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
.crewlet-slide-filmstrip--horizontal .crewlet-slide-filmstrip__controls {
|
|
211
|
+
grid-area: handle;
|
|
212
|
+
flex-direction: row;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
.crewlet-slide-filmstrip--horizontal .crewlet-slide-filmstrip__footer {
|
|
216
|
+
flex: none;
|
|
217
|
+
padding: var(--spacing-1) var(--spacing-2);
|
|
218
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { type TextareaHTMLAttributes } from "react";
|
|
2
|
+
/** How a marked line reads: a refusal, or advice. */
|
|
3
|
+
export type SourceMarkTone = "danger" | "warning";
|
|
4
|
+
/** One line called out in the source, as a checker found it. */
|
|
5
|
+
export interface SourceMark {
|
|
6
|
+
/** The line, counted from 1. A line past the end is ignored. */
|
|
7
|
+
line: number;
|
|
8
|
+
tone: SourceMarkTone;
|
|
9
|
+
/** What is wrong on the line, shown as the gutter number's tooltip. */
|
|
10
|
+
message?: string;
|
|
11
|
+
}
|
|
12
|
+
export interface SourceEditorProps extends Omit<TextareaHTMLAttributes<HTMLTextAreaElement>, "value" | "onChange" | "onSubmit" | "children" | "wrap" | "spellCheck"> {
|
|
13
|
+
value: string;
|
|
14
|
+
onChange: (value: string) => void;
|
|
15
|
+
/** Names the field for a screen reader when no visible label points at it. */
|
|
16
|
+
label?: string;
|
|
17
|
+
/** Lines to call out in the gutter and behind the text. */
|
|
18
|
+
marks?: readonly SourceMark[];
|
|
19
|
+
/** Called on Command+Enter (Control+Enter elsewhere). */
|
|
20
|
+
onSubmit?: (() => void) | undefined;
|
|
21
|
+
/** Spaces one Tab indents by. */
|
|
22
|
+
indent?: number;
|
|
23
|
+
/** Fill the parent's height rather than size to `rows`. */
|
|
24
|
+
fill?: boolean;
|
|
25
|
+
className?: string | undefined;
|
|
26
|
+
/** The field's own class, for a consumer that sets its height. */
|
|
27
|
+
fieldClassName?: string | undefined;
|
|
28
|
+
}
|
|
29
|
+
/** What a parent can ask of the editor. */
|
|
30
|
+
export interface SourceEditorHandle {
|
|
31
|
+
/** Focus the field with the caret at the start of `line` (from 1), scrolled into view. */
|
|
32
|
+
revealLine: (line: number) => void;
|
|
33
|
+
focus: () => void;
|
|
34
|
+
/** The field itself. */
|
|
35
|
+
readonly element: HTMLTextAreaElement | null;
|
|
36
|
+
}
|
|
37
|
+
/** The keyboard instructions every editor carries for a screen reader. */
|
|
38
|
+
export declare const SOURCE_EDITOR_KEYS = "Tab indents and Shift+Tab outdents. Press Escape, then Tab, to move to the next control.";
|
|
39
|
+
/** The offset of the start of `line` (from 1) in `text`, clamped to the text. */
|
|
40
|
+
export declare function lineStart(text: string, line: number): number;
|
|
41
|
+
/**
|
|
42
|
+
* Source text written in place: a monospaced field with a line gutter, and
|
|
43
|
+
* lines a checker called out marked in the gutter and behind the text.
|
|
44
|
+
*
|
|
45
|
+
* A REAL TEXTAREA, so everything a browser gives a field (selection, undo,
|
|
46
|
+
* spelling off, a screen reader's editing commands, autofill off) is there
|
|
47
|
+
* without being rebuilt. The gutter and the marks are drawn behind and beside
|
|
48
|
+
* it and scroll with it; they are hidden from assistive technology, which
|
|
49
|
+
* reads the findings where the consumer lists them.
|
|
50
|
+
*
|
|
51
|
+
* LINES NEVER WRAP, so a line number and a mark always sit on the line they
|
|
52
|
+
* name: a long line scrolls sideways.
|
|
53
|
+
*
|
|
54
|
+
* TAB INDENTS, AND ESCAPE GIVES TAB BACK. Tab and Shift+Tab indent and outdent
|
|
55
|
+
* the lines under the selection, as every code editor does. A keyboard user
|
|
56
|
+
* leaves by pressing Escape first: the next Tab then moves focus as usual. The
|
|
57
|
+
* instructions are the field's description.
|
|
58
|
+
*
|
|
59
|
+
* ENTER KEEPS THE INDENT of the line it breaks, and Command+Enter (Control+Enter)
|
|
60
|
+
* calls `onSubmit`.
|
|
61
|
+
*/
|
|
62
|
+
export declare const SourceEditor: import("react").ForwardRefExoticComponent<SourceEditorProps & import("react").RefAttributes<SourceEditorHandle>>;
|