@richardmcquiston01/dashboard-widgets-toolkit 0.13.0 → 0.14.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.
@@ -775,6 +775,14 @@ interface WidgetDefinition {
775
775
  * give widgets more room automatically.
776
776
  */
777
777
  readonly width?: number;
778
+ /**
779
+ * The narrowest and widest a viewer may make the widget (integers from 2 to
780
+ * 12, `minWidth <= width <= maxWidth`). A table that needs room sets
781
+ * `minWidth: 6`; a KPI tile that looks silly wide sets `maxWidth: 4`.
782
+ * Without them the full 2 to 12 range applies.
783
+ */
784
+ readonly minWidth?: number;
785
+ readonly maxWidth?: number;
778
786
  /**
779
787
  * Gives the widget a detail view: a full list with sorting, filtering and
780
788
  * paging. `true` uses defaults. The data comes from a detail provider.
@@ -790,8 +798,8 @@ interface WidgetDefinition {
790
798
  /** Fill free space in the row (height, width or both). Default: none. */
791
799
  readonly fill?: WidgetFill;
792
800
  /**
793
- * Keeps viewers from rearranging this widget. `true` locks everything:
794
- * move, hide and minimize. Use an object to lock only some; fields left out
801
+ * Keeps viewers from changing this widget. `true` locks everything:
802
+ * move, hide, minimize and options. Use an object to lock only some; fields left out
795
803
  * are not locked.
796
804
  */
797
805
  readonly locked?: boolean | WidgetLock;
@@ -816,6 +824,8 @@ interface WidgetLock {
816
824
  readonly hide?: boolean;
817
825
  /** Can't be collapsed to its header. */
818
826
  readonly minimize?: boolean;
827
+ /** Can't be given a title, width or option values of the viewer's own. */
828
+ readonly options?: boolean;
819
829
  }
820
830
  /** `WidgetLock` with every default filled in. */
821
831
  type ResolvedWidgetLock = Required<WidgetLock>;
@@ -900,6 +910,132 @@ declare function placeRows(items: readonly GridItem[]): readonly PlacedRow[];
900
910
  */
901
911
  declare function fitCount(items: readonly GridItem[], maxRows: number): number;
902
912
 
913
+ /**
914
+ * A viewer's own choices for a widget: a title, a width and values for the
915
+ * options its author declared. They live in the layout (`layout.settings`),
916
+ * so the consumer's existing persistence saves them, and they override what
917
+ * the definition says without changing it. Pure functions, no I/O.
918
+ */
919
+
920
+ /** What one viewer chose for one widget. Every field is optional. */
921
+ interface WidgetViewerSettings {
922
+ /** Replaces the widget's title. Plain text, at most 80 characters. */
923
+ readonly title?: string;
924
+ /** Share of the row in twelfths, within the definition's min and max. */
925
+ readonly width?: number;
926
+ /** May grow into the columns left over in its row (see `fill`). */
927
+ readonly flexible?: boolean;
928
+ /** Values for declared options, by option key. */
929
+ readonly options?: Readonly<Record<string, OptionValue>>;
930
+ }
931
+ /** Viewer settings by widget key. */
932
+ type LayoutSettings = Readonly<Record<string, WidgetViewerSettings>>;
933
+ /** Longest title a viewer can give a widget; longer ones are cut. */
934
+ declare const MAX_WIDGET_TITLE_LENGTH = 80;
935
+ /**
936
+ * Most widgets `parseLayout` keeps settings for: a safety ceiling against
937
+ * malformed or hostile JSON, not a product limit.
938
+ */
939
+ declare const MAX_PARSED_SETTINGS = 500;
940
+ /** What these functions need from a definition. */
941
+ type SettingsItem = Pick<WidgetDefinition, 'key'> & Partial<Pick<WidgetDefinition, 'title' | 'width' | 'minWidth' | 'maxWidth' | 'fill' | 'locked' | 'options'>>;
942
+ /**
943
+ * Reads the `settings` field of a saved layout. Anything malformed is
944
+ * dropped (wrong types, titles over the limit are cut, widths outside 2 to
945
+ * 12), never an error. Returns undefined when nothing usable is left.
946
+ */
947
+ declare function parseSettings(raw: unknown): LayoutSettings | undefined;
948
+ /** The JSON-ready form of `layout.settings`; fields keep a stable order. */
949
+ declare function serializeSettings(settings: LayoutSettings | undefined): Record<string, WidgetViewerSettings> | undefined;
950
+ /** The narrowest and widest share a widget may take. */
951
+ declare function widthRange(item: Pick<SettingsItem, 'minWidth' | 'maxWidth'>): {
952
+ readonly min: number;
953
+ readonly max: number;
954
+ };
955
+ /** A width as a share of the row: 2 is `1/6`, 6 is `1/2`, 12 is `Full`. */
956
+ declare function widthShareLabel(width: number): string;
957
+ /** Whether the lock on this widget forbids viewer settings. */
958
+ declare function isOptionsLocked(item: Pick<SettingsItem, 'locked'>): boolean;
959
+ /** Whether the widget grows into free columns: the viewer's choice, else its `fill`. */
960
+ declare function isFlexible(item: Pick<SettingsItem, 'fill'>, settings: WidgetViewerSettings | undefined): boolean;
961
+ /**
962
+ * The definition as this viewer sees it: their title, their width (kept
963
+ * within the definition's limits) and their choice of Flexible applied on
964
+ * top of the author's. Returns the same object when there is nothing to
965
+ * apply. Options are not part of the definition; read them with
966
+ * `widgetOptionValues`.
967
+ */
968
+ declare function applySettings<D extends SettingsItem>(definition: D, settings: WidgetViewerSettings | undefined): D;
969
+ /**
970
+ * The definitions with each viewer's settings applied. A widget whose lock
971
+ * forbids options (`locked.options`) ignores them, so a saved layout can't
972
+ * reach around a lock. Pass `overrideLocks` for an administrator.
973
+ */
974
+ declare function effectiveDefinitions<D extends SettingsItem>(definitions: readonly D[], layout: {
975
+ readonly settings?: LayoutSettings;
976
+ }, options?: {
977
+ readonly overrideLocks?: boolean;
978
+ }): D[];
979
+ /**
980
+ * The chosen option values for a widget, resolved: the viewer's where valid,
981
+ * else the author's defaults. Empty when it declares no options.
982
+ */
983
+ declare function widgetOptionValues(definition: Pick<SettingsItem, 'options'>, settings: WidgetViewerSettings | undefined): OptionValues;
984
+ /**
985
+ * What to pass `useWidgets({ optionValues })` so the data follows the
986
+ * layout: for every widget that declares options, the viewer's chosen
987
+ * values (empty when they haven't chosen, which means the defaults). Every
988
+ * such widget is listed so Reset sends its defaults back to the provider.
989
+ */
990
+ declare function optionValuesFromLayout(definitions: readonly Pick<SettingsItem, 'key' | 'options' | 'locked'>[], layout: {
991
+ readonly settings?: LayoutSettings;
992
+ }, options?: {
993
+ readonly overrideLocks?: boolean;
994
+ }): Record<string, Readonly<Record<string, OptionValue>>>;
995
+ /** Fields `setWidgetSettings` can change; `undefined` clears one. */
996
+ interface WidgetSettingsPatch {
997
+ readonly title?: string | undefined;
998
+ readonly width?: number | undefined;
999
+ readonly flexible?: boolean | undefined;
1000
+ /** Replaces all of the widget's option values (`undefined` clears them). */
1001
+ readonly options?: Readonly<Record<string, OptionValue>> | undefined;
1002
+ }
1003
+ type LayoutWithSettings<L> = L & {
1004
+ readonly settings?: LayoutSettings;
1005
+ };
1006
+ /**
1007
+ * A layout with `patch` applied to one widget's settings. Fields the patch
1008
+ * names as `undefined` are cleared; others stay. An entry left empty is
1009
+ * removed. Returns the same layout when nothing changes.
1010
+ */
1011
+ declare function setWidgetSettings<L extends object>(layout: LayoutWithSettings<L>, key: string, patch: WidgetSettingsPatch): LayoutWithSettings<L>;
1012
+ /** A layout without one widget's settings (Reset to defaults). */
1013
+ declare function clearWidgetSettings<L extends object>(layout: LayoutWithSettings<L>, key: string): LayoutWithSettings<L>;
1014
+ /** Lower-cased, trimmed and Unicode-normalized, for comparing titles. */
1015
+ declare function normalizeTitle(title: string): string;
1016
+ /**
1017
+ * Whether another widget already shows `title`: compared trimmed,
1018
+ * case-insensitive and Unicode-normalized, against the other widgets'
1019
+ * effective titles. A dialog uses it to refuse a duplicate.
1020
+ */
1021
+ declare function isTitleInUse<D extends SettingsItem>(definitions: readonly D[], layout: {
1022
+ readonly settings?: LayoutSettings;
1023
+ }, key: string, title: string): boolean;
1024
+ /** Options for `normalizeSettings`. */
1025
+ interface NormalizeSettingsOptions {
1026
+ /** Keep settings that a widget's `locked.options` forbids. */
1027
+ readonly overrideLocks?: boolean;
1028
+ }
1029
+ /**
1030
+ * Cleans a layout's settings against the definitions, for a save endpoint:
1031
+ * drops settings of unknown widgets and of widgets locked against options,
1032
+ * clamps widths to `minWidth` and `maxWidth`, trims titles, drops option
1033
+ * values the definition didn't declare or that aren't valid for their
1034
+ * option, and makes titles unique by appending "(#n)". Idempotent; returns
1035
+ * the same layout when nothing changes.
1036
+ */
1037
+ declare function normalizeSettings<D extends SettingsItem, L extends object>(definitions: readonly D[], layout: LayoutWithSettings<L>, options?: NormalizeSettingsOptions): LayoutWithSettings<L>;
1038
+
903
1039
  /**
904
1040
  * A viewer's dashboard customization: order, hidden and minimized widgets.
905
1041
  * Pure functions over a small JSON-serialisable object. Persist it however
@@ -931,6 +1067,11 @@ interface DashboardLayout {
931
1067
  * empty. See `pages.ts`.
932
1068
  */
933
1069
  readonly pages?: readonly LayoutPage[];
1070
+ /**
1071
+ * What the viewer chose for each widget (title, width, option values), by
1072
+ * widget key. See `settings.ts`. Absent when they chose nothing.
1073
+ */
1074
+ readonly settings?: LayoutSettings;
934
1075
  }
935
1076
  /** One page of a paged layout: the same lists as a layout, plus a name. */
936
1077
  interface LayoutPage {
@@ -1330,4 +1471,4 @@ interface LayoutPersistence {
1330
1471
  */
1331
1472
  declare function createLayoutPersistence(adapter: StorageAdapter, options?: LayoutPersistenceOptions): LayoutPersistence;
1332
1473
 
1333
- export { type DetailCell as $, type AlertListWidgetData as A, type BarListWidgetData as B, type CachedPayload as C, type DashboardWidget as D, DATE_RANGE_PRESETS as E, DEFAULT_COMPARISON_LABEL as F, type GraphWidgetData as G, DEFAULT_CURRENCY as H, DEFAULT_DETAIL_PAGE_SIZE as I, DEFAULT_EMPTY_TEXT as J, type KpiWidgetData as K, type Locale as L, DEFAULT_MAX_LAYOUT_BYTES as M, type NiceDomain as N, type OptionValues as O, type PageItem as P, DEFAULT_PAGE_KEY as Q, type ResolvedTableControls as R, type StoreScope as S, type TableWidgetData as T, DEFAULT_PAGE_ROWS as U, DETAIL_MODES as V, type WidgetSize as W, type DateRangeOption as X, type DateRangePreset as Y, type DeltaDirection as Z, type DeltaSentiment as _, type WidgetFill as a, WIDGET_SIZES as a$, type DetailColumn as a0, type DetailMode as a1, type DetailPage as a2, type DetailProvider as a3, type DetailProviders as a4, EMPTY_LAYOUT as a5, type EmptyWidget as a6, type EncodingOptions as a7, type EnforceLocksOptions as a8, type Err as a9, type OptionContext as aA, type OptionValue as aB, type PageOptions as aC, type PageRoom as aD, type PlacedRow as aE, type ProviderOptions as aF, type ResolvedDetailOptions as aG, type ResolvedWidget as aH, type ResolvedWidgetLock as aI, type RetryOptions as aJ, type SaveOptions as aK, type SavedLayout as aL, type SortDirection as aM, type SortOption as aN, type StorageAdapter as aO, type StorageLogEvent as aP, type StoreErrorCode as aQ, type StoreResult as aR, type StoredValue as aS, type TableCell as aT, type TableColumn as aU, type TextOption as aV, VALUE_FORMATS as aW, type ValueFormat as aX, WIDGET_FILLS as aY, WIDGET_KINDS as aZ, WIDGET_OPTION_TYPES as a_, type ErrorWidget as aa, type FormatOptions as ab, type GraphPoint as ac, type GraphSeries as ad, type GridItem as ae, type KpiDelta as af, type KpiDeltaOptions as ag, LAYOUT_ENVELOPE_VERSION as ah, type LayoutItem as ai, type LayoutPage as aj, type LayoutPersistenceOptions as ak, type LoadedLayout as al, type LoadingWidget as am, MAX_DETAIL_PAGE_SIZE as an, MAX_GRAPH_SERIES as ao, MAX_PAGE_ROWS as ap, MAX_PAGE_TITLE_LENGTH as aq, MAX_PARSED_PAGES as ar, MAX_TEXT_OPTION_LENGTH as as, MAX_WIDGET_OPTIONS as at, MAX_WIDGET_WIDTH as au, MIN_WIDGET_WIDTH as av, type NumberOption as aw, OPTION_KEY_PATTERN as ax, type Ok as ay, type OkWidget as az, type WidgetDefinition as b, normalizeLayout as b$, WIDTH_COLUMNS as b0, type WidgetCache as b1, type WidgetDataOf as b2, type WidgetDetailOptions as b3, type WidgetEmptyState as b4, type WidgetLock as b5, type WidgetOption as b6, type WidgetProvider as b7, type WidgetStatus as b8, type WidgetTableControls as b9, hasPages as bA, hiddenWidgets as bB, hideWidget as bC, isClientApplied as bD, isColumnKeyFor as bE, isHidden as bF, isIsoInterval as bG, isMinimized as bH, isWidgetEmptyState as bI, isWidgetKind as bJ, isWidgetVisibleTo as bK, isWidgetWidth as bL, itemWidth as bM, kpiDelta as bN, labelStride as bO, loadingWidgets as bP, memoryAdapter as bQ, minimizeWidget as bR, movePage as bS, moveWidget as bT, moveWidgetBy as bU, moveWidgetDown as bV, moveWidgetToPage as bW, moveWidgetUp as bX, nextPageKey as bY, niceDomain as bZ, niceStep as b_, addPage as ba, applyClientOptions as bb, assignPages as bc, baseColumnSpan as bd, cacheKeyFor as be, coerceOptionValue as bf, createLayoutPersistence as bg, defaultDetailQuery as bh, defaultOptionValue as bi, defineWidget as bj, deriveDetailData as bk, describeUnknownError as bl, emptyTextFor as bm, emptyWidget as bn, enforceLocks as bo, err as bp, failedWidget as bq, fillColumnSpans as br, fillWidthSpans as bs, fillsHeight as bt, fillsWidth as bu, finalizeWidget as bv, fitCount as bw, formatCount as bx, formatPercentChange as by, formatValue as bz, type DetailProviderOptions as c, ok as c0, optionValuesFor as c1, optionsCacheSuffix as c2, pageLayout as c3, pageList as c4, pageOf as c5, pageRoom as c6, pageWidgets as c7, parseDetailQuery as c8, parseLayout as c9, tableDetailData as cA, toggleHidden as cB, toggleMinimized as cC, usesWidthColumns as cD, utf8Length as cE, validateDetailData as cF, visibleWidgets as cG, widgetsFor as cH, widthForSize as cI, withEncoding as cJ, withFallback as cK, withLogging as cL, withPageLayout as cM, withPrefix as cN, withReadCache as cO, withRetry as cP, parseSortValue as ca, percentChange as cb, placeRows as cc, pruneLayout as cd, queryRows as ce, readOnly as cf, removePage as cg, renamePage as ch, resolveDateRange as ci, resolveDetailOptions as cj, resolveOptionValues as ck, resolvePageKey as cl, resolvePayload as cm, resolveTableControls as cn, resolveWidget as co, resolveWidgetLock as cp, resolveWidgetUnapplied as cq, resolveWidgets as cr, restoreWidget as cs, sameOptionValues as ct, serializeDetailQuery as cu, serializeLayout as cv, shareOf as cw, showWidget as cx, sortDefinitions as cy, sortFromOptions as cz, type DetailData as d, type DetailQuery as e, type DashboardLayout as f, type GaugeWidgetData as g, type DetailSort as h, type TextWidgetData as i, type WidgetData as j, type LayoutPersistence as k, type NormalizeOptions as l, type ResolveOptions as m, type WidgetContext as n, type WidgetProviders as o, type Result as p, type WidgetKind as q, type WidgetPayload as r, type AddPageOptions as s, type AlertListItem as t, type BarListItem as u, type BooleanOption as v, type ChoiceOption as w, type ColorOption as x, type ColumnsOption as y, type ConflictPolicy as z };
1474
+ export { type DeltaDirection as $, type AlertListWidgetData as A, type BarListWidgetData as B, type CachedPayload as C, type DashboardWidget as D, type ColumnsOption as E, type ConflictPolicy as F, type GraphWidgetData as G, DATE_RANGE_PRESETS as H, DEFAULT_COMPARISON_LABEL as I, DEFAULT_CURRENCY as J, type KpiWidgetData as K, type Locale as L, DEFAULT_DETAIL_PAGE_SIZE as M, type NiceDomain as N, type OptionValues as O, type PageItem as P, DEFAULT_EMPTY_TEXT as Q, type ResolvedTableControls as R, type StoreScope as S, type TableWidgetData as T, DEFAULT_MAX_LAYOUT_BYTES as U, DEFAULT_PAGE_KEY as V, type WidgetSize as W, DEFAULT_PAGE_ROWS as X, DETAIL_MODES as Y, type DateRangeOption as Z, type DateRangePreset as _, type WidgetFill as a, type TableColumn as a$, type DeltaSentiment as a0, type DetailCell as a1, type DetailColumn as a2, type DetailMode as a3, type DetailPage as a4, type DetailProvider as a5, type DetailProviders as a6, EMPTY_LAYOUT as a7, type EmptyWidget as a8, type EncodingOptions as a9, MIN_WIDGET_WIDTH as aA, type NormalizeSettingsOptions as aB, type NumberOption as aC, OPTION_KEY_PATTERN as aD, type Ok as aE, type OkWidget as aF, type OptionContext as aG, type OptionValue as aH, type PageOptions as aI, type PageRoom as aJ, type PlacedRow as aK, type ProviderOptions as aL, type ResolvedDetailOptions as aM, type ResolvedWidget as aN, type ResolvedWidgetLock as aO, type RetryOptions as aP, type SaveOptions as aQ, type SavedLayout as aR, type SettingsItem as aS, type SortDirection as aT, type SortOption as aU, type StorageAdapter as aV, type StorageLogEvent as aW, type StoreErrorCode as aX, type StoreResult as aY, type StoredValue as aZ, type TableCell as a_, type EnforceLocksOptions as aa, type Err as ab, type ErrorWidget as ac, type FormatOptions as ad, type GraphPoint as ae, type GraphSeries as af, type GridItem as ag, type KpiDelta as ah, type KpiDeltaOptions as ai, LAYOUT_ENVELOPE_VERSION as aj, type LayoutItem as ak, type LayoutPage as al, type LayoutPersistenceOptions as am, type LayoutSettings as an, type LoadedLayout as ao, type LoadingWidget as ap, MAX_DETAIL_PAGE_SIZE as aq, MAX_GRAPH_SERIES as ar, MAX_PAGE_ROWS as as, MAX_PAGE_TITLE_LENGTH as at, MAX_PARSED_PAGES as au, MAX_PARSED_SETTINGS as av, MAX_TEXT_OPTION_LENGTH as aw, MAX_WIDGET_OPTIONS as ax, MAX_WIDGET_TITLE_LENGTH as ay, MAX_WIDGET_WIDTH as az, type WidgetDefinition as b, labelStride as b$, type TextOption as b0, VALUE_FORMATS as b1, type ValueFormat as b2, WIDGET_FILLS as b3, WIDGET_KINDS as b4, WIDGET_OPTION_TYPES as b5, WIDGET_SIZES as b6, WIDTH_COLUMNS as b7, type WidgetCache as b8, type WidgetDataOf as b9, failedWidget as bA, fillColumnSpans as bB, fillWidthSpans as bC, fillsHeight as bD, fillsWidth as bE, finalizeWidget as bF, fitCount as bG, formatCount as bH, formatPercentChange as bI, formatValue as bJ, hasPages as bK, hiddenWidgets as bL, hideWidget as bM, isClientApplied as bN, isColumnKeyFor as bO, isFlexible as bP, isHidden as bQ, isIsoInterval as bR, isMinimized as bS, isOptionsLocked as bT, isTitleInUse as bU, isWidgetEmptyState as bV, isWidgetKind as bW, isWidgetVisibleTo as bX, isWidgetWidth as bY, itemWidth as bZ, kpiDelta as b_, type WidgetDetailOptions as ba, type WidgetEmptyState as bb, type WidgetLock as bc, type WidgetOption as bd, type WidgetProvider as be, type WidgetStatus as bf, type WidgetTableControls as bg, addPage as bh, applyClientOptions as bi, applySettings as bj, assignPages as bk, baseColumnSpan as bl, cacheKeyFor as bm, clearWidgetSettings as bn, coerceOptionValue as bo, createLayoutPersistence as bp, defaultDetailQuery as bq, defaultOptionValue as br, defineWidget as bs, deriveDetailData as bt, describeUnknownError as bu, effectiveDefinitions as bv, emptyTextFor as bw, emptyWidget as bx, enforceLocks as by, err as bz, type DetailProviderOptions as c, widgetsFor as c$, loadingWidgets as c0, memoryAdapter as c1, minimizeWidget as c2, movePage as c3, moveWidget as c4, moveWidgetBy as c5, moveWidgetDown as c6, moveWidgetToPage as c7, moveWidgetUp as c8, nextPageKey as c9, resolveDetailOptions as cA, resolveOptionValues as cB, resolvePageKey as cC, resolvePayload as cD, resolveTableControls as cE, resolveWidget as cF, resolveWidgetLock as cG, resolveWidgetUnapplied as cH, resolveWidgets as cI, restoreWidget as cJ, sameOptionValues as cK, serializeDetailQuery as cL, serializeLayout as cM, serializeSettings as cN, setWidgetSettings as cO, shareOf as cP, showWidget as cQ, sortDefinitions as cR, sortFromOptions as cS, tableDetailData as cT, toggleHidden as cU, toggleMinimized as cV, usesWidthColumns as cW, utf8Length as cX, validateDetailData as cY, visibleWidgets as cZ, widgetOptionValues as c_, niceDomain as ca, niceStep as cb, normalizeLayout as cc, normalizeSettings as cd, normalizeTitle as ce, ok as cf, optionValuesFor as cg, optionValuesFromLayout as ch, optionsCacheSuffix as ci, pageLayout as cj, pageList as ck, pageOf as cl, pageRoom as cm, pageWidgets as cn, parseDetailQuery as co, parseLayout as cp, parseSettings as cq, parseSortValue as cr, percentChange as cs, placeRows as ct, pruneLayout as cu, queryRows as cv, readOnly as cw, removePage as cx, renamePage as cy, resolveDateRange as cz, type DetailData as d, widthForSize as d0, widthRange as d1, widthShareLabel as d2, withEncoding as d3, withFallback as d4, withLogging as d5, withPageLayout as d6, withPrefix as d7, withReadCache as d8, withRetry as d9, type DetailQuery as e, type DashboardLayout as f, type WidgetViewerSettings as g, type WidgetSettingsPatch as h, type GaugeWidgetData as i, type DetailSort as j, type TextWidgetData as k, type WidgetData as l, type LayoutPersistence as m, type NormalizeOptions as n, type ResolveOptions as o, type WidgetContext as p, type WidgetProviders as q, type Result as r, type WidgetKind as s, type WidgetPayload as t, type AddPageOptions as u, type AlertListItem as v, type BarListItem as w, type BooleanOption as x, type ChoiceOption as y, type ColorOption as z };
@@ -775,6 +775,14 @@ interface WidgetDefinition {
775
775
  * give widgets more room automatically.
776
776
  */
777
777
  readonly width?: number;
778
+ /**
779
+ * The narrowest and widest a viewer may make the widget (integers from 2 to
780
+ * 12, `minWidth <= width <= maxWidth`). A table that needs room sets
781
+ * `minWidth: 6`; a KPI tile that looks silly wide sets `maxWidth: 4`.
782
+ * Without them the full 2 to 12 range applies.
783
+ */
784
+ readonly minWidth?: number;
785
+ readonly maxWidth?: number;
778
786
  /**
779
787
  * Gives the widget a detail view: a full list with sorting, filtering and
780
788
  * paging. `true` uses defaults. The data comes from a detail provider.
@@ -790,8 +798,8 @@ interface WidgetDefinition {
790
798
  /** Fill free space in the row (height, width or both). Default: none. */
791
799
  readonly fill?: WidgetFill;
792
800
  /**
793
- * Keeps viewers from rearranging this widget. `true` locks everything:
794
- * move, hide and minimize. Use an object to lock only some; fields left out
801
+ * Keeps viewers from changing this widget. `true` locks everything:
802
+ * move, hide, minimize and options. Use an object to lock only some; fields left out
795
803
  * are not locked.
796
804
  */
797
805
  readonly locked?: boolean | WidgetLock;
@@ -816,6 +824,8 @@ interface WidgetLock {
816
824
  readonly hide?: boolean;
817
825
  /** Can't be collapsed to its header. */
818
826
  readonly minimize?: boolean;
827
+ /** Can't be given a title, width or option values of the viewer's own. */
828
+ readonly options?: boolean;
819
829
  }
820
830
  /** `WidgetLock` with every default filled in. */
821
831
  type ResolvedWidgetLock = Required<WidgetLock>;
@@ -900,6 +910,132 @@ declare function placeRows(items: readonly GridItem[]): readonly PlacedRow[];
900
910
  */
901
911
  declare function fitCount(items: readonly GridItem[], maxRows: number): number;
902
912
 
913
+ /**
914
+ * A viewer's own choices for a widget: a title, a width and values for the
915
+ * options its author declared. They live in the layout (`layout.settings`),
916
+ * so the consumer's existing persistence saves them, and they override what
917
+ * the definition says without changing it. Pure functions, no I/O.
918
+ */
919
+
920
+ /** What one viewer chose for one widget. Every field is optional. */
921
+ interface WidgetViewerSettings {
922
+ /** Replaces the widget's title. Plain text, at most 80 characters. */
923
+ readonly title?: string;
924
+ /** Share of the row in twelfths, within the definition's min and max. */
925
+ readonly width?: number;
926
+ /** May grow into the columns left over in its row (see `fill`). */
927
+ readonly flexible?: boolean;
928
+ /** Values for declared options, by option key. */
929
+ readonly options?: Readonly<Record<string, OptionValue>>;
930
+ }
931
+ /** Viewer settings by widget key. */
932
+ type LayoutSettings = Readonly<Record<string, WidgetViewerSettings>>;
933
+ /** Longest title a viewer can give a widget; longer ones are cut. */
934
+ declare const MAX_WIDGET_TITLE_LENGTH = 80;
935
+ /**
936
+ * Most widgets `parseLayout` keeps settings for: a safety ceiling against
937
+ * malformed or hostile JSON, not a product limit.
938
+ */
939
+ declare const MAX_PARSED_SETTINGS = 500;
940
+ /** What these functions need from a definition. */
941
+ type SettingsItem = Pick<WidgetDefinition, 'key'> & Partial<Pick<WidgetDefinition, 'title' | 'width' | 'minWidth' | 'maxWidth' | 'fill' | 'locked' | 'options'>>;
942
+ /**
943
+ * Reads the `settings` field of a saved layout. Anything malformed is
944
+ * dropped (wrong types, titles over the limit are cut, widths outside 2 to
945
+ * 12), never an error. Returns undefined when nothing usable is left.
946
+ */
947
+ declare function parseSettings(raw: unknown): LayoutSettings | undefined;
948
+ /** The JSON-ready form of `layout.settings`; fields keep a stable order. */
949
+ declare function serializeSettings(settings: LayoutSettings | undefined): Record<string, WidgetViewerSettings> | undefined;
950
+ /** The narrowest and widest share a widget may take. */
951
+ declare function widthRange(item: Pick<SettingsItem, 'minWidth' | 'maxWidth'>): {
952
+ readonly min: number;
953
+ readonly max: number;
954
+ };
955
+ /** A width as a share of the row: 2 is `1/6`, 6 is `1/2`, 12 is `Full`. */
956
+ declare function widthShareLabel(width: number): string;
957
+ /** Whether the lock on this widget forbids viewer settings. */
958
+ declare function isOptionsLocked(item: Pick<SettingsItem, 'locked'>): boolean;
959
+ /** Whether the widget grows into free columns: the viewer's choice, else its `fill`. */
960
+ declare function isFlexible(item: Pick<SettingsItem, 'fill'>, settings: WidgetViewerSettings | undefined): boolean;
961
+ /**
962
+ * The definition as this viewer sees it: their title, their width (kept
963
+ * within the definition's limits) and their choice of Flexible applied on
964
+ * top of the author's. Returns the same object when there is nothing to
965
+ * apply. Options are not part of the definition; read them with
966
+ * `widgetOptionValues`.
967
+ */
968
+ declare function applySettings<D extends SettingsItem>(definition: D, settings: WidgetViewerSettings | undefined): D;
969
+ /**
970
+ * The definitions with each viewer's settings applied. A widget whose lock
971
+ * forbids options (`locked.options`) ignores them, so a saved layout can't
972
+ * reach around a lock. Pass `overrideLocks` for an administrator.
973
+ */
974
+ declare function effectiveDefinitions<D extends SettingsItem>(definitions: readonly D[], layout: {
975
+ readonly settings?: LayoutSettings;
976
+ }, options?: {
977
+ readonly overrideLocks?: boolean;
978
+ }): D[];
979
+ /**
980
+ * The chosen option values for a widget, resolved: the viewer's where valid,
981
+ * else the author's defaults. Empty when it declares no options.
982
+ */
983
+ declare function widgetOptionValues(definition: Pick<SettingsItem, 'options'>, settings: WidgetViewerSettings | undefined): OptionValues;
984
+ /**
985
+ * What to pass `useWidgets({ optionValues })` so the data follows the
986
+ * layout: for every widget that declares options, the viewer's chosen
987
+ * values (empty when they haven't chosen, which means the defaults). Every
988
+ * such widget is listed so Reset sends its defaults back to the provider.
989
+ */
990
+ declare function optionValuesFromLayout(definitions: readonly Pick<SettingsItem, 'key' | 'options' | 'locked'>[], layout: {
991
+ readonly settings?: LayoutSettings;
992
+ }, options?: {
993
+ readonly overrideLocks?: boolean;
994
+ }): Record<string, Readonly<Record<string, OptionValue>>>;
995
+ /** Fields `setWidgetSettings` can change; `undefined` clears one. */
996
+ interface WidgetSettingsPatch {
997
+ readonly title?: string | undefined;
998
+ readonly width?: number | undefined;
999
+ readonly flexible?: boolean | undefined;
1000
+ /** Replaces all of the widget's option values (`undefined` clears them). */
1001
+ readonly options?: Readonly<Record<string, OptionValue>> | undefined;
1002
+ }
1003
+ type LayoutWithSettings<L> = L & {
1004
+ readonly settings?: LayoutSettings;
1005
+ };
1006
+ /**
1007
+ * A layout with `patch` applied to one widget's settings. Fields the patch
1008
+ * names as `undefined` are cleared; others stay. An entry left empty is
1009
+ * removed. Returns the same layout when nothing changes.
1010
+ */
1011
+ declare function setWidgetSettings<L extends object>(layout: LayoutWithSettings<L>, key: string, patch: WidgetSettingsPatch): LayoutWithSettings<L>;
1012
+ /** A layout without one widget's settings (Reset to defaults). */
1013
+ declare function clearWidgetSettings<L extends object>(layout: LayoutWithSettings<L>, key: string): LayoutWithSettings<L>;
1014
+ /** Lower-cased, trimmed and Unicode-normalized, for comparing titles. */
1015
+ declare function normalizeTitle(title: string): string;
1016
+ /**
1017
+ * Whether another widget already shows `title`: compared trimmed,
1018
+ * case-insensitive and Unicode-normalized, against the other widgets'
1019
+ * effective titles. A dialog uses it to refuse a duplicate.
1020
+ */
1021
+ declare function isTitleInUse<D extends SettingsItem>(definitions: readonly D[], layout: {
1022
+ readonly settings?: LayoutSettings;
1023
+ }, key: string, title: string): boolean;
1024
+ /** Options for `normalizeSettings`. */
1025
+ interface NormalizeSettingsOptions {
1026
+ /** Keep settings that a widget's `locked.options` forbids. */
1027
+ readonly overrideLocks?: boolean;
1028
+ }
1029
+ /**
1030
+ * Cleans a layout's settings against the definitions, for a save endpoint:
1031
+ * drops settings of unknown widgets and of widgets locked against options,
1032
+ * clamps widths to `minWidth` and `maxWidth`, trims titles, drops option
1033
+ * values the definition didn't declare or that aren't valid for their
1034
+ * option, and makes titles unique by appending "(#n)". Idempotent; returns
1035
+ * the same layout when nothing changes.
1036
+ */
1037
+ declare function normalizeSettings<D extends SettingsItem, L extends object>(definitions: readonly D[], layout: LayoutWithSettings<L>, options?: NormalizeSettingsOptions): LayoutWithSettings<L>;
1038
+
903
1039
  /**
904
1040
  * A viewer's dashboard customization: order, hidden and minimized widgets.
905
1041
  * Pure functions over a small JSON-serialisable object. Persist it however
@@ -931,6 +1067,11 @@ interface DashboardLayout {
931
1067
  * empty. See `pages.ts`.
932
1068
  */
933
1069
  readonly pages?: readonly LayoutPage[];
1070
+ /**
1071
+ * What the viewer chose for each widget (title, width, option values), by
1072
+ * widget key. See `settings.ts`. Absent when they chose nothing.
1073
+ */
1074
+ readonly settings?: LayoutSettings;
934
1075
  }
935
1076
  /** One page of a paged layout: the same lists as a layout, plus a name. */
936
1077
  interface LayoutPage {
@@ -1330,4 +1471,4 @@ interface LayoutPersistence {
1330
1471
  */
1331
1472
  declare function createLayoutPersistence(adapter: StorageAdapter, options?: LayoutPersistenceOptions): LayoutPersistence;
1332
1473
 
1333
- export { type DetailCell as $, type AlertListWidgetData as A, type BarListWidgetData as B, type CachedPayload as C, type DashboardWidget as D, DATE_RANGE_PRESETS as E, DEFAULT_COMPARISON_LABEL as F, type GraphWidgetData as G, DEFAULT_CURRENCY as H, DEFAULT_DETAIL_PAGE_SIZE as I, DEFAULT_EMPTY_TEXT as J, type KpiWidgetData as K, type Locale as L, DEFAULT_MAX_LAYOUT_BYTES as M, type NiceDomain as N, type OptionValues as O, type PageItem as P, DEFAULT_PAGE_KEY as Q, type ResolvedTableControls as R, type StoreScope as S, type TableWidgetData as T, DEFAULT_PAGE_ROWS as U, DETAIL_MODES as V, type WidgetSize as W, type DateRangeOption as X, type DateRangePreset as Y, type DeltaDirection as Z, type DeltaSentiment as _, type WidgetFill as a, WIDGET_SIZES as a$, type DetailColumn as a0, type DetailMode as a1, type DetailPage as a2, type DetailProvider as a3, type DetailProviders as a4, EMPTY_LAYOUT as a5, type EmptyWidget as a6, type EncodingOptions as a7, type EnforceLocksOptions as a8, type Err as a9, type OptionContext as aA, type OptionValue as aB, type PageOptions as aC, type PageRoom as aD, type PlacedRow as aE, type ProviderOptions as aF, type ResolvedDetailOptions as aG, type ResolvedWidget as aH, type ResolvedWidgetLock as aI, type RetryOptions as aJ, type SaveOptions as aK, type SavedLayout as aL, type SortDirection as aM, type SortOption as aN, type StorageAdapter as aO, type StorageLogEvent as aP, type StoreErrorCode as aQ, type StoreResult as aR, type StoredValue as aS, type TableCell as aT, type TableColumn as aU, type TextOption as aV, VALUE_FORMATS as aW, type ValueFormat as aX, WIDGET_FILLS as aY, WIDGET_KINDS as aZ, WIDGET_OPTION_TYPES as a_, type ErrorWidget as aa, type FormatOptions as ab, type GraphPoint as ac, type GraphSeries as ad, type GridItem as ae, type KpiDelta as af, type KpiDeltaOptions as ag, LAYOUT_ENVELOPE_VERSION as ah, type LayoutItem as ai, type LayoutPage as aj, type LayoutPersistenceOptions as ak, type LoadedLayout as al, type LoadingWidget as am, MAX_DETAIL_PAGE_SIZE as an, MAX_GRAPH_SERIES as ao, MAX_PAGE_ROWS as ap, MAX_PAGE_TITLE_LENGTH as aq, MAX_PARSED_PAGES as ar, MAX_TEXT_OPTION_LENGTH as as, MAX_WIDGET_OPTIONS as at, MAX_WIDGET_WIDTH as au, MIN_WIDGET_WIDTH as av, type NumberOption as aw, OPTION_KEY_PATTERN as ax, type Ok as ay, type OkWidget as az, type WidgetDefinition as b, normalizeLayout as b$, WIDTH_COLUMNS as b0, type WidgetCache as b1, type WidgetDataOf as b2, type WidgetDetailOptions as b3, type WidgetEmptyState as b4, type WidgetLock as b5, type WidgetOption as b6, type WidgetProvider as b7, type WidgetStatus as b8, type WidgetTableControls as b9, hasPages as bA, hiddenWidgets as bB, hideWidget as bC, isClientApplied as bD, isColumnKeyFor as bE, isHidden as bF, isIsoInterval as bG, isMinimized as bH, isWidgetEmptyState as bI, isWidgetKind as bJ, isWidgetVisibleTo as bK, isWidgetWidth as bL, itemWidth as bM, kpiDelta as bN, labelStride as bO, loadingWidgets as bP, memoryAdapter as bQ, minimizeWidget as bR, movePage as bS, moveWidget as bT, moveWidgetBy as bU, moveWidgetDown as bV, moveWidgetToPage as bW, moveWidgetUp as bX, nextPageKey as bY, niceDomain as bZ, niceStep as b_, addPage as ba, applyClientOptions as bb, assignPages as bc, baseColumnSpan as bd, cacheKeyFor as be, coerceOptionValue as bf, createLayoutPersistence as bg, defaultDetailQuery as bh, defaultOptionValue as bi, defineWidget as bj, deriveDetailData as bk, describeUnknownError as bl, emptyTextFor as bm, emptyWidget as bn, enforceLocks as bo, err as bp, failedWidget as bq, fillColumnSpans as br, fillWidthSpans as bs, fillsHeight as bt, fillsWidth as bu, finalizeWidget as bv, fitCount as bw, formatCount as bx, formatPercentChange as by, formatValue as bz, type DetailProviderOptions as c, ok as c0, optionValuesFor as c1, optionsCacheSuffix as c2, pageLayout as c3, pageList as c4, pageOf as c5, pageRoom as c6, pageWidgets as c7, parseDetailQuery as c8, parseLayout as c9, tableDetailData as cA, toggleHidden as cB, toggleMinimized as cC, usesWidthColumns as cD, utf8Length as cE, validateDetailData as cF, visibleWidgets as cG, widgetsFor as cH, widthForSize as cI, withEncoding as cJ, withFallback as cK, withLogging as cL, withPageLayout as cM, withPrefix as cN, withReadCache as cO, withRetry as cP, parseSortValue as ca, percentChange as cb, placeRows as cc, pruneLayout as cd, queryRows as ce, readOnly as cf, removePage as cg, renamePage as ch, resolveDateRange as ci, resolveDetailOptions as cj, resolveOptionValues as ck, resolvePageKey as cl, resolvePayload as cm, resolveTableControls as cn, resolveWidget as co, resolveWidgetLock as cp, resolveWidgetUnapplied as cq, resolveWidgets as cr, restoreWidget as cs, sameOptionValues as ct, serializeDetailQuery as cu, serializeLayout as cv, shareOf as cw, showWidget as cx, sortDefinitions as cy, sortFromOptions as cz, type DetailData as d, type DetailQuery as e, type DashboardLayout as f, type GaugeWidgetData as g, type DetailSort as h, type TextWidgetData as i, type WidgetData as j, type LayoutPersistence as k, type NormalizeOptions as l, type ResolveOptions as m, type WidgetContext as n, type WidgetProviders as o, type Result as p, type WidgetKind as q, type WidgetPayload as r, type AddPageOptions as s, type AlertListItem as t, type BarListItem as u, type BooleanOption as v, type ChoiceOption as w, type ColorOption as x, type ColumnsOption as y, type ConflictPolicy as z };
1474
+ export { type DeltaDirection as $, type AlertListWidgetData as A, type BarListWidgetData as B, type CachedPayload as C, type DashboardWidget as D, type ColumnsOption as E, type ConflictPolicy as F, type GraphWidgetData as G, DATE_RANGE_PRESETS as H, DEFAULT_COMPARISON_LABEL as I, DEFAULT_CURRENCY as J, type KpiWidgetData as K, type Locale as L, DEFAULT_DETAIL_PAGE_SIZE as M, type NiceDomain as N, type OptionValues as O, type PageItem as P, DEFAULT_EMPTY_TEXT as Q, type ResolvedTableControls as R, type StoreScope as S, type TableWidgetData as T, DEFAULT_MAX_LAYOUT_BYTES as U, DEFAULT_PAGE_KEY as V, type WidgetSize as W, DEFAULT_PAGE_ROWS as X, DETAIL_MODES as Y, type DateRangeOption as Z, type DateRangePreset as _, type WidgetFill as a, type TableColumn as a$, type DeltaSentiment as a0, type DetailCell as a1, type DetailColumn as a2, type DetailMode as a3, type DetailPage as a4, type DetailProvider as a5, type DetailProviders as a6, EMPTY_LAYOUT as a7, type EmptyWidget as a8, type EncodingOptions as a9, MIN_WIDGET_WIDTH as aA, type NormalizeSettingsOptions as aB, type NumberOption as aC, OPTION_KEY_PATTERN as aD, type Ok as aE, type OkWidget as aF, type OptionContext as aG, type OptionValue as aH, type PageOptions as aI, type PageRoom as aJ, type PlacedRow as aK, type ProviderOptions as aL, type ResolvedDetailOptions as aM, type ResolvedWidget as aN, type ResolvedWidgetLock as aO, type RetryOptions as aP, type SaveOptions as aQ, type SavedLayout as aR, type SettingsItem as aS, type SortDirection as aT, type SortOption as aU, type StorageAdapter as aV, type StorageLogEvent as aW, type StoreErrorCode as aX, type StoreResult as aY, type StoredValue as aZ, type TableCell as a_, type EnforceLocksOptions as aa, type Err as ab, type ErrorWidget as ac, type FormatOptions as ad, type GraphPoint as ae, type GraphSeries as af, type GridItem as ag, type KpiDelta as ah, type KpiDeltaOptions as ai, LAYOUT_ENVELOPE_VERSION as aj, type LayoutItem as ak, type LayoutPage as al, type LayoutPersistenceOptions as am, type LayoutSettings as an, type LoadedLayout as ao, type LoadingWidget as ap, MAX_DETAIL_PAGE_SIZE as aq, MAX_GRAPH_SERIES as ar, MAX_PAGE_ROWS as as, MAX_PAGE_TITLE_LENGTH as at, MAX_PARSED_PAGES as au, MAX_PARSED_SETTINGS as av, MAX_TEXT_OPTION_LENGTH as aw, MAX_WIDGET_OPTIONS as ax, MAX_WIDGET_TITLE_LENGTH as ay, MAX_WIDGET_WIDTH as az, type WidgetDefinition as b, labelStride as b$, type TextOption as b0, VALUE_FORMATS as b1, type ValueFormat as b2, WIDGET_FILLS as b3, WIDGET_KINDS as b4, WIDGET_OPTION_TYPES as b5, WIDGET_SIZES as b6, WIDTH_COLUMNS as b7, type WidgetCache as b8, type WidgetDataOf as b9, failedWidget as bA, fillColumnSpans as bB, fillWidthSpans as bC, fillsHeight as bD, fillsWidth as bE, finalizeWidget as bF, fitCount as bG, formatCount as bH, formatPercentChange as bI, formatValue as bJ, hasPages as bK, hiddenWidgets as bL, hideWidget as bM, isClientApplied as bN, isColumnKeyFor as bO, isFlexible as bP, isHidden as bQ, isIsoInterval as bR, isMinimized as bS, isOptionsLocked as bT, isTitleInUse as bU, isWidgetEmptyState as bV, isWidgetKind as bW, isWidgetVisibleTo as bX, isWidgetWidth as bY, itemWidth as bZ, kpiDelta as b_, type WidgetDetailOptions as ba, type WidgetEmptyState as bb, type WidgetLock as bc, type WidgetOption as bd, type WidgetProvider as be, type WidgetStatus as bf, type WidgetTableControls as bg, addPage as bh, applyClientOptions as bi, applySettings as bj, assignPages as bk, baseColumnSpan as bl, cacheKeyFor as bm, clearWidgetSettings as bn, coerceOptionValue as bo, createLayoutPersistence as bp, defaultDetailQuery as bq, defaultOptionValue as br, defineWidget as bs, deriveDetailData as bt, describeUnknownError as bu, effectiveDefinitions as bv, emptyTextFor as bw, emptyWidget as bx, enforceLocks as by, err as bz, type DetailProviderOptions as c, widgetsFor as c$, loadingWidgets as c0, memoryAdapter as c1, minimizeWidget as c2, movePage as c3, moveWidget as c4, moveWidgetBy as c5, moveWidgetDown as c6, moveWidgetToPage as c7, moveWidgetUp as c8, nextPageKey as c9, resolveDetailOptions as cA, resolveOptionValues as cB, resolvePageKey as cC, resolvePayload as cD, resolveTableControls as cE, resolveWidget as cF, resolveWidgetLock as cG, resolveWidgetUnapplied as cH, resolveWidgets as cI, restoreWidget as cJ, sameOptionValues as cK, serializeDetailQuery as cL, serializeLayout as cM, serializeSettings as cN, setWidgetSettings as cO, shareOf as cP, showWidget as cQ, sortDefinitions as cR, sortFromOptions as cS, tableDetailData as cT, toggleHidden as cU, toggleMinimized as cV, usesWidthColumns as cW, utf8Length as cX, validateDetailData as cY, visibleWidgets as cZ, widgetOptionValues as c_, niceDomain as ca, niceStep as cb, normalizeLayout as cc, normalizeSettings as cd, normalizeTitle as ce, ok as cf, optionValuesFor as cg, optionValuesFromLayout as ch, optionsCacheSuffix as ci, pageLayout as cj, pageList as ck, pageOf as cl, pageRoom as cm, pageWidgets as cn, parseDetailQuery as co, parseLayout as cp, parseSettings as cq, parseSortValue as cr, percentChange as cs, placeRows as ct, pruneLayout as cu, queryRows as cv, readOnly as cw, removePage as cx, renamePage as cy, resolveDateRange as cz, type DetailData as d, widthForSize as d0, widthRange as d1, widthShareLabel as d2, withEncoding as d3, withFallback as d4, withLogging as d5, withPageLayout as d6, withPrefix as d7, withReadCache as d8, withRetry as d9, type DetailQuery as e, type DashboardLayout as f, type WidgetViewerSettings as g, type WidgetSettingsPatch as h, type GaugeWidgetData as i, type DetailSort as j, type TextWidgetData as k, type WidgetData as l, type LayoutPersistence as m, type NormalizeOptions as n, type ResolveOptions as o, type WidgetContext as p, type WidgetProviders as q, type Result as r, type WidgetKind as s, type WidgetPayload as t, type AddPageOptions as u, type AlertListItem as v, type BarListItem as w, type BooleanOption as x, type ChoiceOption as y, type ColorOption as z };
package/dist/styles.css CHANGED
@@ -935,3 +935,149 @@
935
935
  display: inline-flex;
936
936
  }
937
937
  }
938
+
939
+ /* Options dialog --------------------------------------------------------- */
940
+
941
+ :where(.dwt-options-dialog) {
942
+ margin: auto;
943
+ box-sizing: border-box;
944
+ width: min(520px, 100vw - 32px);
945
+ max-height: calc(100vh - 32px);
946
+ padding: 0;
947
+ overflow: auto;
948
+ color: var(--dwt-text);
949
+ background: var(--dwt-surface);
950
+ border: 1px solid var(--dwt-border);
951
+ border-radius: var(--dwt-radius, 8px);
952
+ font-family: var(--dwt-font);
953
+ }
954
+
955
+ :where(.dwt-options-dialog)::backdrop {
956
+ background: rgba(0, 0, 0, 0.5);
957
+ }
958
+
959
+ :where(.dwt-options) {
960
+ display: flex;
961
+ flex-direction: column;
962
+ gap: 14px;
963
+ padding: 20px;
964
+ }
965
+
966
+ :where(.dwt-options-heading) {
967
+ margin: 0;
968
+ font-size: 1.125rem;
969
+ }
970
+
971
+ :where(.dwt-options-field) {
972
+ display: flex;
973
+ flex-direction: column;
974
+ gap: 4px;
975
+ font-size: 0.875rem;
976
+ }
977
+
978
+ :where(.dwt-options-field label, .dwt-options-group legend) {
979
+ color: var(--dwt-text-secondary);
980
+ }
981
+
982
+ :where(.dwt-options-field input, .dwt-options-field select) {
983
+ box-sizing: border-box;
984
+ max-width: 100%;
985
+ min-height: 32px;
986
+ padding: 4px 8px;
987
+ color: var(--dwt-text);
988
+ background: var(--dwt-surface);
989
+ border: 1px solid var(--dwt-border);
990
+ border-radius: 6px;
991
+ font: inherit;
992
+ }
993
+
994
+ :where(.dwt-options-field input[type='color']) {
995
+ width: 56px;
996
+ padding: 2px;
997
+ }
998
+
999
+ :where(.dwt-options-pair) {
1000
+ display: flex;
1001
+ flex-wrap: wrap;
1002
+ gap: 8px;
1003
+ }
1004
+
1005
+ :where(.dwt-options-check) {
1006
+ display: flex;
1007
+ align-items: center;
1008
+ gap: 8px;
1009
+ font-size: 0.875rem;
1010
+ }
1011
+
1012
+ :where(.dwt-options-group, .dwt-options-columns) {
1013
+ display: flex;
1014
+ flex-direction: column;
1015
+ gap: 12px;
1016
+ margin: 0;
1017
+ padding: 12px;
1018
+ border: 1px solid var(--dwt-border);
1019
+ border-radius: 6px;
1020
+ }
1021
+
1022
+ :where(.dwt-options-columns) {
1023
+ padding: 8px 12px;
1024
+ font-size: 0.875rem;
1025
+ }
1026
+
1027
+ :where(.dwt-options-columns ul) {
1028
+ margin: 0;
1029
+ padding: 0;
1030
+ list-style: none;
1031
+ }
1032
+
1033
+ :where(.dwt-options-columns li) {
1034
+ display: flex;
1035
+ align-items: center;
1036
+ justify-content: space-between;
1037
+ gap: 8px;
1038
+ min-height: 32px;
1039
+ }
1040
+
1041
+ :where(.dwt-options-columns label) {
1042
+ display: flex;
1043
+ align-items: center;
1044
+ gap: 8px;
1045
+ }
1046
+
1047
+ :where(.dwt-options-move) {
1048
+ display: inline-flex;
1049
+ gap: 4px;
1050
+ }
1051
+
1052
+ :where(.dwt-options-error) {
1053
+ margin: 0;
1054
+ color: var(--dwt-bad);
1055
+ font-size: 0.8125rem;
1056
+ }
1057
+
1058
+ :where(.dwt-options-actions) {
1059
+ display: flex;
1060
+ flex-wrap: wrap;
1061
+ align-items: center;
1062
+ gap: 8px;
1063
+ }
1064
+
1065
+ :where(.dwt-options-actions button:disabled) {
1066
+ opacity: 0.5;
1067
+ cursor: default;
1068
+ }
1069
+
1070
+ @media (max-width: 640px) {
1071
+ :where(.dwt-options-dialog) {
1072
+ width: 100vw;
1073
+ max-width: 100vw;
1074
+ max-height: 100vh;
1075
+ border-radius: 0;
1076
+ }
1077
+ }
1078
+
1079
+ :where(.dwt-button-primary) {
1080
+ color: var(--dwt-surface);
1081
+ background: var(--dwt-link);
1082
+ border-color: transparent;
1083
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@richardmcquiston01/dashboard-widgets-toolkit",
3
- "version": "0.13.0",
3
+ "version": "0.14.0",
4
4
  "description": "Framework-agnostic dashboard widget toolkit: typed widget definitions and data payloads (KPI, gauge, table, bar list, alert list, chart), user layout (order, hide, minimise), and React renderers. Bring your own data providers.",
5
5
  "keywords": [
6
6
  "dashboard",